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

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

Powered by Google App Engine
This is Rietveld 408576698