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/MC/TargetRegistry.h"
7 #include "llvm/Support/MemoryBuffer.h"
8 #include "llvm/Support/TargetSelect.h"
10 #include "gtest/gtest.h"
15 /// The \p InputIRSnippet is only needed for things that can't be expressed in
16 /// the \p InputMIRSnippet (global variables etc)
17 /// TODO: Some of this might be useful for other architectures as well - extract
18 /// the platform-independent parts somewhere they can be reused.
20 LLVMTargetMachine
*TM
, const ARMBaseInstrInfo
*II
,
21 const StringRef InputIRSnippet
, const StringRef InputMIRSnippet
,
23 std::function
<void(const ARMBaseInstrInfo
&, MachineFunction
&, unsigned &)>
27 auto MIRString
= "--- |\n"
28 " declare void @sizes()\n" +
29 InputIRSnippet
.str() +
35 " value: i32 12345678\n"
41 " blocks: [ '%bb.0' ]\n"
44 InputMIRSnippet
.str();
46 std::unique_ptr
<MemoryBuffer
> MBuffer
= MemoryBuffer::getMemBuffer(MIRString
);
47 std::unique_ptr
<MIRParser
> MParser
=
48 createMIRParser(std::move(MBuffer
), Context
);
51 std::unique_ptr
<Module
> M
= MParser
->parseIRModule();
54 M
->setTargetTriple(TM
->getTargetTriple().getTriple());
55 M
->setDataLayout(TM
->createDataLayout());
57 MachineModuleInfo
MMI(TM
);
58 bool Res
= MParser
->parseMachineFunctions(*M
, MMI
);
61 auto F
= M
->getFunction("sizes");
62 ASSERT_TRUE(F
!= nullptr);
63 auto &MF
= MMI
.getOrCreateMachineFunction(*F
);
65 Checks(*II
, MF
, Expected
);
68 } // anonymous namespace
70 TEST(InstSizes
, PseudoInst
) {
71 LLVMInitializeARMTargetInfo();
72 LLVMInitializeARMTarget();
73 LLVMInitializeARMTargetMC();
75 auto TT(Triple::normalize("thumbv8.1m.main-none-none-eabi"));
77 const Target
*T
= TargetRegistry::lookupTarget(TT
, Error
);
83 TargetOptions Options
;
84 auto TM
= std::unique_ptr
<LLVMTargetMachine
>(static_cast<LLVMTargetMachine
*>(
85 T
->createTargetMachine(TT
, "generic", "", Options
, std::nullopt
,
86 std::nullopt
, CodeGenOptLevel::Default
)));
87 ARMSubtarget
ST(TM
->getTargetTriple(), std::string(TM
->getTargetCPU()),
88 std::string(TM
->getTargetFeatureString()),
89 *static_cast<const ARMBaseTargetMachine
*>(TM
.get()), false);
90 const ARMBaseInstrInfo
*II
= ST
.getInstrInfo();
92 auto cmpInstSize
= [](const ARMBaseInstrInfo
&II
, MachineFunction
&MF
,
94 auto I
= MF
.begin()->begin();
95 EXPECT_EQ(Expected
, II
.getInstSizeInBytes(*I
));
98 runChecks(TM
.get(), II
, "",
99 " $r0 = MOVi16_ga_pcrel"
100 " target-flags(arm-lo16, arm-nonlazy) @sizes, 0\n",
103 runChecks(TM
.get(), II
, "",
104 " $r0 = MOVTi16_ga_pcrel $r0,"
105 " target-flags(arm-hi16, arm-nonlazy) @sizes, 0\n",
108 runChecks(TM
.get(), II
, "",
109 " $r0 = t2MOVi16_ga_pcrel"
110 " target-flags(arm-lo16, arm-nonlazy) @sizes, 0\n",
113 runChecks(TM
.get(), II
, "",
114 " $r0 = t2MOVTi16_ga_pcrel $r0,"
115 " target-flags(arm-hi16, arm-nonlazy) @sizes, 0\n",
118 runChecks(TM
.get(), II
, "", " $r0 = MOVi32imm 2\n", 8u, cmpInstSize
);
120 runChecks(TM
.get(), II
, "", " $r0 = t2MOVi32imm 2\n", 8u, cmpInstSize
);
122 runChecks(TM
.get(), II
, "",
123 " SpeculationBarrierISBDSBEndBB\n"
124 " tBX_RET 14, $noreg, implicit $r0\n",
127 runChecks(TM
.get(), II
, "",
128 " t2SpeculationBarrierISBDSBEndBB\n"
129 " tBX_RET 14, $noreg, implicit $r0\n",
132 runChecks(TM
.get(), II
, "",
133 " SpeculationBarrierSBEndBB\n"
134 " tBX_RET 14, $noreg, implicit $r0\n",
137 runChecks(TM
.get(), II
, "",
138 " t2SpeculationBarrierSBEndBB\n"
139 " tBX_RET 14, $noreg, implicit $r0\n",
142 runChecks(TM
.get(), II
, "",
143 " Int_eh_sjlj_longjmp $r0, $r1, implicit-def $r7,"
144 " implicit-def $lr, implicit-def $sp\n",
147 runChecks(TM
.get(), II
, "",
148 " tInt_eh_sjlj_longjmp $r0, $r1, implicit-def $r7,"
149 " implicit-def $lr, implicit-def $sp\n",
152 runChecks(TM
.get(), II
, "",
153 " tInt_WIN_eh_sjlj_longjmp $r0, $r1, implicit-def $r11,"
154 " implicit-def $lr, implicit-def $sp\n",
157 runChecks(TM
.get(), II
, "",
158 " Int_eh_sjlj_setjmp $r0, $r1, implicit-def $r0,"
159 " implicit-def $r1, implicit-def $r2, implicit-def $r3,"
160 " implicit-def $r4, implicit-def $r5, implicit-def $r6,"
161 " implicit-def $r7, implicit-def $r8, implicit-def $r9,"
162 " implicit-def $r10, implicit-def $r11, implicit-def $r12,"
163 " implicit-def $lr, implicit-def $cpsr, implicit-def $q0,"
164 " implicit-def $q1, implicit-def $q2, implicit-def $q3,"
165 " implicit-def $q4, implicit-def $q5, implicit-def $q6,"
166 " implicit-def $q7, implicit-def $q8, implicit-def $q9,"
167 " implicit-def $q10, implicit-def $q11, implicit-def $q12,"
168 " implicit-def $q13, implicit-def $q14, implicit-def $q15\n"
169 " tBX_RET 14, $noreg, implicit $r0\n",
172 runChecks(TM
.get(), II
, "",
173 " Int_eh_sjlj_setjmp_nofp $r0, $r1, implicit-def $r0,"
174 " implicit-def $r1, implicit-def $r2, implicit-def $r3,"
175 " implicit-def $r4, implicit-def $r5, implicit-def $r6,"
176 " implicit-def $r7, implicit-def $r8, implicit-def $r9,"
177 " implicit-def $r10, implicit-def $r11, implicit-def $r12,"
178 " implicit-def $lr, implicit-def $cpsr\n"
179 " tBX_RET 14, $noreg, implicit $r0\n",
182 runChecks(TM
.get(), II
, "",
183 " tInt_eh_sjlj_setjmp $r0, $r1, implicit-def $r0,"
184 " implicit-def $r1, implicit-def $r2, implicit-def $r3,"
185 " implicit-def $r4, implicit-def $r5, implicit-def $r6,"
186 " implicit-def $r7, implicit-def $r12, implicit-def $cpsr\n"
187 " tBX_RET 14, $noreg, implicit $r0\n",
190 runChecks(TM
.get(), II
, "",
191 " t2Int_eh_sjlj_setjmp $r0, $r1, implicit-def $r0,"
192 " implicit-def $r1, implicit-def $r2, implicit-def $r3,"
193 " implicit-def $r4, implicit-def $r5, implicit-def $r6,"
194 " implicit-def $r7, implicit-def $r8, implicit-def $r9,"
195 " implicit-def $r10, implicit-def $r11, implicit-def $r12,"
196 " implicit-def $lr, implicit-def $cpsr, implicit-def $q0,"
197 " implicit-def $q1, implicit-def $q2, implicit-def $q3,"
198 " implicit-def $q8, implicit-def $q9, implicit-def $q10,"
199 " implicit-def $q11, implicit-def $q12, implicit-def $q13,"
200 " implicit-def $q14, implicit-def $q15\n"
201 " tBX_RET 14, $noreg, implicit $r0\n",
204 runChecks(TM
.get(), II
, "",
205 " t2Int_eh_sjlj_setjmp_nofp $r0, $r1, implicit-def $r0,"
206 " implicit-def $r1, implicit-def $r2, implicit-def $r3,"
207 " implicit-def $r4, implicit-def $r5, implicit-def $r6,"
208 " implicit-def $r7, implicit-def $r8, implicit-def $r9,"
209 " implicit-def $r10, implicit-def $r11, implicit-def $r12,"
210 " implicit-def $lr, implicit-def $cpsr\n"
211 " tBX_RET 14, $noreg, implicit $r0\n",
214 runChecks(TM
.get(), II
, "", " CONSTPOOL_ENTRY 3, %const.0, 8\n", 8u,
217 runChecks(TM
.get(), II
, "", " JUMPTABLE_ADDRS 0, %jump-table.0, 123\n", 123u,
220 runChecks(TM
.get(), II
, "", " JUMPTABLE_INSTS 0, %jump-table.0, 456\n", 456u,
223 runChecks(TM
.get(), II
, "", " JUMPTABLE_TBB 0, %jump-table.0, 789\n", 789u,
226 runChecks(TM
.get(), II
, "", " JUMPTABLE_TBH 0, %jump-table.0, 188\n", 188u,
229 runChecks(TM
.get(), II
, "", " $r0 = SPACE 40, undef $r0\n", 40u,
232 runChecks(TM
.get(), II
, "", " INLINEASM &\"movs r0, #42\", 1\n", 6u,
235 runChecks(TM
.get(), II
,
236 " define void @foo() {\n"
240 " INLINEASM_BR &\"b ${0:l}\", 1, 13, blockaddress(@foo, "
241 "%ir-block.entry)\n",