1 #include "Target.h"
2
3 #include <cassert>
4 #include <memory>
5
6 #include "MCTargetDesc/X86MCTargetDesc.h"
7 #include "llvm/Support/TargetRegistry.h"
8 #include "llvm/Support/TargetSelect.h"
9 #include "gmock/gmock.h"
10 #include "gtest/gtest.h"
11
12 namespace exegesis {
13
14 void InitializeX86ExegesisTarget();
15
16 namespace {
17
18 using testing::Gt;
19 using testing::NotNull;
20 using testing::SizeIs;
21
22 constexpr const char kTriple[] = "x86_64-unknown-linux";
23
24 class X86TargetTest : public ::testing::Test {
25 protected:
X86TargetTest()26 X86TargetTest()
27 : ExegesisTarget_(ExegesisTarget::lookup(llvm::Triple(kTriple))) {
28 EXPECT_THAT(ExegesisTarget_, NotNull());
29 std::string error;
30 Target_ = llvm::TargetRegistry::lookupTarget(kTriple, error);
31 EXPECT_THAT(Target_, NotNull());
32 }
SetUpTestCase()33 static void SetUpTestCase() {
34 LLVMInitializeX86TargetInfo();
35 LLVMInitializeX86Target();
36 LLVMInitializeX86TargetMC();
37 InitializeX86ExegesisTarget();
38 }
39
40 const llvm::Target *Target_;
41 const ExegesisTarget *const ExegesisTarget_;
42 };
43
TEST_F(X86TargetTest,SetRegToConstantGPR)44 TEST_F(X86TargetTest, SetRegToConstantGPR) {
45 const std::unique_ptr<llvm::MCSubtargetInfo> STI(
46 Target_->createMCSubtargetInfo(kTriple, "core2", ""));
47 const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::EAX);
48 EXPECT_THAT(Insts, SizeIs(1));
49 EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::MOV32ri);
50 EXPECT_EQ(Insts[0].getOperand(0).getReg(), llvm::X86::EAX);
51 }
52
TEST_F(X86TargetTest,SetRegToConstantXMM_SSE2)53 TEST_F(X86TargetTest, SetRegToConstantXMM_SSE2) {
54 const std::unique_ptr<llvm::MCSubtargetInfo> STI(
55 Target_->createMCSubtargetInfo(kTriple, "core2", ""));
56 const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::XMM1);
57 EXPECT_THAT(Insts, SizeIs(7U));
58 EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
59 EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
60 EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
61 EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi);
62 EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi);
63 EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::MOVDQUrm);
64 EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::ADD64ri8);
65 }
66
TEST_F(X86TargetTest,SetRegToConstantXMM_AVX)67 TEST_F(X86TargetTest, SetRegToConstantXMM_AVX) {
68 const std::unique_ptr<llvm::MCSubtargetInfo> STI(
69 Target_->createMCSubtargetInfo(kTriple, "core2", "+avx"));
70 const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::XMM1);
71 EXPECT_THAT(Insts, SizeIs(7U));
72 EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
73 EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
74 EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
75 EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi);
76 EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi);
77 EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::VMOVDQUrm);
78 EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::ADD64ri8);
79 }
80
TEST_F(X86TargetTest,SetRegToConstantXMM_AVX512)81 TEST_F(X86TargetTest, SetRegToConstantXMM_AVX512) {
82 const std::unique_ptr<llvm::MCSubtargetInfo> STI(
83 Target_->createMCSubtargetInfo(kTriple, "core2", "+avx512vl"));
84 const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::XMM1);
85 EXPECT_THAT(Insts, SizeIs(7U));
86 EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
87 EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
88 EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
89 EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi);
90 EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi);
91 EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::VMOVDQU32Z128rm);
92 EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::ADD64ri8);
93 }
94
TEST_F(X86TargetTest,SetRegToConstantMMX)95 TEST_F(X86TargetTest, SetRegToConstantMMX) {
96 const std::unique_ptr<llvm::MCSubtargetInfo> STI(
97 Target_->createMCSubtargetInfo(kTriple, "core2", ""));
98 const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::MM1);
99 EXPECT_THAT(Insts, SizeIs(5U));
100 EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
101 EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
102 EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
103 EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MMX_MOVQ64rm);
104 EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::ADD64ri8);
105 }
106
TEST_F(X86TargetTest,SetRegToConstantYMM_AVX)107 TEST_F(X86TargetTest, SetRegToConstantYMM_AVX) {
108 const std::unique_ptr<llvm::MCSubtargetInfo> STI(
109 Target_->createMCSubtargetInfo(kTriple, "core2", "+avx"));
110 const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::YMM1);
111 EXPECT_THAT(Insts, SizeIs(11U));
112 EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
113 EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
114 EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
115 EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi);
116 EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi);
117 EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::MOV32mi);
118 EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::MOV32mi);
119 EXPECT_EQ(Insts[7].getOpcode(), llvm::X86::MOV32mi);
120 EXPECT_EQ(Insts[8].getOpcode(), llvm::X86::MOV32mi);
121 EXPECT_EQ(Insts[9].getOpcode(), llvm::X86::VMOVDQUYrm);
122 EXPECT_EQ(Insts[10].getOpcode(), llvm::X86::ADD64ri8);
123 }
124
TEST_F(X86TargetTest,SetRegToConstantYMM_AVX512)125 TEST_F(X86TargetTest, SetRegToConstantYMM_AVX512) {
126 const std::unique_ptr<llvm::MCSubtargetInfo> STI(
127 Target_->createMCSubtargetInfo(kTriple, "core2", "+avx512vl"));
128 const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::YMM1);
129 EXPECT_THAT(Insts, SizeIs(11U));
130 EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
131 EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
132 EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
133 EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi);
134 EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi);
135 EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::MOV32mi);
136 EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::MOV32mi);
137 EXPECT_EQ(Insts[7].getOpcode(), llvm::X86::MOV32mi);
138 EXPECT_EQ(Insts[8].getOpcode(), llvm::X86::MOV32mi);
139 EXPECT_EQ(Insts[9].getOpcode(), llvm::X86::VMOVDQU32Z256rm);
140 EXPECT_EQ(Insts[10].getOpcode(), llvm::X86::ADD64ri8);
141 }
142
TEST_F(X86TargetTest,SetRegToConstantZMM_AVX512)143 TEST_F(X86TargetTest, SetRegToConstantZMM_AVX512) {
144 const std::unique_ptr<llvm::MCSubtargetInfo> STI(
145 Target_->createMCSubtargetInfo(kTriple, "core2", "+avx512vl"));
146 const auto Insts = ExegesisTarget_->setRegToConstant(*STI, llvm::X86::ZMM1);
147 EXPECT_THAT(Insts, SizeIs(19U));
148 EXPECT_EQ(Insts[0].getOpcode(), llvm::X86::SUB64ri8);
149 EXPECT_EQ(Insts[1].getOpcode(), llvm::X86::MOV32mi);
150 EXPECT_EQ(Insts[2].getOpcode(), llvm::X86::MOV32mi);
151 EXPECT_EQ(Insts[3].getOpcode(), llvm::X86::MOV32mi);
152 EXPECT_EQ(Insts[4].getOpcode(), llvm::X86::MOV32mi);
153 EXPECT_EQ(Insts[5].getOpcode(), llvm::X86::MOV32mi);
154 EXPECT_EQ(Insts[6].getOpcode(), llvm::X86::MOV32mi);
155 EXPECT_EQ(Insts[7].getOpcode(), llvm::X86::MOV32mi);
156 EXPECT_EQ(Insts[8].getOpcode(), llvm::X86::MOV32mi);
157 EXPECT_EQ(Insts[9].getOpcode(), llvm::X86::MOV32mi);
158 EXPECT_EQ(Insts[10].getOpcode(), llvm::X86::MOV32mi);
159 EXPECT_EQ(Insts[11].getOpcode(), llvm::X86::MOV32mi);
160 EXPECT_EQ(Insts[12].getOpcode(), llvm::X86::MOV32mi);
161 EXPECT_EQ(Insts[13].getOpcode(), llvm::X86::MOV32mi);
162 EXPECT_EQ(Insts[14].getOpcode(), llvm::X86::MOV32mi);
163 EXPECT_EQ(Insts[15].getOpcode(), llvm::X86::MOV32mi);
164 EXPECT_EQ(Insts[16].getOpcode(), llvm::X86::MOV32mi);
165 EXPECT_EQ(Insts[17].getOpcode(), llvm::X86::VMOVDQU32Zrm);
166 EXPECT_EQ(Insts[18].getOpcode(), llvm::X86::ADD64ri8);
167 }
168
169 } // namespace
170 } // namespace exegesis
171