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