xref: /llvm-project/llvm/unittests/tools/llvm-exegesis/X86/TargetTest.cpp (revision 6fb3c3a3cb72d932868a31f0a2139df9af292aa6)
1 //===-- TargetTest.cpp -----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "Target.h"
10 
11 #include <cassert>
12 #include <memory>
13 
14 #include "MCTargetDesc/X86MCTargetDesc.h"
15 #include "llvm/MC/TargetRegistry.h"
16 #include "llvm/Support/TargetSelect.h"
17 #include "gmock/gmock.h"
18 #include "gtest/gtest.h"
19 
20 #include "llvm/MC/MCInstPrinter.h"
21 
22 namespace llvm {
23 
24 bool operator==(const MCOperand &a, const MCOperand &b) {
25   if (a.isImm() && b.isImm())
26     return a.getImm() == b.getImm();
27   if (a.isReg() && b.isReg())
28     return a.getReg() == b.getReg();
29   return false;
30 }
31 
32 bool operator==(const MCInst &a, const MCInst &b) {
33   if (a.getOpcode() != b.getOpcode())
34     return false;
35   if (a.getNumOperands() != b.getNumOperands())
36     return false;
37   for (unsigned I = 0; I < a.getNumOperands(); ++I) {
38     if (!(a.getOperand(I) == b.getOperand(I)))
39       return false;
40   }
41   return true;
42 }
43 
44 } // namespace llvm
45 
46 namespace llvm {
47 namespace exegesis {
48 
49 void InitializeX86ExegesisTarget();
50 
51 namespace {
52 
53 using testing::AllOf;
54 using testing::ElementsAre;
55 using testing::ElementsAreArray;
56 using testing::Eq;
57 using testing::Gt;
58 using testing::IsEmpty;
59 using testing::Matcher;
60 using testing::NotNull;
61 using testing::Property;
62 using testing::SizeIs;
63 
64 Matcher<MCOperand> IsImm(int64_t Value) {
65   return AllOf(Property(&MCOperand::isImm, Eq(true)),
66                Property(&MCOperand::getImm, Eq(Value)));
67 }
68 
69 Matcher<MCOperand> IsReg(unsigned Reg) {
70   return AllOf(Property(&MCOperand::isReg, Eq(true)),
71                Property(&MCOperand::getReg, Eq(Reg)));
72 }
73 
74 Matcher<MCInst> OpcodeIs(unsigned Opcode) {
75   return Property(&MCInst::getOpcode, Eq(Opcode));
76 }
77 
78 Matcher<MCInst> IsMovImmediate(unsigned Opcode, int64_t Reg, int64_t Value) {
79   return AllOf(OpcodeIs(Opcode), ElementsAre(IsReg(Reg), IsImm(Value)));
80 }
81 
82 Matcher<MCInst> IsMovValueToStack(unsigned Opcode, int64_t Value,
83                                   size_t Offset) {
84   return AllOf(OpcodeIs(Opcode),
85                ElementsAre(IsReg(X86::RSP), IsImm(1), IsReg(0), IsImm(Offset),
86                            IsReg(0), IsImm(Value)));
87 }
88 
89 Matcher<MCInst> IsMovValueFromStack(unsigned Opcode, unsigned Reg) {
90   return AllOf(OpcodeIs(Opcode),
91                ElementsAre(IsReg(Reg), IsReg(X86::RSP), IsImm(1), IsReg(0),
92                            IsImm(0), IsReg(0)));
93 }
94 
95 Matcher<MCInst> IsStackAllocate(unsigned Size) {
96   return AllOf(OpcodeIs(X86::SUB64ri8),
97                ElementsAre(IsReg(X86::RSP), IsReg(X86::RSP), IsImm(Size)));
98 }
99 
100 Matcher<MCInst> IsStackDeallocate(unsigned Size) {
101   return AllOf(OpcodeIs(X86::ADD64ri8),
102                ElementsAre(IsReg(X86::RSP), IsReg(X86::RSP), IsImm(Size)));
103 }
104 
105 constexpr const char kTriple[] = "x86_64-unknown-linux";
106 
107 class X86TargetTest : public ::testing::Test {
108 protected:
109   X86TargetTest(const char *Features)
110       : State(cantFail(LLVMState::Create(kTriple, "core2", Features))) {}
111 
112   static void SetUpTestCase() {
113     LLVMInitializeX86TargetInfo();
114     LLVMInitializeX86Target();
115     LLVMInitializeX86TargetMC();
116     InitializeX86ExegesisTarget();
117   }
118 
119   std::vector<MCInst> setRegTo(unsigned Reg, const APInt &Value) {
120     return State.getExegesisTarget().setRegTo(State.getSubtargetInfo(), Reg,
121                                               Value);
122   }
123 
124   const Instruction &getInstr(unsigned OpCode) {
125     return State.getIC().getInstr(OpCode);
126   }
127 
128   LLVMState State;
129 };
130 
131 class X86Core2TargetTest : public X86TargetTest {
132 public:
133   X86Core2TargetTest() : X86TargetTest("") {}
134 };
135 
136 class X86Core2AvxTargetTest : public X86TargetTest {
137 public:
138   X86Core2AvxTargetTest() : X86TargetTest("+avx") {}
139 };
140 
141 class X86Core2Avx512TargetTest : public X86TargetTest {
142 public:
143   X86Core2Avx512TargetTest() : X86TargetTest("+avx512vl") {}
144 };
145 
146 class X86Core2Avx512DQTargetTest : public X86TargetTest {
147 public:
148   X86Core2Avx512DQTargetTest() : X86TargetTest("+avx512dq") {}
149 };
150 
151 class X86Core2Avx512BWTargetTest : public X86TargetTest {
152 public:
153   X86Core2Avx512BWTargetTest() : X86TargetTest("+avx512bw") {}
154 };
155 
156 class X86Core2Avx512DQBWTargetTest : public X86TargetTest {
157 public:
158   X86Core2Avx512DQBWTargetTest() : X86TargetTest("+avx512dq,+avx512bw") {}
159 };
160 
161 TEST_F(X86Core2TargetTest, NoHighByteRegs) {
162   EXPECT_TRUE(State.getRATC().reservedRegisters().test(X86::AH));
163 }
164 
165 TEST_F(X86Core2TargetTest, SetFlags) {
166   const unsigned Reg = X86::EFLAGS;
167   EXPECT_THAT(setRegTo(Reg, APInt(64, 0x1111222233334444ULL)),
168               ElementsAre(IsStackAllocate(8),
169                           IsMovValueToStack(X86::MOV32mi, 0x33334444UL, 0),
170                           IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 4),
171                           OpcodeIs(X86::POPF64)));
172 }
173 
174 TEST_F(X86Core2TargetTest, SetRegToGR8Value) {
175   const uint8_t Value = 0xFFU;
176   const unsigned Reg = X86::AL;
177   EXPECT_THAT(setRegTo(Reg, APInt(8, Value)),
178               ElementsAre(IsMovImmediate(X86::MOV8ri, Reg, Value)));
179 }
180 
181 TEST_F(X86Core2TargetTest, SetRegToGR16Value) {
182   const uint16_t Value = 0xFFFFU;
183   const unsigned Reg = X86::BX;
184   EXPECT_THAT(setRegTo(Reg, APInt(16, Value)),
185               ElementsAre(IsMovImmediate(X86::MOV16ri, Reg, Value)));
186 }
187 
188 TEST_F(X86Core2TargetTest, SetRegToGR32Value) {
189   const uint32_t Value = 0x7FFFFU;
190   const unsigned Reg = X86::ECX;
191   EXPECT_THAT(setRegTo(Reg, APInt(32, Value)),
192               ElementsAre(IsMovImmediate(X86::MOV32ri, Reg, Value)));
193 }
194 
195 TEST_F(X86Core2TargetTest, SetRegToGR64Value) {
196   const uint64_t Value = 0x7FFFFFFFFFFFFFFFULL;
197   const unsigned Reg = X86::RDX;
198   EXPECT_THAT(setRegTo(Reg, APInt(64, Value)),
199               ElementsAre(IsMovImmediate(X86::MOV64ri, Reg, Value)));
200 }
201 
202 TEST_F(X86Core2TargetTest, SetRegToVR64Value) {
203   EXPECT_THAT(setRegTo(X86::MM0, APInt(64, 0x1111222233334444ULL)),
204               ElementsAre(IsStackAllocate(8),
205                           IsMovValueToStack(X86::MOV32mi, 0x33334444UL, 0),
206                           IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 4),
207                           IsMovValueFromStack(X86::MMX_MOVQ64rm, X86::MM0),
208                           IsStackDeallocate(8)));
209 }
210 
211 TEST_F(X86Core2TargetTest, SetRegToVR128Value_Use_MOVDQUrm) {
212   EXPECT_THAT(
213       setRegTo(X86::XMM0, APInt(128, "11112222333344445555666677778888", 16)),
214       ElementsAre(IsStackAllocate(16),
215                   IsMovValueToStack(X86::MOV32mi, 0x77778888UL, 0),
216                   IsMovValueToStack(X86::MOV32mi, 0x55556666UL, 4),
217                   IsMovValueToStack(X86::MOV32mi, 0x33334444UL, 8),
218                   IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 12),
219                   IsMovValueFromStack(X86::MOVDQUrm, X86::XMM0),
220                   IsStackDeallocate(16)));
221 }
222 
223 TEST_F(X86Core2AvxTargetTest, SetRegToVR128Value_Use_VMOVDQUrm) {
224   EXPECT_THAT(
225       setRegTo(X86::XMM0, APInt(128, "11112222333344445555666677778888", 16)),
226       ElementsAre(IsStackAllocate(16),
227                   IsMovValueToStack(X86::MOV32mi, 0x77778888UL, 0),
228                   IsMovValueToStack(X86::MOV32mi, 0x55556666UL, 4),
229                   IsMovValueToStack(X86::MOV32mi, 0x33334444UL, 8),
230                   IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 12),
231                   IsMovValueFromStack(X86::VMOVDQUrm, X86::XMM0),
232                   IsStackDeallocate(16)));
233 }
234 
235 TEST_F(X86Core2Avx512TargetTest, SetRegToVR128Value_Use_VMOVDQU32Z128rm) {
236   EXPECT_THAT(
237       setRegTo(X86::XMM0, APInt(128, "11112222333344445555666677778888", 16)),
238       ElementsAre(IsStackAllocate(16),
239                   IsMovValueToStack(X86::MOV32mi, 0x77778888UL, 0),
240                   IsMovValueToStack(X86::MOV32mi, 0x55556666UL, 4),
241                   IsMovValueToStack(X86::MOV32mi, 0x33334444UL, 8),
242                   IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 12),
243                   IsMovValueFromStack(X86::VMOVDQU32Z128rm, X86::XMM0),
244                   IsStackDeallocate(16)));
245 }
246 
247 TEST_F(X86Core2AvxTargetTest, SetRegToVR256Value_Use_VMOVDQUYrm) {
248   const char ValueStr[] =
249       "1111111122222222333333334444444455555555666666667777777788888888";
250   EXPECT_THAT(
251       setRegTo(X86::YMM0, APInt(256, ValueStr, 16)),
252       ElementsAreArray({IsStackAllocate(32),
253                         IsMovValueToStack(X86::MOV32mi, 0x88888888UL, 0),
254                         IsMovValueToStack(X86::MOV32mi, 0x77777777UL, 4),
255                         IsMovValueToStack(X86::MOV32mi, 0x66666666UL, 8),
256                         IsMovValueToStack(X86::MOV32mi, 0x55555555UL, 12),
257                         IsMovValueToStack(X86::MOV32mi, 0x44444444UL, 16),
258                         IsMovValueToStack(X86::MOV32mi, 0x33333333UL, 20),
259                         IsMovValueToStack(X86::MOV32mi, 0x22222222UL, 24),
260                         IsMovValueToStack(X86::MOV32mi, 0x11111111UL, 28),
261                         IsMovValueFromStack(X86::VMOVDQUYrm, X86::YMM0),
262                         IsStackDeallocate(32)}));
263 }
264 
265 TEST_F(X86Core2Avx512TargetTest, SetRegToVR256Value_Use_VMOVDQU32Z256rm) {
266   const char ValueStr[] =
267       "1111111122222222333333334444444455555555666666667777777788888888";
268   EXPECT_THAT(
269       setRegTo(X86::YMM0, APInt(256, ValueStr, 16)),
270       ElementsAreArray({IsStackAllocate(32),
271                         IsMovValueToStack(X86::MOV32mi, 0x88888888UL, 0),
272                         IsMovValueToStack(X86::MOV32mi, 0x77777777UL, 4),
273                         IsMovValueToStack(X86::MOV32mi, 0x66666666UL, 8),
274                         IsMovValueToStack(X86::MOV32mi, 0x55555555UL, 12),
275                         IsMovValueToStack(X86::MOV32mi, 0x44444444UL, 16),
276                         IsMovValueToStack(X86::MOV32mi, 0x33333333UL, 20),
277                         IsMovValueToStack(X86::MOV32mi, 0x22222222UL, 24),
278                         IsMovValueToStack(X86::MOV32mi, 0x11111111UL, 28),
279                         IsMovValueFromStack(X86::VMOVDQU32Z256rm, X86::YMM0),
280                         IsStackDeallocate(32)}));
281 }
282 
283 TEST_F(X86Core2Avx512TargetTest, SetRegToVR512Value) {
284   const char ValueStr[] =
285       "1111111122222222333333334444444455555555666666667777777788888888"
286       "99999999AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDDEEEEEEEEFFFFFFFF00000000";
287   EXPECT_THAT(
288       setRegTo(X86::ZMM0, APInt(512, ValueStr, 16)),
289       ElementsAreArray({IsStackAllocate(64),
290                         IsMovValueToStack(X86::MOV32mi, 0x00000000UL, 0),
291                         IsMovValueToStack(X86::MOV32mi, 0xFFFFFFFFUL, 4),
292                         IsMovValueToStack(X86::MOV32mi, 0xEEEEEEEEUL, 8),
293                         IsMovValueToStack(X86::MOV32mi, 0xDDDDDDDDUL, 12),
294                         IsMovValueToStack(X86::MOV32mi, 0xCCCCCCCCUL, 16),
295                         IsMovValueToStack(X86::MOV32mi, 0xBBBBBBBBUL, 20),
296                         IsMovValueToStack(X86::MOV32mi, 0xAAAAAAAAUL, 24),
297                         IsMovValueToStack(X86::MOV32mi, 0x99999999UL, 28),
298                         IsMovValueToStack(X86::MOV32mi, 0x88888888UL, 32),
299                         IsMovValueToStack(X86::MOV32mi, 0x77777777UL, 36),
300                         IsMovValueToStack(X86::MOV32mi, 0x66666666UL, 40),
301                         IsMovValueToStack(X86::MOV32mi, 0x55555555UL, 44),
302                         IsMovValueToStack(X86::MOV32mi, 0x44444444UL, 48),
303                         IsMovValueToStack(X86::MOV32mi, 0x33333333UL, 52),
304                         IsMovValueToStack(X86::MOV32mi, 0x22222222UL, 56),
305                         IsMovValueToStack(X86::MOV32mi, 0x11111111UL, 60),
306                         IsMovValueFromStack(X86::VMOVDQU32Zrm, X86::ZMM0),
307                         IsStackDeallocate(64)}));
308 }
309 
310 TEST_F(X86Core2Avx512TargetTest, SetRegToK0_16Bits) {
311   const uint16_t Value = 0xABCDU;
312   const unsigned Reg = X86::K0;
313   const unsigned RegBitWidth = 16;
314   EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
315               ElementsAre(IsStackAllocate(2),
316                           IsMovValueToStack(X86::MOV16mi, Value, 0),
317                           IsMovValueFromStack(X86::KMOVWkm, Reg),
318                           IsStackDeallocate(2)));
319 }
320 
321 TEST_F(X86Core2Avx512DQTargetTest, SetRegToK0_16Bits) {
322   const uint16_t Value = 0xABCDU;
323   const unsigned Reg = X86::K0;
324   const unsigned RegBitWidth = 16;
325   EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
326               ElementsAre(IsStackAllocate(2),
327                           IsMovValueToStack(X86::MOV16mi, Value, 0),
328                           IsMovValueFromStack(X86::KMOVWkm, Reg),
329                           IsStackDeallocate(2)));
330 }
331 
332 TEST_F(X86Core2Avx512BWTargetTest, SetRegToK0_16Bits) {
333   const uint16_t Value = 0xABCDU;
334   const unsigned Reg = X86::K0;
335   const unsigned RegBitWidth = 16;
336   EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
337               ElementsAre(IsStackAllocate(RegBitWidth / 8),
338                           IsMovValueToStack(X86::MOV16mi, Value, 0),
339                           IsMovValueFromStack(X86::KMOVWkm, Reg),
340                           IsStackDeallocate(RegBitWidth / 8)));
341 }
342 
343 TEST_F(X86Core2Avx512DQBWTargetTest, SetRegToK0_16Bits) {
344   const uint16_t Value = 0xABCDU;
345   const unsigned Reg = X86::K0;
346   const unsigned RegBitWidth = 16;
347   EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
348               ElementsAre(IsStackAllocate(RegBitWidth / 8),
349                           IsMovValueToStack(X86::MOV16mi, Value, 0),
350                           IsMovValueFromStack(X86::KMOVWkm, Reg),
351                           IsStackDeallocate(RegBitWidth / 8)));
352 }
353 
354 TEST_F(X86Core2Avx512TargetTest, SetRegToK0_8Bits) {
355   const uint8_t Value = 0xABU;
356   const unsigned Reg = X86::K0;
357   const unsigned RegBitWidth = 8;
358   EXPECT_THAT(
359       setRegTo(Reg, APInt(RegBitWidth, Value)),
360       ElementsAre(IsStackAllocate(2),
361                   IsMovValueToStack(
362                       X86::MOV16mi,
363                       APInt(RegBitWidth, Value).zext(16).getZExtValue(), 0),
364                   IsMovValueFromStack(X86::KMOVWkm, Reg),
365                   IsStackDeallocate(2)));
366 }
367 
368 TEST_F(X86Core2Avx512DQTargetTest, SetRegToK0_8Bits) {
369   const uint8_t Value = 0xABU;
370   const unsigned Reg = X86::K0;
371   const unsigned RegBitWidth = 8;
372   EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
373               ElementsAre(IsStackAllocate(RegBitWidth / 8),
374                           IsMovValueToStack(X86::MOV8mi, Value, 0),
375                           IsMovValueFromStack(X86::KMOVBkm, Reg),
376                           IsStackDeallocate(RegBitWidth / 8)));
377 }
378 
379 TEST_F(X86Core2Avx512BWTargetTest, SetRegToK0_8Bits) {
380   const uint8_t Value = 0xABU;
381   const unsigned Reg = X86::K0;
382   const unsigned RegBitWidth = 8;
383   EXPECT_THAT(
384       setRegTo(Reg, APInt(RegBitWidth, Value)),
385       ElementsAre(IsStackAllocate(2),
386                   IsMovValueToStack(
387                       X86::MOV16mi,
388                       APInt(RegBitWidth, Value).zext(16).getZExtValue(), 0),
389                   IsMovValueFromStack(X86::KMOVWkm, Reg),
390                   IsStackDeallocate(2)));
391 }
392 
393 TEST_F(X86Core2Avx512DQBWTargetTest, SetRegToK0_8Bits) {
394   const uint8_t Value = 0xABU;
395   const unsigned Reg = X86::K0;
396   const unsigned RegBitWidth = 8;
397   EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
398               ElementsAre(IsStackAllocate(RegBitWidth / 8),
399                           IsMovValueToStack(X86::MOV8mi, Value, 0),
400                           IsMovValueFromStack(X86::KMOVBkm, Reg),
401                           IsStackDeallocate(RegBitWidth / 8)));
402 }
403 
404 TEST_F(X86Core2Avx512TargetTest, SetRegToK0_32Bits) {
405   const uint32_t Value = 0xABCDCABDU;
406   const unsigned Reg = X86::K0;
407   const unsigned RegBitWidth = 32;
408   EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)), IsEmpty());
409 }
410 
411 TEST_F(X86Core2Avx512DQTargetTest, SetRegToK0_32Bits) {
412   const uint32_t Value = 0xABCDCABDU;
413   const unsigned Reg = X86::K0;
414   const unsigned RegBitWidth = 32;
415   EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)), IsEmpty());
416 }
417 
418 TEST_F(X86Core2Avx512BWTargetTest, SetRegToK0_32Bits) {
419   const uint32_t Value = 0xABCDCABDU;
420   const unsigned Reg = X86::K0;
421   const unsigned RegBitWidth = 32;
422   EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
423               ElementsAre(IsStackAllocate(RegBitWidth / 8),
424                           IsMovValueToStack(X86::MOV32mi, Value, 0),
425                           IsMovValueFromStack(X86::KMOVDkm, Reg),
426                           IsStackDeallocate(RegBitWidth / 8)));
427 }
428 
429 TEST_F(X86Core2Avx512DQBWTargetTest, SetRegToK0_32Bits) {
430   const uint32_t Value = 0xABCDCABDU;
431   const unsigned Reg = X86::K0;
432   const unsigned RegBitWidth = 32;
433   EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
434               ElementsAre(IsStackAllocate(RegBitWidth / 8),
435                           IsMovValueToStack(X86::MOV32mi, Value, 0),
436                           IsMovValueFromStack(X86::KMOVDkm, Reg),
437                           IsStackDeallocate(RegBitWidth / 8)));
438 }
439 
440 TEST_F(X86Core2Avx512TargetTest, SetRegToK0_64Bits) {
441   const uint64_t Value = 0xABCDABCDCABDCABDU;
442   const unsigned Reg = X86::K0;
443   const unsigned RegBitWidth = 64;
444   EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)), IsEmpty());
445 }
446 
447 TEST_F(X86Core2Avx512DQTargetTest, SetRegToK0_64Bits) {
448   const uint64_t Value = 0xABCDABCDCABDCABDU;
449   const unsigned Reg = X86::K0;
450   const unsigned RegBitWidth = 64;
451   EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)), IsEmpty());
452 }
453 
454 TEST_F(X86Core2Avx512BWTargetTest, SetRegToK0_64Bits) {
455   const uint64_t Value = 0xABCDABCDCABDCABDUL;
456   const unsigned Reg = X86::K0;
457   const unsigned RegBitWidth = 64;
458   EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
459               ElementsAre(IsStackAllocate(RegBitWidth / 8),
460                           IsMovValueToStack(X86::MOV32mi, 0XCABDCABDUL, 0),
461                           IsMovValueToStack(X86::MOV32mi, 0xABCDABCDUL, 4),
462                           IsMovValueFromStack(X86::KMOVQkm, Reg),
463                           IsStackDeallocate(RegBitWidth / 8)));
464 }
465 
466 TEST_F(X86Core2Avx512DQBWTargetTest, SetRegToK0_64Bits) {
467   const uint64_t Value = 0xABCDABCDCABDCABDU;
468   const unsigned Reg = X86::K0;
469   const unsigned RegBitWidth = 64;
470   EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),
471               ElementsAre(IsStackAllocate(RegBitWidth / 8),
472                           IsMovValueToStack(X86::MOV32mi, 0XCABDCABDUL, 0),
473                           IsMovValueToStack(X86::MOV32mi, 0xABCDABCDUL, 4),
474                           IsMovValueFromStack(X86::KMOVQkm, Reg),
475                           IsStackDeallocate(RegBitWidth / 8)));
476 }
477 
478 // Note: We always put 80 bits on the stack independently of the size of the
479 // value. This uses a bit more space but makes the code simpler.
480 
481 TEST_F(X86Core2TargetTest, SetRegToST0_32Bits) {
482   EXPECT_THAT(setRegTo(X86::ST0, APInt(32, 0x11112222ULL)),
483               ElementsAre(IsStackAllocate(10),
484                           IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 0),
485                           IsMovValueToStack(X86::MOV32mi, 0x00000000UL, 4),
486                           IsMovValueToStack(X86::MOV16mi, 0x0000UL, 8),
487                           OpcodeIs(X86::LD_F80m), IsStackDeallocate(10)));
488 }
489 
490 TEST_F(X86Core2TargetTest, SetRegToST1_32Bits) {
491   const MCInst CopySt0ToSt1 = MCInstBuilder(X86::ST_Frr).addReg(X86::ST1);
492   EXPECT_THAT(setRegTo(X86::ST1, APInt(32, 0x11112222ULL)),
493               ElementsAre(IsStackAllocate(10),
494                           IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 0),
495                           IsMovValueToStack(X86::MOV32mi, 0x00000000UL, 4),
496                           IsMovValueToStack(X86::MOV16mi, 0x0000UL, 8),
497                           OpcodeIs(X86::LD_F80m), CopySt0ToSt1,
498                           IsStackDeallocate(10)));
499 }
500 
501 TEST_F(X86Core2TargetTest, SetRegToST0_64Bits) {
502   EXPECT_THAT(setRegTo(X86::ST0, APInt(64, 0x1111222233334444ULL)),
503               ElementsAre(IsStackAllocate(10),
504                           IsMovValueToStack(X86::MOV32mi, 0x33334444UL, 0),
505                           IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 4),
506                           IsMovValueToStack(X86::MOV16mi, 0x0000UL, 8),
507                           OpcodeIs(X86::LD_F80m), IsStackDeallocate(10)));
508 }
509 
510 TEST_F(X86Core2TargetTest, SetRegToST0_80Bits) {
511   EXPECT_THAT(setRegTo(X86::ST0, APInt(80, "11112222333344445555", 16)),
512               ElementsAre(IsStackAllocate(10),
513                           IsMovValueToStack(X86::MOV32mi, 0x44445555UL, 0),
514                           IsMovValueToStack(X86::MOV32mi, 0x22223333UL, 4),
515                           IsMovValueToStack(X86::MOV16mi, 0x1111UL, 8),
516                           OpcodeIs(X86::LD_F80m), IsStackDeallocate(10)));
517 }
518 
519 TEST_F(X86Core2TargetTest, SetRegToFP0_80Bits) {
520   EXPECT_THAT(setRegTo(X86::FP0, APInt(80, "11112222333344445555", 16)),
521               ElementsAre(IsStackAllocate(10),
522                           IsMovValueToStack(X86::MOV32mi, 0x44445555UL, 0),
523                           IsMovValueToStack(X86::MOV32mi, 0x22223333UL, 4),
524                           IsMovValueToStack(X86::MOV16mi, 0x1111UL, 8),
525                           OpcodeIs(X86::LD_Fp80m), IsStackDeallocate(10)));
526 }
527 
528 TEST_F(X86Core2TargetTest, SetRegToFP1_32Bits) {
529   EXPECT_THAT(setRegTo(X86::FP1, APInt(32, 0x11112222ULL)),
530               ElementsAre(IsStackAllocate(10),
531                           IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 0),
532                           IsMovValueToStack(X86::MOV32mi, 0x00000000UL, 4),
533                           IsMovValueToStack(X86::MOV16mi, 0x0000UL, 8),
534                           OpcodeIs(X86::LD_Fp80m), IsStackDeallocate(10)));
535 }
536 
537 TEST_F(X86Core2TargetTest, SetRegToFP1_4Bits) {
538   EXPECT_THAT(setRegTo(X86::FP1, APInt(4, 0x1ULL)),
539               ElementsAre(IsStackAllocate(10),
540                           IsMovValueToStack(X86::MOV32mi, 0x00000001UL, 0),
541                           IsMovValueToStack(X86::MOV32mi, 0x00000000UL, 4),
542                           IsMovValueToStack(X86::MOV16mi, 0x0000UL, 8),
543                           OpcodeIs(X86::LD_Fp80m), IsStackDeallocate(10)));
544 }
545 
546 TEST_F(X86Core2Avx512TargetTest, FillMemoryOperands_ADD64rm) {
547   const Instruction &I = getInstr(X86::ADD64rm);
548   InstructionTemplate IT(&I);
549   constexpr const int kOffset = 42;
550   State.getExegesisTarget().fillMemoryOperands(IT, X86::RDI, kOffset);
551   // Memory is operands 2-6.
552   EXPECT_THAT(IT.getValueFor(I.Operands[2]), IsReg(X86::RDI));
553   EXPECT_THAT(IT.getValueFor(I.Operands[3]), IsImm(1));
554   EXPECT_THAT(IT.getValueFor(I.Operands[4]), IsReg(0));
555   EXPECT_THAT(IT.getValueFor(I.Operands[5]), IsImm(kOffset));
556   EXPECT_THAT(IT.getValueFor(I.Operands[6]), IsReg(0));
557 }
558 
559 TEST_F(X86Core2Avx512TargetTest, FillMemoryOperands_VGATHERDPSZ128rm) {
560   const Instruction &I = getInstr(X86::VGATHERDPSZ128rm);
561   InstructionTemplate IT(&I);
562   constexpr const int kOffset = 42;
563   State.getExegesisTarget().fillMemoryOperands(IT, X86::RDI, kOffset);
564   // Memory is operands 4-8.
565   EXPECT_THAT(IT.getValueFor(I.Operands[4]), IsReg(X86::RDI));
566   EXPECT_THAT(IT.getValueFor(I.Operands[5]), IsImm(1));
567   EXPECT_THAT(IT.getValueFor(I.Operands[6]), IsReg(0));
568   EXPECT_THAT(IT.getValueFor(I.Operands[7]), IsImm(kOffset));
569   EXPECT_THAT(IT.getValueFor(I.Operands[8]), IsReg(0));
570 }
571 
572 TEST_F(X86Core2TargetTest, AllowAsBackToBack) {
573   EXPECT_TRUE(
574       State.getExegesisTarget().allowAsBackToBack(getInstr(X86::ADD64rr)));
575   EXPECT_FALSE(
576       State.getExegesisTarget().allowAsBackToBack(getInstr(X86::LEA64r)));
577 }
578 
579 } // namespace
580 } // namespace exegesis
581 } // namespace llvm
582