comparison lphobos/std/intrinsic.d @ 1:c53b6e3fe49a trunk

[svn r5] Initial commit. Most things are very rough.
author lindquist
date Sat, 01 Sep 2007 21:43:27 +0200
parents
children 0b9b286b67b6
comparison
equal deleted inserted replaced
0:a9e71648e74d 1:c53b6e3fe49a
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)
210 pragma(LLVM_internal, "intrinsic", "llvm.bswap.i32.i32")
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