docs: update for new data placement options
[fio.git] / arch / arch-x86_64.h
1 #ifndef ARCH_X86_64_H
2 #define ARCH_X86_64_H
3
4 static inline void do_cpuid(unsigned int *eax, unsigned int *ebx,
5                             unsigned int *ecx, unsigned int *edx)
6 {
7         asm volatile("cpuid"
8                 : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
9                 : "0" (*eax), "2" (*ecx)
10                 : "memory");
11 }
12
13 #include "arch-x86-common.h" /* IWYU pragma: export */
14
15 #define FIO_ARCH        (arch_x86_64)
16
17 #define FIO_HUGE_PAGE           2097152
18
19 #define nop             __asm__ __volatile__("rep;nop": : :"memory")
20 #define read_barrier()  __asm__ __volatile__("":::"memory")
21 #define write_barrier() __asm__ __volatile__("":::"memory")
22
23 static inline unsigned long arch_ffz(unsigned long bitmask)
24 {
25         __asm__("bsf %1,%0" :"=r" (bitmask) :"r" (~bitmask));
26         return bitmask;
27 }
28
29 static inline void tsc_barrier(void)
30 {
31         __asm__ __volatile__("mfence":::"memory");
32 }
33
34 static inline unsigned long long get_cpu_clock(void)
35 {
36         unsigned int lo, hi;
37
38         __asm__ __volatile__("rdtsc" : "=a" (lo), "=d" (hi));
39         return ((unsigned long long) hi << 32ULL) | lo;
40 }
41
42 #define ARCH_HAVE_FFZ
43 #define ARCH_HAVE_SSE4_2
44 #define ARCH_HAVE_CPU_CLOCK
45
46 #define RDRAND_LONG     ".byte 0x48,0x0f,0xc7,0xf0"
47 #define RDSEED_LONG     ".byte 0x48,0x0f,0xc7,0xf8"
48 #define RDRAND_RETRY    100
49
50 static inline int arch_rand_long(unsigned long *val)
51 {
52         int ok;
53
54         asm volatile("1: " RDRAND_LONG "\n\t"
55                      "jc 2f\n\t"
56                      "decl %0\n\t"
57                      "jnz 1b\n\t"
58                      "2:"
59                      : "=r" (ok), "=a" (*val)
60                      : "0" (RDRAND_RETRY));
61
62         return ok;
63 }
64
65 static inline int arch_rand_seed(unsigned long *seed)
66 {
67         unsigned char ok;
68
69         asm volatile(RDSEED_LONG "\n\t"
70                         "setc %0"
71                         : "=qm" (ok), "=a" (*seed));
72
73         return 0;
74 }
75
76 #define __do_syscall0(NUM) ({                   \
77         intptr_t rax;                           \
78                                                 \
79         __asm__ volatile(                       \
80                 "syscall"                       \
81                 : "=a"(rax)     /* %rax */      \
82                 : "a"(NUM)      /* %rax */      \
83                 : "rcx", "r11", "memory"        \
84         );                                      \
85         rax;                                    \
86 })
87
88 #define __do_syscall1(NUM, ARG1) ({             \
89         intptr_t rax;                           \
90                                                 \
91         __asm__ volatile(                       \
92                 "syscall"                       \
93                 : "=a"(rax)     /* %rax */      \
94                 : "a"((NUM)),   /* %rax */      \
95                   "D"((ARG1))   /* %rdi */      \
96                 : "rcx", "r11", "memory"        \
97         );                                      \
98         rax;                                    \
99 })
100
101 #define __do_syscall2(NUM, ARG1, ARG2) ({       \
102         intptr_t rax;                           \
103                                                 \
104         __asm__ volatile(                       \
105                 "syscall"                       \
106                 : "=a"(rax)     /* %rax */      \
107                 : "a"((NUM)),   /* %rax */      \
108                   "D"((ARG1)),  /* %rdi */      \
109                   "S"((ARG2))   /* %rsi */      \
110                 : "rcx", "r11", "memory"        \
111         );                                      \
112         rax;                                    \
113 })
114
115 #define __do_syscall3(NUM, ARG1, ARG2, ARG3) ({ \
116         intptr_t rax;                           \
117                                                 \
118         __asm__ volatile(                       \
119                 "syscall"                       \
120                 : "=a"(rax)     /* %rax */      \
121                 : "a"((NUM)),   /* %rax */      \
122                   "D"((ARG1)),  /* %rdi */      \
123                   "S"((ARG2)),  /* %rsi */      \
124                   "d"((ARG3))   /* %rdx */      \
125                 : "rcx", "r11", "memory"        \
126         );                                      \
127         rax;                                    \
128 })
129
130 #define __do_syscall4(NUM, ARG1, ARG2, ARG3, ARG4) ({                   \
131         intptr_t rax;                                                   \
132         register __typeof__(ARG4) __r10 __asm__("r10") = (ARG4);        \
133                                                                         \
134         __asm__ volatile(                                               \
135                 "syscall"                                               \
136                 : "=a"(rax)     /* %rax */                              \
137                 : "a"((NUM)),   /* %rax */                              \
138                   "D"((ARG1)),  /* %rdi */                              \
139                   "S"((ARG2)),  /* %rsi */                              \
140                   "d"((ARG3)),  /* %rdx */                              \
141                   "r"(__r10)    /* %r10 */                              \
142                 : "rcx", "r11", "memory"                                \
143         );                                                              \
144         rax;                                                            \
145 })
146
147 #define __do_syscall5(NUM, ARG1, ARG2, ARG3, ARG4, ARG5) ({             \
148         intptr_t rax;                                                   \
149         register __typeof__(ARG4) __r10 __asm__("r10") = (ARG4);        \
150         register __typeof__(ARG5) __r8 __asm__("r8") = (ARG5);          \
151                                                                         \
152         __asm__ volatile(                                               \
153                 "syscall"                                               \
154                 : "=a"(rax)     /* %rax */                              \
155                 : "a"((NUM)),   /* %rax */                              \
156                   "D"((ARG1)),  /* %rdi */                              \
157                   "S"((ARG2)),  /* %rsi */                              \
158                   "d"((ARG3)),  /* %rdx */                              \
159                   "r"(__r10),   /* %r10 */                              \
160                   "r"(__r8)     /* %r8 */                               \
161                 : "rcx", "r11", "memory"                                \
162         );                                                              \
163         rax;                                                            \
164 })
165
166 #define __do_syscall6(NUM, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) ({       \
167         intptr_t rax;                                                   \
168         register __typeof__(ARG4) __r10 __asm__("r10") = (ARG4);        \
169         register __typeof__(ARG5) __r8 __asm__("r8") = (ARG5);          \
170         register __typeof__(ARG6) __r9 __asm__("r9") = (ARG6);          \
171                                                                         \
172         __asm__ volatile(                                               \
173                 "syscall"                                               \
174                 : "=a"(rax)     /* %rax */                              \
175                 : "a"((NUM)),   /* %rax */                              \
176                   "D"((ARG1)),  /* %rdi */                              \
177                   "S"((ARG2)),  /* %rsi */                              \
178                   "d"((ARG3)),  /* %rdx */                              \
179                   "r"(__r10),   /* %r10 */                              \
180                   "r"(__r8),    /* %r8 */                               \
181                   "r"(__r9)     /* %r9 */                               \
182                 : "rcx", "r11", "memory"                                \
183         );                                                              \
184         rax;                                                            \
185 })
186
187 #define FIO_ARCH_HAS_SYSCALL
188
189 #endif