-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathinlines.h
149 lines (128 loc) · 3.18 KB
/
inlines.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Abstract: Inlined functions.
// Author: Per Lundberg <per@chaosdev.io>
// I think much of this is ripped from "somewhere" though... so this is probably more GPL than BSD.
// © Copyright 1999 chaos development
#pragma once
// Inlined functions.
// Copy a string.
static inline char *string_copy(char *destination, const char *source)
{
int esi, edi, eax;
asm volatile
("cld\n"
"1: lodsb\n"
"stosb\n"
"testb %%al,%%al\n"
"jne 1b"
: "=&S"(esi), "=&D"(edi), "=&a"(eax)
: "0"(source), "1"(destination)
: "memory");
return destination;
}
// Copy a string, but no more than 'count' bytes.
static inline char *string_copy_max(char *destination,
const char *source,
unsigned int count)
{
int esi, edi, ecx, eax;
asm volatile
("cld\n"
"1: decl %2\n"
"js 2f\n"
"lodsb\n"
"stosb\n"
"testb %%al,%%al\n"
"jne 1b\n"
"rep\n"
"stosb\n"
"2:"
: "=&S"(esi), "=&D"(edi), "=&c"(ecx), "=&a"(eax)
: "0"(source), "1"(destination), "2"(count)
: "memory");
return destination;
}
// Compare two strings. Returns 0 if equal.
static inline int string_compare(const char *string1, const char *string2)
{
int esi, edi;
register int result;
asm volatile
("cld\n"
"1: lodsb\n"
"scasb\n"
"jne 2f\n"
"testb %%al, %%al\n"
"jne 1b\n"
"xorl %%eax, %%eax\n"
"jmp 3f\n"
"2: sbbl %%eax, %%eax\n"
"orb $1, %%al\n"
"3:"
: "=a"(result), "=&S"(esi), "=&D"(edi)
: "1"(string1), "2"(string2));
return result;
}
// Compare two strings, but no more than count characters.
static inline int string_compare_max(const char *string1, const char *string2,
unsigned int count)
{
/* FIXME: Change those names. */
register int __res;
int d0, d1, d2;
asm volatile
("cld\n"
"1: decl %3\n"
"js 2f\n"
"lodsb\n"
"scasb\n"
"jne 3f\n"
"testb %%al, %%al\n"
"jne 1b\n"
"2: xorl %%eax, %%eax\n"
"jmp 4f\n"
"3: sbbl %%eax, %%eax\n"
"orb $1, %%al\n"
"4:"
: "=a"(__res), "=&S"(d0), "=&D"(d1), "=&c"(d2)
: "1"(string1), "2"(string2), "3"(count));
return __res;
}
// Returns the string length.
static inline unsigned int string_length(const char *string)
{
int d0;
register int __res;
asm volatile
("cld\n"
"repne\n"
"scasb\n"
"notl %0\n"
"decl %0"
: "=c"(__res), "=&D"(d0)
: "1"(string), "a"(0), "0"(0xffffffff));
return __res;
}
// Returns the string length, but only if it is less than size.
static inline unsigned int string_length_max(const char *string,
unsigned int count)
{
int d0;
register int __res;
asm volatile
("movl %2, %0\n"
"jmp 2f\n"
"1: cmpb $0, (%0)\n"
"je 3f\n"
"incl %0\n"
"2: decl %1\n"
"cmpl $-1, %1\n"
"jne 1b\n"
"3: subl %2, %0"
: "=a"(__res), "=&d"(d0)
:"c"(string),"1"(count));
return __res;
}
static inline void string_append(char *destination, char *source)
{
string_copy(&destination[string_length(destination)], source);
}