blob: b8533fb111642d601093fcf2eae5c9b7481b167c [file] [log] [blame]
Clement Courbet44b4c542018-06-19 11:28:59 +00001#include "Target.h"
2
3#include <cassert>
4#include <memory>
5
Clement Courbeta51efc22018-06-25 13:12:02 +00006#include "MCTargetDesc/X86MCTargetDesc.h"
Clement Courbete7851692018-07-03 06:17:05 +00007#include "llvm/Support/TargetRegistry.h"
8#include "llvm/Support/TargetSelect.h"
Clement Courbet44b4c542018-06-19 11:28:59 +00009#include "gmock/gmock.h"
10#include "gtest/gtest.h"
11
Guillaume Chatelet5ad29092018-09-18 11:26:27 +000012#include "llvm/MC/MCInstPrinter.h"
13
14namespace llvm {
15
16bool operator==(const llvm::MCOperand &a, const llvm::MCOperand &b) {
17 if (a.isImm() && b.isImm())
18 return a.getImm() == b.getImm();
19 if (a.isReg() && b.isReg())
20 return a.getReg() == b.getReg();
21 return false;
22}
23
24bool operator==(const llvm::MCInst &a, const llvm::MCInst &b) {
25 if (a.getOpcode() != b.getOpcode())
26 return false;
27 if (a.getNumOperands() != b.getNumOperands())
28 return false;
29 for (unsigned I = 0; I < a.getNumOperands(); ++I) {
30 if (!(a.getOperand(I) == b.getOperand(I)))
31 return false;
32 }
33 return true;
34}
35
36} // namespace llvm
37
Clement Courbet44b4c542018-06-19 11:28:59 +000038namespace exegesis {
39
40void InitializeX86ExegesisTarget();
41
42namespace {
43
Guillaume Chatelet5ad29092018-09-18 11:26:27 +000044using testing::ElementsAre;
Clement Courbeta51efc22018-06-25 13:12:02 +000045using testing::Gt;
Clement Courbet44b4c542018-06-19 11:28:59 +000046using testing::NotNull;
Clement Courbeta51efc22018-06-25 13:12:02 +000047using testing::SizeIs;
Clement Courbet44b4c542018-06-19 11:28:59 +000048
Guillaume Chatelet5ad29092018-09-18 11:26:27 +000049using llvm::APInt;
50using llvm::MCInst;
51using llvm::MCInstBuilder;
52
Clement Courbete7851692018-07-03 06:17:05 +000053constexpr const char kTriple[] = "x86_64-unknown-linux";
54
Clement Courbet44b4c542018-06-19 11:28:59 +000055class X86TargetTest : public ::testing::Test {
56protected:
Clement Courbeta51efc22018-06-25 13:12:02 +000057 X86TargetTest()
Clement Courbete7851692018-07-03 06:17:05 +000058 : ExegesisTarget_(ExegesisTarget::lookup(llvm::Triple(kTriple))) {
59 EXPECT_THAT(ExegesisTarget_, NotNull());
60 std::string error;
61 Target_ = llvm::TargetRegistry::lookupTarget(kTriple, error);
Clement Courbeta51efc22018-06-25 13:12:02 +000062 EXPECT_THAT(Target_, NotNull());
63 }
Clement Courbete7851692018-07-03 06:17:05 +000064 static void SetUpTestCase() {
65 LLVMInitializeX86TargetInfo();
66 LLVMInitializeX86Target();
67 LLVMInitializeX86TargetMC();
68 InitializeX86ExegesisTarget();
69 }
Clement Courbeta51efc22018-06-25 13:12:02 +000070
Clement Courbete7851692018-07-03 06:17:05 +000071 const llvm::Target *Target_;
72 const ExegesisTarget *const ExegesisTarget_;
Clement Courbet44b4c542018-06-19 11:28:59 +000073};
74
Clement Courbeta51efc22018-06-25 13:12:02 +000075TEST_F(X86TargetTest, SetRegToConstantGPR) {
Clement Courbete7851692018-07-03 06:17:05 +000076 const std::unique_ptr<llvm::MCSubtargetInfo> STI(
77 Target_->createMCSubtargetInfo(kTriple, "core2", ""));
78 const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::EAX);
Clement Courbeta51efc22018-06-25 13:12:02 +000079 EXPECT_THAT(Insts, SizeIs(1));
80 EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::MOV32ri);
81 EXPECT_EQ(Insts[0].getOperand(0).getReg(), llvm::X86::EAX);
82}
83
Clement Courbete7851692018-07-03 06:17:05 +000084TEST_F(X86TargetTest, SetRegToConstantXMM_SSE2) {
85 const std::unique_ptr<llvm::MCSubtargetInfo> STI(
86 Target_->createMCSubtargetInfo(kTriple, "core2", ""));
87 const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::XMM1);
88 EXPECT_THAT(Insts, SizeIs(7U));
89 EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
90 EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
91 EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
92 EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi);
93 EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi);
94 EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::MOVDQUrm);
95 EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::ADD64ri8);
96}
97
98TEST_F(X86TargetTest, SetRegToConstantXMM_AVX) {
99 const std::unique_ptr<llvm::MCSubtargetInfo> STI(
100 Target_->createMCSubtargetInfo(kTriple, "core2", "+avx"));
101 const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::XMM1);
102 EXPECT_THAT(Insts, SizeIs(7U));
103 EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
104 EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
105 EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
106 EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi);
107 EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi);
108 EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::VMOVDQUrm);
109 EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::ADD64ri8);
110}
111
112TEST_F(X86TargetTest, SetRegToConstantXMM_AVX512) {
113 const std::unique_ptr<llvm::MCSubtargetInfo> STI(
114 Target_->createMCSubtargetInfo(kTriple, "core2", "+avx512vl"));
115 const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::XMM1);
116 EXPECT_THAT(Insts, SizeIs(7U));
117 EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
118 EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
119 EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
120 EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi);
121 EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi);
122 EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::VMOVDQU32Z128rm);
123 EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::ADD64ri8);
124}
125
126TEST_F(X86TargetTest, SetRegToConstantMMX) {
127 const std::unique_ptr<llvm::MCSubtargetInfo> STI(
128 Target_->createMCSubtargetInfo(kTriple, "core2", ""));
129 const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::MM1);
130 EXPECT_THAT(Insts, SizeIs(5U));
131 EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
132 EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
133 EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
134 EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MMX_MOVQ64rm);
135 EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::ADD64ri8);
136}
137
138TEST_F(X86TargetTest, SetRegToConstantYMM_AVX) {
139 const std::unique_ptr<llvm::MCSubtargetInfo> STI(
140 Target_->createMCSubtargetInfo(kTriple, "core2", "+avx"));
141 const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::YMM1);
142 EXPECT_THAT(Insts, SizeIs(11U));
143 EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
144 EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
145 EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
146 EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi);
147 EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi);
148 EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::MOV32mi);
149 EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::MOV32mi);
150 EXPECT_EQ(Insts[7].getOpcode(), llvm::X86::MOV32mi);
151 EXPECT_EQ(Insts[8].getOpcode(), llvm::X86::MOV32mi);
152 EXPECT_EQ(Insts[9].getOpcode(), llvm::X86::VMOVDQUYrm);
153 EXPECT_EQ(Insts[10].getOpcode(), llvm::X86::ADD64ri8);
154}
155
156TEST_F(X86TargetTest, SetRegToConstantYMM_AVX512) {
157 const std::unique_ptr<llvm::MCSubtargetInfo> STI(
158 Target_->createMCSubtargetInfo(kTriple, "core2", "+avx512vl"));
159 const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::YMM1);
160 EXPECT_THAT(Insts, SizeIs(11U));
161 EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
162 EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
163 EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
164 EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi);
165 EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi);
166 EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::MOV32mi);
167 EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::MOV32mi);
168 EXPECT_EQ(Insts[7].getOpcode(), llvm::X86::MOV32mi);
169 EXPECT_EQ(Insts[8].getOpcode(), llvm::X86::MOV32mi);
170 EXPECT_EQ(Insts[9].getOpcode(), llvm::X86::VMOVDQU32Z256rm);
171 EXPECT_EQ(Insts[10].getOpcode(), llvm::X86::ADD64ri8);
172}
173
174TEST_F(X86TargetTest, SetRegToConstantZMM_AVX512) {
175 const std::unique_ptr<llvm::MCSubtargetInfo> STI(
176 Target_->createMCSubtargetInfo(kTriple, "core2", "+avx512vl"));
177 const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::ZMM1);
178 EXPECT_THAT(Insts, SizeIs(19U));
179 EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
180 EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
181 EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
182 EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi);
183 EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi);
184 EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::MOV32mi);
185 EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::MOV32mi);
186 EXPECT_EQ(Insts[7].getOpcode(), llvm::X86::MOV32mi);
187 EXPECT_EQ(Insts[8].getOpcode(), llvm::X86::MOV32mi);
188 EXPECT_EQ(Insts[9].getOpcode(), llvm::X86::MOV32mi);
189 EXPECT_EQ(Insts[10].getOpcode(), llvm::X86::MOV32mi);
190 EXPECT_EQ(Insts[11].getOpcode(), llvm::X86::MOV32mi);
191 EXPECT_EQ(Insts[12].getOpcode(), llvm::X86::MOV32mi);
192 EXPECT_EQ(Insts[13].getOpcode(), llvm::X86::MOV32mi);
193 EXPECT_EQ(Insts[14].getOpcode(), llvm::X86::MOV32mi);
194 EXPECT_EQ(Insts[15].getOpcode(), llvm::X86::MOV32mi);
195 EXPECT_EQ(Insts[16].getOpcode(), llvm::X86::MOV32mi);
196 EXPECT_EQ(Insts[17].getOpcode(), llvm::X86::VMOVDQU32Zrm);
197 EXPECT_EQ(Insts[18].getOpcode(), llvm::X86::ADD64ri8);
Clement Courbet44b4c542018-06-19 11:28:59 +0000198}
199
Guillaume Chatelet5ad29092018-09-18 11:26:27 +0000200TEST_F(X86TargetTest, SetToAPInt) {
201 const std::unique_ptr<llvm::MCSubtargetInfo> STI(
202 Target_->createMCSubtargetInfo(kTriple, "core2", ""));
203 // EXPECT_THAT(ExegesisTarget_->setRegTo(*STI, APInt(8, 0xFFU),
204 // llvm::X86::AL),
205 // ElementsAre((MCInst)MCInstBuilder(llvm::X86::MOV8ri)
206 // .addReg(llvm::X86::AL)
207 // .addImm(0xFFU)));
208 // EXPECT_THAT(
209 // ExegesisTarget_->setRegTo(*STI, APInt(16, 0xFFFFU), llvm::X86::BX),
210 // ElementsAre((MCInst)MCInstBuilder(llvm::X86::MOV16ri)
211 // .addReg(llvm::X86::BX)
212 // .addImm(0xFFFFU)));
213 // EXPECT_THAT(
214 // ExegesisTarget_->setRegTo(*STI, APInt(32, 0x7FFFFU), llvm::X86::ECX),
215 // ElementsAre((MCInst)MCInstBuilder(llvm::X86::MOV32ri)
216 // .addReg(llvm::X86::ECX)
217 // .addImm(0x7FFFFU)));
218 // EXPECT_THAT(ExegesisTarget_->setRegTo(*STI, APInt(64,
219 // 0x7FFFFFFFFFFFFFFFULL),
220 // llvm::X86::RDX),
221 // ElementsAre((MCInst)MCInstBuilder(llvm::X86::MOV64ri)
222 // .addReg(llvm::X86::RDX)
223 // .addImm(0x7FFFFFFFFFFFFFFFULL)));
224
225 const std::unique_ptr<llvm::MCRegisterInfo> MRI(
226 Target_->createMCRegInfo(kTriple));
227 const std::unique_ptr<llvm::MCAsmInfo> MAI(
228 Target_->createMCAsmInfo(*MRI, kTriple));
229 const std::unique_ptr<llvm::MCInstrInfo> MII(Target_->createMCInstrInfo());
230 const std::unique_ptr<llvm::MCInstPrinter> MIP(
231 Target_->createMCInstPrinter(llvm::Triple(kTriple), 1, *MAI, *MII, *MRI));
232
233 for (const auto M : ExegesisTarget_->setRegTo(
234 *STI, APInt(80, "ABCD1234123456785678", 16), llvm::X86::MM0)) {
235 MIP->printInst(&M, llvm::errs(), "", *STI);
236 llvm::errs() << "\n";
237 }
238}
239
Clement Courbet44b4c542018-06-19 11:28:59 +0000240} // namespace
241} // namespace exegesis