1 /// X86 platform specific utils
2 module mecca.platform.x86;
3 
4 // Licensed under the Boost license. Full copyright information in the AUTHORS file
5 
6 /// Size in bytes of a single cache line
7 enum CACHE_LINE_SIZE = 64;
8 
9 version(LDC) {
10     public import ldc.intrinsics: readTSC = llvm_readcyclecounter;
11 }
12 else version (D_InlineAsm_X86_64) {
13     ulong readTSC() nothrow @nogc @safe {
14         asm nothrow @nogc @safe {
15             naked;
16             rdtsc;         // EDX(hi):EAX(lo)
17             shl RDX, 32;
18             or RAX, RDX;   // RAX |= (RDX << 32)
19             ret;
20         }
21     }
22 }
23 else {
24     static assert (false, "RDTSC not supported on platform");
25 }
26 
27 unittest {
28     assert (readTSC() != 0);
29 }
30 
31 /+version(LDC) {
32     private pure pragma(LDC_intrinsic, "llvm.x86.sse42.crc32.64.64") ulong crc32(ulong crc, ulong v) nothrow @safe @nogc;
33 }
34 
35 uint crc32c(ulong crc, ulong v) @nogc nothrow @system {
36     if (__ctfe) {
37         return 0;
38     } else {
39         version(LDC) {
40             return cast(uint)crc32(crc, v);
41         } else {
42             return 0;
43         }
44     }
45 }
46 
47 unittest {
48     ulong crc = 0x000011115555AAAA;
49     ulong v = 0x88889999EEEE3333;
50 
51     assert(crc32c(crc, v) == 0x16f57621);
52     v = 0x00000000EEEE3333;
53     assert(crc32c(crc, v) == 0x8e5d3bf9);
54 }
55 +/
56 
57 version (LDC) {
58     import ldc.intrinsics;
59 
60     void prefetch(const void* p) pure nothrow @trusted @nogc {
61         pragma(inline, true);
62         llvm_prefetch(cast(void*)p, 0 /*read*/, 3 /*very local*/, 1 /*data*/);
63     }
64 }
65 else version (D_InlineAsm_X86_64) {
66     void prefetch(const void* p /* RDI */) pure nothrow @safe @nogc {
67         pragma(inline, true);
68         asm pure nothrow @safe @nogc {
69             naked;
70             prefetcht0 [RDI];
71             ret;
72         }
73     }
74 }
75 else {
76     static assert (false, "prefetch not supported");
77 }
78 
79 unittest {
80     // prefetching will not segfault
81     prefetch(null);
82 
83     ulong[1000] x = void;
84     prefetch(&x[800]);
85 }
86 
87 
88