1 module bc.core.intrinsics;
2 
3 version(LDC)
4 {
5     import ldc.intrinsics: llvm_expect;
6     import ldc.gccbuiltins_x86;
7     public import core.simd;
8 
9     enum LDC_with_SSE42 = __traits(targetHasFeature, "sse4.2");
10 
11     // some definition aliases to commonly used names
12     alias __m128i = int4;
13 
14     // some used methods aliases
15     alias _expect = llvm_expect;
16     alias _mm_loadu_si128 = loadUnaligned!__m128i;
17     alias _mm_cmpestri = __builtin_ia32_pcmpestri128;
18 
19     // These specify the type of data that we're comparing.
20     enum _SIDD_UBYTE_OPS            = 0x00;
21     enum _SIDD_UWORD_OPS            = 0x01;
22     enum _SIDD_SBYTE_OPS            = 0x02;
23     enum _SIDD_SWORD_OPS            = 0x03;
24 
25     // These specify the type of comparison operation.
26     enum _SIDD_CMP_EQUAL_ANY        = 0x00;
27     enum _SIDD_CMP_RANGES           = 0x04;
28     enum _SIDD_CMP_EQUAL_EACH       = 0x08;
29     enum _SIDD_CMP_EQUAL_ORDERED    = 0x0c;
30 
31     // These are used in _mm_cmpXstri() to specify the return.
32     enum _SIDD_LEAST_SIGNIFICANT    = 0x00;
33     enum _SIDD_MOST_SIGNIFICANT     = 0x40;
34 
35     // These macros are used in _mm_cmpXstri() to specify the return.
36     enum _SIDD_BIT_MASK             = 0x00;
37     enum _SIDD_UNIT_MASK            = 0x40;
38 }
39 else version(GNU)
40 {
41     import gcc.builtins: __builtin_expect, __builtin_clong;
42 
43     ///
44     T _expect(T)(in T val, in T expected_val) if (__traits(isIntegral, T))
45     {
46         static if (T.sizeof <= __builtin_clong.sizeof)
47             return cast(T) __builtin_expect(val, expected_val);
48         else
49             return val;
50     }
51 
52     enum LDC_with_SSE42 = false;
53 }
54 else
55 {
56     ///
57     T _expect(T)(T val, T expected_val) if (__traits(isIntegral, T))
58     {
59         return val;
60     }
61 
62     enum LDC_with_SSE42 = false;
63 }
64 
65 version (unittest) pragma(msg, "SSE: ", LDC_with_SSE42);
66 
67 // Workarounds for betterC
68 version (D_BetterC)
69 {
70     pragma(mangle, "_D4core8lifetime16testEmplaceChunkFNaNbNiNfAvmmZv")
71     nothrow @nogc @safe pure void testEmplaceChunk(void[] chunk, size_t typeSize, size_t typeAlignment) {}
72 
73     version (DigitalMars)
74     {
75         // see: https://issues.dlang.org/show_bug.cgi?id=19946
76         extern (C) nothrow @nogc:
77 
78         short* _memset16(short *p, short value, size_t count)
79         {
80             short *pstart = p;
81             short *ptop;
82 
83             for (ptop = &p[count]; p < ptop; p++)
84                 *p = value;
85             return pstart;
86         }
87 
88         int*_memset32(int *p, int value, size_t count)
89         {
90             version (D_InlineAsm_X86)
91             {
92                 asm
93                 {
94                     mov     EDI,p           ;
95                     mov     EAX,value       ;
96                     mov     ECX,count       ;
97                     mov     EDX,EDI         ;
98                     rep                     ;
99                     stosd                   ;
100                     mov     EAX,EDX         ;
101                 }
102             }
103             else
104             {
105                 int *pstart = p;
106                 int *ptop;
107 
108                 for (ptop = &p[count]; p < ptop; p++)
109                     *p = value;
110                 return pstart;
111             }
112         }
113     }
114 
115     version (assert)
116     {
117         version (LDC)
118         {
119             // See: https://github.com/ldc-developers/ldc/issues/2425
120             // See: https://forum.dlang.org/post/heksucpdamkgwnztyitr@forum.dlang.org
121             extern(C)
122             nothrow @nogc
123             void _d_array_slice_copy(void* dst, size_t dstlen, void* src, size_t srclen, size_t elemsz)
124             {
125                 import ldc.intrinsics : llvm_memcpy;
126                 llvm_memcpy!size_t(dst, src, dstlen * elemsz, 0);
127             }
128         }
129     }
130 }