Merge branch 'master' of https://github.com/guoanwu/fio
[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 unsigned long long get_cpu_clock(void)
30 {
31         unsigned int lo, hi;
32
33         __asm__ __volatile__("rdtsc" : "=a" (lo), "=d" (hi));
34         return ((unsigned long long) hi << 32ULL) | lo;
35 }
36
37 #define ARCH_HAVE_FFZ
38 #define ARCH_HAVE_SSE4_2
39 #define ARCH_HAVE_CPU_CLOCK
40
41 #define RDRAND_LONG     ".byte 0x48,0x0f,0xc7,0xf0"
42 #define RDSEED_LONG     ".byte 0x48,0x0f,0xc7,0xf8"
43 #define RDRAND_RETRY    100
44
45 static inline int arch_rand_long(unsigned long *val)
46 {
47         int ok;
48
49         asm volatile("1: " RDRAND_LONG "\n\t"
50                      "jc 2f\n\t"
51                      "decl %0\n\t"
52                      "jnz 1b\n\t"
53                      "2:"
54                      : "=r" (ok), "=a" (*val)
55                      : "0" (RDRAND_RETRY));
56
57         return ok;
58 }
59
60 static inline int arch_rand_seed(unsigned long *seed)
61 {
62         unsigned char ok;
63
64         asm volatile(RDSEED_LONG "\n\t"
65                         "setc %0"
66                         : "=qm" (ok), "=a" (*seed));
67
68         return 0;
69 }
70
71 #define __do_syscall0(NUM) ({                   \
72         intptr_t rax;                           \
73                                                 \
74         __asm__ volatile(                       \
75                 "syscall"                       \
76                 : "=a"(rax)     /* %rax */      \
77                 : "a"(NUM)      /* %rax */      \
78                 : "rcx", "r11", "memory"        \
79         );                                      \
80         rax;                                    \
81 })
82
83 #define __do_syscall1(NUM, ARG1) ({             \
84         intptr_t rax;                           \
85                                                 \
86         __asm__ volatile(                       \
87                 "syscall"                       \
88                 : "=a"(rax)     /* %rax */      \
89                 : "a"((NUM)),   /* %rax */      \
90                   "D"((ARG1))   /* %rdi */      \
91                 : "rcx", "r11", "memory"        \
92         );                                      \
93         rax;                                    \
94 })
95
96 #define __do_syscall2(NUM, ARG1, ARG2) ({       \
97         intptr_t rax;                           \
98                                                 \
99         __asm__ volatile(                       \
100                 "syscall"                       \
101                 : "=a"(rax)     /* %rax */      \
102                 : "a"((NUM)),   /* %rax */      \
103                   "D"((ARG1)),  /* %rdi */      \
104                   "S"((ARG2))   /* %rsi */      \
105                 : "rcx", "r11", "memory"        \
106         );                                      \
107         rax;                                    \
108 })
109
110 #define __do_syscall3(NUM, ARG1, ARG2, ARG3) ({ \
111         intptr_t rax;                           \
112                                                 \
113         __asm__ volatile(                       \
114                 "syscall"                       \
115                 : "=a"(rax)     /* %rax */      \
116                 : "a"((NUM)),   /* %rax */      \
117                   "D"((ARG1)),  /* %rdi */      \
118                   "S"((ARG2)),  /* %rsi */      \
119                   "d"((ARG3))   /* %rdx */      \
120                 : "rcx", "r11", "memory"        \
121         );                                      \
122         rax;                                    \
123 })
124
125 #define __do_syscall4(NUM, ARG1, ARG2, ARG3, ARG4) ({                   \
126         intptr_t rax;                                                   \
127         register __typeof__(ARG4) __r10 __asm__("r10") = (ARG4);        \
128                                                                         \
129         __asm__ volatile(                                               \
130                 "syscall"                                               \
131                 : "=a"(rax)     /* %rax */                              \
132                 : "a"((NUM)),   /* %rax */                              \
133                   "D"((ARG1)),  /* %rdi */                              \
134                   "S"((ARG2)),  /* %rsi */                              \
135                   "d"((ARG3)),  /* %rdx */                              \
136                   "r"(__r10)    /* %r10 */                              \
137                 : "rcx", "r11", "memory"                                \
138         );                                                              \
139         rax;                                                            \
140 })
141
142 #define __do_syscall5(NUM, ARG1, ARG2, ARG3, ARG4, ARG5) ({             \
143         intptr_t rax;                                                   \
144         register __typeof__(ARG4) __r10 __asm__("r10") = (ARG4);        \
145         register __typeof__(ARG5) __r8 __asm__("r8") = (ARG5);          \
146                                                                         \
147         __asm__ volatile(                                               \
148                 "syscall"                                               \
149                 : "=a"(rax)     /* %rax */                              \
150                 : "a"((NUM)),   /* %rax */                              \
151                   "D"((ARG1)),  /* %rdi */                              \
152                   "S"((ARG2)),  /* %rsi */                              \
153                   "d"((ARG3)),  /* %rdx */                              \
154                   "r"(__r10),   /* %r10 */                              \
155                   "r"(__r8)     /* %r8 */                               \
156                 : "rcx", "r11", "memory"                                \
157         );                                                              \
158         rax;                                                            \
159 })
160
161 #define __do_syscall6(NUM, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) ({       \
162         intptr_t rax;                                                   \
163         register __typeof__(ARG4) __r10 __asm__("r10") = (ARG4);        \
164         register __typeof__(ARG5) __r8 __asm__("r8") = (ARG5);          \
165         register __typeof__(ARG6) __r9 __asm__("r9") = (ARG6);          \
166                                                                         \
167         __asm__ volatile(                                               \
168                 "syscall"                                               \
169                 : "=a"(rax)     /* %rax */                              \
170                 : "a"((NUM)),   /* %rax */                              \
171                   "D"((ARG1)),  /* %rdi */                              \
172                   "S"((ARG2)),  /* %rsi */                              \
173                   "d"((ARG3)),  /* %rdx */                              \
174                   "r"(__r10),   /* %r10 */                              \
175                   "r"(__r8),    /* %r8 */                               \
176                   "r"(__r9)     /* %r9 */                               \
177                 : "rcx", "r11", "memory"                                \
178         );                                                              \
179         rax;                                                            \
180 })
181
182 #define FIO_ARCH_HAS_SYSCALL
183
184 #endif