1 #include "ARMInstrInfo.h"
2 #include "ARMSubtarget.h"
3 #include "ARMTargetMachine.h"
4 #include "llvm/CodeGen/MIRParser/MIRParser.h"
5 #include "llvm/CodeGen/MachineModuleInfo.h"
6 #include "llvm/IR/Module.h"
7 #include "llvm/MC/TargetRegistry.h"
8 #include "llvm/Support/MemoryBuffer.h"
9 #include "llvm/Support/TargetSelect.h"
11 #include "gtest/gtest.h"
16 /// The \p InputIRSnippet is only needed for things that can't be expressed in
17 /// the \p InputMIRSnippet (global variables etc)
18 /// TODO: Some of this might be useful for other architectures as well - extract
19 /// the platform-independent parts somewhere they can be reused.
21 TargetMachine
*TM
, const ARMBaseInstrInfo
*II
,
22 const StringRef InputIRSnippet
, const StringRef InputMIRSnippet
,
24 std::function
<void(const ARMBaseInstrInfo
&, MachineFunction
&, unsigned &)>
28 auto MIRString
= "--- |\n"
29 " declare void @sizes()\n" +
30 InputIRSnippet
.str() +
36 " value: i32 12345678\n"
42 " blocks: [ '%bb.0' ]\n"
45 InputMIRSnippet
.str();
47 std::unique_ptr
<MemoryBuffer
> MBuffer
= MemoryBuffer::getMemBuffer(MIRString
);
48 std::unique_ptr
<MIRParser
> MParser
=
49 createMIRParser(std::move(MBuffer
), Context
);
52 std::unique_ptr
<Module
> M
= MParser
->parseIRModule();
55 M
->setTargetTriple(TM
->getTargetTriple().getTriple());
56 M
->setDataLayout(TM
->createDataLayout());
58 MachineModuleInfo
MMI(TM
);
59 bool Res
= MParser
->parseMachineFunctions(*M
, MMI
);
62 auto F
= M
->getFunction("sizes");
63 ASSERT_TRUE(F
!= nullptr);
64 auto &MF
= MMI
.getOrCreateMachineFunction(*F
);
66 Checks(*II
, MF
, Expected
);
69 } // anonymous namespace
71 TEST(InstSizes
, PseudoInst
) {
72 LLVMInitializeARMTargetInfo();
73 LLVMInitializeARMTarget();
74 LLVMInitializeARMTargetMC();
76 auto TT(Triple::normalize("thumbv8.1m.main-none-none-eabi"));
78 const Target
*T
= TargetRegistry::lookupTarget(TT
, Error
);
84 TargetOptions Options
;
85 auto TM
= std::unique_ptr
<TargetMachine
>(
86 T
->createTargetMachine(TT
, "generic", "", Options
, std::nullopt
,
87 std::nullopt
, CodeGenOptLevel::Default
));
88 ARMSubtarget
ST(TM
->getTargetTriple(), std::string(TM
->getTargetCPU()),
89 std::string(TM
->getTargetFeatureString()),
90 *static_cast<const ARMBaseTargetMachine
*>(TM
.get()), false);
91 const ARMBaseInstrInfo
*II
= ST
.getInstrInfo();
93 auto cmpInstSize
= [](const ARMBaseInstrInfo
&II
, MachineFunction
&MF
,
95 auto I
= MF
.begin()->begin();
96 EXPECT_EQ(Expected
, II
.getInstSizeInBytes(*I
));
99 runChecks(TM
.get(), II
, "",
100 " $r0 = MOVi16_ga_pcrel"
101 " target-flags(arm-lo16, arm-nonlazy) @sizes, 0\n",
104 runChecks(TM
.get(), II
, "",
105 " $r0 = MOVTi16_ga_pcrel $r0,"
106 " target-flags(arm-hi16, arm-nonlazy) @sizes, 0\n",
109 runChecks(TM
.get(), II
, "",
110 " $r0 = t2MOVi16_ga_pcrel"
111 " target-flags(arm-lo16, arm-nonlazy) @sizes, 0\n",
114 runChecks(TM
.get(), II
, "",
115 " $r0 = t2MOVTi16_ga_pcrel $r0,"
116 " target-flags(arm-hi16, arm-nonlazy) @sizes, 0\n",
119 runChecks(TM
.get(), II
, "", " $r0 = MOVi32imm 2\n", 8u, cmpInstSize
);
121 runChecks(TM
.get(), II
, "", " $r0 = t2MOVi32imm 2\n", 8u, cmpInstSize
);
123 runChecks(TM
.get(), II
, "",
124 " SpeculationBarrierISBDSBEndBB\n"
125 " tBX_RET 14, $noreg, implicit $r0\n",
128 runChecks(TM
.get(), II
, "",
129 " t2SpeculationBarrierISBDSBEndBB\n"
130 " tBX_RET 14, $noreg, implicit $r0\n",
133 runChecks(TM
.get(), II
, "",
134 " SpeculationBarrierSBEndBB\n"
135 " tBX_RET 14, $noreg, implicit $r0\n",
138 runChecks(TM
.get(), II
, "",
139 " t2SpeculationBarrierSBEndBB\n"
140 " tBX_RET 14, $noreg, implicit $r0\n",
143 runChecks(TM
.get(), II
, "",
144 " Int_eh_sjlj_longjmp $r0, $r1, implicit-def $r7,"
145 " implicit-def $lr, implicit-def $sp\n",
148 runChecks(TM
.get(), II
, "",
149 " tInt_eh_sjlj_longjmp $r0, $r1, implicit-def $r7,"
150 " implicit-def $lr, implicit-def $sp\n",
153 runChecks(TM
.get(), II
, "",
154 " tInt_WIN_eh_sjlj_longjmp $r0, $r1, implicit-def $r11,"
155 " implicit-def $lr, implicit-def $sp\n",
158 runChecks(TM
.get(), II
, "",
159 " Int_eh_sjlj_setjmp $r0, $r1, implicit-def $r0,"
160 " implicit-def $r1, implicit-def $r2, implicit-def $r3,"
161 " implicit-def $r4, implicit-def $r5, implicit-def $r6,"
162 " implicit-def $r7, implicit-def $r8, implicit-def $r9,"
163 " implicit-def $r10, implicit-def $r11, implicit-def $r12,"
164 " implicit-def $lr, implicit-def $cpsr, implicit-def $q0,"
165 " implicit-def $q1, implicit-def $q2, implicit-def $q3,"
166 " implicit-def $q4, implicit-def $q5, implicit-def $q6,"
167 " implicit-def $q7, implicit-def $q8, implicit-def $q9,"
168 " implicit-def $q10, implicit-def $q11, implicit-def $q12,"
169 " implicit-def $q13, implicit-def $q14, implicit-def $q15\n"
170 " tBX_RET 14, $noreg, implicit $r0\n",
173 runChecks(TM
.get(), II
, "",
174 " Int_eh_sjlj_setjmp_nofp $r0, $r1, implicit-def $r0,"
175 " implicit-def $r1, implicit-def $r2, implicit-def $r3,"
176 " implicit-def $r4, implicit-def $r5, implicit-def $r6,"
177 " implicit-def $r7, implicit-def $r8, implicit-def $r9,"
178 " implicit-def $r10, implicit-def $r11, implicit-def $r12,"
179 " implicit-def $lr, implicit-def $cpsr\n"
180 " tBX_RET 14, $noreg, implicit $r0\n",
183 runChecks(TM
.get(), II
, "",
184 " tInt_eh_sjlj_setjmp $r0, $r1, implicit-def $r0,"
185 " implicit-def $r1, implicit-def $r2, implicit-def $r3,"
186 " implicit-def $r4, implicit-def $r5, implicit-def $r6,"
187 " implicit-def $r7, implicit-def $r12, implicit-def $cpsr\n"
188 " tBX_RET 14, $noreg, implicit $r0\n",
191 runChecks(TM
.get(), II
, "",
192 " t2Int_eh_sjlj_setjmp $r0, $r1, implicit-def $r0,"
193 " implicit-def $r1, implicit-def $r2, implicit-def $r3,"
194 " implicit-def $r4, implicit-def $r5, implicit-def $r6,"
195 " implicit-def $r7, implicit-def $r8, implicit-def $r9,"
196 " implicit-def $r10, implicit-def $r11, implicit-def $r12,"
197 " implicit-def $lr, implicit-def $cpsr, implicit-def $q0,"
198 " implicit-def $q1, implicit-def $q2, implicit-def $q3,"
199 " implicit-def $q8, implicit-def $q9, implicit-def $q10,"
200 " implicit-def $q11, implicit-def $q12, implicit-def $q13,"
201 " implicit-def $q14, implicit-def $q15\n"
202 " tBX_RET 14, $noreg, implicit $r0\n",
205 runChecks(TM
.get(), II
, "",
206 " t2Int_eh_sjlj_setjmp_nofp $r0, $r1, implicit-def $r0,"
207 " implicit-def $r1, implicit-def $r2, implicit-def $r3,"
208 " implicit-def $r4, implicit-def $r5, implicit-def $r6,"
209 " implicit-def $r7, implicit-def $r8, implicit-def $r9,"
210 " implicit-def $r10, implicit-def $r11, implicit-def $r12,"
211 " implicit-def $lr, implicit-def $cpsr\n"
212 " tBX_RET 14, $noreg, implicit $r0\n",
215 runChecks(TM
.get(), II
, "", " CONSTPOOL_ENTRY 3, %const.0, 8\n", 8u,
218 runChecks(TM
.get(), II
, "", " JUMPTABLE_ADDRS 0, %jump-table.0, 123\n", 123u,
221 runChecks(TM
.get(), II
, "", " JUMPTABLE_INSTS 0, %jump-table.0, 456\n", 456u,
224 runChecks(TM
.get(), II
, "", " JUMPTABLE_TBB 0, %jump-table.0, 789\n", 789u,
227 runChecks(TM
.get(), II
, "", " JUMPTABLE_TBH 0, %jump-table.0, 188\n", 188u,
230 runChecks(TM
.get(), II
, "", " $r0 = SPACE 40, undef $r0\n", 40u,
233 runChecks(TM
.get(), II
, "", " INLINEASM &\"movs r0, #42\", 1\n", 6u,
236 runChecks(TM
.get(), II
,
237 " define void @foo() {\n"
241 " INLINEASM_BR &\"b ${0:l}\", 1, 13, blockaddress(@foo, "
242 "%ir-block.entry)\n",