Mercurial > projects > ldc
annotate lphobos/std/intrinsic.d @ 650:aa6a0b7968f7
Added test case for bug #100
Removed dubious check for not emitting static private global in other modules without access. This should be handled properly somewhere else, it's causing unresolved global errors for stuff that should work (in MiniD)
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Sun, 05 Oct 2008 17:28:15 +0200 |
parents | 373489eeaf90 |
children | eef8ac26c66c |
rev | line source |
---|---|
1 | 1 |
2 | |
3 // written by Walter Bright | |
4 // www.digitalmars.com | |
5 // Placed into the public domain | |
6 | |
7 /* NOTE: This file has been patched from the original DMD distribution to | |
8 work with the GDC compiler. | |
9 NOTE: This file has been patched from the original GDC distribution to | |
10 work with the LLVMDC compiler. | |
11 | |
12 Modified by David Friedman, May 2006 | |
13 Modified by Tomas Lindquist Olsen, August 2007 | |
14 */ | |
15 | |
16 /** These functions are built-in intrinsics to the compiler. | |
17 * | |
18 Intrinsic functions are functions built in to the compiler, | |
19 usually to take advantage of specific CPU features that | |
20 are inefficient to handle via external functions. | |
21 The compiler's optimizer and code generator are fully | |
22 integrated in with intrinsic functions, bringing to bear | |
23 their full power on them. | |
24 This can result in some surprising speedups. | |
25 * Macros: | |
26 * WIKI=Phobos/StdIntrinsic | |
27 */ | |
28 | |
29 module std.intrinsic; | |
30 | |
31 /** | |
32 * Scans the bits in v starting with bit 0, looking | |
33 * for the first set bit. | |
34 * Returns: | |
35 * The bit number of the first bit set. | |
36 * The return value is undefined if v is zero. | |
37 */ | |
38 version (LLVM) | |
39 int bsf(uint v) | |
40 { | |
41 uint m = 1; | |
42 uint i; | |
43 for (i = 0; i < 32; i++,m<<=1) { | |
44 if (v&m) | |
45 return i; | |
46 } | |
47 return i; // supposed to be undefined | |
48 } | |
49 else | |
50 int bsf(uint v); | |
51 | |
52 /** | |
53 * Scans the bits in v from the most significant bit | |
54 * to the least significant bit, looking | |
55 * for the first set bit. | |
56 * Returns: | |
57 * The bit number of the first bit set. | |
58 * The return value is undefined if v is zero. | |
59 * Example: | |
60 * --- | |
61 * import std.intrinsic; | |
62 * | |
63 * int main() | |
64 * { | |
65 * uint v; | |
66 * int x; | |
67 * | |
68 * v = 0x21; | |
69 * x = bsf(v); | |
70 * printf("bsf(x%x) = %d\n", v, x); | |
71 * x = bsr(v); | |
72 * printf("bsr(x%x) = %d\n", v, x); | |
73 * return 0; | |
74 * } | |
75 * --- | |
76 * Output: | |
77 * bsf(x21) = 0<br> | |
78 * bsr(x21) = 5 | |
79 */ | |
80 version (LLVM) | |
81 int bsr(uint v) | |
82 { | |
83 uint m = 0x80000000; | |
84 uint i; | |
85 for (i = 32; i ; i--,m>>>=1) { | |
86 if (v&m) | |
87 return i-1; | |
88 } | |
89 return i; // supposed to be undefined | |
90 } | |
91 else | |
92 int bsr(uint v); | |
93 | |
94 /** | |
95 * Tests the bit. | |
96 */ | |
97 version (LLVM) | |
98 int bt(uint *p, uint bitnum) | |
99 { | |
100 return (p[bitnum / (uint.sizeof*8)] & (1<<(bitnum & ((uint.sizeof*8)-1)))) ? -1 : 0 ; | |
101 } | |
102 else | |
103 int bt(uint *p, uint bitnum); | |
104 | |
105 /** | |
106 * Tests and complements the bit. | |
107 */ | |
108 version (LLVM) | |
109 int btc(uint *p, uint bitnum) | |
110 { | |
111 uint * q = p + (bitnum / (uint.sizeof*8)); | |
112 uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1)); | |
113 int result = *q & mask; | |
114 *q ^= mask; | |
115 return result ? -1 : 0; | |
116 } | |
117 else | |
118 int btc(uint *p, uint bitnum); | |
119 | |
120 /** | |
121 * Tests and resets (sets to 0) the bit. | |
122 */ | |
123 version (LLVM) | |
124 int btr(uint *p, uint bitnum) | |
125 { | |
126 uint * q = p + (bitnum / (uint.sizeof*8)); | |
127 uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1)); | |
128 int result = *q & mask; | |
129 *q &= ~mask; | |
130 return result ? -1 : 0; | |
131 } | |
132 else | |
133 int btr(uint *p, uint bitnum); | |
134 | |
135 /** | |
136 * Tests and sets the bit. | |
137 * Params: | |
138 * p = a non-NULL pointer to an array of uints. | |
139 * index = a bit number, starting with bit 0 of p[0], | |
140 * and progressing. It addresses bits like the expression: | |
141 --- | |
142 p[index / (uint.sizeof*8)] & (1 << (index & ((uint.sizeof*8) - 1))) | |
143 --- | |
144 * Returns: | |
145 * A non-zero value if the bit was set, and a zero | |
146 * if it was clear. | |
147 * | |
148 * Example: | |
149 * --- | |
150 import std.intrinsic; | |
151 | |
152 int main() | |
153 { | |
154 uint array[2]; | |
155 | |
156 array[0] = 2; | |
157 array[1] = 0x100; | |
158 | |
159 printf("btc(array, 35) = %d\n", <b>btc</b>(array, 35)); | |
160 printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]); | |
161 | |
162 printf("btc(array, 35) = %d\n", <b>btc</b>(array, 35)); | |
163 printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]); | |
164 | |
165 printf("bts(array, 35) = %d\n", <b>bts</b>(array, 35)); | |
166 printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]); | |
167 | |
168 printf("btr(array, 35) = %d\n", <b>btr</b>(array, 35)); | |
169 printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]); | |
170 | |
171 printf("bt(array, 1) = %d\n", <b>bt</b>(array, 1)); | |
172 printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]); | |
173 | |
174 return 0; | |
175 } | |
176 * --- | |
177 * Output: | |
178 <pre> | |
179 btc(array, 35) = 0 | |
180 array = [0]:x2, [1]:x108 | |
181 btc(array, 35) = -1 | |
182 array = [0]:x2, [1]:x100 | |
183 bts(array, 35) = 0 | |
184 array = [0]:x2, [1]:x108 | |
185 btr(array, 35) = -1 | |
186 array = [0]:x2, [1]:x100 | |
187 bt(array, 1) = -1 | |
188 array = [0]:x2, [1]:x100 | |
189 </pre> | |
190 */ | |
191 version (LLVM) | |
192 int bts(uint *p, uint bitnum) | |
193 { | |
194 uint * q = p + (bitnum / (uint.sizeof*8)); | |
195 uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1)); | |
196 int result = *q & mask; | |
197 *q |= mask; | |
198 return result ? -1 : 0; | |
199 } | |
200 else | |
201 int bts(uint *p, uint bitnum); | |
202 | |
203 | |
204 /** | |
205 * Swaps bytes in a 4 byte uint end-to-end, i.e. byte 0 becomes | |
206 byte 3, byte 1 becomes byte 2, byte 2 becomes byte 1, byte 3 | |
207 becomes byte 0. | |
208 */ | |
209 version (LLVM) | |
473
373489eeaf90
Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents:
42
diff
changeset
|
210 pragma(intrinsic, "llvm.bswap.i32") |
1 | 211 uint bswap(uint val); |
212 else | |
213 uint bswap(uint v); | |
214 | |
215 | |
216 /** | |
217 * Reads I/O port at port_address. | |
218 */ | |
219 version (LLVM) | |
220 ubyte inp(uint p) { return 0; } | |
221 else | |
222 ubyte inp(uint port_address); | |
223 | |
224 /** | |
225 * ditto | |
226 */ | |
227 version (LLVM) | |
228 ushort inpw(uint p) { return 0; } | |
229 else | |
230 ushort inpw(uint port_address); | |
231 | |
232 /** | |
233 * ditto | |
234 */ | |
235 version (LLVM) | |
236 uint inpl(uint p) { return 0; } | |
237 else | |
238 uint inpl(uint port_address); | |
239 | |
240 | |
241 /** | |
242 * Writes and returns value to I/O port at port_address. | |
243 */ | |
244 version (LLVM) | |
245 ubyte outp(uint p, ubyte v) { return v; } | |
246 else | |
247 ubyte outp(uint port_address, ubyte value); | |
248 | |
249 /** | |
250 * ditto | |
251 */ | |
252 version (LLVM) | |
253 ushort outpw(uint p, ushort v) { return v; } | |
254 else | |
255 ushort outpw(uint port_address, ushort value); | |
256 | |
257 /** | |
258 * ditto | |
259 */ | |
260 version (LLVM) | |
261 uint outpl(uint p, uint v) { return v; } | |
262 else | |
263 uint outpl(uint port_address, uint value); | |
264 | |
265 |