[ARM] Make getInstSizeInBytes() use instruction size from InstrInfo.td
Currently, ARMBaseInstrInfo::getInstSizeInBytes() uses hard-coded instruction size for some pseudo-instructions, while this information should ideally be found in ARMInstrInfo.td, ARMInstrThumb(2).td files (which can be accessed via MCInstrDesc). Hence, the .td files should be updated and no hard-coded instruction sizes should be used by getInstSizeInBytes() anymore. Differential Revision: https://reviews.llvm.org/D118009
This commit is contained in:
@@ -752,23 +752,17 @@ unsigned ARMBaseInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
|
||||
const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo();
|
||||
|
||||
const MCInstrDesc &MCID = MI.getDesc();
|
||||
if (MCID.getSize())
|
||||
return MCID.getSize();
|
||||
|
||||
switch (MI.getOpcode()) {
|
||||
default:
|
||||
// pseudo-instruction sizes are zero.
|
||||
return 0;
|
||||
// Return the size specified in .td file. If there's none, return 0, as we
|
||||
// can't define a default size (Thumb1 instructions are 2 bytes, Thumb2
|
||||
// instructions are 2-4 bytes, and ARM instructions are 4 bytes), in
|
||||
// contrast to AArch64 instructions which have a default size of 4 bytes for
|
||||
// example.
|
||||
return MCID.getSize();
|
||||
case TargetOpcode::BUNDLE:
|
||||
return getInstBundleLength(MI);
|
||||
case ARM::MOVi16_ga_pcrel:
|
||||
case ARM::MOVTi16_ga_pcrel:
|
||||
case ARM::t2MOVi16_ga_pcrel:
|
||||
case ARM::t2MOVTi16_ga_pcrel:
|
||||
return 4;
|
||||
case ARM::MOVi32imm:
|
||||
case ARM::t2MOVi32imm:
|
||||
return 8;
|
||||
case ARM::CONSTPOOL_ENTRY:
|
||||
case ARM::JUMPTABLE_INSTS:
|
||||
case ARM::JUMPTABLE_ADDRS:
|
||||
@@ -777,19 +771,6 @@ unsigned ARMBaseInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
|
||||
// If this machine instr is a constant pool entry, its size is recorded as
|
||||
// operand #2.
|
||||
return MI.getOperand(2).getImm();
|
||||
case ARM::Int_eh_sjlj_longjmp:
|
||||
return 16;
|
||||
case ARM::tInt_eh_sjlj_longjmp:
|
||||
return 10;
|
||||
case ARM::tInt_WIN_eh_sjlj_longjmp:
|
||||
return 12;
|
||||
case ARM::Int_eh_sjlj_setjmp:
|
||||
case ARM::Int_eh_sjlj_setjmp_nofp:
|
||||
return 20;
|
||||
case ARM::tInt_eh_sjlj_setjmp:
|
||||
case ARM::t2Int_eh_sjlj_setjmp:
|
||||
case ARM::t2Int_eh_sjlj_setjmp_nofp:
|
||||
return 12;
|
||||
case ARM::SPACE:
|
||||
return MI.getOperand(1).getImm();
|
||||
case ARM::INLINEASM:
|
||||
@@ -800,14 +781,6 @@ unsigned ARMBaseInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
|
||||
Size = alignTo(Size, 4);
|
||||
return Size;
|
||||
}
|
||||
case ARM::SpeculationBarrierISBDSBEndBB:
|
||||
case ARM::t2SpeculationBarrierISBDSBEndBB:
|
||||
// This gets lowered to 2 4-byte instructions.
|
||||
return 8;
|
||||
case ARM::SpeculationBarrierSBEndBB:
|
||||
case ARM::t2SpeculationBarrierSBEndBB:
|
||||
// This gets lowered to 1 4-byte instructions.
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3657,6 +3657,8 @@ def : InstAlias<"mov${p} $Rd, $imm",
|
||||
(MOVi16 GPR:$Rd, imm0_65535_expr:$imm, pred:$p), 0>,
|
||||
Requires<[IsARM, HasV6T2]>;
|
||||
|
||||
// This gets lowered to a single 4-byte instructions
|
||||
let Size = 4 in
|
||||
def MOVi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
|
||||
(ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>,
|
||||
Sched<[WriteALU]>;
|
||||
@@ -3680,6 +3682,8 @@ def MOVTi16 : AI1<0b1010, (outs GPRnopc:$Rd),
|
||||
let DecoderMethod = "DecodeArmMOVTWInstruction";
|
||||
}
|
||||
|
||||
// This gets lowered to a single 4-byte instructions
|
||||
let Size = 4 in
|
||||
def MOVTi16_ga_pcrel : PseudoInst<(outs GPR:$Rd),
|
||||
(ins GPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>,
|
||||
Sched<[WriteALU]>;
|
||||
@@ -5895,27 +5899,30 @@ def : ARMPat<(ARMthread_pointer), (MRC 15, 0, 13, 0, 3)>,
|
||||
//
|
||||
// These are pseudo-instructions and are lowered to individual MC-insts, so
|
||||
// no encoding information is necessary.
|
||||
// This gets lowered to an instruction sequence of 20 bytes
|
||||
let Defs =
|
||||
[ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR,
|
||||
Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15 ],
|
||||
hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1 in {
|
||||
hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1, Size = 20 in {
|
||||
def Int_eh_sjlj_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
|
||||
NoItinerary,
|
||||
[(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
|
||||
Requires<[IsARM, HasVFP2]>;
|
||||
}
|
||||
|
||||
// This gets lowered to an instruction sequence of 20 bytes
|
||||
let Defs =
|
||||
[ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR ],
|
||||
hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1 in {
|
||||
hasSideEffects = 1, isBarrier = 1, usesCustomInserter = 1, Size = 20 in {
|
||||
def Int_eh_sjlj_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val),
|
||||
NoItinerary,
|
||||
[(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>,
|
||||
Requires<[IsARM, NoVFP]>;
|
||||
}
|
||||
|
||||
// This gets lowered to an instruction sequence of 16 bytes
|
||||
// FIXME: Non-IOS version(s)
|
||||
let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
|
||||
let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, Size = 16,
|
||||
Defs = [ R7, LR, SP ] in {
|
||||
def Int_eh_sjlj_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch),
|
||||
NoItinerary,
|
||||
@@ -5958,7 +5965,7 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [SP] in
|
||||
// This is a single pseudo instruction, the benefit is that it can be remat'd
|
||||
// as a single unit instead of having to handle reg inputs.
|
||||
// FIXME: Remove this when we can do generalized remat.
|
||||
let isReMaterializable = 1, isMoveImm = 1 in
|
||||
let isReMaterializable = 1, isMoveImm = 1, Size = 8 in
|
||||
def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
|
||||
[(set GPR:$dst, (arm_i32imm:$src))]>,
|
||||
Requires<[IsARM]>;
|
||||
@@ -6419,8 +6426,12 @@ def SPACE : PseudoInst<(outs GPR:$Rd), (ins i32imm:$size, GPR:$Rn),
|
||||
// SpeculationBarrierEndBB must only be used after an unconditional control
|
||||
// flow, i.e. after a terminator for which isBarrier is True.
|
||||
let hasSideEffects = 1, isCodeGenOnly = 1, isTerminator = 1, isBarrier = 1 in {
|
||||
// This gets lowered to a pair of 4-byte instructions
|
||||
let Size = 8 in
|
||||
def SpeculationBarrierISBDSBEndBB
|
||||
: PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
|
||||
// This gets lowered to a single 4-byte instructions
|
||||
let Size = 4 in
|
||||
def SpeculationBarrierSBEndBB
|
||||
: PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
|
||||
}
|
||||
|
||||
@@ -1537,25 +1537,28 @@ def tTPsoft : tPseudoInst<(outs), (ins), 4, IIC_Br,
|
||||
// Defs. By doing so, we also cause the prologue/epilogue code to actively
|
||||
// preserve all of the callee-saved registers, which is exactly what we want.
|
||||
// $val is a scratch register for our use.
|
||||
// This gets lowered to an instruction sequence of 12 bytes
|
||||
let Defs = [ R0, R1, R2, R3, R4, R5, R6, R7, R12, CPSR ],
|
||||
hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1,
|
||||
hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1, Size = 12,
|
||||
usesCustomInserter = 1 in
|
||||
def tInt_eh_sjlj_setjmp : ThumbXI<(outs),(ins tGPR:$src, tGPR:$val),
|
||||
AddrModeNone, 0, NoItinerary, "","",
|
||||
[(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>;
|
||||
|
||||
// This gets lowered to an instruction sequence of 10 bytes
|
||||
// FIXME: Non-IOS version(s)
|
||||
let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, isCodeGenOnly = 1,
|
||||
Defs = [ R7, LR, SP ] in
|
||||
Size = 10, Defs = [ R7, LR, SP ] in
|
||||
def tInt_eh_sjlj_longjmp : XI<(outs), (ins tGPR:$src, tGPR:$scratch),
|
||||
AddrModeNone, 0, IndexModeNone,
|
||||
Pseudo, NoItinerary, "", "",
|
||||
[(ARMeh_sjlj_longjmp tGPR:$src, tGPR:$scratch)]>,
|
||||
Requires<[IsThumb,IsNotWindows]>;
|
||||
|
||||
// This gets lowered to an instruction sequence of 12 bytes
|
||||
// (Windows is Thumb2-only)
|
||||
let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, isCodeGenOnly = 1,
|
||||
Defs = [ R11, LR, SP ] in
|
||||
Size = 12, Defs = [ R11, LR, SP ] in
|
||||
def tInt_WIN_eh_sjlj_longjmp
|
||||
: XI<(outs), (ins GPR:$src, GPR:$scratch), AddrModeNone, 0, IndexModeNone,
|
||||
Pseudo, NoItinerary, "", "", [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
|
||||
|
||||
@@ -2194,6 +2194,8 @@ def : InstAlias<"mov${p} $Rd, $imm",
|
||||
(t2MOVi16 rGPR:$Rd, imm256_65535_expr:$imm, pred:$p), 0>,
|
||||
Requires<[IsThumb, HasV8MBaseline]>, Sched<[WriteALU]>;
|
||||
|
||||
// This gets lowered to a single 4-byte instructions
|
||||
let Size = 4 in
|
||||
def t2MOVi16_ga_pcrel : PseudoInst<(outs rGPR:$Rd),
|
||||
(ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>,
|
||||
Sched<[WriteALU]>;
|
||||
@@ -2223,6 +2225,8 @@ def t2MOVTi16 : T2I<(outs rGPR:$Rd),
|
||||
let DecoderMethod = "DecodeT2MOVTWInstruction";
|
||||
}
|
||||
|
||||
// This gets lowered to a single 4-byte instructions
|
||||
let Size = 4 in
|
||||
def t2MOVTi16_ga_pcrel : PseudoInst<(outs rGPR:$Rd),
|
||||
(ins rGPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>,
|
||||
Sched<[WriteALU]>, Requires<[IsThumb, HasV8MBaseline]>;
|
||||
@@ -3814,10 +3818,11 @@ def : T2Pat<(stlex_2 (and GPR:$Rt, 0xffff), addr_offset_none:$addr),
|
||||
// doing so, we also cause the prologue/epilogue code to actively preserve
|
||||
// all of the callee-saved registers, which is exactly what we want.
|
||||
// $val is a scratch register for our use.
|
||||
// This gets lowered to an instruction sequence of 12 bytes
|
||||
let Defs =
|
||||
[ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR,
|
||||
Q0, Q1, Q2, Q3, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15],
|
||||
hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1,
|
||||
hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1, Size = 12,
|
||||
usesCustomInserter = 1 in {
|
||||
def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
|
||||
AddrModeNone, 0, NoItinerary, "", "",
|
||||
@@ -3825,9 +3830,10 @@ let Defs =
|
||||
Requires<[IsThumb2, HasVFP2]>;
|
||||
}
|
||||
|
||||
// This gets lowered to an instruction sequence of 12 bytes
|
||||
let Defs =
|
||||
[ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR ],
|
||||
hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1,
|
||||
hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1, Size = 12,
|
||||
usesCustomInserter = 1 in {
|
||||
def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
|
||||
AddrModeNone, 0, NoItinerary, "", "",
|
||||
@@ -4224,7 +4230,7 @@ def : t2InstAlias<"hvc\t$imm16", (t2HVC imm0_65535:$imm16)>;
|
||||
// 32-bit immediate using movw + movt.
|
||||
// This is a single pseudo instruction to make it re-materializable.
|
||||
// FIXME: Remove this when we can do generalized remat.
|
||||
let isReMaterializable = 1, isMoveImm = 1 in
|
||||
let isReMaterializable = 1, isMoveImm = 1, Size = 8 in
|
||||
def t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
|
||||
[(set rGPR:$dst, (i32 imm:$src))]>,
|
||||
Requires<[IsThumb, UseMovt]>;
|
||||
@@ -5006,8 +5012,12 @@ def : InstAlias<"dfb${p}", (t2DSB 0xc, pred:$p), 1>, Requires<[HasDFB]>;
|
||||
// SpeculationBarrierEndBB must only be used after an unconditional control
|
||||
// flow, i.e. after a terminator for which isBarrier is True.
|
||||
let hasSideEffects = 1, isCodeGenOnly = 1, isTerminator = 1, isBarrier = 1 in {
|
||||
// This gets lowered to a pair of 4-byte instructions
|
||||
let Size = 8 in
|
||||
def t2SpeculationBarrierISBDSBEndBB
|
||||
: PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
|
||||
// This gets lowered to a single 4-byte instructions
|
||||
let Size = 4 in
|
||||
def t2SpeculationBarrierSBEndBB
|
||||
: PseudoInst<(outs), (ins), NoItinerary, []>, Sched<[]>;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ set(LLVM_LINK_COMPONENTS
|
||||
CodeGen
|
||||
GlobalISel
|
||||
MC
|
||||
MIRParser
|
||||
SelectionDAG
|
||||
Support
|
||||
Target
|
||||
@@ -17,4 +18,5 @@ set(LLVM_LINK_COMPONENTS
|
||||
|
||||
add_llvm_target_unittest(ARMTests
|
||||
MachineInstrTest.cpp
|
||||
InstSizes.cpp
|
||||
)
|
||||
|
||||
242
llvm/unittests/Target/ARM/InstSizes.cpp
Normal file
242
llvm/unittests/Target/ARM/InstSizes.cpp
Normal file
@@ -0,0 +1,242 @@
|
||||
#include "ARMInstrInfo.h"
|
||||
#include "ARMSubtarget.h"
|
||||
#include "ARMTargetMachine.h"
|
||||
#include "llvm/CodeGen/MIRParser/MIRParser.h"
|
||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||
#include "llvm/MC/TargetRegistry.h"
|
||||
#include "llvm/Support/TargetSelect.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
/// The \p InputIRSnippet is only needed for things that can't be expressed in
|
||||
/// the \p InputMIRSnippet (global variables etc)
|
||||
/// TODO: Some of this might be useful for other architectures as well - extract
|
||||
/// the platform-independent parts somewhere they can be reused.
|
||||
void runChecks(
|
||||
LLVMTargetMachine *TM, const ARMBaseInstrInfo *II,
|
||||
const StringRef InputIRSnippet, const StringRef InputMIRSnippet,
|
||||
unsigned Expected,
|
||||
std::function<void(const ARMBaseInstrInfo &, MachineFunction &, unsigned &)>
|
||||
Checks) {
|
||||
LLVMContext Context;
|
||||
|
||||
auto MIRString = "--- |\n"
|
||||
" declare void @sizes()\n" +
|
||||
InputIRSnippet.str() +
|
||||
"...\n"
|
||||
"---\n"
|
||||
"name: sizes\n"
|
||||
"constants:\n"
|
||||
" - id: 0\n"
|
||||
" value: i32 12345678\n"
|
||||
" alignment: 4\n"
|
||||
"jumpTable:\n"
|
||||
" kind: inline\n"
|
||||
" entries:\n"
|
||||
" - id: 0\n"
|
||||
" blocks: [ '%bb.0' ]\n"
|
||||
"body: |\n"
|
||||
" bb.0:\n" +
|
||||
InputMIRSnippet.str();
|
||||
|
||||
std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRString);
|
||||
std::unique_ptr<MIRParser> MParser =
|
||||
createMIRParser(std::move(MBuffer), Context);
|
||||
ASSERT_TRUE(MParser);
|
||||
|
||||
std::unique_ptr<Module> M = MParser->parseIRModule();
|
||||
ASSERT_TRUE(M);
|
||||
|
||||
M->setTargetTriple(TM->getTargetTriple().getTriple());
|
||||
M->setDataLayout(TM->createDataLayout());
|
||||
|
||||
MachineModuleInfo MMI(TM);
|
||||
bool Res = MParser->parseMachineFunctions(*M, MMI);
|
||||
ASSERT_FALSE(Res);
|
||||
|
||||
auto F = M->getFunction("sizes");
|
||||
ASSERT_TRUE(F != nullptr);
|
||||
auto &MF = MMI.getOrCreateMachineFunction(*F);
|
||||
|
||||
Checks(*II, MF, Expected);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
TEST(InstSizes, PseudoInst) {
|
||||
LLVMInitializeARMTargetInfo();
|
||||
LLVMInitializeARMTarget();
|
||||
LLVMInitializeARMTargetMC();
|
||||
|
||||
auto TT(Triple::normalize("thumbv8.1m.main-none-none-eabi"));
|
||||
std::string Error;
|
||||
const Target *T = TargetRegistry::lookupTarget(TT, Error);
|
||||
if (!T) {
|
||||
dbgs() << Error;
|
||||
return;
|
||||
}
|
||||
|
||||
TargetOptions Options;
|
||||
auto TM = std::unique_ptr<LLVMTargetMachine>(
|
||||
static_cast<LLVMTargetMachine *>(T->createTargetMachine(
|
||||
TT, "generic", "", Options, None, None, CodeGenOpt::Default)));
|
||||
ARMSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()),
|
||||
std::string(TM->getTargetFeatureString()),
|
||||
*static_cast<const ARMBaseTargetMachine *>(TM.get()), false);
|
||||
const ARMBaseInstrInfo *II = ST.getInstrInfo();
|
||||
|
||||
auto cmpInstSize = [](const ARMBaseInstrInfo &II, MachineFunction &MF,
|
||||
unsigned &Expected) {
|
||||
auto I = MF.begin()->begin();
|
||||
EXPECT_EQ(Expected, II.getInstSizeInBytes(*I));
|
||||
};
|
||||
|
||||
runChecks(TM.get(), II, "",
|
||||
" $r0 = MOVi16_ga_pcrel"
|
||||
" target-flags(arm-lo16, arm-nonlazy) @sizes, 0\n",
|
||||
4u, cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "",
|
||||
" $r0 = MOVTi16_ga_pcrel $r0,"
|
||||
" target-flags(arm-hi16, arm-nonlazy) @sizes, 0\n",
|
||||
4u, cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "",
|
||||
" $r0 = t2MOVi16_ga_pcrel"
|
||||
" target-flags(arm-lo16, arm-nonlazy) @sizes, 0\n",
|
||||
4u, cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "",
|
||||
" $r0 = t2MOVTi16_ga_pcrel $r0,"
|
||||
" target-flags(arm-hi16, arm-nonlazy) @sizes, 0\n",
|
||||
4u, cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "", " $r0 = MOVi32imm 2\n", 8u, cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "", " $r0 = t2MOVi32imm 2\n", 8u, cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "",
|
||||
" SpeculationBarrierISBDSBEndBB\n"
|
||||
" tBX_RET 14, $noreg, implicit $r0\n",
|
||||
8u, cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "",
|
||||
" t2SpeculationBarrierISBDSBEndBB\n"
|
||||
" tBX_RET 14, $noreg, implicit $r0\n",
|
||||
8u, cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "",
|
||||
" SpeculationBarrierSBEndBB\n"
|
||||
" tBX_RET 14, $noreg, implicit $r0\n",
|
||||
4u, cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "",
|
||||
" t2SpeculationBarrierSBEndBB\n"
|
||||
" tBX_RET 14, $noreg, implicit $r0\n",
|
||||
4u, cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "",
|
||||
" Int_eh_sjlj_longjmp $r0, $r1, implicit-def $r7,"
|
||||
" implicit-def $lr, implicit-def $sp\n",
|
||||
16u, cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "",
|
||||
" tInt_eh_sjlj_longjmp $r0, $r1, implicit-def $r7,"
|
||||
" implicit-def $lr, implicit-def $sp\n",
|
||||
10u, cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "",
|
||||
" tInt_WIN_eh_sjlj_longjmp $r0, $r1, implicit-def $r11,"
|
||||
" implicit-def $lr, implicit-def $sp\n",
|
||||
12u, cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "",
|
||||
" Int_eh_sjlj_setjmp $r0, $r1, implicit-def $r0,"
|
||||
" implicit-def $r1, implicit-def $r2, implicit-def $r3,"
|
||||
" implicit-def $r4, implicit-def $r5, implicit-def $r6,"
|
||||
" implicit-def $r7, implicit-def $r8, implicit-def $r9,"
|
||||
" implicit-def $r10, implicit-def $r11, implicit-def $r12,"
|
||||
" implicit-def $lr, implicit-def $cpsr, implicit-def $q0,"
|
||||
" implicit-def $q1, implicit-def $q2, implicit-def $q3,"
|
||||
" implicit-def $q4, implicit-def $q5, implicit-def $q6,"
|
||||
" implicit-def $q7, implicit-def $q8, implicit-def $q9,"
|
||||
" implicit-def $q10, implicit-def $q11, implicit-def $q12,"
|
||||
" implicit-def $q13, implicit-def $q14, implicit-def $q15\n"
|
||||
" tBX_RET 14, $noreg, implicit $r0\n",
|
||||
20u, cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "",
|
||||
" Int_eh_sjlj_setjmp_nofp $r0, $r1, implicit-def $r0,"
|
||||
" implicit-def $r1, implicit-def $r2, implicit-def $r3,"
|
||||
" implicit-def $r4, implicit-def $r5, implicit-def $r6,"
|
||||
" implicit-def $r7, implicit-def $r8, implicit-def $r9,"
|
||||
" implicit-def $r10, implicit-def $r11, implicit-def $r12,"
|
||||
" implicit-def $lr, implicit-def $cpsr\n"
|
||||
" tBX_RET 14, $noreg, implicit $r0\n",
|
||||
20u, cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "",
|
||||
" tInt_eh_sjlj_setjmp $r0, $r1, implicit-def $r0,"
|
||||
" implicit-def $r1, implicit-def $r2, implicit-def $r3,"
|
||||
" implicit-def $r4, implicit-def $r5, implicit-def $r6,"
|
||||
" implicit-def $r7, implicit-def $r12, implicit-def $cpsr\n"
|
||||
" tBX_RET 14, $noreg, implicit $r0\n",
|
||||
12u, cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "",
|
||||
" t2Int_eh_sjlj_setjmp $r0, $r1, implicit-def $r0,"
|
||||
" implicit-def $r1, implicit-def $r2, implicit-def $r3,"
|
||||
" implicit-def $r4, implicit-def $r5, implicit-def $r6,"
|
||||
" implicit-def $r7, implicit-def $r8, implicit-def $r9,"
|
||||
" implicit-def $r10, implicit-def $r11, implicit-def $r12,"
|
||||
" implicit-def $lr, implicit-def $cpsr, implicit-def $q0,"
|
||||
" implicit-def $q1, implicit-def $q2, implicit-def $q3,"
|
||||
" implicit-def $q8, implicit-def $q9, implicit-def $q10,"
|
||||
" implicit-def $q11, implicit-def $q12, implicit-def $q13,"
|
||||
" implicit-def $q14, implicit-def $q15\n"
|
||||
" tBX_RET 14, $noreg, implicit $r0\n",
|
||||
12u, cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "",
|
||||
" t2Int_eh_sjlj_setjmp_nofp $r0, $r1, implicit-def $r0,"
|
||||
" implicit-def $r1, implicit-def $r2, implicit-def $r3,"
|
||||
" implicit-def $r4, implicit-def $r5, implicit-def $r6,"
|
||||
" implicit-def $r7, implicit-def $r8, implicit-def $r9,"
|
||||
" implicit-def $r10, implicit-def $r11, implicit-def $r12,"
|
||||
" implicit-def $lr, implicit-def $cpsr\n"
|
||||
" tBX_RET 14, $noreg, implicit $r0\n",
|
||||
12u, cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "", " CONSTPOOL_ENTRY 3, %const.0, 8\n", 8u,
|
||||
cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "", " JUMPTABLE_ADDRS 0, %jump-table.0, 123\n", 123u,
|
||||
cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "", " JUMPTABLE_INSTS 0, %jump-table.0, 456\n", 456u,
|
||||
cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "", " JUMPTABLE_TBB 0, %jump-table.0, 789\n", 789u,
|
||||
cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "", " JUMPTABLE_TBH 0, %jump-table.0, 188\n", 188u,
|
||||
cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "", " $r0 = SPACE 40, undef $r0\n", 40u,
|
||||
cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II, "", " INLINEASM &\"movs r0, #42\", 1\n", 6u,
|
||||
cmpInstSize);
|
||||
|
||||
runChecks(TM.get(), II,
|
||||
" define void @foo() {\n"
|
||||
" entry:\n"
|
||||
" ret void\n"
|
||||
" }\n",
|
||||
" INLINEASM_BR &\"b ${0:l}\", 1, 13, blockaddress(@foo, "
|
||||
"%ir-block.entry)\n",
|
||||
6u, cmpInstSize);
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import("//llvm/utils/unittest/unittest.gni")
|
||||
|
||||
unittest("ARMTests") {
|
||||
deps = [
|
||||
"//llvm/lib/CodeGen/MIRParser",
|
||||
"//llvm/lib/MC",
|
||||
"//llvm/lib/Support",
|
||||
"//llvm/lib/Target",
|
||||
@@ -11,5 +12,5 @@ unittest("ARMTests") {
|
||||
"//llvm/lib/Target/ARM/Utils",
|
||||
]
|
||||
include_dirs = [ "//llvm/lib/Target/ARM" ]
|
||||
sources = [ "MachineInstrTest.cpp" ]
|
||||
sources = [ "MachineInstrTest.cpp", "InstSizes.cpp" ]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user