Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(787)

Side by Side Diff: unittest/AssemblerX8664/Locked.cpp

Issue 1224173006: Adds the x86-64 assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses comments; make format Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « unittest/AssemblerX8664/GPRArith.cpp ('k') | unittest/AssemblerX8664/LowLevel.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 //===- subzero/unittest/AssemblerX8664/Locked.cpp -------------------------===//
2 //
3 // The Subzero Code Generator
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #include "AssemblerX8664/TestUtil.h"
10
11 namespace Ice {
12 namespace X8664 {
13 namespace Test {
14 namespace {
15
16 TEST_F(AssemblerX8664LowLevelTest, Mfence) {
17 __ mfence();
18
19 static constexpr uint8_t ByteCount = 3;
20 ASSERT_EQ(ByteCount, codeBytesSize());
21 verifyBytes<ByteCount>(codeBytes(), 0x0F, 0xAE, 0xF0);
22 }
23
24 TEST_F(AssemblerX8664LowLevelTest, Lock) {
25 __ lock();
26
27 static constexpr uint8_t ByteCount = 1;
28 ASSERT_EQ(ByteCount, codeBytesSize());
29 verifyBytes<ByteCount>(codeBytes(), 0xF0);
30 }
31
32 TEST_F(AssemblerX8664Test, Xchg) {
33 static constexpr uint32_t Mask8 = 0x000000FF;
34 static constexpr uint32_t Mask16 = 0x0000FFFF;
35 static constexpr uint32_t Mask32 = 0xFFFFFFFF;
36
37 #define TestImplAddrReg(Value0, Dst1, Value1, Size) \
38 do { \
39 static constexpr char TestString[] = \
40 "(" #Value0 ", " #Dst1 ", " #Value1 ", " #Size ")"; \
41 const uint32_t T0 = allocateDword(); \
42 const uint32_t V0 = (Value0)&Mask##Size; \
43 const uint32_t V1 = (Value1)&Mask##Size; \
44 \
45 __ mov(IceType_i##Size, Encoded_GPR_##Dst1(), Immediate(Value1)); \
46 __ xchg(IceType_i##Size, dwordAddress(T0), Encoded_GPR_##Dst1()); \
47 __ And(IceType_i32, Encoded_GPR_##Dst1(), Immediate(Mask##Size)); \
48 \
49 AssembledTest test = assemble(); \
50 test.setDwordTo(T0, V0); \
51 test.run(); \
52 \
53 ASSERT_EQ(V0, test.Dst1()) << TestString; \
54 ASSERT_EQ(V1, test.contentsOfDword(T0)) << TestString; \
55 reset(); \
56 } while (0)
57
58 #define TestImplSize(Dst1, Size) \
59 do { \
60 TestImplAddrReg(0xa2b34567, Dst1, 0x0507ddee, Size); \
61 } while (0)
62
63 #define TestImpl(Dst1) \
64 do { \
65 TestImplSize(Dst1, 8); \
66 TestImplSize(Dst1, 16); \
67 TestImplSize(Dst1, 32); \
68 } while (0)
69
70 TestImpl(r1);
71 TestImpl(r2);
72 TestImpl(r3);
73 TestImpl(r4);
74 TestImpl(r5);
75 TestImpl(r6);
76 TestImpl(r7);
77 TestImpl(r8);
78 TestImpl(r10);
79 TestImpl(r11);
80 TestImpl(r12);
81 TestImpl(r13);
82 TestImpl(r14);
83 TestImpl(r15);
84
85 #undef TestImpl
86 #undef TestImplSize
87 #undef TestImplAddrReg
88 }
89
90 TEST_F(AssemblerX8664Test, Xadd) {
91 static constexpr bool NotLocked = false;
92 static constexpr bool Locked = true;
93
94 static constexpr uint32_t Mask8 = 0x000000FF;
95 static constexpr uint32_t Mask16 = 0x0000FFFF;
96 static constexpr uint32_t Mask32 = 0xFFFFFFFF;
97
98 #define TestImplAddrReg(Value0, Dst1, Value1, LockedOrNot, Size) \
99 do { \
100 static constexpr char TestString[] = \
101 "(" #Value0 ", " #Dst1 ", " #Value1 ", " #Size ")"; \
102 const uint32_t T0 = allocateDword(); \
103 const uint32_t V0 = (Value0)&Mask##Size; \
104 const uint32_t V1 = (Value1)&Mask##Size; \
105 \
106 __ mov(IceType_i##Size, Encoded_GPR_##Dst1(), Immediate(Value1)); \
107 __ xadd(IceType_i##Size, dwordAddress(T0), Encoded_GPR_##Dst1(), \
108 LockedOrNot); \
109 __ And(IceType_i32, Encoded_GPR_##Dst1(), Immediate(Mask##Size)); \
110 \
111 AssembledTest test = assemble(); \
112 test.setDwordTo(T0, V0); \
113 test.run(); \
114 \
115 ASSERT_EQ(V0, test.Dst1()) << TestString; \
116 ASSERT_EQ(Mask##Size &(V1 + V0), test.contentsOfDword(T0)) << TestString; \
117 reset(); \
118 } while (0)
119
120 #define TestImplSize(Dst1, Size) \
121 do { \
122 TestImplAddrReg(0xa2b34567, Dst1, 0x0507ddee, NotLocked, Size); \
123 TestImplAddrReg(0xa2b34567, Dst1, 0x0507ddee, Locked, Size); \
124 } while (0)
125
126 #define TestImpl(Dst1) \
127 do { \
128 TestImplSize(Dst1, 8); \
129 TestImplSize(Dst1, 16); \
130 TestImplSize(Dst1, 32); \
131 } while (0)
132
133 TestImpl(r1);
134 TestImpl(r2);
135 TestImpl(r3);
136 TestImpl(r4);
137 TestImpl(r5);
138 TestImpl(r6);
139 TestImpl(r7);
140 TestImpl(r8);
141 TestImpl(r10);
142 TestImpl(r11);
143 TestImpl(r12);
144 TestImpl(r13);
145 TestImpl(r14);
146 TestImpl(r15);
147
148 #undef TestImpl
149 #undef TestImplSize
150 #undef TestImplAddrReg
151 }
152
153 TEST_F(AssemblerX8664LowLevelTest, Xadd) {
154 static constexpr bool NotLocked = false;
155 static constexpr bool Locked = true;
156
157 // Ensures that xadd emits a lock prefix accordingly.
158 {
159 __ xadd(IceType_i8, Address::Absolute(0x1FF00), Encoded_GPR_r14(),
160 NotLocked);
161 static constexpr uint8_t ByteCountNotLocked8 = 8;
162 ASSERT_EQ(ByteCountNotLocked8, codeBytesSize());
163 ASSERT_TRUE(verifyBytes<ByteCountNotLocked8>(codeBytes(), 0x44, 0x0F, 0xC0,
164 0x35, 0x00, 0xFF, 0x01, 0x00));
165 reset();
166
167 __ xadd(IceType_i8, Address::Absolute(0x1FF00), Encoded_GPR_r14(), Locked);
168 static constexpr uint8_t ByteCountLocked8 = 1 + ByteCountNotLocked8;
169 ASSERT_EQ(ByteCountLocked8, codeBytesSize());
170 ASSERT_TRUE(verifyBytes<ByteCountLocked8>(
171 codeBytes(), 0xF0, 0x44, 0x0F, 0xC0, 0x35, 0x00, 0xFF, 0x01, 0x00));
172 reset();
173 }
174
175 {
176 __ xadd(IceType_i16, Address::Absolute(0x1FF00), Encoded_GPR_r14(),
177 NotLocked);
178 static constexpr uint8_t ByteCountNotLocked16 = 9;
179 ASSERT_EQ(ByteCountNotLocked16, codeBytesSize());
180 ASSERT_TRUE(verifyBytes<ByteCountNotLocked16>(
181 codeBytes(), 0x66, 0x44, 0x0F, 0xC1, 0x35, 0x00, 0xFF, 0x01, 0x00));
182 reset();
183
184 __ xadd(IceType_i16, Address::Absolute(0x1FF00), Encoded_GPR_r14(), Locked);
185 static constexpr uint8_t ByteCountLocked16 = 1 + ByteCountNotLocked16;
186 ASSERT_EQ(ByteCountLocked16, codeBytesSize());
187 ASSERT_TRUE(verifyBytes<ByteCountLocked16>(codeBytes(), 0x66, 0xF0, 0x44,
188 0x0F, 0xC1, 0x35, 0x00, 0xFF,
189 0x01, 0x00));
190 reset();
191 }
192
193 {
194 __ xadd(IceType_i32, Address::Absolute(0x1FF00), Encoded_GPR_r14(),
195 NotLocked);
196 static constexpr uint8_t ByteCountNotLocked32 = 8;
197 ASSERT_EQ(ByteCountNotLocked32, codeBytesSize());
198 ASSERT_TRUE(verifyBytes<ByteCountNotLocked32>(
199 codeBytes(), 0x44, 0x0F, 0xC1, 0x35, 0x00, 0xFF, 0x01, 0x00));
200 reset();
201
202 __ xadd(IceType_i32, Address::Absolute(0x1FF00), Encoded_GPR_r14(), Locked);
203 static constexpr uint8_t ByteCountLocked32 = 1 + ByteCountNotLocked32;
204 ASSERT_EQ(ByteCountLocked32, codeBytesSize());
205 ASSERT_TRUE(verifyBytes<ByteCountLocked32>(
206 codeBytes(), 0xF0, 0x44, 0x0F, 0xC1, 0x35, 0x00, 0xFF, 0x01, 0x00));
207 reset();
208 }
209 }
210
211 TEST_F(AssemblerX8664LowLevelTest, EmitSegmentOverride) {
212 #define TestImpl(Prefix) \
213 do { \
214 static constexpr uint8_t ByteCount = 1; \
215 __ emitSegmentOverride(Prefix); \
216 ASSERT_EQ(ByteCount, codeBytesSize()) << Prefix; \
217 ASSERT_TRUE(verifyBytes<ByteCount>(codeBytes(), Prefix)); \
218 reset(); \
219 } while (0)
220
221 TestImpl(0x26);
222 TestImpl(0x2E);
223 TestImpl(0x36);
224 TestImpl(0x3E);
225 TestImpl(0x64);
226 TestImpl(0x65);
227 TestImpl(0x66);
228 TestImpl(0x67);
229
230 #undef TestImpl
231 }
232
233 TEST_F(AssemblerX8664Test, Cmpxchg8b) {
234 static constexpr bool NotLocked = false;
235 static constexpr bool Locked = true;
236
237 #define TestImpl(Value0, Value1, ValueMem, LockedOrNot) \
238 do { \
239 static constexpr char TestString[] = \
240 "(" #Value0 ", " #Value1 ", " #ValueMem ", " #LockedOrNot ")"; \
241 const uint32_t T0 = allocateQword(); \
242 static constexpr uint64_t V0 = ValueMem; \
243 const uint32_t ZeroFlag = allocateDword(); \
244 \
245 __ mov(IceType_i32, Encoded_GPR_eax(), \
246 Immediate(uint64_t(Value0) & 0xFFFFFFFF)); \
247 __ mov(IceType_i32, Encoded_GPR_edx(), Immediate(uint64_t(Value0) >> 32)); \
248 __ mov(IceType_i32, Encoded_GPR_ebx(), \
249 Immediate(uint64_t(Value1) & 0xFFFFFFFF)); \
250 __ mov(IceType_i32, Encoded_GPR_ecx(), Immediate(uint64_t(Value1) >> 32)); \
251 __ cmpxchg8b(dwordAddress(T0), LockedOrNot); \
252 __ setcc(Cond::Br_e, dwordAddress(ZeroFlag)); \
253 \
254 AssembledTest test = assemble(); \
255 test.setQwordTo(T0, V0); \
256 test.setDwordTo(ZeroFlag, uint32_t(0xFF)); \
257 test.run(); \
258 \
259 if (V0 == (Value0)) { \
260 ASSERT_EQ(uint64_t(Value1), test.contentsOfQword(T0)) << TestString; \
261 ASSERT_EQ(1u, test.contentsOfDword(ZeroFlag)) << TestString; \
262 } else { \
263 ASSERT_EQ(uint64_t(ValueMem) & 0xFFFFFFFF, test.eax()) << TestString; \
264 ASSERT_EQ((uint64_t(ValueMem) >> 32) & 0xFFFFFFFF, test.edx()) \
265 << TestString; \
266 ASSERT_EQ(0u, test.contentsOfDword(ZeroFlag)) << TestString; \
267 } \
268 reset(); \
269 } while (0)
270
271 TestImpl(0x98987676543210ull, 0x1, 0x98987676543210ull, NotLocked);
272 TestImpl(0x98987676543210ull, 0x1, 0x98987676543210ull, Locked);
273 TestImpl(0x98987676543210ull, 0x1, 0x98987676543211ull, NotLocked);
274 TestImpl(0x98987676543210ull, 0x1, 0x98987676543211ull, Locked);
275
276 #undef TestImpl
277 }
278
279 TEST_F(AssemblerX8664LowLevelTest, Cmpxchg8b) {
280 static constexpr bool NotLocked = false;
281 static constexpr bool Locked = true;
282
283 // Ensures that cmpxchg8b emits a lock prefix accordingly.
284 __ cmpxchg8b(Address::Absolute(0x1FF00), NotLocked);
285 static constexpr uint8_t ByteCountNotLocked = 7;
286 ASSERT_EQ(ByteCountNotLocked, codeBytesSize());
287 ASSERT_TRUE(verifyBytes<ByteCountNotLocked>(codeBytes(), 0x0F, 0xC7, 0x0D,
288 0x00, 0xFF, 0x01, 0x00));
289 reset();
290
291 __ cmpxchg8b(Address::Absolute(0x1FF00), Locked);
292 static constexpr uint8_t ByteCountLocked = 1 + ByteCountNotLocked;
293 ASSERT_EQ(ByteCountLocked, codeBytesSize());
294 ASSERT_TRUE(verifyBytes<ByteCountLocked>(codeBytes(), 0xF0, 0x0F, 0xC7, 0x0D,
295 0x00, 0xFF, 0x01, 0x00));
296 reset();
297 }
298
299 TEST_F(AssemblerX8664Test, Cmpxchg) {
300 static constexpr bool NotLocked = false;
301 static constexpr bool Locked = true;
302
303 static constexpr uint32_t Mask8 = 0x000000FF;
304 static constexpr uint32_t Mask16 = 0x0000FFFF;
305 static constexpr uint32_t Mask32 = 0xFFFFFFFF;
306
307 #define TestImplAddrReg(Value0, Src, Value1, ValueMem, LockedOrNot, Size) \
308 do { \
309 static constexpr char TestString[] = \
310 "(" #Value0 ", " #Src ", " #Value1 ", " #ValueMem ", " #LockedOrNot \
311 ", " #Size ")"; \
312 const uint32_t T0 = allocateDword(); \
313 static constexpr uint32_t V0 = (ValueMem)&Mask##Size; \
314 const uint32_t ZeroFlag = allocateDword(); \
315 \
316 __ mov(IceType_i##Size, Encoded_GPR_eax(), \
317 Immediate((Value0)&Mask##Size)); \
318 __ mov(IceType_i##Size, Encoded_GPR_##Src(), \
319 Immediate((Value1)&Mask##Size)); \
320 __ cmpxchg(IceType_i##Size, dwordAddress(T0), Encoded_GPR_##Src(), \
321 LockedOrNot); \
322 __ setcc(Cond::Br_e, dwordAddress(ZeroFlag)); \
323 \
324 AssembledTest test = assemble(); \
325 test.setDwordTo(T0, V0); \
326 test.setDwordTo(ZeroFlag, uint32_t(0xFF)); \
327 test.run(); \
328 \
329 if (V0 == (Mask##Size & (Value0))) { \
330 ASSERT_EQ(uint32_t((Value1)&Mask##Size), test.contentsOfDword(T0)) \
331 << TestString; \
332 ASSERT_EQ(1u, test.contentsOfDword(ZeroFlag)) << TestString; \
333 } else { \
334 ASSERT_EQ(uint32_t((ValueMem)&Mask##Size), test.eax()) << TestString; \
335 ASSERT_EQ(0u, test.contentsOfDword(ZeroFlag)) << TestString; \
336 } \
337 reset(); \
338 } while (0)
339
340 #define TestImplValue(Value0, Src, Value1, ValueMem, LockedOrNot) \
341 do { \
342 TestImplAddrReg(Value0, Src, Value1, ValueMem, LockedOrNot, 8); \
343 TestImplAddrReg(Value0, Src, Value1, ValueMem, LockedOrNot, 16); \
344 TestImplAddrReg(Value0, Src, Value1, ValueMem, LockedOrNot, 32); \
345 } while (0)
346
347 #define TestImpl(Src, LockedOrNot) \
348 do { \
349 TestImplValue(0xFFFFFFFF, Src, 0x1, 0xFFFFFFFF, LockedOrNot); \
350 TestImplValue(0x0FFF0F0F, Src, 0x1, 0xFFFFFFFF, LockedOrNot); \
351 } while (0)
352
353 TestImpl(r2, Locked);
354 TestImpl(r2, NotLocked);
355 TestImpl(r3, Locked);
356 TestImpl(r3, NotLocked);
357 TestImpl(r4, Locked);
358 TestImpl(r4, NotLocked);
359 TestImpl(r5, Locked);
360 TestImpl(r5, NotLocked);
361 TestImpl(r6, Locked);
362 TestImpl(r6, NotLocked);
363 TestImpl(r7, Locked);
364 TestImpl(r7, NotLocked);
365 TestImpl(r8, Locked);
366 TestImpl(r8, NotLocked);
367 TestImpl(r10, Locked);
368 TestImpl(r10, NotLocked);
369 TestImpl(r11, Locked);
370 TestImpl(r11, NotLocked);
371 TestImpl(r12, Locked);
372 TestImpl(r12, NotLocked);
373 TestImpl(r13, Locked);
374 TestImpl(r13, NotLocked);
375 TestImpl(r14, Locked);
376 TestImpl(r14, NotLocked);
377 TestImpl(r15, Locked);
378 TestImpl(r15, NotLocked);
379
380 #undef TestImpl
381 #undef TestImplValue
382 #undef TestImplAddrReg
383 }
384
385 TEST_F(AssemblerX8664LowLevelTest, Cmpxchg) {
386 static constexpr bool NotLocked = false;
387 static constexpr bool Locked = true;
388
389 // Ensures that cmpxchg emits a lock prefix accordingly.
390 {
391 __ cmpxchg(IceType_i8, Address::Absolute(0x1FF00), Encoded_GPR_r14(),
392 NotLocked);
393 static constexpr uint8_t ByteCountNotLocked8 = 8;
394 ASSERT_EQ(ByteCountNotLocked8, codeBytesSize());
395 ASSERT_TRUE(verifyBytes<ByteCountNotLocked8>(codeBytes(), 0x44, 0x0F, 0xB0,
396 0x35, 0x00, 0xFF, 0x01, 0x00));
397 reset();
398
399 __ cmpxchg(IceType_i8, Address::Absolute(0x1FF00), Encoded_GPR_r14(),
400 Locked);
401 static constexpr uint8_t ByteCountLocked8 = 1 + ByteCountNotLocked8;
402 ASSERT_EQ(ByteCountLocked8, codeBytesSize());
403 ASSERT_TRUE(verifyBytes<ByteCountLocked8>(
404 codeBytes(), 0xF0, 0x44, 0x0F, 0xB0, 0x35, 0x00, 0xFF, 0x01, 0x00));
405 reset();
406 }
407
408 {
409 __ cmpxchg(IceType_i16, Address::Absolute(0x1FF00), Encoded_GPR_r14(),
410 NotLocked);
411 static constexpr uint8_t ByteCountNotLocked16 = 9;
412 ASSERT_EQ(ByteCountNotLocked16, codeBytesSize());
413 ASSERT_TRUE(verifyBytes<ByteCountNotLocked16>(
414 codeBytes(), 0x66, 0x44, 0x0F, 0xB1, 0x35, 0x00, 0xFF, 0x01, 0x00));
415 reset();
416
417 __ cmpxchg(IceType_i16, Address::Absolute(0x1FF00), Encoded_GPR_r14(),
418 Locked);
419 static constexpr uint8_t ByteCountLocked16 = 1 + ByteCountNotLocked16;
420 ASSERT_EQ(ByteCountLocked16, codeBytesSize());
421 ASSERT_TRUE(verifyBytes<ByteCountLocked16>(codeBytes(), 0x66, 0xF0, 0x44,
422 0x0F, 0xB1, 0x35, 0x00, 0xFF,
423 0x01, 0x00));
424 reset();
425 }
426
427 {
428 __ cmpxchg(IceType_i32, Address::Absolute(0x1FF00), Encoded_GPR_r14(),
429 NotLocked);
430 static constexpr uint8_t ByteCountNotLocked32 = 8;
431 ASSERT_EQ(ByteCountNotLocked32, codeBytesSize());
432 ASSERT_TRUE(verifyBytes<ByteCountNotLocked32>(
433 codeBytes(), 0x44, 0x0F, 0xB1, 0x35, 0x00, 0xFF, 0x01, 0x00));
434 reset();
435
436 __ cmpxchg(IceType_i32, Address::Absolute(0x1FF00), Encoded_GPR_r14(),
437 Locked);
438 static constexpr uint8_t ByteCountLocked32 = 1 + ByteCountNotLocked32;
439 ASSERT_EQ(ByteCountLocked32, codeBytesSize());
440 ASSERT_TRUE(verifyBytes<ByteCountLocked32>(
441 codeBytes(), 0xF0, 0x44, 0x0F, 0xB1, 0x35, 0x00, 0xFF, 0x01, 0x00));
442 reset();
443 }
444 }
445
446 } // end of anonymous namespace
447 } // end of namespace Test
448 } // end of namespace X8664
449 } // end of namespace Ice
OLDNEW
« no previous file with comments | « unittest/AssemblerX8664/GPRArith.cpp ('k') | unittest/AssemblerX8664/LowLevel.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698