comparison runtime/internal/dmdintrinsic.d @ 606:c7fbcb6b923e

Add implementations for dmd intrinsics. Fixes #92.
author Christian Kamm <kamm incasoftware de>
date Wed, 17 Sep 2008 19:54:37 +0200
parents
children
comparison
equal deleted inserted replaced
605:e235b80c92bc 606:c7fbcb6b923e
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
10 Modified by David Friedman, May 2006
11 Modified by Christian Kamm, Sep 2008
12 */
13
14 /** These functions are built-in intrinsics to the compiler.
15 *
16 Intrinsic functions are functions built in to the compiler,
17 usually to take advantage of specific CPU features that
18 are inefficient to handle via external functions.
19 The compiler's optimizer and code generator are fully
20 integrated in with intrinsic functions, bringing to bear
21 their full power on them.
22 This can result in some surprising speedups.
23 * Macros:
24 * WIKI=Phobos/StdIntrinsic
25 */
26
27 module std.intrinsic;
28
29 /**
30 * Scans the bits in v starting with bit 0, looking
31 * for the first set bit.
32 * Returns:
33 * The bit number of the first bit set.
34 * The return value is undefined if v is zero.
35 */
36 int bsf(uint v)
37 {
38 uint m = 1;
39 uint i;
40 for (i = 0; i < 32; i++,m<<=1) {
41 if (v&m)
42 return i;
43 }
44 return i; // supposed to be undefined
45 }
46
47 /**
48 * Scans the bits in v from the most significant bit
49 * to the least significant bit, looking
50 * for the first set bit.
51 * Returns:
52 * The bit number of the first bit set.
53 * The return value is undefined if v is zero.
54 * Example:
55 * ---
56 * import std.intrinsic;
57 *
58 * int main()
59 * {
60 * uint v;
61 * int x;
62 *
63 * v = 0x21;
64 * x = bsf(v);
65 * printf("bsf(x%x) = %d\n", v, x);
66 * x = bsr(v);
67 * printf("bsr(x%x) = %d\n", v, x);
68 * return 0;
69 * }
70 * ---
71 * Output:
72 * bsf(x21) = 0<br>
73 * bsr(x21) = 5
74 */
75 int bsr(uint v)
76 {
77 uint m = 0x80000000;
78 uint i;
79 for (i = 32; i ; i--,m>>>=1) {
80 if (v&m)
81 return i-1;
82 }
83 return i; // supposed to be undefined
84 }
85
86 /**
87 * Tests the bit.
88 */
89 int bt(uint *p, uint bitnum)
90 {
91 return (p[bitnum / (uint.sizeof*8)] & (1<<(bitnum & ((uint.sizeof*8)-1)))) ? -1 : 0 ;
92 }
93
94 /**
95 * Tests and complements the bit.
96 */
97 int btc(uint *p, uint bitnum)
98 {
99 uint * q = p + (bitnum / (uint.sizeof*8));
100 uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1));
101 int result = *q & mask;
102 *q ^= mask;
103 return result ? -1 : 0;
104 }
105
106 /**
107 * Tests and resets (sets to 0) the bit.
108 */
109 int btr(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
118 /**
119 * Tests and sets the bit.
120 * Params:
121 * p = a non-NULL pointer to an array of uints.
122 * index = a bit number, starting with bit 0 of p[0],
123 * and progressing. It addresses bits like the expression:
124 ---
125 p[index / (uint.sizeof*8)] & (1 << (index & ((uint.sizeof*8) - 1)))
126 ---
127 * Returns:
128 * A non-zero value if the bit was set, and a zero
129 * if it was clear.
130 *
131 * Example:
132 * ---
133 import std.intrinsic;
134
135 int main()
136 {
137 uint array[2];
138
139 array[0] = 2;
140 array[1] = 0x100;
141
142 printf("btc(array, 35) = %d\n", <b>btc</b>(array, 35));
143 printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
144
145 printf("btc(array, 35) = %d\n", <b>btc</b>(array, 35));
146 printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
147
148 printf("bts(array, 35) = %d\n", <b>bts</b>(array, 35));
149 printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
150
151 printf("btr(array, 35) = %d\n", <b>btr</b>(array, 35));
152 printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
153
154 printf("bt(array, 1) = %d\n", <b>bt</b>(array, 1));
155 printf("array = [0]:x%x, [1]:x%x\n", array[0], array[1]);
156
157 return 0;
158 }
159 * ---
160 * Output:
161 <pre>
162 btc(array, 35) = 0
163 array = [0]:x2, [1]:x108
164 btc(array, 35) = -1
165 array = [0]:x2, [1]:x100
166 bts(array, 35) = 0
167 array = [0]:x2, [1]:x108
168 btr(array, 35) = -1
169 array = [0]:x2, [1]:x100
170 bt(array, 1) = -1
171 array = [0]:x2, [1]:x100
172 </pre>
173 */
174 int bts(uint *p, uint bitnum)
175 {
176 uint * q = p + (bitnum / (uint.sizeof*8));
177 uint mask = 1 << (bitnum & ((uint.sizeof*8) - 1));
178 int result = *q & mask;
179 *q |= mask;
180 return result ? -1 : 0;
181 }
182
183
184 /**
185 * Swaps bytes in a 4 byte uint end-to-end, i.e. byte 0 becomes
186 byte 3, byte 1 becomes byte 2, byte 2 becomes byte 1, byte 3
187 becomes byte 0.
188 */
189 uint bswap(uint v)
190 {
191 return ((v&0xFF)<<24)|((v&0xFF00)<<8)|((v&0xFF0000)>>>8)|((v&0xFF000000)>>>24);
192 }
193
194
195 //
196 // Unimplemented functions
197 //
198 /+
199
200 /**
201 * Reads I/O port at port_address.
202 */
203 ubyte inp(uint port_address);
204
205 /**
206 * ditto
207 */
208 ushort inpw(uint port_address);
209
210 /**
211 * ditto
212 */
213 uint inpl(uint port_address);
214
215
216 /**
217 * Writes and returns value to I/O port at port_address.
218 */
219 ubyte outp(uint port_address, ubyte value);
220
221 /**
222 * ditto
223 */
224 ushort outpw(uint port_address, ushort value);
225
226 /**
227 * ditto
228 */
229 uint outpl(uint port_address, uint value);
230
231 +/