245 lines · cpp
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"10 11#include "gtest/gtest.h"12 13using namespace llvm;14 15namespace {16/// The \p InputIRSnippet is only needed for things that can't be expressed in17/// the \p InputMIRSnippet (global variables etc)18/// TODO: Some of this might be useful for other architectures as well - extract19/// the platform-independent parts somewhere they can be reused.20void runChecks(21 TargetMachine *TM, const ARMBaseInstrInfo *II,22 const StringRef InputIRSnippet, const StringRef InputMIRSnippet,23 unsigned Expected,24 std::function<void(const ARMBaseInstrInfo &, MachineFunction &, unsigned &)>25 Checks) {26 LLVMContext Context;27 28 auto MIRString = "--- |\n"29 " declare void @sizes()\n" +30 InputIRSnippet.str() +31 "...\n"32 "---\n"33 "name: sizes\n"34 "constants:\n"35 " - id: 0\n"36 " value: i32 12345678\n"37 " alignment: 4\n"38 "jumpTable:\n"39 " kind: inline\n"40 " entries:\n"41 " - id: 0\n"42 " blocks: [ '%bb.0' ]\n"43 "body: |\n"44 " bb.0:\n" +45 InputMIRSnippet.str();46 47 std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRString);48 std::unique_ptr<MIRParser> MParser =49 createMIRParser(std::move(MBuffer), Context);50 ASSERT_TRUE(MParser);51 52 std::unique_ptr<Module> M = MParser->parseIRModule();53 ASSERT_TRUE(M);54 55 M->setTargetTriple(TM->getTargetTriple());56 M->setDataLayout(TM->createDataLayout());57 58 MachineModuleInfo MMI(TM);59 bool Res = MParser->parseMachineFunctions(*M, MMI);60 ASSERT_FALSE(Res);61 62 auto F = M->getFunction("sizes");63 ASSERT_TRUE(F != nullptr);64 auto &MF = MMI.getOrCreateMachineFunction(*F);65 66 Checks(*II, MF, Expected);67}68 69} // anonymous namespace70 71TEST(InstSizes, PseudoInst) {72 LLVMInitializeARMTargetInfo();73 LLVMInitializeARMTarget();74 LLVMInitializeARMTargetMC();75 76 Triple TT("thumbv8.1m.main-none-none-eabi");77 std::string Error;78 const Target *T = TargetRegistry::lookupTarget(TT, Error);79 if (!T) {80 dbgs() << Error;81 GTEST_SKIP();82 }83 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();92 93 auto cmpInstSize = [](const ARMBaseInstrInfo &II, MachineFunction &MF,94 unsigned &Expected) {95 auto I = MF.begin()->begin();96 EXPECT_EQ(Expected, II.getInstSizeInBytes(*I));97 };98 99 runChecks(TM.get(), II, "",100 " $r0 = MOVi16_ga_pcrel"101 " target-flags(arm-lo16, arm-nonlazy) @sizes, 0\n",102 4u, cmpInstSize);103 104 runChecks(TM.get(), II, "",105 " $r0 = MOVTi16_ga_pcrel $r0,"106 " target-flags(arm-hi16, arm-nonlazy) @sizes, 0\n",107 4u, cmpInstSize);108 109 runChecks(TM.get(), II, "",110 " $r0 = t2MOVi16_ga_pcrel"111 " target-flags(arm-lo16, arm-nonlazy) @sizes, 0\n",112 4u, cmpInstSize);113 114 runChecks(TM.get(), II, "",115 " $r0 = t2MOVTi16_ga_pcrel $r0,"116 " target-flags(arm-hi16, arm-nonlazy) @sizes, 0\n",117 4u, cmpInstSize);118 119 runChecks(TM.get(), II, "", " $r0 = MOVi32imm 2\n", 8u, cmpInstSize);120 121 runChecks(TM.get(), II, "", " $r0 = t2MOVi32imm 2\n", 8u, cmpInstSize);122 123 runChecks(TM.get(), II, "",124 " SpeculationBarrierISBDSBEndBB\n"125 " tBX_RET 14, $noreg, implicit $r0\n",126 8u, cmpInstSize);127 128 runChecks(TM.get(), II, "",129 " t2SpeculationBarrierISBDSBEndBB\n"130 " tBX_RET 14, $noreg, implicit $r0\n",131 8u, cmpInstSize);132 133 runChecks(TM.get(), II, "",134 " SpeculationBarrierSBEndBB\n"135 " tBX_RET 14, $noreg, implicit $r0\n",136 4u, cmpInstSize);137 138 runChecks(TM.get(), II, "",139 " t2SpeculationBarrierSBEndBB\n"140 " tBX_RET 14, $noreg, implicit $r0\n",141 4u, cmpInstSize);142 143 runChecks(TM.get(), II, "",144 " Int_eh_sjlj_longjmp $r0, $r1, implicit-def $r7,"145 " implicit-def $lr, implicit-def $sp\n",146 16u, cmpInstSize);147 148 runChecks(TM.get(), II, "",149 " tInt_eh_sjlj_longjmp $r0, $r1, implicit-def $r7,"150 " implicit-def $lr, implicit-def $sp\n",151 10u, cmpInstSize);152 153 runChecks(TM.get(), II, "",154 " tInt_WIN_eh_sjlj_longjmp $r0, $r1, implicit-def $r11,"155 " implicit-def $lr, implicit-def $sp\n",156 12u, cmpInstSize);157 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",171 20u, cmpInstSize);172 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",181 20u, cmpInstSize);182 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",189 12u, cmpInstSize);190 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",203 12u, cmpInstSize);204 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",213 12u, cmpInstSize);214 215 runChecks(TM.get(), II, "", " CONSTPOOL_ENTRY 3, %const.0, 8\n", 8u,216 cmpInstSize);217 218 runChecks(TM.get(), II, "", " JUMPTABLE_ADDRS 0, %jump-table.0, 123\n", 123u,219 cmpInstSize);220 221 runChecks(TM.get(), II, "", " JUMPTABLE_INSTS 0, %jump-table.0, 456\n", 456u,222 cmpInstSize);223 224 runChecks(TM.get(), II, "", " JUMPTABLE_TBB 0, %jump-table.0, 789\n", 789u,225 cmpInstSize);226 227 runChecks(TM.get(), II, "", " JUMPTABLE_TBH 0, %jump-table.0, 188\n", 188u,228 cmpInstSize);229 230 runChecks(TM.get(), II, "", " $r0 = SPACE 40, undef $r0\n", 40u,231 cmpInstSize);232 233 runChecks(TM.get(), II, "", " INLINEASM &\"movs r0, #42\", 1\n", 6u,234 cmpInstSize);235 236 runChecks(TM.get(), II,237 " define void @foo() {\n"238 " entry:\n"239 " ret void\n"240 " }\n",241 " INLINEASM_BR &\"b ${0:l}\", 1, 13, blockaddress(@foo, "242 "%ir-block.entry)\n",243 6u, cmpInstSize);244}245