brintos

brintos / llvm-project-archived public Read only

0
0
Text · 28.5 KiB · e375856 Raw
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