comparison runtime/import/ldc/intrinsics.di @ 1079:4e388d9d0e25

Intrinsics overhaul: - More error checking for pragma(intrinsic) - Properly handle templating for real (use actual nr of bits, not .sizeof * 8) - Template all .i* and .f* intrinsics - The old names are deprecated aliases now I also added a preliminary patch to make tango.math.Math use the new versions. (I think it looks a lot nicer now)
author Frits van Bommel <fvbommel wxs.nl>
date Tue, 10 Mar 2009 04:45:32 +0100
parents 39b7c32cd010
children 34f2fd925de3
comparison
equal deleted inserted replaced
1077:bb57632d27ea 1079:4e388d9d0e25
17 else 17 else
18 { 18 {
19 static assert(false, "This module is only valid for LDC"); 19 static assert(false, "This module is only valid for LDC");
20 } 20 }
21 21
22 version(X86)
23 version = Reals_80Bit;
24 else version(X86_64)
25 version = Reals_80Bit;
26
27 // 22 //
28 // CODE GENERATOR INTRINSICS 23 // CODE GENERATOR INTRINSICS
29 // 24 //
30 25
31 26
104 // The 'llvm.memcpy.*' intrinsics copy a block of memory from the source 99 // The 'llvm.memcpy.*' intrinsics copy a block of memory from the source
105 // location to the destination location. 100 // location to the destination location.
106 // Note that, unlike the standard libc function, the llvm.memcpy.* intrinsics do 101 // Note that, unlike the standard libc function, the llvm.memcpy.* intrinsics do
107 // not return a value, and takes an extra alignment argument. 102 // not return a value, and takes an extra alignment argument.
108 103
109 pragma(intrinsic, "llvm.memcpy.i32") 104 pragma(intrinsic, "llvm.memcpy.i#")
110 void llvm_memcpy_i32(void* dst, void* src, uint len, uint alignment); 105 void llvm_memcpy(T)(void* dst, void* src, T len, uint alignment);
111 106
112 pragma(intrinsic, "llvm.memcpy.i64") 107 deprecated {
113 void llvm_memcpy_i64(void* dst, void* src, ulong len, uint alignment); 108 alias llvm_memcpy!(uint) llvm_memcpy_i32;
109 alias llvm_memcpy!(ulong) llvm_memcpy_i64;
110 }
114 111
115 112
116 // The 'llvm.memmove.*' intrinsics move a block of memory from the source 113 // The 'llvm.memmove.*' intrinsics move a block of memory from the source
117 // location to the destination location. It is similar to the 'llvm.memcpy' 114 // location to the destination location. It is similar to the 'llvm.memcpy'
118 // intrinsic but allows the two memory locations to overlap. 115 // intrinsic but allows the two memory locations to overlap.
119 // Note that, unlike the standard libc function, the llvm.memmove.* intrinsics 116 // Note that, unlike the standard libc function, the llvm.memmove.* intrinsics
120 // do not return a value, and takes an extra alignment argument. 117 // do not return a value, and takes an extra alignment argument.
121 118
122 pragma(intrinsic, "llvm.memmove.i32") 119 pragma(intrinsic, "llvm.memmove.i#")
123 void llvm_memmove_i32(void* dst, void* src, uint len, uint alignment); 120 void llvm_memmove(T)(void* dst, void* src, T len, uint alignment);
124 121
125 pragma(intrinsic, "llvm.memmove.i64") 122 deprecated {
126 void llvm_memmove_i64(void* dst, void* src, ulong len, int alignment); 123 alias llvm_memmove!(uint) llvm_memmove_i32;
124 alias llvm_memmove!(ulong) llvm_memmove_i64;
125 }
127 126
128 127
129 // The 'llvm.memset.*' intrinsics fill a block of memory with a particular byte 128 // The 'llvm.memset.*' intrinsics fill a block of memory with a particular byte
130 // value. 129 // value.
131 // Note that, unlike the standard libc function, the llvm.memset intrinsic does 130 // Note that, unlike the standard libc function, the llvm.memset intrinsic does
132 // not return a value, and takes an extra alignment argument. 131 // not return a value, and takes an extra alignment argument.
133 132
134 pragma(intrinsic, "llvm.memset.i32") 133 pragma(intrinsic, "llvm.memset.i#")
135 void llvm_memset_i32(void* dst, ubyte val, uint len, uint alignment); 134 void llvm_memset(T)(void* dst, ubyte val, T len, uint alignment);
136 135
137 pragma(intrinsic, "llvm.memset.i64") 136 deprecated {
138 void llvm_memset_i64(void* dst, ubyte val, ulong len, uint alignment); 137 alias llvm_memset!(uint) llvm_memset_i32;
138 alias llvm_memset!(ulong) llvm_memset_i64;
139 }
139 140
140 141
141 // The 'llvm.sqrt' intrinsics return the sqrt of the specified operand, 142 // The 'llvm.sqrt' intrinsics return the sqrt of the specified operand,
142 // returning the same value as the libm 'sqrt' functions would. Unlike sqrt in 143 // returning the same value as the libm 'sqrt' functions would. Unlike sqrt in
143 // libm, however, llvm.sqrt has undefined behavior for negative numbers other 144 // libm, however, llvm.sqrt has undefined behavior for negative numbers other
144 // than -0.0 (which allows for better optimization, because there is no need to 145 // than -0.0 (which allows for better optimization, because there is no need to
145 // worry about errno being set). llvm.sqrt(-0.0) is defined to return -0.0 like 146 // worry about errno being set). llvm.sqrt(-0.0) is defined to return -0.0 like
146 // IEEE sqrt. 147 // IEEE sqrt.
147 148
148 pragma(intrinsic, "llvm.sqrt.f32") 149 pragma(intrinsic, "llvm.sqrt.f#")
149 float llvm_sqrt_f32(float val); 150 T llvm_sqrt(T)(T val);
150 151
151 pragma(intrinsic, "llvm.sqrt.f64") 152 deprecated {
152 double llvm_sqrt_f64(double val); 153 alias llvm_sqrt!(float) llvm_sqrt_f32;
153 154 alias llvm_sqrt!(double) llvm_sqrt_f64;
154 version(Reals_80Bit) 155 alias llvm_sqrt!(real) llvm_sqrt_f80; // may not actually be .f80
155 {
156 pragma(intrinsic, "llvm.sqrt.f80")
157 real llvm_sqrt_f80(real val);
158 alias llvm_sqrt_f80 llvm_sqrt_real;
159 }
160 else
161 {
162 pragma(intrinsic, "llvm.sqrt.f64")
163 real llvm_sqrt_real(real val);
164 } 156 }
165 157
166 158
167 // The 'llvm.sin.*' intrinsics return the sine of the operand. 159 // The 'llvm.sin.*' intrinsics return the sine of the operand.
168 160
169 pragma(intrinsic, "llvm.sin.f32") 161 pragma(intrinsic, "llvm.sin.f#")
170 float llvm_sin_f32(float val); 162 T llvm_sin(T)(T val);
171 163
172 pragma(intrinsic, "llvm.sin.f64") 164 deprecated {
173 double llvm_sin_f64(double val); 165 alias llvm_sin!(float) llvm_sin_f32;
174 166 alias llvm_sin!(double) llvm_sin_f64;
175 version(Reals_80Bit) 167 alias llvm_sin!(real) llvm_sin_f80; // may not actually be .f80
176 {
177 pragma(intrinsic, "llvm.sin.f80")
178 real llvm_sin_f80(real val);
179 alias llvm_sin_f80 llvm_sin_real;
180 }
181 else
182 {
183 pragma(intrinsic, "llvm.sin.f64")
184 real llvm_sin_real(real val);
185 } 168 }
186 169
187 170
188 // The 'llvm.cos.*' intrinsics return the cosine of the operand. 171 // The 'llvm.cos.*' intrinsics return the cosine of the operand.
189 172
190 pragma(intrinsic, "llvm.cos.f32") 173 pragma(intrinsic, "llvm.cos.f#")
191 float llvm_cos_f32(float val); 174 T llvm_cos(T)(T val);
192 175
193 pragma(intrinsic, "llvm.cos.f64") 176 deprecated {
194 double llvm_cos_f64(double val); 177 alias llvm_cos!(float) llvm_cos_f32;
195 178 alias llvm_cos!(double) llvm_cos_f64;
196 version(Reals_80Bit) 179 alias llvm_cos!(real) llvm_cos_f80; // may not actually be .f80
197 {
198 pragma(intrinsic, "llvm.cos.f80")
199 real llvm_cos_f80(real val);
200 alias llvm_cos_f80 llvm_cos_real;
201 }
202 else
203 {
204 pragma(intrinsic, "llvm.cos.f64")
205 real llvm_cos_real(real val);
206 } 180 }
207 181
208 182
209 // The 'llvm.powi.*' intrinsics return the first operand raised to the specified 183 // The 'llvm.powi.*' intrinsics return the first operand raised to the specified
210 // (positive or negative) power. The order of evaluation of multiplications is 184 // (positive or negative) power. The order of evaluation of multiplications is
211 // not defined. When a vector of floating point type is used, the second 185 // not defined. When a vector of floating point type is used, the second
212 // argument remains a scalar integer value. 186 // argument remains a scalar integer value.
213 187
214 pragma(intrinsic, "llvm.powi.f32") 188 pragma(intrinsic, "llvm.powi.f#")
215 float llvm_powi_f32(float val, int power); 189 T llvm_powi(T)(T val, int power);
216 190
217 pragma(intrinsic, "llvm.powi.f64") 191 deprecated {
218 double llvm_powi_f64(double val, int power); 192 alias llvm_powi!(float) llvm_powi_f32;
219 193 alias llvm_powi!(double) llvm_powi_f64;
220 version(Reals_80Bit) 194 alias llvm_powi!(real) llvm_powi_f80; // may not actually be .f80
221 {
222 pragma(intrinsic, "llvm.powi.f80")
223 real llvm_powi_f80(real val, int power);
224 alias llvm_powi_f80 llvm_powi_real;
225 }
226 else
227 {
228 pragma(intrinsic, "llvm.powi.f64")
229 real llvm_powi_real(real val, int power);
230 } 195 }
231 196
232 197
233 // The 'llvm.pow.*' intrinsics return the first operand raised to the specified 198 // The 'llvm.pow.*' intrinsics return the first operand raised to the specified
234 // (positive or negative) power. 199 // (positive or negative) power.
235 200
236 pragma(intrinsic, "llvm.pow.f32") 201 pragma(intrinsic, "llvm.pow.f#")
237 float llvm_pow_f32(float val, float power); 202 T llvm_pow(T)(T val, T power);
238 203
239 pragma(intrinsic, "llvm.pow.f64") 204 deprecated {
240 double llvm_pow_f64(double val, double power); 205 alias llvm_pow!(float) llvm_pow_f32;
241 206 alias llvm_pow!(double) llvm_pow_f64;
242 version(Reals_80Bit) 207 alias llvm_pow!(real) llvm_pow_f80; // may not actually be .f80
243 {
244 pragma(intrinsic, "llvm.pow.f80")
245 real llvm_pow_f80(real val, real power);
246 alias llvm_pow_f80 llvm_pow_real;
247 }
248 else
249 {
250 pragma(intrinsic, "llvm.pow.f64")
251 real llvm_pow_real(real val, real power);
252 } 208 }
253 209
254 210
255 // 211 //
256 // BIT MANIPULATION INTRINSICS 212 // BIT MANIPULATION INTRINSICS
259 // The 'llvm.bswap' family of intrinsics is used to byte swap integer values 215 // The 'llvm.bswap' family of intrinsics is used to byte swap integer values
260 // with an even number of bytes (positive multiple of 16 bits). These are 216 // with an even number of bytes (positive multiple of 16 bits). These are
261 // useful for performing operations on data that is not in the target's native 217 // useful for performing operations on data that is not in the target's native
262 // byte order. 218 // byte order.
263 219
264 pragma(intrinsic, "llvm.bswap.i16.i16") 220 pragma(intrinsic, "llvm.bswap.i#.i#")
265 ushort llvm_bswap_i16(ushort val); 221 T llvm_bswap(T)(T val);
266 222
267 pragma(intrinsic, "llvm.bswap.i32.i32") 223 deprecated {
268 uint llvm_bswap_i32(uint val); 224 alias llvm_bswap!(ushort) llvm_bswap_i16;
269 225 alias llvm_bswap!(uint) llvm_bswap_i32;
270 pragma(intrinsic, "llvm.bswap.i64.i64") 226 alias llvm_bswap!(ulong) llvm_bswap_i64;
271 ulong llvm_bswap_i64(ulong val); 227 }
272 228
273 229
274 // The 'llvm.ctpop' family of intrinsics counts the number of bits set in a 230 // The 'llvm.ctpop' family of intrinsics counts the number of bits set in a
275 // value. 231 // value.
276 232
277 pragma(intrinsic, "llvm.ctpop.i8") 233 pragma(intrinsic, "llvm.ctpop.i#")
278 ubyte llvm_ctpop_i8(ubyte src); 234 T llvm_ctpop(T)(T src);
279 235
280 pragma(intrinsic, "llvm.ctpop.i16") 236 deprecated {
281 ushort llvm_ctpop_i16(ushort src); 237 alias llvm_ctpop!(ubyte) llvm_ctpop_i8;
282 238 alias llvm_ctpop!(ushort) llvm_ctpop_i16;
283 pragma(intrinsic, "llvm.ctpop.i32") 239 alias llvm_ctpop!(uint) llvm_ctpop_i32;
284 uint llvm_ctpop_i32(uint src); 240 alias llvm_ctpop!(ulong) llvm_ctpop_i64;
285 241 }
286 pragma(intrinsic, "llvm.ctpop.i64")
287 ulong llvm_ctpop_i64(ulong src);
288 242
289 243
290 // The 'llvm.ctlz' family of intrinsic functions counts the number of leading 244 // The 'llvm.ctlz' family of intrinsic functions counts the number of leading
291 // zeros in a variable. 245 // zeros in a variable.
292 246
293 pragma(intrinsic, "llvm.ctlz.i8") 247 pragma(intrinsic, "llvm.ctlz.i#")
294 ubyte llvm_ctlz_i8(ubyte src); 248 T llvm_ctlz(T)(T src);
295 249
296 pragma(intrinsic, "llvm.ctlz.i16") 250 deprecated {
297 ushort llvm_ctlz_i16(ushort src); 251 alias llvm_ctlz!(ubyte) llvm_ctlz_i8;
298 252 alias llvm_ctlz!(ushort) llvm_ctlz_i16;
299 pragma(intrinsic, "llvm.ctlz.i32") 253 alias llvm_ctlz!(uint) llvm_ctlz_i32;
300 uint llvm_ctlz_i32(uint src); 254 alias llvm_ctlz!(ulong) llvm_ctlz_i64;
301 255 }
302 pragma(intrinsic, "llvm.ctlz.i64")
303 ulong llvm_ctlz_i64(ulong src);
304 256
305 257
306 // The 'llvm.cttz' family of intrinsic functions counts the number of trailing 258 // The 'llvm.cttz' family of intrinsic functions counts the number of trailing
307 // zeros. 259 // zeros.
308 260
309 pragma(intrinsic, "llvm.cttz.i8") 261 pragma(intrinsic, "llvm.cttz.i#")
310 ubyte llvm_cttz_i8(ubyte src); 262 T llvm_cttz(T)(T src);
311 263
312 pragma(intrinsic, "llvm.cttz.i16") 264 deprecated {
313 ushort llvm_cttz_i16(ushort src); 265 alias llvm_cttz!(ubyte) llvm_cttz_i8;
314 266 alias llvm_cttz!(ushort) llvm_cttz_i16;
315 pragma(intrinsic, "llvm.cttz.i32") 267 alias llvm_cttz!(uint) llvm_cttz_i32;
316 uint llvm_cttz_i32(uint src); 268 alias llvm_cttz!(ulong) llvm_cttz_i64;
317 269 }
318 pragma(intrinsic, "llvm.cttz.i64")
319 ulong llvm_cttz_i64(ulong src);
320 270
321 271
322 // The 'llvm.part.select' family of intrinsic functions selects a range of bits 272 // The 'llvm.part.select' family of intrinsic functions selects a range of bits
323 // from an integer value and returns them in the same bit width as the original 273 // from an integer value and returns them in the same bit width as the original
324 // value. 274 // value.
325 275
326 pragma(intrinsic, "llvm.part.select.i8") 276 pragma(intrinsic, "llvm.part.select.i#")
327 ubyte llvm_part_select_i(ubyte val, uint loBit, uint hiBit); 277 T llvm_part_select(T)(T val, uint loBit, uint hiBit);
328 278
329 pragma(intrinsic, "llvm.part.select.i16") 279 deprecated {
330 ushort llvm_part_select_i(ushort val, uint loBit, uint hiBit); 280 alias llvm_part_select!(ubyte) llvm_part_select_i;
331 281 alias llvm_part_select!(ushort) llvm_part_select_i;
332 pragma(intrinsic, "llvm.part.select.i32") 282 alias llvm_part_select!(uint) llvm_part_select_i;
333 uint llvm_part_select_i(uint val, uint loBit, uint hiBit); 283 alias llvm_part_select!(ulong) llvm_part_select_i;
334 284 }
335 pragma(intrinsic, "llvm.part.select.i64")
336 ulong llvm_part_select_i(ulong val, uint loBit, uint hiBit);
337 285
338 286
339 // The 'llvm.part.set' family of intrinsic functions replaces a range of bits 287 // The 'llvm.part.set' family of intrinsic functions replaces a range of bits
340 // in an integer value with another integer value. It returns the integer with 288 // in an integer value with another integer value. It returns the integer with
341 // the replaced bits. 289 // the replaced bits.