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