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

Side by Side Diff: unittest/AssemblerX8664/DataMov.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/ControlFlow.cpp ('k') | unittest/AssemblerX8664/GPRArith.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/DataMov.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(AssemblerX8664Test, MovRegImm) {
17 static constexpr uint32_t Mask8 = 0x000000FF;
18 static constexpr uint32_t Mask16 = 0x0000FFFF;
19 static constexpr uint32_t Mask32 = 0xFFFFFFFF;
20
21 #define MovRegImm(Reg, Suffix, Size) \
22 do { \
23 static constexpr char TestString[] = "(" #Reg ", " #Size ")"; \
24 static constexpr uint32_t Value = (0xABCD7645) & Mask##Size; \
25 static constexpr uint32_t Marker = 0xBEEFFEEB; \
26 __ mov(IceType_i32, Encoded_GPR_##Reg##q(), Immediate(Marker)); \
27 __ mov(IceType_i##Size, Encoded_GPR_##Reg##Suffix(), Immediate(Value)); \
28 \
29 AssembledTest test = assemble(); \
30 test.run(); \
31 \
32 ASSERT_EQ(Value, test.Reg##Suffix()) << TestString; \
33 ASSERT_EQ((Marker & ~Mask##Size) | Value, test.Reg##d()) << TestString; \
34 reset(); \
35 } while (0)
36
37 #define TestImpl(Reg) \
38 do { \
39 MovRegImm(Reg, l, 8); \
40 MovRegImm(Reg, w, 16); \
41 MovRegImm(Reg, d, 32); \
42 /* MovRegImm64 not implemented */ \
43 } while (0)
44
45 TestImpl(r1);
46 TestImpl(r2);
47 TestImpl(r3);
48 TestImpl(r4);
49 TestImpl(r5);
50 TestImpl(r6);
51 TestImpl(r7);
52 TestImpl(r8);
53 TestImpl(r10);
54 TestImpl(r11);
55 TestImpl(r12);
56 TestImpl(r13);
57 TestImpl(r14);
58 TestImpl(r15);
59
60 #undef TestImpl
61 #undef MovRegImm
62 }
63
64 TEST_F(AssemblerX8664Test, MovMemImm) {
65 const uint32_t T0 = allocateDword();
66 constexpr uint32_t ExpectedT0 = 0x00111100ul;
67 const uint32_t T1 = allocateDword();
68 constexpr uint32_t ExpectedT1 = 0x00222200ul;
69 const uint32_t T2 = allocateDword();
70 constexpr uint32_t ExpectedT2 = 0x03333000ul;
71 const uint32_t T3 = allocateDword();
72 constexpr uint32_t ExpectedT3 = 0x00444400ul;
73
74 __ mov(IceType_i32, dwordAddress(T0), Immediate(ExpectedT0));
75 __ mov(IceType_i16, dwordAddress(T1), Immediate(ExpectedT1));
76 __ mov(IceType_i8, dwordAddress(T2), Immediate(ExpectedT2));
77 __ mov(IceType_i32, dwordAddress(T3), Immediate(ExpectedT3));
78
79 AssembledTest test = assemble();
80 test.run();
81 EXPECT_EQ(0ul, test.eax());
82 EXPECT_EQ(0ul, test.ebx());
83 EXPECT_EQ(0ul, test.ecx());
84 EXPECT_EQ(0ul, test.edx());
85 EXPECT_EQ(0ul, test.edi());
86 EXPECT_EQ(0ul, test.esi());
87 EXPECT_EQ(ExpectedT0, test.contentsOfDword(T0));
88 EXPECT_EQ(ExpectedT1 & 0xFFFF, test.contentsOfDword(T1));
89 EXPECT_EQ(ExpectedT2 & 0xFF, test.contentsOfDword(T2));
90 EXPECT_EQ(ExpectedT3, test.contentsOfDword(T3));
91 }
92
93 TEST_F(AssemblerX8664Test, MovMemReg) {
94 static constexpr uint64_t Mask8 = 0x00000000000000FF;
95 static constexpr uint64_t Mask16 = 0x000000000000FFFF;
96 static constexpr uint64_t Mask32 = 0x00000000FFFFFFFF;
97 static constexpr uint64_t Mask64 = 0xFFFFFFFFFFFFFFFF;
98
99 #define TestMemReg(Src, Size) \
100 do { \
101 static constexpr char TestString[] = "(" #Src ", " #Size ")"; \
102 static constexpr uint32_t Value = 0x1a4d567e & Mask##Size; \
103 static constexpr uint64_t Marker = 0xD0DA33EEBEEFFEEB; \
104 const uint32_t T0 = allocateQword(); \
105 \
106 __ mov(IceType_i32, Encoded_GPR_##Src(), Immediate(Value)); \
107 __ mov(IceType_i##Size, dwordAddress(T0), Encoded_GPR_##Src()); \
108 \
109 AssembledTest test = assemble(); \
110 test.setQwordTo(T0, Marker); \
111 test.run(); \
112 \
113 ASSERT_EQ((Marker & ~Mask##Size) | Value, test.contentsOfQword(T0)) \
114 << TestString; \
115 reset(); \
116 } while (0)
117
118 #define TestImpl(Src) \
119 do { \
120 TestMemReg(Src, 8); \
121 TestMemReg(Src, 16); \
122 TestMemReg(Src, 32); \
123 TestMemReg(Src, 64); \
124 } while (0)
125
126 TestImpl(r1);
127 TestImpl(r2);
128 TestImpl(r3);
129 TestImpl(r4);
130 TestImpl(r5);
131 TestImpl(r6);
132 TestImpl(r7);
133 TestImpl(r8);
134 TestImpl(r10);
135 TestImpl(r11);
136 TestImpl(r12);
137 TestImpl(r13);
138 TestImpl(r14);
139 TestImpl(r15);
140
141 #undef TestImpl
142 #undef TestMemReg
143 }
144
145 TEST_F(AssemblerX8664Test, MovRegReg) {
146 static constexpr uint64_t Mask8 = 0x00000000000000FFull;
147 static constexpr uint64_t Mask16 = 0x000000000000FFFFull;
148 static constexpr uint64_t Mask32 = 0x00000000FFFFFFFFull;
149 static constexpr uint64_t Mask64 = 0xFFFFFFFFFFFFFFFFull;
150
151 static constexpr uint64_t MaskResult8 = 0x00000000000000FFull;
152 static constexpr uint64_t MaskResult16 = 0x000000000000FFFFull;
153 static constexpr uint64_t MaskResult32 = 0xFFFFFFFFFFFFFFFFull;
154 static constexpr uint64_t MaskResult64 = 0xFFFFFFFFFFFFFFFFull;
155
156 #define TestRegReg(Dst, Src, Suffix, Size) \
157 do { \
158 static constexpr char TestString[] = \
159 "(" #Dst ", " #Src ", " #Suffix ", " #Size ")"; \
160 const uint8_t T0 = allocateQword(); \
161 static constexpr uint64_t Value = 0xA4DD30Af86CCE321ull & Mask##Size; \
162 const uint8_t T1 = allocateQword(); \
163 static constexpr uint64_t Marker = 0xC0FFEEA0BEEFFEEFull; \
164 \
165 __ mov(IceType_i64, Encoded_GPR_##Src(), dwordAddress(T0)); \
166 __ mov(IceType_i64, Encoded_GPR_##Dst(), dwordAddress(T1)); \
167 __ mov(IceType_i##Size, Encoded_GPR_##Dst(), Encoded_GPR_##Src()); \
168 \
169 AssembledTest test = assemble(); \
170 test.setQwordTo(T0, Value); \
171 test.setQwordTo(T1, Marker); \
172 test.run(); \
173 \
174 ASSERT_EQ((Marker & ~MaskResult##Size) | Value, test.Dst()) << TestString; \
175 ASSERT_EQ(Value, test.Dst##Suffix()) << TestString; \
176 reset(); \
177 } while (0)
178
179 #define TestImpl(Dst, Src) \
180 do { \
181 TestRegReg(Dst, Src, l, 8); \
182 TestRegReg(Dst, Src, w, 16); \
183 TestRegReg(Dst, Src, d, 32); \
184 TestRegReg(Dst, Src, q, 64); \
185 } while (0)
186
187 TestImpl(r1, r2);
188 TestImpl(r2, r3);
189 TestImpl(r3, r4);
190 TestImpl(r4, r5);
191 TestImpl(r5, r6);
192 TestImpl(r6, r7);
193 TestImpl(r7, r8);
194 TestImpl(r8, r10);
195 TestImpl(r10, r11);
196 TestImpl(r11, r12);
197 TestImpl(r12, r13);
198 TestImpl(r13, r14);
199 TestImpl(r14, r15);
200 TestImpl(r15, r1);
201
202 #undef TestImpl
203 #undef TestRegReg
204 }
205
206 TEST_F(AssemblerX8664Test, MovRegMem) {
207 static constexpr uint64_t Mask8 = 0x00000000000000FFull;
208 static constexpr uint64_t Mask16 = 0x000000000000FFFFull;
209 static constexpr uint64_t Mask32 = 0x00000000FFFFFFFFull;
210 static constexpr uint64_t Mask64 = 0xFFFFFFFFFFFFFFFFull;
211
212 static constexpr uint64_t MaskResult8 = ~0x00000000000000FFull;
213 static constexpr uint64_t MaskResult16 = ~0x000000000000FFFFull;
214 static constexpr uint64_t MaskResult32 = ~0xFFFFFFFFFFFFFFFFull;
215 static constexpr uint64_t MaskResult64 = ~0xFFFFFFFFFFFFFFFFull;
216
217 #define TestRegAddr(Dst, Suffix, Size) \
218 do { \
219 static constexpr char TestString[] = \
220 "(" #Dst ", Addr, " #Suffix ", " #Size ")"; \
221 const uint8_t T0 = allocateQword(); \
222 static constexpr uint64_t Value = 0xA4DD30Af86CCE321ull & Mask##Size; \
223 const uint8_t T1 = allocateQword(); \
224 static constexpr uint64_t Marker = 0xC0FFEEA0BEEFFEEFull; \
225 \
226 __ mov(IceType_i64, Encoded_GPR_##Dst(), dwordAddress(T1)); \
227 __ mov(IceType_i##Size, Encoded_GPR_##Dst(), dwordAddress(T0)); \
228 \
229 AssembledTest test = assemble(); \
230 test.setQwordTo(T0, Value); \
231 test.setQwordTo(T1, Marker); \
232 test.run(); \
233 \
234 ASSERT_EQ((Marker & MaskResult##Size) | Value, test.Dst()) << TestString; \
235 ASSERT_EQ(Value, test.Dst##Suffix()) << TestString; \
236 reset(); \
237 } while (0)
238
239 #define TestImpl(Dst) \
240 do { \
241 TestRegAddr(Dst, l, 8); \
242 TestRegAddr(Dst, w, 16); \
243 TestRegAddr(Dst, d, 32); \
244 TestRegAddr(Dst, q, 64); \
245 } while (0)
246
247 TestImpl(r1);
248 TestImpl(r2);
249 TestImpl(r3);
250 TestImpl(r4);
251 TestImpl(r5);
252 TestImpl(r6);
253 TestImpl(r7);
254 TestImpl(r8);
255 TestImpl(r10);
256 TestImpl(r11);
257 TestImpl(r12);
258 TestImpl(r13);
259 TestImpl(r14);
260 TestImpl(r15);
261
262 #undef TestImpl
263 #undef TestRegAddr
264 }
265
266 TEST_F(AssemblerX8664Test, Movzx) {
267 static constexpr uint32_t Mask8 = 0x000000FF;
268 static constexpr uint32_t Mask16 = 0x0000FFFF;
269
270 #define TestImplRegReg(Dst, Src, Suffix, Size) \
271 do { \
272 const uint32_t T0 = allocateDqword(); \
273 static constexpr uint64_t V0 = 0xAAAAAAAAAAAAAAAAull; \
274 static constexpr uint32_t Value = (0xBEEF) & Mask##Size; \
275 __ mov(IceType_i64, Encoded_GPR_##Dst##q(), dwordAddress(T0)); \
276 __ mov(IceType_i##Size, Encoded_GPR_##Src##Suffix(), Immediate(Value)); \
277 __ movzx(IceType_i##Size, Encoded_GPR_##Dst##d(), \
278 Encoded_GPR_##Src##Suffix()); \
279 AssembledTest test = assemble(); \
280 test.setQwordTo(T0, V0); \
281 test.run(); \
282 ASSERT_EQ(Value, test.Dst##q()) << "(" #Dst ", " #Src ", " #Size ")"; \
283 reset(); \
284 } while (0)
285
286 #define TestImplRegAddr(Dst, Suffix, Size) \
287 do { \
288 const uint32_t T0 = allocateDqword(); \
289 static constexpr uint64_t V0 = 0xAAAAAAAAAAAAAAAAull; \
290 static constexpr uint32_t Value = (0xBEEF) & Mask##Size; \
291 __ movzx(IceType_i##Size, Encoded_GPR_##Dst##d(), dwordAddress(T0)); \
292 \
293 AssembledTest test = assemble(); \
294 test.setQwordTo(T0, (V0 & ~Mask##Size) | Value); \
295 test.run(); \
296 ASSERT_EQ(Value, test.Dst##q()) << "(" #Dst ", Addr, " #Size ")"; \
297 reset(); \
298 } while (0)
299
300 #define TestImpl(Dst, Src) \
301 do { \
302 TestImplRegReg(Dst, Src, l, 8); \
303 TestImplRegAddr(Dst, l, 8); \
304 TestImplRegReg(Dst, Src, w, 16); \
305 TestImplRegAddr(Dst, w, 16); \
306 } while (0)
307
308 TestImpl(r1, r2);
309 TestImpl(r2, r3);
310 TestImpl(r3, r4);
311 TestImpl(r4, r5);
312 TestImpl(r5, r6);
313 TestImpl(r6, r7);
314 TestImpl(r7, r8);
315 TestImpl(r8, r10);
316 TestImpl(r10, r11);
317 TestImpl(r11, r12);
318 TestImpl(r12, r13);
319 TestImpl(r13, r14);
320 TestImpl(r14, r15);
321 TestImpl(r15, r1);
322
323 #undef TestImpl
324 #undef TestImplRegAddr
325 #undef TestImplRegReg
326 }
327
328 TEST_F(AssemblerX8664Test, Movsx) {
329 static constexpr uint64_t Mask8 = 0x000000FF;
330 static constexpr uint64_t Mask16 = 0x0000FFFF;
331 static constexpr uint64_t Mask32 = 0xFFFFFFFF;
332
333 #define TestImplRegReg(Dst, Src, Suffix, Size) \
334 do { \
335 const uint32_t T0 = allocateDqword(); \
336 static constexpr uint64_t V0 = 0xAAAAAAAAAAAAAAAAull; \
337 static constexpr uint64_t Value = (0xC0BEBEEF) & Mask##Size; \
338 __ mov(IceType_i64, Encoded_GPR_##Dst##q(), dwordAddress(T0)); \
339 __ mov(IceType_i##Size, Encoded_GPR_##Src##Suffix(), Immediate(Value)); \
340 __ movsx(IceType_i##Size, Encoded_GPR_##Dst##d(), \
341 Encoded_GPR_##Src##Suffix()); \
342 AssembledTest test = assemble(); \
343 test.setQwordTo(T0, V0); \
344 test.run(); \
345 ASSERT_EQ((uint64_t(-1) & ~Mask##Size) | Value, test.Dst##q()) \
346 << "(" #Dst ", " #Src ", " #Size ")"; \
347 reset(); \
348 } while (0)
349
350 #define TestImplRegAddr(Dst, Suffix, Size) \
351 do { \
352 const uint32_t T0 = allocateDqword(); \
353 static constexpr uint64_t V0 = 0xC0BEBEEF & Mask##Size; \
354 static constexpr uint64_t Value = (0xC0BEBEEF) & Mask##Size; \
355 __ movsx(IceType_i##Size, Encoded_GPR_##Dst##d(), dwordAddress(T0)); \
356 \
357 AssembledTest test = assemble(); \
358 test.setQwordTo(T0, V0); \
359 test.run(); \
360 ASSERT_EQ((uint64_t(-1) & ~Mask##Size) | Value, test.Dst##q()) \
361 << "(" #Dst ", Addr, " #Size ")"; \
362 reset(); \
363 } while (0)
364
365 #define TestImpl(Dst, Src) \
366 do { \
367 TestImplRegReg(Dst, Src, l, 8); \
368 TestImplRegAddr(Dst, l, 8); \
369 TestImplRegReg(Dst, Src, w, 16); \
370 TestImplRegAddr(Dst, w, 16); \
371 TestImplRegReg(Dst, Src, w, 32); \
372 TestImplRegAddr(Dst, w, 32); \
373 } while (0)
374
375 TestImpl(r1, r2);
376 TestImpl(r2, r3);
377 TestImpl(r3, r4);
378 TestImpl(r4, r5);
379 TestImpl(r5, r6);
380 TestImpl(r6, r7);
381 TestImpl(r7, r8);
382 TestImpl(r8, r10);
383 TestImpl(r10, r11);
384 TestImpl(r11, r12);
385 TestImpl(r12, r13);
386 TestImpl(r13, r14);
387 TestImpl(r14, r15);
388 TestImpl(r15, r1);
389
390 #undef TestImpl
391 #undef TestImplRegAddr
392 #undef TestImplRegReg
393 }
394
395 TEST_F(AssemblerX8664Test, Cmov) {
396 #define TestRegReg(C, Dest, IsTrue, Src0, Value0, Src1, Value1) \
397 do { \
398 static constexpr char TestString[] = \
399 "(" #C ", " #Dest ", " #IsTrue ", " #Src0 ", " #Value0 ", " #Src1 \
400 ", " #Value1 ")"; \
401 __ mov(IceType_i32, Encoded_GPR_##Src0(), Immediate(Value0)); \
402 __ mov(IceType_i32, Encoded_GPR_##Src1(), Immediate(Value1)); \
403 __ mov(IceType_i32, Encoded_GPR_##Dest(), Immediate(Value0)); \
404 __ cmp(IceType_i32, Encoded_GPR_##Src0(), Encoded_GPR_##Src1()); \
405 __ cmov(IceType_i32, Cond::Br_##C, Encoded_GPR_##Dest(), \
406 Encoded_GPR_##Src1()); \
407 \
408 AssembledTest test = assemble(); \
409 test.run(); \
410 ASSERT_EQ((IsTrue) ? (Value1) : (Value0), test.Dest()) << TestString; \
411 \
412 reset(); \
413 } while (0)
414
415 #define TestRegAddr(C, Dest, IsTrue, Src0, Value0, Value1) \
416 do { \
417 static constexpr char TestString[] = \
418 "(" #C ", " #Dest ", " #IsTrue ", " #Src0 ", " #Value0 \
419 ", Addr, " #Value1 ")"; \
420 const uint32_t T0 = allocateDword(); \
421 const uint32_t V0 = Value1; \
422 __ mov(IceType_i32, Encoded_GPR_##Src0(), Immediate(Value0)); \
423 __ mov(IceType_i32, Encoded_GPR_##Dest(), Immediate(Value0)); \
424 __ cmp(IceType_i32, Encoded_GPR_##Src0(), dwordAddress(T0)); \
425 __ cmov(IceType_i32, Cond::Br_##C, Encoded_GPR_##Dest(), \
426 dwordAddress(T0)); \
427 \
428 AssembledTest test = assemble(); \
429 test.setDwordTo(T0, V0); \
430 test.run(); \
431 ASSERT_EQ((IsTrue) ? (Value1) : (Value0), test.Dest()) << TestString; \
432 \
433 reset(); \
434 } while (0)
435
436 #define TestValue(C, Dest, IsTrue, Src0, Value0, Src1, Value1) \
437 do { \
438 TestRegReg(C, Dest, IsTrue, Src0, Value0, Src1, Value1); \
439 TestRegAddr(C, Dest, IsTrue, Src0, Value0, Value1); \
440 } while (0)
441
442 #define TestImpl(Dest, Src0, Src1) \
443 do { \
444 TestValue(o, Dest, 1u, Src0, 0x80000000u, Src1, 0x1u); \
445 TestValue(o, Dest, 0u, Src0, 0x1u, Src1, 0x10000000u); \
446 TestValue(no, Dest, 1u, Src0, 0x1u, Src1, 0x10000000u); \
447 TestValue(no, Dest, 0u, Src0, 0x80000000u, Src1, 0x1u); \
448 TestValue(b, Dest, 1u, Src0, 0x1, Src1, 0x80000000u); \
449 TestValue(b, Dest, 0u, Src0, 0x80000000u, Src1, 0x1u); \
450 TestValue(ae, Dest, 1u, Src0, 0x80000000u, Src1, 0x1u); \
451 TestValue(ae, Dest, 0u, Src0, 0x1u, Src1, 0x80000000u); \
452 TestValue(e, Dest, 1u, Src0, 0x1u, Src1, 0x1u); \
453 TestValue(e, Dest, 0u, Src0, 0x1u, Src1, 0x11111u); \
454 TestValue(ne, Dest, 1u, Src0, 0x80000000u, Src1, 0x1u); \
455 TestValue(ne, Dest, 0u, Src0, 0x1u, Src1, 0x1u); \
456 TestValue(be, Dest, 1u, Src0, 0x1u, Src1, 0x80000000u); \
457 TestValue(be, Dest, 0u, Src0, 0x80000000u, Src1, 0x1u); \
458 TestValue(a, Dest, 1u, Src0, 0x80000000u, Src1, 0x1u); \
459 TestValue(a, Dest, 0u, Src0, 0x1u, Src1, 0x80000000u); \
460 TestValue(s, Dest, 1u, Src0, 0x1u, Src1, 0x80000000u); \
461 TestValue(s, Dest, 0u, Src0, 0x80000000u, Src1, 0x1u); \
462 TestValue(ns, Dest, 1u, Src0, 0x80000000u, Src1, 0x1u); \
463 TestValue(ns, Dest, 0u, Src0, 0x1u, Src1, 0x80000000u); \
464 TestValue(p, Dest, 1u, Src0, 0x80000000u, Src1, 0x1u); \
465 TestValue(p, Dest, 0u, Src0, 0x1u, Src1, 0x80000000u); \
466 TestValue(np, Dest, 1u, Src0, 0x1u, Src1, 0x80000000u); \
467 TestValue(np, Dest, 0u, Src0, 0x80000000u, Src1, 0x1u); \
468 TestValue(l, Dest, 1u, Src0, 0x80000000u, Src1, 0x1u); \
469 TestValue(l, Dest, 0u, Src0, 0x1u, Src1, 0x80000000u); \
470 TestValue(ge, Dest, 1u, Src0, 0x1u, Src1, 0x80000000u); \
471 TestValue(ge, Dest, 0u, Src0, 0x80000000u, Src1, 0x1u); \
472 TestValue(le, Dest, 1u, Src0, 0x80000000u, Src1, 0x1u); \
473 TestValue(le, Dest, 0u, Src0, 0x1u, Src1, 0x80000000u); \
474 } while (0)
475
476 TestImpl(r1, r2, r3);
477
478 #undef TestImpl
479 #undef TestValue
480 #undef TestRegAddr
481 #undef TestRegReg
482 }
483
484 TEST_F(AssemblerX8664LowLevelTest, RepMovsb) {
485 __ rep_movsb();
486
487 static constexpr uint32_t ByteCount = 2;
488 static constexpr uint8_t Prefix = 0xF3;
489 static constexpr uint8_t Opcode = 0xA4;
490
491 ASSERT_EQ(ByteCount, codeBytesSize());
492 verifyBytes<ByteCount>(codeBytes(), Prefix, Opcode);
493 }
494
495 TEST_F(AssemblerX8664Test, MovssXmmAddr) {
496 #define TestMovssXmmAddrFloatLength(FloatLength, Xmm, Value) \
497 do { \
498 static_assert((FloatLength) == 32 || (FloatLength) == 64, \
499 "Invalid fp length #FloatLength"); \
500 using Type = std::conditional<FloatLength == 32, float, double>::type; \
501 \
502 static constexpr char TestString[] = "(" #FloatLength ", " #Xmm ")"; \
503 static constexpr bool IsDouble = std::is_same<Type, double>::value; \
504 const uint32_t T0 = allocateQword(); \
505 const Type V0 = Value; \
506 \
507 __ movss(IceType_f##FloatLength, Encoded_Xmm_##Xmm(), dwordAddress(T0)); \
508 \
509 AssembledTest test = assemble(); \
510 if (IsDouble) { \
511 test.setQwordTo(T0, static_cast<double>(V0)); \
512 } else { \
513 test.setDwordTo(T0, static_cast<float>(V0)); \
514 } \
515 test.run(); \
516 ASSERT_DOUBLE_EQ(Value, test.Xmm<Type>()) << TestString << " value is " \
517 << Value; \
518 reset(); \
519 } while (0)
520
521 #define TestMovssXmmAddr(FloatLength) \
522 do { \
523 using Type = std::conditional<FloatLength == 32, float, double>::type; \
524 for (const Type Value : {0.0, -0.0, 1.0, -1.0, 3.14, 99999.9999}) { \
525 TestMovssXmmAddrFloatLength(FloatLength, xmm0, Value); \
526 TestMovssXmmAddrFloatLength(FloatLength, xmm1, Value); \
527 TestMovssXmmAddrFloatLength(FloatLength, xmm2, Value); \
528 TestMovssXmmAddrFloatLength(FloatLength, xmm3, Value); \
529 TestMovssXmmAddrFloatLength(FloatLength, xmm4, Value); \
530 TestMovssXmmAddrFloatLength(FloatLength, xmm5, Value); \
531 TestMovssXmmAddrFloatLength(FloatLength, xmm6, Value); \
532 TestMovssXmmAddrFloatLength(FloatLength, xmm7, Value); \
533 TestMovssXmmAddrFloatLength(FloatLength, xmm8, Value); \
534 TestMovssXmmAddrFloatLength(FloatLength, xmm9, Value); \
535 TestMovssXmmAddrFloatLength(FloatLength, xmm10, Value); \
536 TestMovssXmmAddrFloatLength(FloatLength, xmm11, Value); \
537 TestMovssXmmAddrFloatLength(FloatLength, xmm12, Value); \
538 TestMovssXmmAddrFloatLength(FloatLength, xmm13, Value); \
539 TestMovssXmmAddrFloatLength(FloatLength, xmm14, Value); \
540 TestMovssXmmAddrFloatLength(FloatLength, xmm15, Value); \
541 } \
542 } while (0)
543
544 TestMovssXmmAddr(32);
545 TestMovssXmmAddr(64);
546
547 #undef TestMovssXmmAddr
548 #undef TestMovssXmmAddrType
549 }
550
551 TEST_F(AssemblerX8664Test, MovssAddrXmm) {
552 #define TestMovssAddrXmmFloatLength(FloatLength, Xmm, Value) \
553 do { \
554 static_assert((FloatLength) == 32 || (FloatLength) == 64, \
555 "Invalid fp length #FloatLength"); \
556 using Type = std::conditional<FloatLength == 32, float, double>::type; \
557 \
558 static constexpr char TestString[] = "(" #FloatLength ", " #Xmm ")"; \
559 static constexpr bool IsDouble = std::is_same<Type, double>::value; \
560 const uint32_t T0 = allocateQword(); \
561 const Type V0 = Value; \
562 const uint32_t T1 = allocateQword(); \
563 static_assert(std::numeric_limits<Type>::has_quiet_NaN, \
564 "f" #FloatLength " does not have quiet nan."); \
565 const Type V1 = std::numeric_limits<Type>::quiet_NaN(); \
566 \
567 __ movss(IceType_f##FloatLength, Encoded_Xmm_##Xmm(), dwordAddress(T0)); \
568 \
569 AssembledTest test = assemble(); \
570 if (IsDouble) { \
571 test.setQwordTo(T0, static_cast<double>(V0)); \
572 test.setQwordTo(T1, static_cast<double>(V1)); \
573 } else { \
574 test.setDwordTo(T0, static_cast<float>(V0)); \
575 test.setDwordTo(T1, static_cast<float>(V1)); \
576 } \
577 test.run(); \
578 ASSERT_DOUBLE_EQ(Value, test.Xmm<Type>()) << TestString << " value is " \
579 << Value; \
580 reset(); \
581 } while (0)
582
583 #define TestMovssAddrXmm(FloatLength) \
584 do { \
585 using Type = std::conditional<FloatLength == 32, float, double>::type; \
586 for (const Type Value : {0.0, -0.0, 1.0, -1.0, 3.14, 99999.9999}) { \
587 TestMovssAddrXmmFloatLength(FloatLength, xmm0, Value); \
588 TestMovssAddrXmmFloatLength(FloatLength, xmm1, Value); \
589 TestMovssAddrXmmFloatLength(FloatLength, xmm2, Value); \
590 TestMovssAddrXmmFloatLength(FloatLength, xmm3, Value); \
591 TestMovssAddrXmmFloatLength(FloatLength, xmm4, Value); \
592 TestMovssAddrXmmFloatLength(FloatLength, xmm5, Value); \
593 TestMovssAddrXmmFloatLength(FloatLength, xmm6, Value); \
594 TestMovssAddrXmmFloatLength(FloatLength, xmm7, Value); \
595 TestMovssAddrXmmFloatLength(FloatLength, xmm8, Value); \
596 TestMovssAddrXmmFloatLength(FloatLength, xmm9, Value); \
597 TestMovssAddrXmmFloatLength(FloatLength, xmm10, Value); \
598 TestMovssAddrXmmFloatLength(FloatLength, xmm11, Value); \
599 TestMovssAddrXmmFloatLength(FloatLength, xmm12, Value); \
600 TestMovssAddrXmmFloatLength(FloatLength, xmm13, Value); \
601 TestMovssAddrXmmFloatLength(FloatLength, xmm14, Value); \
602 TestMovssAddrXmmFloatLength(FloatLength, xmm15, Value); \
603 } \
604 } while (0)
605
606 TestMovssAddrXmm(32);
607 TestMovssAddrXmm(64);
608
609 #undef TestMovssAddrXmm
610 #undef TestMovssAddrXmmType
611 }
612
613 TEST_F(AssemblerX8664Test, MovssXmmXmm) {
614 #define TestMovssXmmXmmFloatLength(FloatLength, Src, Dst, Value) \
615 do { \
616 static_assert((FloatLength) == 32 || (FloatLength) == 64, \
617 "Invalid fp length #FloatLength"); \
618 using Type = std::conditional<FloatLength == 32, float, double>::type; \
619 \
620 static constexpr char TestString[] = \
621 "(" #FloatLength ", " #Src ", " #Dst ")"; \
622 static constexpr bool IsDouble = std::is_same<Type, double>::value; \
623 const uint32_t T0 = allocateQword(); \
624 const Type V0 = Value; \
625 const uint32_t T1 = allocateQword(); \
626 static_assert(std::numeric_limits<Type>::has_quiet_NaN, \
627 "f" #FloatLength " does not have quiet nan."); \
628 const Type V1 = std::numeric_limits<Type>::quiet_NaN(); \
629 \
630 __ movss(IceType_f##FloatLength, Encoded_Xmm_##Src(), dwordAddress(T0)); \
631 __ movss(IceType_f##FloatLength, Encoded_Xmm_##Dst(), dwordAddress(T1)); \
632 __ movss(IceType_f##FloatLength, Encoded_Xmm_##Dst(), \
633 Encoded_Xmm_##Src()); \
634 \
635 AssembledTest test = assemble(); \
636 if (IsDouble) { \
637 test.setQwordTo(T0, static_cast<double>(V0)); \
638 test.setQwordTo(T1, static_cast<double>(V1)); \
639 } else { \
640 test.setDwordTo(T0, static_cast<float>(V0)); \
641 test.setDwordTo(T1, static_cast<float>(V1)); \
642 } \
643 test.run(); \
644 ASSERT_DOUBLE_EQ(Value, test.Dst<Type>()) << TestString << " value is " \
645 << Value; \
646 reset(); \
647 } while (0)
648
649 #define TestMovssXmmXmm(FloatLength) \
650 do { \
651 using Type = std::conditional<FloatLength == 32, float, double>::type; \
652 for (const Type Value : {0.0, -0.0, 1.0, -1.0, 3.14, 99999.9999}) { \
653 TestMovssXmmXmmFloatLength(FloatLength, xmm0, xmm1, Value); \
654 TestMovssXmmXmmFloatLength(FloatLength, xmm1, xmm2, Value); \
655 TestMovssXmmXmmFloatLength(FloatLength, xmm2, xmm3, Value); \
656 TestMovssXmmXmmFloatLength(FloatLength, xmm3, xmm4, Value); \
657 TestMovssXmmXmmFloatLength(FloatLength, xmm4, xmm5, Value); \
658 TestMovssXmmXmmFloatLength(FloatLength, xmm5, xmm6, Value); \
659 TestMovssXmmXmmFloatLength(FloatLength, xmm6, xmm7, Value); \
660 TestMovssXmmXmmFloatLength(FloatLength, xmm7, xmm8, Value); \
661 TestMovssXmmXmmFloatLength(FloatLength, xmm8, xmm9, Value); \
662 TestMovssXmmXmmFloatLength(FloatLength, xmm9, xmm10, Value); \
663 TestMovssXmmXmmFloatLength(FloatLength, xmm10, xmm11, Value); \
664 TestMovssXmmXmmFloatLength(FloatLength, xmm11, xmm12, Value); \
665 TestMovssXmmXmmFloatLength(FloatLength, xmm12, xmm13, Value); \
666 TestMovssXmmXmmFloatLength(FloatLength, xmm13, xmm14, Value); \
667 TestMovssXmmXmmFloatLength(FloatLength, xmm14, xmm15, Value); \
668 TestMovssXmmXmmFloatLength(FloatLength, xmm15, xmm0, Value); \
669 } \
670 } while (0)
671
672 TestMovssXmmXmm(32);
673 TestMovssXmmXmm(64);
674
675 #undef TestMovssXmmXmm
676 #undef TestMovssXmmXmmType
677 }
678
679 TEST_F(AssemblerX8664Test, MovdToXmm) {
680 #define TestMovdXmmReg(Src, Dst, Value) \
681 do { \
682 assert(((Value)&0xFFFFFFFF) == (Value)); \
683 static constexpr char TestString[] = "(" #Src ", " #Dst ")"; \
684 const uint32_t T0 = allocateQword(); \
685 const uint64_t V0 = 0xFFFFFFFF00000000ull; \
686 \
687 __ mov(IceType_i32, Encoded_GPR_##Src(), Immediate(Value)); \
688 __ movss(IceType_f64, Encoded_Xmm_##Dst(), dwordAddress(T0)); \
689 __ movd(Encoded_Xmm_##Dst(), Encoded_GPR_##Src()); \
690 \
691 AssembledTest test = assemble(); \
692 \
693 test.setQwordTo(T0, V0); \
694 test.run(); \
695 \
696 ASSERT_EQ(Value, test.Dst<uint64_t>()) << TestString << " value is " \
697 << Value; \
698 reset(); \
699 } while (0)
700
701 #define TestMovdXmmAddr(Dst, Value) \
702 do { \
703 assert(((Value)&0xFFFFFFFF) == (Value)); \
704 static constexpr char TestString[] = "(" #Dst ", Addr)"; \
705 const uint32_t T0 = allocateQword(); \
706 const uint32_t V0 = Value; \
707 const uint32_t T1 = allocateQword(); \
708 const uint64_t V1 = 0xFFFFFFFF00000000ull; \
709 \
710 __ movss(IceType_f64, Encoded_Xmm_##Dst(), dwordAddress(T1)); \
711 __ movd(Encoded_Xmm_##Dst(), dwordAddress(T0)); \
712 \
713 AssembledTest test = assemble(); \
714 \
715 test.setDwordTo(T0, V0); \
716 test.setQwordTo(T1, V1); \
717 test.run(); \
718 \
719 ASSERT_EQ(Value, test.Dst<uint64_t>()) << TestString << " value is " \
720 << Value; \
721 reset(); \
722 } while (0)
723
724 #define TestMovd(Dst) \
725 do { \
726 for (uint32_t Value : {0u, 1u, 0x7FFFFFFFu, 0x80000000u, 0xFFFFFFFFu}) { \
727 TestMovdXmmReg(r1, Dst, Value); \
728 TestMovdXmmReg(r2, Dst, Value); \
729 TestMovdXmmReg(r3, Dst, Value); \
730 TestMovdXmmReg(r4, Dst, Value); \
731 TestMovdXmmReg(r5, Dst, Value); \
732 TestMovdXmmReg(r6, Dst, Value); \
733 TestMovdXmmReg(r7, Dst, Value); \
734 TestMovdXmmReg(r8, Dst, Value); \
735 TestMovdXmmReg(r10, Dst, Value); \
736 TestMovdXmmReg(r11, Dst, Value); \
737 TestMovdXmmReg(r12, Dst, Value); \
738 TestMovdXmmReg(r13, Dst, Value); \
739 TestMovdXmmReg(r14, Dst, Value); \
740 TestMovdXmmReg(r15, Dst, Value); \
741 TestMovdXmmAddr(Dst, Value); \
742 } \
743 } while (0)
744
745 TestMovd(xmm0);
746 TestMovd(xmm1);
747 TestMovd(xmm2);
748 TestMovd(xmm3);
749 TestMovd(xmm4);
750 TestMovd(xmm5);
751 TestMovd(xmm6);
752 TestMovd(xmm7);
753 TestMovd(xmm8);
754 TestMovd(xmm9);
755 TestMovd(xmm10);
756 TestMovd(xmm11);
757 TestMovd(xmm12);
758 TestMovd(xmm13);
759 TestMovd(xmm14);
760 TestMovd(xmm15);
761
762 #undef TestMovdXmmAddr
763 #undef TestMovdXmmReg
764 #undef TestMovd
765 }
766
767 TEST_F(AssemblerX8664Test, MovdFromXmm) {
768 #define TestMovdRegXmm(Src, Dst, Value) \
769 do { \
770 assert(((Value)&0xFFFFFFFF) == (Value)); \
771 static constexpr char TestString[] = "(" #Src ", " #Dst ")"; \
772 const uint32_t T0 = allocateDword(); \
773 const uint32_t V0 = Value; \
774 \
775 __ movss(IceType_f64, Encoded_Xmm_##Src(), dwordAddress(T0)); \
776 __ movd(Encoded_GPR_##Dst(), Encoded_Xmm_##Src()); \
777 \
778 AssembledTest test = assemble(); \
779 \
780 test.setDwordTo(T0, V0); \
781 test.run(); \
782 \
783 ASSERT_EQ(Value, test.contentsOfDword(T0)) << TestString << " value is " \
784 << Value; \
785 reset(); \
786 } while (0)
787
788 #define TestMovdAddrXmm(Src, Value) \
789 do { \
790 assert(((Value)&0xFFFFFFFF) == (Value)); \
791 static constexpr char TestString[] = "(" #Src ", Addr)"; \
792 const uint32_t T0 = allocateDword(); \
793 const uint32_t V0 = Value; \
794 const uint32_t T1 = allocateDword(); \
795 const uint32_t V1 = ~(Value); \
796 \
797 __ movss(IceType_f64, Encoded_Xmm_##Src(), dwordAddress(T0)); \
798 __ movd(dwordAddress(T1), Encoded_Xmm_##Src()); \
799 \
800 AssembledTest test = assemble(); \
801 \
802 test.setDwordTo(T0, V0); \
803 test.setDwordTo(T1, V1); \
804 test.run(); \
805 \
806 ASSERT_EQ(Value, test.contentsOfDword(T1)) << TestString << " value is " \
807 << Value; \
808 reset(); \
809 } while (0)
810
811 #define TestMovd(Src) \
812 do { \
813 for (uint32_t Value : {0u, 1u, 0x7FFFFFFFu, 0x80000000u, 0xFFFFFFFFu}) { \
814 TestMovdRegXmm(Src, r1, Value); \
815 TestMovdRegXmm(Src, r2, Value); \
816 TestMovdRegXmm(Src, r3, Value); \
817 TestMovdRegXmm(Src, r4, Value); \
818 TestMovdRegXmm(Src, r5, Value); \
819 TestMovdRegXmm(Src, r6, Value); \
820 TestMovdRegXmm(Src, r7, Value); \
821 TestMovdRegXmm(Src, r8, Value); \
822 TestMovdRegXmm(Src, r10, Value); \
823 TestMovdRegXmm(Src, r11, Value); \
824 TestMovdRegXmm(Src, r12, Value); \
825 TestMovdRegXmm(Src, r13, Value); \
826 TestMovdRegXmm(Src, r14, Value); \
827 TestMovdRegXmm(Src, r15, Value); \
828 TestMovdAddrXmm(Src, Value); \
829 } \
830 } while (0)
831
832 TestMovd(xmm0);
833 TestMovd(xmm1);
834 TestMovd(xmm2);
835 TestMovd(xmm3);
836 TestMovd(xmm4);
837 TestMovd(xmm5);
838 TestMovd(xmm6);
839 TestMovd(xmm7);
840 TestMovd(xmm8);
841 TestMovd(xmm9);
842 TestMovd(xmm10);
843 TestMovd(xmm11);
844 TestMovd(xmm12);
845 TestMovd(xmm13);
846 TestMovd(xmm14);
847 TestMovd(xmm15);
848
849 #undef TestMovdAddrXmm
850 #undef TestMovdRegXmm
851 #undef TestMovd
852 }
853
854 TEST_F(AssemblerX8664Test, MovqXmmAddr) {
855 #define TestMovd(Dst, Value) \
856 do { \
857 static constexpr char TestString[] = "(" #Dst ", Addr)"; \
858 const uint32_t T0 = allocateQword(); \
859 const uint64_t V0 = Value; \
860 const uint32_t T1 = allocateQword(); \
861 const uint64_t V1 = ~(Value); \
862 \
863 __ movss(IceType_f64, Encoded_Xmm_##Dst(), dwordAddress(T1)); \
864 __ movq(Encoded_Xmm_##Dst(), dwordAddress(T0)); \
865 \
866 AssembledTest test = assemble(); \
867 \
868 test.setQwordTo(T0, V0); \
869 test.setQwordTo(T1, V1); \
870 test.run(); \
871 \
872 ASSERT_EQ(Value, test.Dst<uint64_t>()) << TestString << " value is " \
873 << Value; \
874 reset(); \
875 } while (0)
876
877 for (uint32_t Value : {0u, 1u, 0x7FFFFFFFu, 0x80000000u, 0xFFFFFFFFu}) {
878 TestMovd(xmm0, Value);
879 TestMovd(xmm1, Value);
880 TestMovd(xmm2, Value);
881 TestMovd(xmm3, Value);
882 TestMovd(xmm4, Value);
883 TestMovd(xmm5, Value);
884 TestMovd(xmm6, Value);
885 TestMovd(xmm7, Value);
886 TestMovd(xmm8, Value);
887 TestMovd(xmm9, Value);
888 TestMovd(xmm10, Value);
889 TestMovd(xmm11, Value);
890 TestMovd(xmm12, Value);
891 TestMovd(xmm13, Value);
892 TestMovd(xmm14, Value);
893 TestMovd(xmm15, Value);
894 }
895
896 #undef TestMovd
897 }
898
899 TEST_F(AssemblerX8664Test, MovqAddrXmm) {
900 #define TestMovd(Dst, Value) \
901 do { \
902 static constexpr char TestString[] = "(" #Dst ", Addr)"; \
903 const uint32_t T0 = allocateQword(); \
904 const uint64_t V0 = Value; \
905 const uint32_t T1 = allocateQword(); \
906 const uint64_t V1 = ~(Value); \
907 \
908 __ movq(Encoded_Xmm_##Dst(), dwordAddress(T0)); \
909 __ movq(dwordAddress(T1), Encoded_Xmm_##Dst()); \
910 \
911 AssembledTest test = assemble(); \
912 \
913 test.setQwordTo(T0, V0); \
914 test.setQwordTo(T1, V1); \
915 test.run(); \
916 \
917 ASSERT_EQ(Value, test.Dst<uint64_t>()) << TestString << " value is " \
918 << Value; \
919 reset(); \
920 } while (0)
921
922 for (uint32_t Value : {0u, 1u, 0x7FFFFFFFu, 0x80000000u, 0xFFFFFFFFu}) {
923 TestMovd(xmm0, Value);
924 TestMovd(xmm1, Value);
925 TestMovd(xmm2, Value);
926 TestMovd(xmm3, Value);
927 TestMovd(xmm4, Value);
928 TestMovd(xmm5, Value);
929 TestMovd(xmm6, Value);
930 TestMovd(xmm7, Value);
931 TestMovd(xmm8, Value);
932 TestMovd(xmm9, Value);
933 TestMovd(xmm10, Value);
934 TestMovd(xmm11, Value);
935 TestMovd(xmm12, Value);
936 TestMovd(xmm13, Value);
937 TestMovd(xmm14, Value);
938 TestMovd(xmm15, Value);
939 }
940
941 #undef TestMovd
942 }
943
944 TEST_F(AssemblerX8664Test, MovqXmmXmm) {
945 #define TestMovd(Src, Dst, Value) \
946 do { \
947 static constexpr char TestString[] = "(" #Src ", " #Dst ")"; \
948 const uint32_t T0 = allocateQword(); \
949 const uint64_t V0 = Value; \
950 const uint32_t T1 = allocateQword(); \
951 const uint64_t V1 = ~(Value); \
952 \
953 __ movq(Encoded_Xmm_##Src(), dwordAddress(T0)); \
954 __ movq(Encoded_Xmm_##Dst(), dwordAddress(T1)); \
955 __ movq(Encoded_Xmm_##Dst(), Encoded_Xmm_##Src()); \
956 \
957 AssembledTest test = assemble(); \
958 \
959 test.setQwordTo(T0, V0); \
960 test.setQwordTo(T1, V1); \
961 test.run(); \
962 \
963 ASSERT_EQ(Value, test.Dst<uint64_t>()) << TestString << " value is " \
964 << Value; \
965 reset(); \
966 } while (0)
967
968 for (uint32_t Value : {0u, 1u, 0x7FFFFFFFu, 0x80000000u, 0xFFFFFFFFu}) {
969 TestMovd(xmm0, xmm1, Value);
970 TestMovd(xmm1, xmm2, Value);
971 TestMovd(xmm2, xmm3, Value);
972 TestMovd(xmm3, xmm4, Value);
973 TestMovd(xmm4, xmm5, Value);
974 TestMovd(xmm5, xmm6, Value);
975 TestMovd(xmm6, xmm7, Value);
976 TestMovd(xmm7, xmm8, Value);
977 TestMovd(xmm8, xmm9, Value);
978 TestMovd(xmm9, xmm10, Value);
979 TestMovd(xmm10, xmm11, Value);
980 TestMovd(xmm11, xmm12, Value);
981 TestMovd(xmm12, xmm13, Value);
982 TestMovd(xmm13, xmm14, Value);
983 TestMovd(xmm14, xmm15, Value);
984 TestMovd(xmm15, xmm0, Value);
985 }
986
987 #undef TestMovd
988 }
989
990 TEST_F(AssemblerX8664Test, MovupsXmmAddr) {
991 #define TestMovups(Dst) \
992 do { \
993 static constexpr char TestString[] = "(" #Dst ")"; \
994 const uint32_t T0 = allocateDqword(); \
995 const Dqword V0(1.0f, -1.0, std::numeric_limits<float>::quiet_NaN(), \
996 std::numeric_limits<float>::infinity()); \
997 \
998 __ movups(Encoded_Xmm_##Dst(), dwordAddress(T0)); \
999 \
1000 AssembledTest test = assemble(); \
1001 test.setDqwordTo(T0, V0); \
1002 test.run(); \
1003 \
1004 ASSERT_EQ(V0, test.Dst<Dqword>()) << TestString; \
1005 reset(); \
1006 } while (0)
1007
1008 TestMovups(xmm0);
1009 TestMovups(xmm1);
1010 TestMovups(xmm2);
1011 TestMovups(xmm3);
1012 TestMovups(xmm4);
1013 TestMovups(xmm5);
1014 TestMovups(xmm6);
1015 TestMovups(xmm7);
1016 TestMovups(xmm8);
1017 TestMovups(xmm9);
1018 TestMovups(xmm10);
1019 TestMovups(xmm11);
1020 TestMovups(xmm12);
1021 TestMovups(xmm13);
1022 TestMovups(xmm14);
1023 TestMovups(xmm15);
1024
1025 #undef TestMovups
1026 }
1027
1028 TEST_F(AssemblerX8664Test, MovupsAddrXmm) {
1029 #define TestMovups(Src) \
1030 do { \
1031 static constexpr char TestString[] = "(" #Src ")"; \
1032 const uint32_t T0 = allocateDqword(); \
1033 const Dqword V0(1.0f, -1.0, std::numeric_limits<float>::quiet_NaN(), \
1034 std::numeric_limits<float>::infinity()); \
1035 const uint32_t T1 = allocateDqword(); \
1036 const Dqword V1(0.0, 0.0, 0.0, 0.0); \
1037 \
1038 __ movups(Encoded_Xmm_##Src(), dwordAddress(T0)); \
1039 __ movups(dwordAddress(T1), Encoded_Xmm_##Src()); \
1040 \
1041 AssembledTest test = assemble(); \
1042 test.setDqwordTo(T0, V0); \
1043 test.setDqwordTo(T1, V1); \
1044 test.run(); \
1045 \
1046 ASSERT_EQ(V0, test.contentsOfDqword(T1)) << TestString; \
1047 reset(); \
1048 } while (0)
1049
1050 TestMovups(xmm0);
1051 TestMovups(xmm1);
1052 TestMovups(xmm2);
1053 TestMovups(xmm3);
1054 TestMovups(xmm4);
1055 TestMovups(xmm5);
1056 TestMovups(xmm6);
1057 TestMovups(xmm7);
1058 TestMovups(xmm8);
1059 TestMovups(xmm9);
1060 TestMovups(xmm10);
1061 TestMovups(xmm11);
1062 TestMovups(xmm12);
1063 TestMovups(xmm13);
1064 TestMovups(xmm14);
1065 TestMovups(xmm15);
1066
1067 #undef TestMovups
1068 }
1069
1070 TEST_F(AssemblerX8664Test, MovupsXmmXmm) {
1071 #define TestMovups(Dst, Src) \
1072 do { \
1073 static constexpr char TestString[] = "(" #Dst ", " #Src ")"; \
1074 const uint32_t T0 = allocateDqword(); \
1075 const Dqword V0(1.0f, -1.0, std::numeric_limits<float>::quiet_NaN(), \
1076 std::numeric_limits<float>::infinity()); \
1077 const uint32_t T1 = allocateDqword(); \
1078 const Dqword V1(0.0, 0.0, 0.0, 0.0); \
1079 \
1080 __ movups(Encoded_Xmm_##Src(), dwordAddress(T0)); \
1081 __ movups(Encoded_Xmm_##Dst(), dwordAddress(T1)); \
1082 __ movups(Encoded_Xmm_##Dst(), Encoded_Xmm_##Src()); \
1083 \
1084 AssembledTest test = assemble(); \
1085 test.setDqwordTo(T0, V0); \
1086 test.setDqwordTo(T1, V1); \
1087 test.run(); \
1088 \
1089 ASSERT_EQ(V0, test.Dst<Dqword>()) << TestString; \
1090 reset(); \
1091 } while (0)
1092
1093 TestMovups(xmm0, xmm1);
1094 TestMovups(xmm1, xmm2);
1095 TestMovups(xmm2, xmm3);
1096 TestMovups(xmm3, xmm4);
1097 TestMovups(xmm4, xmm5);
1098 TestMovups(xmm5, xmm6);
1099 TestMovups(xmm6, xmm7);
1100 TestMovups(xmm7, xmm8);
1101 TestMovups(xmm8, xmm9);
1102 TestMovups(xmm9, xmm10);
1103 TestMovups(xmm10, xmm11);
1104 TestMovups(xmm11, xmm12);
1105 TestMovups(xmm12, xmm13);
1106 TestMovups(xmm13, xmm14);
1107 TestMovups(xmm14, xmm15);
1108 TestMovups(xmm15, xmm0);
1109
1110 #undef TestMovups
1111 }
1112
1113 TEST_F(AssemblerX8664Test, MovapsXmmXmm) {
1114 #define TestMovaps(Dst, Src) \
1115 do { \
1116 static constexpr char TestString[] = "(" #Dst ", " #Src ")"; \
1117 const uint32_t T0 = allocateDqword(); \
1118 const Dqword V0(1.0f, -1.0, std::numeric_limits<float>::quiet_NaN(), \
1119 std::numeric_limits<float>::infinity()); \
1120 const uint32_t T1 = allocateDqword(); \
1121 const Dqword V1(0.0, 0.0, 0.0, 0.0); \
1122 \
1123 __ movups(Encoded_Xmm_##Src(), dwordAddress(T0)); \
1124 __ movups(Encoded_Xmm_##Dst(), dwordAddress(T1)); \
1125 __ movaps(Encoded_Xmm_##Dst(), Encoded_Xmm_##Src()); \
1126 \
1127 AssembledTest test = assemble(); \
1128 test.setDqwordTo(T0, V0); \
1129 test.setDqwordTo(T1, V1); \
1130 test.run(); \
1131 \
1132 ASSERT_EQ(V0, test.Dst<Dqword>()) << TestString; \
1133 reset(); \
1134 } while (0)
1135
1136 TestMovaps(xmm0, xmm1);
1137 TestMovaps(xmm1, xmm2);
1138 TestMovaps(xmm2, xmm3);
1139 TestMovaps(xmm3, xmm4);
1140 TestMovaps(xmm4, xmm5);
1141 TestMovaps(xmm5, xmm6);
1142 TestMovaps(xmm6, xmm7);
1143 TestMovaps(xmm7, xmm8);
1144 TestMovaps(xmm8, xmm9);
1145 TestMovaps(xmm9, xmm10);
1146 TestMovaps(xmm10, xmm11);
1147 TestMovaps(xmm11, xmm12);
1148 TestMovaps(xmm12, xmm13);
1149 TestMovaps(xmm13, xmm14);
1150 TestMovaps(xmm14, xmm15);
1151 TestMovaps(xmm15, xmm0);
1152
1153 #undef TestMovaps
1154 }
1155
1156 TEST_F(AssemblerX8664Test, Movhlps_Movlhps) {
1157 #define TestImplSingle(Dst, Src, Inst, Expect) \
1158 do { \
1159 static constexpr char TestString[] = "(" #Dst ", " #Src ", " #Inst ")"; \
1160 const uint32_t T0 = allocateDqword(); \
1161 const Dqword V0(uint64_t(0xAAAAAAAABBBBBBBBull), \
1162 uint64_t(0xCCCCCCCCDDDDDDDDull)); \
1163 const uint32_t T1 = allocateDqword(); \
1164 const Dqword V1(uint64_t(0xEEEEEEEEFFFFFFFFull), \
1165 uint64_t(0x9999999988888888ull)); \
1166 \
1167 __ movups(Encoded_Xmm_##Dst(), dwordAddress(T0)); \
1168 __ movups(Encoded_Xmm_##Src(), dwordAddress(T1)); \
1169 __ Inst(Encoded_Xmm_##Dst(), Encoded_Xmm_##Src()); \
1170 \
1171 AssembledTest test = assemble(); \
1172 test.setDqwordTo(T0, V0); \
1173 test.setDqwordTo(T1, V1); \
1174 test.run(); \
1175 \
1176 ASSERT_EQ(Dqword Expect, test.Dst<Dqword>()) << TestString; \
1177 reset(); \
1178 } while (0)
1179
1180 #define TestImpl(Dst, Src) \
1181 do { \
1182 TestImplSingle(Dst, Src, movhlps, (uint64_t(0x9999999988888888ull), \
1183 uint64_t(0xCCCCCCCCDDDDDDDDull))); \
1184 TestImplSingle(Dst, Src, movlhps, (uint64_t(0xAAAAAAAABBBBBBBBull), \
1185 uint64_t(0xEEEEEEEEFFFFFFFFull))); \
1186 } while (0)
1187
1188 TestImpl(xmm0, xmm1);
1189 TestImpl(xmm1, xmm2);
1190 TestImpl(xmm2, xmm3);
1191 TestImpl(xmm3, xmm4);
1192 TestImpl(xmm4, xmm5);
1193 TestImpl(xmm5, xmm6);
1194 TestImpl(xmm6, xmm7);
1195 TestImpl(xmm7, xmm8);
1196 TestImpl(xmm8, xmm9);
1197 TestImpl(xmm9, xmm10);
1198 TestImpl(xmm10, xmm11);
1199 TestImpl(xmm11, xmm12);
1200 TestImpl(xmm12, xmm13);
1201 TestImpl(xmm13, xmm14);
1202 TestImpl(xmm14, xmm15);
1203 TestImpl(xmm15, xmm0);
1204
1205 #undef TestImpl
1206 #undef TestImplSingle
1207 }
1208
1209 TEST_F(AssemblerX8664Test, Movmsk) {
1210 #define TestMovmskGPRXmm(GPR, Src, Value1, Expected, Inst) \
1211 do { \
1212 static constexpr char TestString[] = \
1213 "(" #GPR ", " #Src ", " #Value1 ", " #Expected ", " #Inst ")"; \
1214 const uint32_t T0 = allocateDqword(); \
1215 const Dqword V0 Value1; \
1216 \
1217 __ movups(Encoded_Xmm_##Src(), dwordAddress(T0)); \
1218 __ Inst(Encoded_GPR_##GPR(), Encoded_Xmm_##Src()); \
1219 \
1220 AssembledTest test = assemble(); \
1221 test.setDqwordTo(T0, V0); \
1222 test.run(); \
1223 \
1224 ASSERT_EQ(Expected, test.GPR()) << TestString; \
1225 reset(); \
1226 } while (0)
1227
1228 #define TestMovmsk(GPR, Src) \
1229 do { \
1230 TestMovmskGPRXmm(GPR, Src, (-1.0, 1.0, -1.0, 1.0), 0x05ul, movmskps); \
1231 TestMovmskGPRXmm(GPR, Src, (1.0, -1.0), 0x02ul, movmskpd); \
1232 } while (0)
1233
1234 TestMovmsk(r1, xmm0);
1235 TestMovmsk(r2, xmm1);
1236 TestMovmsk(r3, xmm2);
1237 TestMovmsk(r4, xmm3);
1238 TestMovmsk(r5, xmm4);
1239 TestMovmsk(r6, xmm5);
1240 TestMovmsk(r7, xmm6);
1241 TestMovmsk(r8, xmm7);
1242 TestMovmsk(r10, xmm8);
1243 TestMovmsk(r11, xmm9);
1244 TestMovmsk(r12, xmm10);
1245 TestMovmsk(r13, xmm11);
1246 TestMovmsk(r14, xmm12);
1247 TestMovmsk(r15, xmm13);
1248 TestMovmsk(r1, xmm14);
1249 TestMovmsk(r2, xmm15);
1250
1251 #undef TestMovmskGPRXmm
1252 #undef TestMovmsk
1253 }
1254
1255 TEST_F(AssemblerX8664Test, Pmovsxdq) {
1256 #define TestPmovsxdqXmmXmm(Dst, Src, Value1) \
1257 do { \
1258 static constexpr char TestString[] = "(" #Dst ", " #Src ", " #Value1 ")"; \
1259 const uint32_t T0 = allocateDqword(); \
1260 const Dqword V0 Value1; \
1261 const uint32_t T1 = allocateDqword(); \
1262 const Dqword V1(uint64_t(0), uint64_t(0)); \
1263 \
1264 __ movups(Encoded_Xmm_##Src(), dwordAddress(T0)); \
1265 __ movups(Encoded_Xmm_##Dst(), dwordAddress(T1)); \
1266 __ pmovsxdq(Encoded_Xmm_##Dst(), Encoded_Xmm_##Src()); \
1267 \
1268 AssembledTest test = assemble(); \
1269 test.setDqwordTo(T0, V0); \
1270 test.setDqwordTo(T1, V1); \
1271 test.run(); \
1272 \
1273 const Dqword Expected(uint64_t(V0.I32[0]), uint64_t(V0.I32[1])); \
1274 ASSERT_EQ(Expected, test.Dst<Dqword>()) << TestString; \
1275 reset(); \
1276 } while (0)
1277
1278 #define TestPmovsxdq(Dst, Src) \
1279 do { \
1280 TestPmovsxdqXmmXmm(Dst, Src, (uint64_t(0x700000007FFFFFFFull), \
1281 uint64_t(0xAAAAAAAAEEEEEEEEull))); \
1282 TestPmovsxdqXmmXmm(Dst, Src, (uint64_t(0x800000007FFFFFFFull), \
1283 uint64_t(0xAAAAAAAAEEEEEEEEull))); \
1284 TestPmovsxdqXmmXmm(Dst, Src, (uint64_t(0x70000000FFFFFFFFull), \
1285 uint64_t(0xAAAAAAAAEEEEEEEEull))); \
1286 TestPmovsxdqXmmXmm(Dst, Src, (uint64_t(0x80000000FFFFFFFFull), \
1287 uint64_t(0xAAAAAAAAEEEEEEEEull))); \
1288 } while (0)
1289
1290 TestPmovsxdq(xmm0, xmm1);
1291 TestPmovsxdq(xmm1, xmm2);
1292 TestPmovsxdq(xmm2, xmm3);
1293 TestPmovsxdq(xmm3, xmm4);
1294 TestPmovsxdq(xmm4, xmm5);
1295 TestPmovsxdq(xmm5, xmm6);
1296 TestPmovsxdq(xmm6, xmm7);
1297 TestPmovsxdq(xmm7, xmm8);
1298 TestPmovsxdq(xmm8, xmm9);
1299 TestPmovsxdq(xmm9, xmm10);
1300 TestPmovsxdq(xmm10, xmm11);
1301 TestPmovsxdq(xmm11, xmm12);
1302 TestPmovsxdq(xmm12, xmm13);
1303 TestPmovsxdq(xmm13, xmm14);
1304 TestPmovsxdq(xmm14, xmm15);
1305 TestPmovsxdq(xmm15, xmm0);
1306
1307 #undef TestPmovsxdq
1308 #undef TestPmovsxdqXmmXmm
1309 }
1310
1311 } // end of anonymous namespace
1312 } // end of namespace Test
1313 } // end of namespace X8664
1314 } // end of namespace Ice
OLDNEW
« no previous file with comments | « unittest/AssemblerX8664/ControlFlow.cpp ('k') | unittest/AssemblerX8664/GPRArith.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698