2 /* This is a test program that checks the parsing of instructions with
3 xacquire and xrelease prefixes. The tested insns are, afaics,
4 exactly those listed in the Intel description for the two prefixes
5 ("XACQUIRE/XRELEASE -- Hardware Lock Elision Prefix Hints"). */
9 typedef unsigned long long int ULong
;
11 #define CAT2(_x,_y) _x##_y
12 #define CAT(_x,_y) CAT2(_x,_y)
14 #define GEN_BINARY(_insn) \
15 void CAT(do_,_insn) ( void ) \
17 volatile ULong n = 0x5555555555555555ULL; \
18 ULong some = 0x271831415927D459ULL; \
19 __asm__ __volatile__( \
22 "xacquire lock " #_insn "q $123456789, (%0)" "\n\t" \
23 "xrelease lock " #_insn "q $123456789, (%0)" "\n\t" \
24 "xacquire lock " #_insn "l $0x12345FE, (%0)" "\n\t" \
25 "xrelease lock " #_insn "l $0x12345FE, (%0)" "\n\t" \
26 "xacquire lock " #_insn "w $0x9876, (%0)" "\n\t" \
27 "xrelease lock " #_insn "w $0x9876, (%0)" "\n\t" \
28 "xacquire lock " #_insn "b $0x45, (%0)" "\n\t" \
29 "xrelease lock " #_insn "b $0x45, (%0)" "\n\t" \
30 "xacquire lock " #_insn "q %1, (%0)" "\n\t" \
31 "xrelease lock " #_insn "q %1, (%0)" "\n\t" \
32 "xacquire lock " #_insn "l %k1, (%0)" "\n\t" \
33 "xrelease lock " #_insn "l %k1, (%0)" "\n\t" \
34 "xacquire lock " #_insn "w %w1, (%0)" "\n\t" \
35 "xrelease lock " #_insn "w %w1, (%0)" "\n\t" \
36 "xacquire lock " #_insn "b %b1, (%0)" "\n\t" \
37 "xrelease lock " #_insn "b %b1, (%0)" "\n\t" \
38 : : "r"(&n), "r"(some) : "cc", "memory" \
40 printf("result for '%-3s' is %016llx\n", #_insn, n); \
51 #define GEN_UNARY(_insn) \
52 void CAT(do_,_insn) ( void ) \
54 volatile ULong n = 0x5555555555555555ULL; \
55 __asm__ __volatile__( \
58 "xacquire lock " #_insn "q (%0)" "\n\t" \
59 "xrelease lock " #_insn "q (%0)" "\n\t" \
60 "xacquire lock " #_insn "l (%0)" "\n\t" \
61 "xrelease lock " #_insn "l (%0)" "\n\t" \
62 "xacquire lock " #_insn "w (%0)" "\n\t" \
63 "xrelease lock " #_insn "w (%0)" "\n\t" \
64 "xacquire lock " #_insn "b (%0)" "\n\t" \
65 "xrelease lock " #_insn "b (%0)" "\n\t" \
66 : : "r"(&n) : "cc", "memory" \
68 printf("result for '%-3s' is %016llx\n", #_insn, n); \
78 volatile ULong n
= 0x5555555555555555ULL
;
80 "xacquire lock btcq %1, (%0)" "\n\t"
81 "xacquire lock btcq $57, (%0)" "\n\t"
82 "xrelease lock btcq %1, (%0)" "\n\t"
83 "xrelease lock btcq $55, (%0)" "\n\t"
84 "xacquire lock btcl %k1, (%0)" "\n\t"
85 "xacquire lock btcl $27, (%0)" "\n\t"
86 "xrelease lock btcl %k1, (%0)" "\n\t"
87 "xrelease lock btcl $25, (%0)" "\n\t"
88 "xacquire lock btcw %w1, (%0)" "\n\t"
89 "xacquire lock btcw $12, (%0)" "\n\t"
90 "xrelease lock btcw %w1, (%0)" "\n\t"
91 "xrelease lock btcw $11, (%0)" "\n\t"
92 : : "r"(&n
), "r"(6ULL) : "cc", "memory"
94 printf("result for '%-3s' is %016llx\n", "btc", n
); \
99 volatile ULong n
= 0x5555555555555555ULL
;
100 __asm__
__volatile__(
101 "xacquire lock btrq %1, (%0)" "\n\t"
102 "xacquire lock btrq $57, (%0)" "\n\t"
103 "xrelease lock btrq %1, (%0)" "\n\t"
104 "xrelease lock btrq $55, (%0)" "\n\t"
105 "xacquire lock btrl %k1, (%0)" "\n\t"
106 "xacquire lock btrl $27, (%0)" "\n\t"
107 "xrelease lock btrl %k1, (%0)" "\n\t"
108 "xrelease lock btrl $25, (%0)" "\n\t"
109 "xacquire lock btrw %w1, (%0)" "\n\t"
110 "xacquire lock btrw $12, (%0)" "\n\t"
111 "xrelease lock btrw %w1, (%0)" "\n\t"
112 "xrelease lock btrw $11, (%0)" "\n\t"
113 : : "r"(&n
), "r"(6ULL) : "cc", "memory"
115 printf("result for '%-3s' is %016llx\n", "btr", n
); \
120 volatile ULong n
= 0x5555555555555555ULL
;
121 __asm__
__volatile__(
122 "xacquire lock btsq %1, (%0)" "\n\t"
123 "xacquire lock btsq $57, (%0)" "\n\t"
124 "xrelease lock btsq %1, (%0)" "\n\t"
125 "xrelease lock btsq $55, (%0)" "\n\t"
126 "xacquire lock btsl %k1, (%0)" "\n\t"
127 "xacquire lock btsl $27, (%0)" "\n\t"
128 "xrelease lock btsl %k1, (%0)" "\n\t"
129 "xrelease lock btsl $25, (%0)" "\n\t"
130 "xacquire lock btsw %w1, (%0)" "\n\t"
131 "xacquire lock btsw $12, (%0)" "\n\t"
132 "xrelease lock btsw %w1, (%0)" "\n\t"
133 "xrelease lock btsw $11, (%0)" "\n\t"
134 : : "r"(&n
), "r"(6ULL) : "cc", "memory"
136 printf("result for '%-3s' is %016llx\n", "bts", n
); \
139 void do_cmpxchg ( void )
141 volatile ULong n
= 0x5555555555555555ULL
;
142 ULong some
= 0x271831415927D459ULL
;
143 __asm__
__volatile__(
146 // zero out rax and get the flags in a known state
147 "xorq %%rax, %%rax" "\n\t"
148 "xacquire lock cmpxchgq %1, (%0)" "\n\t"
149 "xrelease lock cmpxchgq %1, (%0)" "\n\t"
150 "xacquire lock cmpxchgl %k1, (%0)" "\n\t"
151 "xrelease lock cmpxchgl %k1, (%0)" "\n\t"
152 "xacquire lock cmpxchgw %w1, (%0)" "\n\t"
153 "xrelease lock cmpxchgw %w1, (%0)" "\n\t"
154 "xacquire lock cmpxchgb %b1, (%0)" "\n\t"
155 "xrelease lock cmpxchgb %b1, (%0)" "\n\t"
156 : : "r"(&n
), "r"(some
) : "cc", "memory", "rax"
158 printf("result for '%-3s' is %016llx\n", "cmpxchg", n
);
161 void do_cmpxchg8b ( void )
163 volatile ULong n
= 0x5555555555555555ULL
;
164 __asm__
__volatile__(
165 "xorq %%rax, %%rax" "\n\t"
166 "xorq %%rdx, %%rdx" "\n\t"
167 "movabsq $0x1122334455667788, %%rcx" "\n\t"
168 "movabsq $0xffeeddccbbaa9988, %%rbx" "\n\t"
169 "xacquire lock cmpxchg8b (%0)" "\n\t"
170 "xrelease lock cmpxchg8b (%0)" "\n\t"
171 : : "r"(&n
) : "cc", "memory", "rax", "rbx", "rcx", "rdx"
173 printf("result for '%-3s' is %016llx\n", "cmpxchg8b", n
);
176 void do_xadd ( void )
178 volatile ULong n
= 0x5555555555555555ULL
;
179 ULong some
= 0x271831415927D459ULL
;
180 __asm__
__volatile__(
183 // zero out rax and get the flags in a known state
184 "xorq %%rax, %%rax" "\n\t"
185 "xacquire lock xaddq %1, (%0)" "\n\t"
186 "xrelease lock xaddq %1, (%0)" "\n\t"
187 "xacquire lock xaddl %k1, (%0)" "\n\t"
188 "xrelease lock xaddl %k1, (%0)" "\n\t"
189 "xacquire lock xaddw %w1, (%0)" "\n\t"
190 "xrelease lock xaddw %w1, (%0)" "\n\t"
191 "xacquire lock xaddb %b1, (%0)" "\n\t"
192 "xrelease lock xaddb %b1, (%0)" "\n\t"
193 : : "r"(&n
), "r"(some
) : "cc", "memory", "rax"
194 // not sure this constraint string is really correct, since %1
195 // is written as well as read, in this case. But I can't figure
196 // out how to tell gcc that.
198 printf("result for '%-3s' is %016llx\n", "xadd", n
);
201 void do_xchg ( void )
203 volatile ULong n
= 0x5555555555555555ULL
;
204 ULong some
= 0x271831415927D459ULL
;
205 __asm__
__volatile__(
208 // zero out rax and get the flags in a known state
209 "xorq %%rax, %%rax" "\n\t"
210 "xacquire lock xchgq %1, (%0)" "\n\t"
211 "xrelease lock xchgq %1, (%0)" "\n\t"
212 "xacquire lock xchgl %k1, (%0)" "\n\t"
213 "xrelease lock xchgl %k1, (%0)" "\n\t"
214 "xacquire lock xchgw %w1, (%0)" "\n\t"
215 "xrelease lock xchgw %w1, (%0)" "\n\t"
216 "xacquire lock xchgb %b1, (%0)" "\n\t"
217 "xrelease lock xchgb %b1, (%0)" "\n\t"
218 : : "r"(&n
), "r"(some
) : "cc", "memory", "rax"
219 // not sure this constraint string is really correct, since %1
220 // is written as well as read, in this case. But I can't figure
221 // out how to tell gcc that.
223 printf("result for '%-3s' is %016llx\n", "xchg", n
);
226 void do_xchg_no_lock ( void )
228 volatile ULong n
= 0x5555555555555555ULL
;
229 ULong some
= 0x271831415927D459ULL
;
230 __asm__
__volatile__(
233 // zero out rax and get the flags in a known state
234 "xorq %%rax, %%rax" "\n\t"
235 "xacquire xchgq %1, (%0)" "\n\t"
236 "xrelease xchgq %1, (%0)" "\n\t"
237 "xacquire xchgl %k1, (%0)" "\n\t"
238 "xrelease xchgl %k1, (%0)" "\n\t"
239 "xacquire xchgw %w1, (%0)" "\n\t"
240 "xrelease xchgw %w1, (%0)" "\n\t"
241 "xacquire xchgb %b1, (%0)" "\n\t"
242 "xrelease xchgb %b1, (%0)" "\n\t"
243 : : "r"(&n
), "r"(some
) : "cc", "memory", "rax"
244 // not sure this constraint string is really correct, since %1
245 // is written as well as read, in this case. But I can't figure
246 // out how to tell gcc that.
248 printf("result for '%-3s' is %016llx\n", "xchg-no-lock", n
);
253 // According to the Intel docs, we only need to allow xrelease here.
254 volatile ULong n
= 0x5555555555555555ULL
;
255 ULong some
= 0x271831415927D459ULL
;
256 __asm__
__volatile__(
258 "xrelease movq %1, 0(%0)" "\n\t"
259 "xrelease movl %k1, 1(%0)" "\n\t"
260 "xrelease movw %w1, 3(%0)" "\n\t"
261 "xrelease movb %b1, 7(%0)" "\n\t"
262 : : "r"(&n
), "r"(some
) : "cc", "memory"
264 printf("result for '%-3s' is %016llx\n", "mov-reg", n
);
265 n
= 0xAAAAAAAAAAAAAAAAULL
;
266 __asm__
__volatile__(
268 "xrelease movq $-0x79876543, 0(%0)" "\n\t"
269 "xrelease movl $0xEFCDAB89, 1(%0)" "\n\t"
270 "xrelease movw $0xF00D, 3(%0)" "\n\t"
271 "xrelease movb $0x42, 7(%0)" "\n\t"
272 : : "r"(&n
) : "cc", "memory"
274 printf("result for '%-3s' is %016llx\n", "mov-imm", n
);