comparison druntime/import/ldc/intrinsics.di @ 759:d3eb054172f9

Added copy of druntime from DMD 2.020 modified for LDC.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 11 Nov 2008 01:52:37 +0100
parents runtime/import/ldc/intrinsics.di@4ac97ec7c18e
children
comparison
equal deleted inserted replaced
758:f04dde6e882c 759:d3eb054172f9
1 /*
2 * This module holds declarations to LLVM intrinsics.
3 *
4 * See the LLVM language reference for more information:
5 *
6 * - http://llvm.org/docs/LangRef.html#intrinsics
7 *
8 */
9
10 module ldc.intrinsics;
11
12 // Check for the right compiler
13 version(LDC)
14 {
15 // OK
16 }
17 else
18 {
19 static assert(false, "This module is only valid for LDC");
20 }
21
22 //
23 // CODE GENERATOR INTRINSICS
24 //
25
26
27 // The 'llvm.returnaddress' intrinsic attempts to compute a target-specific value indicating the return address of the current function or one of its callers.
28
29 pragma(intrinsic, "llvm.returnaddress")
30 void* llvm_returnaddress(uint level);
31
32
33 // The 'llvm.frameaddress' intrinsic attempts to return the target-specific frame pointer value for the specified stack frame.
34
35 pragma(intrinsic, "llvm.frameaddress")
36 void* llvm_frameaddress(uint level);
37
38
39 // The 'llvm.stacksave' intrinsic is used to remember the current state of the function stack, for use with llvm.stackrestore. This is useful for implementing language features like scoped automatic variable sized arrays in C99.
40
41 pragma(intrinsic, "llvm.stacksave")
42 void* llvm_stacksave();
43
44
45 // The 'llvm.stackrestore' intrinsic is used to restore the state of the function stack to the state it was in when the corresponding llvm.stacksave intrinsic executed. This is useful for implementing language features like scoped automatic variable sized arrays in C99.
46
47 pragma(intrinsic, "llvm.stackrestore")
48 void llvm_stackrestore(void* ptr);
49
50
51 // The 'llvm.prefetch' intrinsic is a hint to the code generator to insert a prefetch instruction if supported; otherwise, it is a noop. Prefetches have no effect on the behavior of the program but can change its performance characteristics.
52
53 pragma(intrinsic, "llvm.prefetch")
54 void llvm_prefetch(void* ptr, uint rw, uint locality);
55
56
57 // The 'llvm.pcmarker' intrinsic is a method to export a Program Counter (PC) in a region of code to simulators and other tools. The method is target specific, but it is expected that the marker will use exported symbols to transmit the PC of the marker. The marker makes no guarantees that it will remain with any specific instruction after optimizations. It is possible that the presence of a marker will inhibit optimizations. The intended use is to be inserted after optimizations to allow correlations of simulation runs.
58
59 pragma(intrinsic, "llvm.pcmarker")
60 void llvm_pcmarker(uint id);
61
62
63 // The 'llvm.readcyclecounter' intrinsic provides access to the cycle counter register (or similar low latency, high accuracy clocks) on those targets that support it. On X86, it should map to RDTSC. On Alpha, it should map to RPCC. As the backing counters overflow quickly (on the order of 9 seconds on alpha), this should only be used for small timings.
64
65 pragma(intrinsic, "llvm.readcyclecounter")
66 ulong readcyclecounter();
67
68
69
70
71 //
72 // STANDARD C LIBRARY INTRINSICS
73 //
74
75
76 // The 'llvm.memcpy.*' intrinsics copy a block of memory from the source location to the destination location.
77 // Note that, unlike the standard libc function, the llvm.memcpy.* intrinsics do not return a value, and takes an extra alignment argument.
78
79 pragma(intrinsic, "llvm.memcpy.i32")
80 void llvm_memcpy_i32(void* dst, void* src, uint len, uint alignment);
81 pragma(intrinsic, "llvm.memcpy.i64")
82 void llvm_memcpy_i64(void* dst, void* src, ulong len, uint alignment);
83
84
85 // The 'llvm.memmove.*' intrinsics move a block of memory from the source location to the destination location. It is similar to the 'llvm.memcpy' intrinsic but allows the two memory locations to overlap.
86 // Note that, unlike the standard libc function, the llvm.memmove.* intrinsics do not return a value, and takes an extra alignment argument.
87
88 pragma(intrinsic, "llvm.memmove.i32")
89 void llvm_memmove_i32(void* dst, void* src, uint len, uint alignment);
90 pragma(intrinsic, "llvm.memmove.i64")
91 void llvm_memmove_i64(void* dst, void* src, ulong len, int alignment);
92
93
94 // The 'llvm.memset.*' intrinsics fill a block of memory with a particular byte value.
95 // Note that, unlike the standard libc function, the llvm.memset intrinsic does not return a value, and takes an extra alignment argument.
96
97 pragma(intrinsic, "llvm.memset.i32")
98 void llvm_memset_i32(void* dst, ubyte val, uint len, uint alignment);
99 pragma(intrinsic, "llvm.memset.i64")
100 void llvm_memset_i64(void* dst, ubyte val, ulong len, uint alignment);
101
102
103 // The 'llvm.sqrt' intrinsics return the sqrt of the specified operand, returning the same value as the libm 'sqrt' functions would. Unlike sqrt in libm, however, llvm.sqrt has undefined behavior for negative numbers other than -0.0 (which allows for better optimization, because there is no need to worry about errno being set). llvm.sqrt(-0.0) is defined to return -0.0 like IEEE sqrt.
104
105 pragma(intrinsic, "llvm.sqrt.f32")
106 float llvm_sqrt_f32(float val);
107 pragma(intrinsic, "llvm.sqrt.f64")
108 double llvm_sqrt_f64(double val);
109 version(X86)
110 {
111 pragma(intrinsic, "llvm.sqrt.f80")
112 real llvm_sqrt_f80(real val);
113 }
114
115 version(X86_64)
116 {
117 pragma(intrinsic, "llvm.sqrt.f80")
118 real llvm_sqrt_f80(real val);
119 }
120
121
122 // The 'llvm.sin.*' intrinsics return the sine of the operand.
123
124 pragma(intrinsic, "llvm.sin.f32")
125 float llvm_sin_f32(float val);
126 pragma(intrinsic, "llvm.sin.f64")
127 double llvm_sin_f64(double val);
128 version(X86)
129 {
130 pragma(intrinsic, "llvm.sin.f80")
131 real llvm_sin_f80(real val);
132 }
133
134 version(X86_64)
135 {
136 pragma(intrinsic, "llvm.sin.f80")
137 real llvm_sin_f80(real val);
138 }
139
140
141 // The 'llvm.cos.*' intrinsics return the cosine of the operand.
142
143 pragma(intrinsic, "llvm.cos.f32")
144 float llvm_cos_f32(float val);
145 pragma(intrinsic, "llvm.cos.f64")
146 double llvm_cos_f64(double val);
147 version(X86)
148 {
149 pragma(intrinsic, "llvm.cos.f80")
150 real llvm_cos_f80(real val);
151 }
152
153 version(X86_64)
154 {
155 pragma(intrinsic, "llvm.cos.f80")
156 real llvm_cos_f80(real val);
157 }
158
159
160 // The 'llvm.powi.*' intrinsics return the first operand raised to the specified (positive or negative) power. The order of evaluation of multiplications is not defined. When a vector of floating point type is used, the second argument remains a scalar integer value.
161
162 pragma(intrinsic, "llvm.powi.f32")
163 float llvm_powi_f32(float val, int power);
164
165 pragma(intrinsic, "llvm.powi.f64")
166 double llvm_powi_f64(double val, int power);
167 version(X86)
168 {
169 pragma(intrinsic, "llvm.powi.f80")
170 real llvm_powi_f80(real val, int power);
171 }
172
173 version(X86_64)
174 {
175 pragma(intrinsic, "llvm.powi.f80")
176 real llvm_powi_f80(real val, int power);
177 }
178
179 // The 'llvm.pow.*' intrinsics return the first operand raised to the specified (positive or negative) power.
180
181 pragma(intrinsic, "llvm.pow.f32")
182 float llvm_pow_f32(float val, float power);
183
184 pragma(intrinsic, "llvm.pow.f64")
185 double llvm_pow_f64(double val, double power);
186 version(X86)
187 {
188 pragma(intrinsic, "llvm.pow.f80")
189 real llvm_pow_f80(real val, real power);
190 }
191
192 version(X86_64)
193 {
194 pragma(intrinsic, "llvm.pow.f80")
195 real llvm_pow_f80(real val, real power);
196 }
197
198
199 //
200 // BIT MANIPULATION INTRINSICS
201 //
202
203 // The 'llvm.bswap' family of intrinsics is used to byte swap integer values with an even number of bytes (positive multiple of 16 bits). These are useful for performing operations on data that is not in the target's native byte order.
204
205 pragma(intrinsic, "llvm.bswap.i16.i16")
206 ushort llvm_bswap_i16(ushort val);
207
208 pragma(intrinsic, "llvm.bswap.i32.i32")
209 uint llvm_bswap_i32(uint val);
210
211 pragma(intrinsic, "llvm.bswap.i64.i64")
212 ulong llvm_bswap_i64(ulong val);
213
214
215 // The 'llvm.ctpop' family of intrinsics counts the number of bits set in a value.
216
217 pragma(intrinsic, "llvm.ctpop.i8")
218 ubyte llvm_ctpop_i8(ubyte src);
219
220 pragma(intrinsic, "llvm.ctpop.i16")
221 ushort llvm_ctpop_i16(ushort src);
222
223 pragma(intrinsic, "llvm.ctpop.i32")
224 uint llvm_ctpop_i32(uint src);
225
226 pragma(intrinsic, "llvm.ctpop.i64")
227 ulong llvm_ctpop_i64(ulong src);
228
229
230 // The 'llvm.ctlz' family of intrinsic functions counts the number of leading zeros in a variable.
231
232 pragma(intrinsic, "llvm.ctlz.i8")
233 ubyte llvm_ctlz_i8(ubyte src);
234
235 pragma(intrinsic, "llvm.ctlz.i16")
236 ushort llvm_ctlz_i16(ushort src);
237
238 pragma(intrinsic, "llvm.ctlz.i32")
239 uint llvm_ctlz_i32(uint src);
240
241 pragma(intrinsic, "llvm.ctlz.i64")
242 ulong llvm_ctlz_i64(ulong src);
243
244
245 // The 'llvm.cttz' family of intrinsic functions counts the number of trailing zeros.
246
247 pragma(intrinsic, "llvm.cttz.i8")
248 ubyte llvm_cttz_i8(ubyte src);
249
250 pragma(intrinsic, "llvm.cttz.i16")
251 ushort llvm_cttz_i16(ushort src);
252
253 pragma(intrinsic, "llvm.cttz.i32")
254 uint llvm_cttz_i32(uint src);
255
256 pragma(intrinsic, "llvm.cttz.i64")
257 ulong llvm_cttz_i64(ulong src);
258
259
260 // The 'llvm.part.select' family of intrinsic functions selects a range of bits from an integer value and returns them in the same bit width as the original value.
261
262 pragma(intrinsic, "llvm.part.select.i8")
263 ubyte llvm_part_select_i(ubyte val, uint loBit, uint hiBit);
264
265 pragma(intrinsic, "llvm.part.select.i16")
266 ushort llvm_part_select_i(ushort val, uint loBit, uint hiBit);
267
268 pragma(intrinsic, "llvm.part.select.i32")
269 uint llvm_part_select_i(uint val, uint loBit, uint hiBit);
270
271 pragma(intrinsic, "llvm.part.select.i64")
272 ulong llvm_part_select_i(ulong val, uint loBit, uint hiBit);
273
274
275 // The 'llvm.part.set' family of intrinsic functions replaces a range of bits in an integer value with another integer value. It returns the integer with the replaced bits.
276
277 // TODO
278 // declare i17 @llvm.part.set.i17.i9 (i17 %val, i9 %repl, i32 %lo, i32 %hi)
279 // declare i29 @llvm.part.set.i29.i9 (i29 %val, i9 %repl, i32 %lo, i32 %hi)
280
281
282
283
284 //
285 // ATOMIC OPERATIONS AND SYNCHRONIZATION INTRINSICS
286 //
287
288 // The llvm.memory.barrier intrinsic guarantees ordering between specific pairs of memory access types.
289
290 pragma(intrinsic, "llvm.memory.barrier")
291 void llvm_memory_barrier(bool ll, bool ls, bool sl, bool ss, bool device);
292
293 // This loads a value in memory and compares it to a given value. If they are equal, it stores a new value into the memory.
294
295 pragma(intrinsic, "llvm.atomic.cmp.swap.i#.p0i#")
296 T llvm_atomic_cmp_swap(T)(T* ptr, T cmp, T val);
297
298 // This intrinsic loads the value stored in memory at ptr and yields the value from memory. It then stores the value in val in the memory at ptr.
299
300 pragma(intrinsic, "llvm.atomic.swap.i#.p0i#")
301 T llvm_atomic_swap(T)(T* ptr, T val);
302
303 // This intrinsic adds delta to the value stored in memory at ptr. It yields the original value at ptr.
304
305 pragma(intrinsic, "llvm.atomic.load.add.i#.p0i#")
306 T llvm_atomic_load_add(T)(T* ptr, T val);
307
308 // This intrinsic subtracts delta to the value stored in memory at ptr. It yields the original value at ptr.
309
310 pragma(intrinsic, "llvm.atomic.load.sub.i#.p0i#")
311 T llvm_atomic_load_sub(T)(T* ptr, T val);
312
313 // These intrinsics bitwise the operation (and, nand, or, xor) delta to the value stored in memory at ptr. It yields the original value at ptr.
314
315 pragma(intrinsic, "llvm.atomic.load.and.i#.p0i#")
316 T llvm_atomic_load_and(T)(T* ptr, T val);
317 pragma(intrinsic, "llvm.atomic.load.nand.i#.p0i#")
318 T llvm_atomic_load_nand(T)(T* ptr, T val);
319 pragma(intrinsic, "llvm.atomic.load.or.i#.p0i#")
320 T llvm_atomic_load_or(T)(T* ptr, T val);
321 pragma(intrinsic, "llvm.atomic.load.xor.i#.p0i#")
322 T llvm_atomic_load_xor(T)(T* ptr, T val);
323
324 // These intrinsics takes the signed or unsigned minimum or maximum of delta and the value stored in memory at ptr. It yields the original value at ptr.
325
326 pragma(intrinsic, "llvm.atomic.load.max.i#.p0i#")
327 T llvm_atomic_load_max(T)(T* ptr, T val);
328 pragma(intrinsic, "llvm.atomic.load.min.i#.p0i#")
329 T llvm_atomic_load_min(T)(T* ptr, T val);
330 pragma(intrinsic, "llvm.atomic.load.umax.i#.p0i#")
331 T llvm_atomic_load_umax(T)(T* ptr, T val);
332 pragma(intrinsic, "llvm.atomic.load.umin.i#.p0i#")
333 T llvm_atomic_load_umin(T)(T* ptr, T val);
334
335 //
336 // GENERAL INTRINSICS
337 //
338
339
340 // This intrinsics is lowered to the target dependent trap instruction. If the target does not have a trap instruction, this intrinsic will be lowered to the call of the abort() function.
341
342 pragma(intrinsic, "llvm.trap")
343 void llvm_trap();