700 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "Target.h"10 11#include <cassert>12 13#include "MCTargetDesc/X86MCTargetDesc.h"14#include "MmapUtils.h"15#include "SubprocessMemory.h"16#include "TestBase.h"17#include "llvm/MC/TargetRegistry.h"18#include "llvm/Support/TargetSelect.h"19#include "gmock/gmock.h"20#include "gtest/gtest.h"21 22#include "llvm/MC/MCInstPrinter.h"23 24#ifdef __linux__25#include <sys/mman.h>26#include <sys/syscall.h>27#endif // __linux__28 29namespace llvm {30 31bool operator==(const MCOperand &a, const MCOperand &b) {32 if (a.isImm() && b.isImm())33 return a.getImm() == b.getImm();34 if (a.isReg() && b.isReg())35 return a.getReg() == b.getReg();36 return false;37}38 39bool operator==(const MCInst &a, const MCInst &b) {40 if (a.getOpcode() != b.getOpcode())41 return false;42 if (a.getNumOperands() != b.getNumOperands())43 return false;44 for (unsigned I = 0; I < a.getNumOperands(); ++I) {45 if (!(a.getOperand(I) == b.getOperand(I)))46 return false;47 }48 return true;49}50 51} // namespace llvm52 53namespace llvm {54namespace exegesis {55namespace {56 57using testing::AllOf;58using testing::ElementsAre;59using testing::ElementsAreArray;60using testing::Eq;61using testing::IsEmpty;62using testing::Matcher;63using testing::Property;64 65Matcher<MCOperand> IsImm(int64_t Value) {66 return AllOf(Property(&MCOperand::isImm, Eq(true)),67 Property(&MCOperand::getImm, Eq(Value)));68}69 70Matcher<MCOperand> IsReg(unsigned Reg) {71 return AllOf(Property(&MCOperand::isReg, Eq(true)),72 Property(&MCOperand::getReg, Eq(Reg)));73}74 75Matcher<MCInst> OpcodeIs(unsigned Opcode) {76 return Property(&MCInst::getOpcode, Eq(Opcode));77}78 79Matcher<MCInst> IsMovImmediate(unsigned Opcode, int64_t Reg, int64_t Value) {80 return AllOf(OpcodeIs(Opcode), ElementsAre(IsReg(Reg), IsImm(Value)));81}82 83#ifdef __linux__84Matcher<MCInst> IsMovRegToReg(unsigned Opcode, int64_t Reg1, int64_t Reg2) {85 return AllOf(OpcodeIs(Opcode), ElementsAre(IsReg(Reg1), IsReg(Reg2)));86}87#endif88 89Matcher<MCInst> IsMovValueToStack(unsigned Opcode, int64_t Value,90 size_t Offset) {91 return AllOf(OpcodeIs(Opcode),92 ElementsAre(IsReg(X86::RSP), IsImm(1), IsReg(0), IsImm(Offset),93 IsReg(0), IsImm(Value)));94}95 96Matcher<MCInst> IsMovValueFromStack(unsigned Opcode, unsigned Reg) {97 return AllOf(OpcodeIs(Opcode),98 ElementsAre(IsReg(Reg), IsReg(X86::RSP), IsImm(1), IsReg(0),99 IsImm(0), IsReg(0)));100}101 102Matcher<MCInst> IsStackAllocate(unsigned Size) {103 return AllOf(OpcodeIs(X86::SUB64ri8),104 ElementsAre(IsReg(X86::RSP), IsReg(X86::RSP), IsImm(Size)));105}106 107Matcher<MCInst> IsStackDeallocate(unsigned Size) {108 return AllOf(OpcodeIs(X86::ADD64ri8),109 ElementsAre(IsReg(X86::RSP), IsReg(X86::RSP), IsImm(Size)));110}111 112class X86TargetTest : public X86TestBase {113protected:114 X86TargetTest(const char *Features) : X86TestBase("core2", Features) {}115 116 std::vector<MCInst> setRegTo(unsigned Reg, const APInt &Value) {117 return State.getExegesisTarget().setRegTo(State.getSubtargetInfo(), Reg,118 Value);119 }120 121 const Instruction &getInstr(unsigned OpCode) {122 return State.getIC().getInstr(OpCode);123 }124};125 126class X86Core2TargetTest : public X86TargetTest {127public:128 X86Core2TargetTest() : X86TargetTest("") {}129};130 131class X86Core2AvxTargetTest : public X86TargetTest {132public:133 X86Core2AvxTargetTest() : X86TargetTest("+avx") {}134};135 136class X86Core2Avx512TargetTest : public X86TargetTest {137public:138 X86Core2Avx512TargetTest() : X86TargetTest("+avx512vl") {}139};140 141class X86Core2Avx512DQTargetTest : public X86TargetTest {142public:143 X86Core2Avx512DQTargetTest() : X86TargetTest("+avx512dq") {}144};145 146class X86Core2Avx512BWTargetTest : public X86TargetTest {147public:148 X86Core2Avx512BWTargetTest() : X86TargetTest("+avx512bw") {}149};150 151class X86Core2Avx512DQBWTargetTest : public X86TargetTest {152public:153 X86Core2Avx512DQBWTargetTest() : X86TargetTest("+avx512dq,+avx512bw") {}154};155 156TEST_F(X86Core2TargetTest, NoHighByteRegs) {157 EXPECT_TRUE(State.getRATC().reservedRegisters().test(X86::AH));158}159 160TEST_F(X86Core2TargetTest, SetFlags) {161 const unsigned Reg = X86::EFLAGS;162 EXPECT_THAT(setRegTo(Reg, APInt(64, 0x1111222233334444ULL)),163 ElementsAre(IsStackAllocate(8),164 IsMovValueToStack(X86::MOV32mi, 0x33334444UL, 0),165 IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 4),166 OpcodeIs(X86::POPF64)));167}168 169TEST_F(X86Core2TargetTest, SetRegToGR8Value) {170 const uint8_t Value = 0xFFU;171 const unsigned Reg = X86::AL;172 EXPECT_THAT(setRegTo(Reg, APInt(8, Value)),173 ElementsAre(IsMovImmediate(X86::MOV8ri, Reg, Value)));174}175 176TEST_F(X86Core2TargetTest, SetRegToGR16Value) {177 const uint16_t Value = 0xFFFFU;178 const unsigned Reg = X86::BX;179 EXPECT_THAT(setRegTo(Reg, APInt(16, Value)),180 ElementsAre(IsMovImmediate(X86::MOV16ri, Reg, Value)));181}182 183TEST_F(X86Core2TargetTest, SetRegToGR32Value) {184 const uint32_t Value = 0x7FFFFU;185 const unsigned Reg = X86::ECX;186 EXPECT_THAT(setRegTo(Reg, APInt(32, Value)),187 ElementsAre(IsMovImmediate(X86::MOV32ri, Reg, Value)));188}189 190TEST_F(X86Core2TargetTest, SetRegToGR64Value) {191 const uint64_t Value = 0x7FFFFFFFFFFFFFFFULL;192 const unsigned Reg = X86::RDX;193 EXPECT_THAT(setRegTo(Reg, APInt(64, Value)),194 ElementsAre(IsMovImmediate(X86::MOV64ri, Reg, Value)));195}196 197TEST_F(X86Core2TargetTest, SetRegToVR64Value) {198 EXPECT_THAT(setRegTo(X86::MM0, APInt(64, 0x1111222233334444ULL)),199 ElementsAre(IsStackAllocate(8),200 IsMovValueToStack(X86::MOV32mi, 0x33334444UL, 0),201 IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 4),202 IsMovValueFromStack(X86::MMX_MOVQ64rm, X86::MM0),203 IsStackDeallocate(8)));204}205 206TEST_F(X86Core2TargetTest, SetRegToVR128Value_Use_MOVDQUrm) {207 EXPECT_THAT(208 setRegTo(X86::XMM0, APInt(128, "11112222333344445555666677778888", 16)),209 ElementsAre(IsStackAllocate(16),210 IsMovValueToStack(X86::MOV32mi, 0x77778888UL, 0),211 IsMovValueToStack(X86::MOV32mi, 0x55556666UL, 4),212 IsMovValueToStack(X86::MOV32mi, 0x33334444UL, 8),213 IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 12),214 IsMovValueFromStack(X86::MOVDQUrm, X86::XMM0),215 IsStackDeallocate(16)));216}217 218TEST_F(X86Core2AvxTargetTest, SetRegToVR128Value_Use_VMOVDQUrm) {219 EXPECT_THAT(220 setRegTo(X86::XMM0, APInt(128, "11112222333344445555666677778888", 16)),221 ElementsAre(IsStackAllocate(16),222 IsMovValueToStack(X86::MOV32mi, 0x77778888UL, 0),223 IsMovValueToStack(X86::MOV32mi, 0x55556666UL, 4),224 IsMovValueToStack(X86::MOV32mi, 0x33334444UL, 8),225 IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 12),226 IsMovValueFromStack(X86::VMOVDQUrm, X86::XMM0),227 IsStackDeallocate(16)));228}229 230TEST_F(X86Core2Avx512TargetTest,231 SetRegToVR128ValueHighXMM_Use_VMOVDQU32Z128rm) {232 EXPECT_THAT(233 setRegTo(X86::XMM16, APInt(128, "11112222333344445555666677778888", 16)),234 ElementsAre(IsStackAllocate(16),235 IsMovValueToStack(X86::MOV32mi, 0x77778888UL, 0),236 IsMovValueToStack(X86::MOV32mi, 0x55556666UL, 4),237 IsMovValueToStack(X86::MOV32mi, 0x33334444UL, 8),238 IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 12),239 IsMovValueFromStack(X86::VMOVDQU32Z128rm, X86::XMM16),240 IsStackDeallocate(16)));241}242 243TEST_F(X86Core2Avx512TargetTest, SetRegToVR128ValueLowXMM_Use_VMOVDQUrm) {244 EXPECT_THAT(245 setRegTo(X86::XMM0, APInt(128, "11112222333344445555666677778888", 16)),246 ElementsAre(IsStackAllocate(16),247 IsMovValueToStack(X86::MOV32mi, 0x77778888UL, 0),248 IsMovValueToStack(X86::MOV32mi, 0x55556666UL, 4),249 IsMovValueToStack(X86::MOV32mi, 0x33334444UL, 8),250 IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 12),251 IsMovValueFromStack(X86::VMOVDQUrm, X86::XMM0),252 IsStackDeallocate(16)));253}254 255TEST_F(X86Core2AvxTargetTest, SetRegToVR256Value_Use_VMOVDQUYrm) {256 const char ValueStr[] =257 "1111111122222222333333334444444455555555666666667777777788888888";258 EXPECT_THAT(259 setRegTo(X86::YMM0, APInt(256, ValueStr, 16)),260 ElementsAreArray({IsStackAllocate(32),261 IsMovValueToStack(X86::MOV32mi, 0x88888888UL, 0),262 IsMovValueToStack(X86::MOV32mi, 0x77777777UL, 4),263 IsMovValueToStack(X86::MOV32mi, 0x66666666UL, 8),264 IsMovValueToStack(X86::MOV32mi, 0x55555555UL, 12),265 IsMovValueToStack(X86::MOV32mi, 0x44444444UL, 16),266 IsMovValueToStack(X86::MOV32mi, 0x33333333UL, 20),267 IsMovValueToStack(X86::MOV32mi, 0x22222222UL, 24),268 IsMovValueToStack(X86::MOV32mi, 0x11111111UL, 28),269 IsMovValueFromStack(X86::VMOVDQUYrm, X86::YMM0),270 IsStackDeallocate(32)}));271}272 273TEST_F(X86Core2Avx512TargetTest,274 SetRegToVR256ValueHighYMM_Use_VMOVDQU32Z256rm) {275 const char ValueStr[] =276 "1111111122222222333333334444444455555555666666667777777788888888";277 EXPECT_THAT(278 setRegTo(X86::YMM16, APInt(256, ValueStr, 16)),279 ElementsAreArray({IsStackAllocate(32),280 IsMovValueToStack(X86::MOV32mi, 0x88888888UL, 0),281 IsMovValueToStack(X86::MOV32mi, 0x77777777UL, 4),282 IsMovValueToStack(X86::MOV32mi, 0x66666666UL, 8),283 IsMovValueToStack(X86::MOV32mi, 0x55555555UL, 12),284 IsMovValueToStack(X86::MOV32mi, 0x44444444UL, 16),285 IsMovValueToStack(X86::MOV32mi, 0x33333333UL, 20),286 IsMovValueToStack(X86::MOV32mi, 0x22222222UL, 24),287 IsMovValueToStack(X86::MOV32mi, 0x11111111UL, 28),288 IsMovValueFromStack(X86::VMOVDQU32Z256rm, X86::YMM16),289 IsStackDeallocate(32)}));290}291 292TEST_F(X86Core2Avx512TargetTest, SetRegToVR256ValueLowYMM_Use_VMOVDQUYrm) {293 const char ValueStr[] =294 "1111111122222222333333334444444455555555666666667777777788888888";295 EXPECT_THAT(296 setRegTo(X86::YMM0, APInt(256, ValueStr, 16)),297 ElementsAreArray({IsStackAllocate(32),298 IsMovValueToStack(X86::MOV32mi, 0x88888888UL, 0),299 IsMovValueToStack(X86::MOV32mi, 0x77777777UL, 4),300 IsMovValueToStack(X86::MOV32mi, 0x66666666UL, 8),301 IsMovValueToStack(X86::MOV32mi, 0x55555555UL, 12),302 IsMovValueToStack(X86::MOV32mi, 0x44444444UL, 16),303 IsMovValueToStack(X86::MOV32mi, 0x33333333UL, 20),304 IsMovValueToStack(X86::MOV32mi, 0x22222222UL, 24),305 IsMovValueToStack(X86::MOV32mi, 0x11111111UL, 28),306 IsMovValueFromStack(X86::VMOVDQUYrm, X86::YMM0),307 IsStackDeallocate(32)}));308}309 310TEST_F(X86Core2Avx512TargetTest, SetRegToVR512Value) {311 const char ValueStr[] =312 "1111111122222222333333334444444455555555666666667777777788888888"313 "99999999AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDDEEEEEEEEFFFFFFFF00000000";314 EXPECT_THAT(315 setRegTo(X86::ZMM0, APInt(512, ValueStr, 16)),316 ElementsAreArray({IsStackAllocate(64),317 IsMovValueToStack(X86::MOV32mi, 0x00000000UL, 0),318 IsMovValueToStack(X86::MOV32mi, 0xFFFFFFFFUL, 4),319 IsMovValueToStack(X86::MOV32mi, 0xEEEEEEEEUL, 8),320 IsMovValueToStack(X86::MOV32mi, 0xDDDDDDDDUL, 12),321 IsMovValueToStack(X86::MOV32mi, 0xCCCCCCCCUL, 16),322 IsMovValueToStack(X86::MOV32mi, 0xBBBBBBBBUL, 20),323 IsMovValueToStack(X86::MOV32mi, 0xAAAAAAAAUL, 24),324 IsMovValueToStack(X86::MOV32mi, 0x99999999UL, 28),325 IsMovValueToStack(X86::MOV32mi, 0x88888888UL, 32),326 IsMovValueToStack(X86::MOV32mi, 0x77777777UL, 36),327 IsMovValueToStack(X86::MOV32mi, 0x66666666UL, 40),328 IsMovValueToStack(X86::MOV32mi, 0x55555555UL, 44),329 IsMovValueToStack(X86::MOV32mi, 0x44444444UL, 48),330 IsMovValueToStack(X86::MOV32mi, 0x33333333UL, 52),331 IsMovValueToStack(X86::MOV32mi, 0x22222222UL, 56),332 IsMovValueToStack(X86::MOV32mi, 0x11111111UL, 60),333 IsMovValueFromStack(X86::VMOVDQU32Zrm, X86::ZMM0),334 IsStackDeallocate(64)}));335}336 337TEST_F(X86Core2Avx512TargetTest, SetRegToK0_16Bits) {338 const uint16_t Value = 0xABCDU;339 const unsigned Reg = X86::K0;340 const unsigned RegBitWidth = 16;341 EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),342 ElementsAre(IsStackAllocate(2),343 IsMovValueToStack(X86::MOV16mi, Value, 0),344 IsMovValueFromStack(X86::KMOVWkm, Reg),345 IsStackDeallocate(2)));346}347 348TEST_F(X86Core2Avx512DQTargetTest, SetRegToK0_16Bits) {349 const uint16_t Value = 0xABCDU;350 const unsigned Reg = X86::K0;351 const unsigned RegBitWidth = 16;352 EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),353 ElementsAre(IsStackAllocate(2),354 IsMovValueToStack(X86::MOV16mi, Value, 0),355 IsMovValueFromStack(X86::KMOVWkm, Reg),356 IsStackDeallocate(2)));357}358 359TEST_F(X86Core2Avx512BWTargetTest, SetRegToK0_16Bits) {360 const uint16_t Value = 0xABCDU;361 const unsigned Reg = X86::K0;362 const unsigned RegBitWidth = 16;363 EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),364 ElementsAre(IsStackAllocate(RegBitWidth / 8),365 IsMovValueToStack(X86::MOV16mi, Value, 0),366 IsMovValueFromStack(X86::KMOVWkm, Reg),367 IsStackDeallocate(RegBitWidth / 8)));368}369 370TEST_F(X86Core2Avx512DQBWTargetTest, SetRegToK0_16Bits) {371 const uint16_t Value = 0xABCDU;372 const unsigned Reg = X86::K0;373 const unsigned RegBitWidth = 16;374 EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),375 ElementsAre(IsStackAllocate(RegBitWidth / 8),376 IsMovValueToStack(X86::MOV16mi, Value, 0),377 IsMovValueFromStack(X86::KMOVWkm, Reg),378 IsStackDeallocate(RegBitWidth / 8)));379}380 381TEST_F(X86Core2Avx512TargetTest, SetRegToK0_8Bits) {382 const uint8_t Value = 0xABU;383 const unsigned Reg = X86::K0;384 const unsigned RegBitWidth = 8;385 EXPECT_THAT(386 setRegTo(Reg, APInt(RegBitWidth, Value)),387 ElementsAre(IsStackAllocate(2),388 IsMovValueToStack(389 X86::MOV16mi,390 APInt(RegBitWidth, Value).zext(16).getZExtValue(), 0),391 IsMovValueFromStack(X86::KMOVWkm, Reg),392 IsStackDeallocate(2)));393}394 395TEST_F(X86Core2Avx512DQTargetTest, SetRegToK0_8Bits) {396 const uint8_t Value = 0xABU;397 const unsigned Reg = X86::K0;398 const unsigned RegBitWidth = 8;399 EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),400 ElementsAre(IsStackAllocate(RegBitWidth / 8),401 IsMovValueToStack(X86::MOV8mi, Value, 0),402 IsMovValueFromStack(X86::KMOVBkm, Reg),403 IsStackDeallocate(RegBitWidth / 8)));404}405 406TEST_F(X86Core2Avx512BWTargetTest, SetRegToK0_8Bits) {407 const uint8_t Value = 0xABU;408 const unsigned Reg = X86::K0;409 const unsigned RegBitWidth = 8;410 EXPECT_THAT(411 setRegTo(Reg, APInt(RegBitWidth, Value)),412 ElementsAre(IsStackAllocate(2),413 IsMovValueToStack(414 X86::MOV16mi,415 APInt(RegBitWidth, Value).zext(16).getZExtValue(), 0),416 IsMovValueFromStack(X86::KMOVWkm, Reg),417 IsStackDeallocate(2)));418}419 420TEST_F(X86Core2Avx512DQBWTargetTest, SetRegToK0_8Bits) {421 const uint8_t Value = 0xABU;422 const unsigned Reg = X86::K0;423 const unsigned RegBitWidth = 8;424 EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),425 ElementsAre(IsStackAllocate(RegBitWidth / 8),426 IsMovValueToStack(X86::MOV8mi, Value, 0),427 IsMovValueFromStack(X86::KMOVBkm, Reg),428 IsStackDeallocate(RegBitWidth / 8)));429}430 431TEST_F(X86Core2Avx512TargetTest, SetRegToK0_32Bits) {432 const uint32_t Value = 0xABCDCABDU;433 const unsigned Reg = X86::K0;434 const unsigned RegBitWidth = 32;435 EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)), IsEmpty());436}437 438TEST_F(X86Core2Avx512DQTargetTest, SetRegToK0_32Bits) {439 const uint32_t Value = 0xABCDCABDU;440 const unsigned Reg = X86::K0;441 const unsigned RegBitWidth = 32;442 EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)), IsEmpty());443}444 445TEST_F(X86Core2Avx512BWTargetTest, SetRegToK0_32Bits) {446 const uint32_t Value = 0xABCDCABDU;447 const unsigned Reg = X86::K0;448 const unsigned RegBitWidth = 32;449 EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),450 ElementsAre(IsStackAllocate(RegBitWidth / 8),451 IsMovValueToStack(X86::MOV32mi, Value, 0),452 IsMovValueFromStack(X86::KMOVDkm, Reg),453 IsStackDeallocate(RegBitWidth / 8)));454}455 456TEST_F(X86Core2Avx512DQBWTargetTest, SetRegToK0_32Bits) {457 const uint32_t Value = 0xABCDCABDU;458 const unsigned Reg = X86::K0;459 const unsigned RegBitWidth = 32;460 EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),461 ElementsAre(IsStackAllocate(RegBitWidth / 8),462 IsMovValueToStack(X86::MOV32mi, Value, 0),463 IsMovValueFromStack(X86::KMOVDkm, Reg),464 IsStackDeallocate(RegBitWidth / 8)));465}466 467TEST_F(X86Core2Avx512TargetTest, SetRegToK0_64Bits) {468 const uint64_t Value = 0xABCDABCDCABDCABDU;469 const unsigned Reg = X86::K0;470 const unsigned RegBitWidth = 64;471 EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)), IsEmpty());472}473 474TEST_F(X86Core2Avx512DQTargetTest, SetRegToK0_64Bits) {475 const uint64_t Value = 0xABCDABCDCABDCABDU;476 const unsigned Reg = X86::K0;477 const unsigned RegBitWidth = 64;478 EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)), IsEmpty());479}480 481TEST_F(X86Core2Avx512BWTargetTest, SetRegToK0_64Bits) {482 const uint64_t Value = 0xABCDABCDCABDCABDUL;483 const unsigned Reg = X86::K0;484 const unsigned RegBitWidth = 64;485 EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),486 ElementsAre(IsStackAllocate(RegBitWidth / 8),487 IsMovValueToStack(X86::MOV32mi, 0XCABDCABDUL, 0),488 IsMovValueToStack(X86::MOV32mi, 0xABCDABCDUL, 4),489 IsMovValueFromStack(X86::KMOVQkm, Reg),490 IsStackDeallocate(RegBitWidth / 8)));491}492 493TEST_F(X86Core2Avx512DQBWTargetTest, SetRegToK0_64Bits) {494 const uint64_t Value = 0xABCDABCDCABDCABDU;495 const unsigned Reg = X86::K0;496 const unsigned RegBitWidth = 64;497 EXPECT_THAT(setRegTo(Reg, APInt(RegBitWidth, Value)),498 ElementsAre(IsStackAllocate(RegBitWidth / 8),499 IsMovValueToStack(X86::MOV32mi, 0XCABDCABDUL, 0),500 IsMovValueToStack(X86::MOV32mi, 0xABCDABCDUL, 4),501 IsMovValueFromStack(X86::KMOVQkm, Reg),502 IsStackDeallocate(RegBitWidth / 8)));503}504 505// Note: We always put 80 bits on the stack independently of the size of the506// value. This uses a bit more space but makes the code simpler.507 508TEST_F(X86Core2TargetTest, SetRegToST0_32Bits) {509 EXPECT_THAT(setRegTo(X86::ST0, APInt(32, 0x11112222ULL)),510 ElementsAre(IsStackAllocate(10),511 IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 0),512 IsMovValueToStack(X86::MOV32mi, 0x00000000UL, 4),513 IsMovValueToStack(X86::MOV16mi, 0x0000UL, 8),514 OpcodeIs(X86::LD_F80m), IsStackDeallocate(10)));515}516 517TEST_F(X86Core2TargetTest, SetRegToST1_32Bits) {518 const MCInst CopySt0ToSt1 = MCInstBuilder(X86::ST_Frr).addReg(X86::ST1);519 EXPECT_THAT(setRegTo(X86::ST1, APInt(32, 0x11112222ULL)),520 ElementsAre(IsStackAllocate(10),521 IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 0),522 IsMovValueToStack(X86::MOV32mi, 0x00000000UL, 4),523 IsMovValueToStack(X86::MOV16mi, 0x0000UL, 8),524 OpcodeIs(X86::LD_F80m), CopySt0ToSt1,525 IsStackDeallocate(10)));526}527 528TEST_F(X86Core2TargetTest, SetRegToST0_64Bits) {529 EXPECT_THAT(setRegTo(X86::ST0, APInt(64, 0x1111222233334444ULL)),530 ElementsAre(IsStackAllocate(10),531 IsMovValueToStack(X86::MOV32mi, 0x33334444UL, 0),532 IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 4),533 IsMovValueToStack(X86::MOV16mi, 0x0000UL, 8),534 OpcodeIs(X86::LD_F80m), IsStackDeallocate(10)));535}536 537TEST_F(X86Core2TargetTest, SetRegToST0_80Bits) {538 EXPECT_THAT(setRegTo(X86::ST0, APInt(80, "11112222333344445555", 16)),539 ElementsAre(IsStackAllocate(10),540 IsMovValueToStack(X86::MOV32mi, 0x44445555UL, 0),541 IsMovValueToStack(X86::MOV32mi, 0x22223333UL, 4),542 IsMovValueToStack(X86::MOV16mi, 0x1111UL, 8),543 OpcodeIs(X86::LD_F80m), IsStackDeallocate(10)));544}545 546TEST_F(X86Core2TargetTest, SetRegToFP0_80Bits) {547 EXPECT_THAT(setRegTo(X86::FP0, APInt(80, "11112222333344445555", 16)),548 ElementsAre(IsStackAllocate(10),549 IsMovValueToStack(X86::MOV32mi, 0x44445555UL, 0),550 IsMovValueToStack(X86::MOV32mi, 0x22223333UL, 4),551 IsMovValueToStack(X86::MOV16mi, 0x1111UL, 8),552 OpcodeIs(X86::LD_Fp80m), IsStackDeallocate(10)));553}554 555TEST_F(X86Core2TargetTest, SetRegToFP1_32Bits) {556 EXPECT_THAT(setRegTo(X86::FP1, APInt(32, 0x11112222ULL)),557 ElementsAre(IsStackAllocate(10),558 IsMovValueToStack(X86::MOV32mi, 0x11112222UL, 0),559 IsMovValueToStack(X86::MOV32mi, 0x00000000UL, 4),560 IsMovValueToStack(X86::MOV16mi, 0x0000UL, 8),561 OpcodeIs(X86::LD_Fp80m), IsStackDeallocate(10)));562}563 564TEST_F(X86Core2TargetTest, SetRegToFP1_4Bits) {565 EXPECT_THAT(setRegTo(X86::FP1, APInt(4, 0x1ULL)),566 ElementsAre(IsStackAllocate(10),567 IsMovValueToStack(X86::MOV32mi, 0x00000001UL, 0),568 IsMovValueToStack(X86::MOV32mi, 0x00000000UL, 4),569 IsMovValueToStack(X86::MOV16mi, 0x0000UL, 8),570 OpcodeIs(X86::LD_Fp80m), IsStackDeallocate(10)));571}572 573TEST_F(X86Core2TargetTest, SetRegToDf1) {574 EXPECT_THAT(setRegTo(X86::DF, APInt(1, 1)), ElementsAre(OpcodeIs(X86::STD)));575}576 577TEST_F(X86Core2TargetTest, SetRegToDf0) {578 EXPECT_THAT(setRegTo(X86::DF, APInt(1, 0)), ElementsAre(OpcodeIs(X86::CLD)));579}580 581TEST_F(X86Core2Avx512TargetTest, FillMemoryOperands_ADD64rm) {582 const Instruction &I = getInstr(X86::ADD64rm);583 InstructionTemplate IT(&I);584 constexpr int kOffset = 42;585 State.getExegesisTarget().fillMemoryOperands(IT, X86::RDI, kOffset);586 // Memory is operands 2-6.587 EXPECT_THAT(IT.getValueFor(I.Operands[2]), IsReg(X86::RDI));588 EXPECT_THAT(IT.getValueFor(I.Operands[3]), IsImm(1));589 EXPECT_THAT(IT.getValueFor(I.Operands[4]), IsReg(0));590 EXPECT_THAT(IT.getValueFor(I.Operands[5]), IsImm(kOffset));591 EXPECT_THAT(IT.getValueFor(I.Operands[6]), IsReg(0));592}593 594TEST_F(X86Core2Avx512TargetTest, FillMemoryOperands_VGATHERDPSZ128rm) {595 const Instruction &I = getInstr(X86::VGATHERDPSZ128rm);596 InstructionTemplate IT(&I);597 constexpr int kOffset = 42;598 State.getExegesisTarget().fillMemoryOperands(IT, X86::RDI, kOffset);599 // Memory is operands 4-8.600 EXPECT_THAT(IT.getValueFor(I.Operands[4]), IsReg(X86::RDI));601 EXPECT_THAT(IT.getValueFor(I.Operands[5]), IsImm(1));602 EXPECT_THAT(IT.getValueFor(I.Operands[6]), IsReg(0));603 EXPECT_THAT(IT.getValueFor(I.Operands[7]), IsImm(kOffset));604 EXPECT_THAT(IT.getValueFor(I.Operands[8]), IsReg(0));605}606 607TEST_F(X86Core2TargetTest, AllowAsBackToBack) {608 EXPECT_TRUE(609 State.getExegesisTarget().allowAsBackToBack(getInstr(X86::ADD64rr)));610 EXPECT_FALSE(611 State.getExegesisTarget().allowAsBackToBack(getInstr(X86::LEA64r)));612}613 614#ifdef __linux__615TEST_F(X86Core2TargetTest, GenerateLowerMunmapTest) {616 std::vector<MCInst> GeneratedCode;617 State.getExegesisTarget().generateLowerMunmap(GeneratedCode);618 EXPECT_THAT(GeneratedCode,619 ElementsAre(IsMovImmediate(X86::MOV64ri, X86::RDI, 0),620 OpcodeIs(X86::LEA64r), OpcodeIs(X86::SHR64ri),621 OpcodeIs(X86::SHL64ri), OpcodeIs(X86::SUB64ri32),622 IsMovImmediate(X86::MOV64ri, X86::RAX, SYS_munmap),623 OpcodeIs(X86::SYSCALL)));624}625 626#ifdef __arm__627static constexpr uintptr_t VAddressSpaceCeiling = 0xC0000000;628#else629static constexpr uintptr_t VAddressSpaceCeiling = 0x0000800000000000;630#endif631 632TEST_F(X86Core2TargetTest, GenerateUpperMunmapTest) {633 std::vector<MCInst> GeneratedCode;634 State.getExegesisTarget().generateUpperMunmap(GeneratedCode);635 EXPECT_THAT(636 GeneratedCode,637 ElementsAreArray({OpcodeIs(X86::LEA64r), OpcodeIs(X86::MOV64rr),638 OpcodeIs(X86::ADD64rr), OpcodeIs(X86::SHR64ri),639 OpcodeIs(X86::SHL64ri), OpcodeIs(X86::ADD64ri32),640 IsMovImmediate(X86::MOV64ri, X86::RSI,641 VAddressSpaceCeiling - getpagesize()),642 OpcodeIs(X86::SUB64rr),643 IsMovImmediate(X86::MOV64ri, X86::RAX, SYS_munmap),644 OpcodeIs(X86::SYSCALL)}));645}646 647TEST_F(X86Core2TargetTest, GenerateExitSyscallTest) {648 EXPECT_THAT(State.getExegesisTarget().generateExitSyscall(127),649 ElementsAre(IsMovImmediate(X86::MOV64ri, X86::RDI, 127),650 IsMovImmediate(X86::MOV64ri, X86::RAX, SYS_exit),651 OpcodeIs(X86::SYSCALL)));652}653 654TEST_F(X86Core2TargetTest, GenerateMmapTest) {655 EXPECT_THAT(State.getExegesisTarget().generateMmap(0x1000, 4096, 0x2000),656 ElementsAre(IsMovImmediate(X86::MOV64ri, X86::RDI, 0x1000),657 IsMovImmediate(X86::MOV64ri, X86::RSI, 4096),658 IsMovImmediate(X86::MOV64ri, X86::RDX,659 PROT_READ | PROT_WRITE),660 IsMovImmediate(X86::MOV64ri, X86::R10,661 MAP_SHARED | MAP_FIXED_NOREPLACE),662 IsMovImmediate(X86::MOV64ri, X86::R8, 0x2000),663 OpcodeIs(X86::MOV32rm),664 IsMovImmediate(X86::MOV64ri, X86::R9, 0),665 IsMovImmediate(X86::MOV64ri, X86::RAX, SYS_mmap),666 OpcodeIs(X86::SYSCALL)));667}668 669TEST_F(X86Core2TargetTest, GenerateMmapAuxMemTest) {670 std::vector<MCInst> GeneratedCode;671 State.getExegesisTarget().generateMmapAuxMem(GeneratedCode);672 EXPECT_THAT(673 GeneratedCode,674 ElementsAre(675 IsMovImmediate(676 X86::MOV64ri, X86::RDI,677 State.getExegesisTarget().getAuxiliaryMemoryStartAddress()),678 IsMovImmediate(X86::MOV64ri, X86::RSI,679 SubprocessMemory::AuxiliaryMemorySize),680 IsMovImmediate(X86::MOV64ri, X86::RDX, PROT_READ | PROT_WRITE),681 IsMovImmediate(X86::MOV64ri, X86::R10,682 MAP_SHARED | MAP_FIXED_NOREPLACE),683 OpcodeIs(X86::MOV64rr), IsMovImmediate(X86::MOV64ri, X86::R9, 0),684 IsMovImmediate(X86::MOV64ri, X86::RAX, SYS_mmap),685 OpcodeIs(X86::SYSCALL)));686}687 688TEST_F(X86Core2TargetTest, MoveArgumentRegistersTest) {689 std::vector<MCInst> GeneratedCode;690 State.getExegesisTarget().moveArgumentRegisters(GeneratedCode);691 EXPECT_THAT(GeneratedCode,692 ElementsAre(IsMovRegToReg(X86::MOV64rr, X86::R12, X86::RDI),693 IsMovRegToReg(X86::MOV64rr, X86::R13, X86::RSI)));694}695#endif // __linux__696 697} // namespace698} // namespace exegesis699} // namespace llvm700