mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-31 10:34:17 +00:00
Use TableGen'erated pseudo lowering for ARM.
Hook up the TableGen lowering for simple pseudo instructions for ARM and use it for a subset of the many pseudos the backend has as proof of concept. More conversions to come. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134705 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
86f9adb8be
commit
53e3fc463e
@ -1069,48 +1069,18 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) {
|
|||||||
|
|
||||||
extern cl::opt<bool> EnableARMEHABI;
|
extern cl::opt<bool> EnableARMEHABI;
|
||||||
|
|
||||||
|
// Simple pseudo-instructions have their lowering (with expansion to real
|
||||||
|
// instructions) auto-generated.
|
||||||
|
#include "ARMGenMCPseudoLowering.inc"
|
||||||
|
|
||||||
void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||||
|
// Do any auto-generated pseudo lowerings.
|
||||||
|
if (emitPseudoExpansionLowering(OutStreamer, MI))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check for manual lowerings.
|
||||||
unsigned Opc = MI->getOpcode();
|
unsigned Opc = MI->getOpcode();
|
||||||
switch (Opc) {
|
switch (Opc) {
|
||||||
default: break;
|
|
||||||
case ARM::B: {
|
|
||||||
// B is just a Bcc with an 'always' predicate.
|
|
||||||
MCInst TmpInst;
|
|
||||||
LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
|
|
||||||
TmpInst.setOpcode(ARM::Bcc);
|
|
||||||
// Add predicate operands.
|
|
||||||
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
|
|
||||||
TmpInst.addOperand(MCOperand::CreateReg(0));
|
|
||||||
OutStreamer.EmitInstruction(TmpInst);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case ARM::LDMIA_RET: {
|
|
||||||
// LDMIA_RET is just a normal LDMIA_UPD instruction that targets PC and as
|
|
||||||
// such has additional code-gen properties and scheduling information.
|
|
||||||
// To emit it, we just construct as normal and set the opcode to LDMIA_UPD.
|
|
||||||
MCInst TmpInst;
|
|
||||||
LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
|
|
||||||
TmpInst.setOpcode(ARM::LDMIA_UPD);
|
|
||||||
OutStreamer.EmitInstruction(TmpInst);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case ARM::t2LDMIA_RET: {
|
|
||||||
// As above for LDMIA_RET. Map to the tPOP instruction.
|
|
||||||
MCInst TmpInst;
|
|
||||||
LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
|
|
||||||
TmpInst.setOpcode(ARM::t2LDMIA_UPD);
|
|
||||||
OutStreamer.EmitInstruction(TmpInst);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case ARM::tPOP_RET: {
|
|
||||||
// As above for LDMIA_RET. Map to the tPOP instruction.
|
|
||||||
MCInst TmpInst;
|
|
||||||
LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
|
|
||||||
TmpInst.setOpcode(ARM::tPOP);
|
|
||||||
OutStreamer.EmitInstruction(TmpInst);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
case ARM::t2MOVi32imm: assert(0 && "Should be lowered by thumb2it pass");
|
case ARM::t2MOVi32imm: assert(0 && "Should be lowered by thumb2it pass");
|
||||||
case ARM::DBG_VALUE: {
|
case ARM::DBG_VALUE: {
|
||||||
if (isVerbose() && OutStreamer.hasRawTextSupport()) {
|
if (isVerbose() && OutStreamer.hasRawTextSupport()) {
|
||||||
@ -1121,14 +1091,6 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case ARM::tBfar: {
|
|
||||||
MCInst TmpInst;
|
|
||||||
TmpInst.setOpcode(ARM::tBL);
|
|
||||||
TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create(
|
|
||||||
MI->getOperand(0).getMBB()->getSymbol(), OutContext)));
|
|
||||||
OutStreamer.EmitInstruction(TmpInst);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case ARM::LEApcrel:
|
case ARM::LEApcrel:
|
||||||
case ARM::tLEApcrel:
|
case ARM::tLEApcrel:
|
||||||
case ARM::t2LEApcrel: {
|
case ARM::t2LEApcrel: {
|
||||||
@ -1159,19 +1121,6 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
|||||||
OutStreamer.EmitInstruction(TmpInst);
|
OutStreamer.EmitInstruction(TmpInst);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case ARM::MOVPCRX: {
|
|
||||||
MCInst TmpInst;
|
|
||||||
TmpInst.setOpcode(ARM::MOVr);
|
|
||||||
TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
|
|
||||||
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
|
|
||||||
// Add predicate operands.
|
|
||||||
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
|
|
||||||
TmpInst.addOperand(MCOperand::CreateReg(0));
|
|
||||||
// Add 's' bit operand (always reg0 for this)
|
|
||||||
TmpInst.addOperand(MCOperand::CreateReg(0));
|
|
||||||
OutStreamer.EmitInstruction(TmpInst);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Darwin call instructions are just normal call instructions with different
|
// Darwin call instructions are just normal call instructions with different
|
||||||
// clobber semantics (they clobber R9).
|
// clobber semantics (they clobber R9).
|
||||||
case ARM::BLr9:
|
case ARM::BLr9:
|
||||||
@ -1912,31 +1861,6 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
|||||||
OutStreamer.EmitInstruction(TmpInst);
|
OutStreamer.EmitInstruction(TmpInst);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// These are the pseudos created to comply with stricter operand restrictions
|
|
||||||
// on ARMv5. Lower them now to "normal" instructions, since all the
|
|
||||||
// restrictions are already satisfied.
|
|
||||||
case ARM::MULv5:
|
|
||||||
EmitPatchedInstruction(MI, ARM::MUL);
|
|
||||||
return;
|
|
||||||
case ARM::MLAv5:
|
|
||||||
EmitPatchedInstruction(MI, ARM::MLA);
|
|
||||||
return;
|
|
||||||
case ARM::SMULLv5:
|
|
||||||
EmitPatchedInstruction(MI, ARM::SMULL);
|
|
||||||
return;
|
|
||||||
case ARM::UMULLv5:
|
|
||||||
EmitPatchedInstruction(MI, ARM::UMULL);
|
|
||||||
return;
|
|
||||||
case ARM::SMLALv5:
|
|
||||||
EmitPatchedInstruction(MI, ARM::SMLAL);
|
|
||||||
return;
|
|
||||||
case ARM::UMLALv5:
|
|
||||||
EmitPatchedInstruction(MI, ARM::UMLAL);
|
|
||||||
return;
|
|
||||||
case ARM::UMAALv5:
|
|
||||||
EmitPatchedInstruction(MI, ARM::UMAAL);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MCInst TmpInst;
|
MCInst TmpInst;
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
|
class MCOperand;
|
||||||
|
|
||||||
namespace ARM {
|
namespace ARM {
|
||||||
enum DW_ISA {
|
enum DW_ISA {
|
||||||
DW_ISA_ARM_thumb = 1,
|
DW_ISA_ARM_thumb = 1,
|
||||||
@ -72,6 +74,9 @@ public:
|
|||||||
void EmitStartOfAsmFile(Module &M);
|
void EmitStartOfAsmFile(Module &M);
|
||||||
void EmitEndOfAsmFile(Module &M);
|
void EmitEndOfAsmFile(Module &M);
|
||||||
|
|
||||||
|
// lowerOperand - Convert a MachineOperand into the equivalent MCOperand.
|
||||||
|
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile()
|
// Helpers for EmitStartOfAsmFile() and EmitEndOfAsmFile()
|
||||||
void emitAttributes();
|
void emitAttributes();
|
||||||
@ -84,6 +89,10 @@ private:
|
|||||||
|
|
||||||
void EmitUnwindingInstruction(const MachineInstr *MI);
|
void EmitUnwindingInstruction(const MachineInstr *MI);
|
||||||
|
|
||||||
|
// emitPseudoExpansionLowering - tblgen'erated.
|
||||||
|
bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
|
||||||
|
const MachineInstr *MI);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
|
void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
|
||||||
|
|
||||||
@ -100,6 +109,7 @@ public:
|
|||||||
llvm::ARM::DW_ISA_ARM_thumb : llvm::ARM::DW_ISA_ARM_arm;
|
llvm::ARM::DW_ISA_ARM_thumb : llvm::ARM::DW_ISA_ARM_arm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol);
|
||||||
MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
|
MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
|
||||||
const MachineBasicBlock *MBB) const;
|
const MachineBasicBlock *MBB) const;
|
||||||
MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const;
|
MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const;
|
||||||
|
@ -314,6 +314,25 @@ class t2PseudoInst<dag oops, dag iops, SizeFlagVal sz, InstrItinClass itin,
|
|||||||
let SZ = sz;
|
let SZ = sz;
|
||||||
list<Predicate> Predicates = [IsThumb2];
|
list<Predicate> Predicates = [IsThumb2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ARMPseudoExpand<dag oops, dag iops, SizeFlagVal sz,
|
||||||
|
InstrItinClass itin, list<dag> pattern,
|
||||||
|
dag Result>
|
||||||
|
: ARMPseudoInst<oops, iops, sz, itin, pattern>,
|
||||||
|
PseudoInstExpansion<Result>;
|
||||||
|
|
||||||
|
class tPseudoExpand<dag oops, dag iops, SizeFlagVal sz,
|
||||||
|
InstrItinClass itin, list<dag> pattern,
|
||||||
|
dag Result>
|
||||||
|
: tPseudoInst<oops, iops, sz, itin, pattern>,
|
||||||
|
PseudoInstExpansion<Result>;
|
||||||
|
|
||||||
|
class t2PseudoExpand<dag oops, dag iops, SizeFlagVal sz,
|
||||||
|
InstrItinClass itin, list<dag> pattern,
|
||||||
|
dag Result>
|
||||||
|
: t2PseudoInst<oops, iops, sz, itin, pattern>,
|
||||||
|
PseudoInstExpansion<Result>;
|
||||||
|
|
||||||
// Almost all ARM instructions are predicable.
|
// Almost all ARM instructions are predicable.
|
||||||
class I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
|
class I<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
|
||||||
IndexMode im, Format f, InstrItinClass itin,
|
IndexMode im, Format f, InstrItinClass itin,
|
||||||
|
@ -1363,14 +1363,6 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
|
|||||||
let Inst{27-4} = 0b000100101111111111110001;
|
let Inst{27-4} = 0b000100101111111111110001;
|
||||||
let Inst{3-0} = dst;
|
let Inst{3-0} = dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ARMV4 only
|
|
||||||
// FIXME: We would really like to define this as a vanilla ARMPat like:
|
|
||||||
// ARMPat<(brind GPR:$dst), (MOVr PC, GPR:$dst)>
|
|
||||||
// With that, however, we can't set isBranch, isTerminator, etc..
|
|
||||||
def MOVPCRX : ARMPseudoInst<(outs), (ins GPR:$dst),
|
|
||||||
Size4Bytes, IIC_Br, [(brind GPR:$dst)]>,
|
|
||||||
Requires<[IsARM, NoV4T]>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// All calls clobber the non-callee saved registers. SP is marked as
|
// All calls clobber the non-callee saved registers. SP is marked as
|
||||||
@ -1526,13 +1518,23 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let isBranch = 1, isTerminator = 1 in {
|
let isBranch = 1, isTerminator = 1 in {
|
||||||
// B is "predicable" since it's just a Bcc with an 'always' condition.
|
// FIXME: should be able to write a pattern for ARMBrcond, but can't use
|
||||||
|
// a two-value operand where a dag node expects two operands. :(
|
||||||
|
def Bcc : ABI<0b1010, (outs), (ins br_target:$target),
|
||||||
|
IIC_Br, "b", "\t$target",
|
||||||
|
[/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
|
||||||
|
bits<24> target;
|
||||||
|
let Inst{23-0} = target;
|
||||||
|
}
|
||||||
|
|
||||||
let isBarrier = 1 in {
|
let isBarrier = 1 in {
|
||||||
|
// B is "predicable" since it's just a Bcc with an 'always' condition.
|
||||||
let isPredicable = 1 in
|
let isPredicable = 1 in
|
||||||
// FIXME: We shouldn't need this pseudo at all. Just using Bcc directly
|
// FIXME: We shouldn't need this pseudo at all. Just using Bcc directly
|
||||||
// should be sufficient.
|
// should be sufficient.
|
||||||
def B : ARMPseudoInst<(outs), (ins brtarget:$target), Size4Bytes, IIC_Br,
|
// FIXME: Is B really a Barrier? That doesn't seem right.
|
||||||
[(br bb:$target)]>;
|
def B : ARMPseudoExpand<(outs), (ins br_target:$target), Size4Bytes, IIC_Br,
|
||||||
|
[(br bb:$target)], (Bcc br_target:$target, (ops 14, zero_reg))>;
|
||||||
|
|
||||||
let isNotDuplicable = 1, isIndirectBranch = 1 in {
|
let isNotDuplicable = 1, isIndirectBranch = 1 in {
|
||||||
def BR_JTr : ARMPseudoInst<(outs),
|
def BR_JTr : ARMPseudoInst<(outs),
|
||||||
@ -1554,14 +1556,6 @@ let isBranch = 1, isTerminator = 1 in {
|
|||||||
} // isNotDuplicable = 1, isIndirectBranch = 1
|
} // isNotDuplicable = 1, isIndirectBranch = 1
|
||||||
} // isBarrier = 1
|
} // isBarrier = 1
|
||||||
|
|
||||||
// FIXME: should be able to write a pattern for ARMBrcond, but can't use
|
|
||||||
// a two-value operand where a dag node expects two operands. :(
|
|
||||||
def Bcc : ABI<0b1010, (outs), (ins br_target:$target),
|
|
||||||
IIC_Br, "b", "\t$target",
|
|
||||||
[/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> {
|
|
||||||
bits<24> target;
|
|
||||||
let Inst{23-0} = target;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BLX (immediate) -- for disassembly only
|
// BLX (immediate) -- for disassembly only
|
||||||
@ -2030,9 +2024,10 @@ def : MnemonicAlias<"stm", "stmia">;
|
|||||||
// FIXME: Should pc be an implicit operand like PICADD, etc?
|
// FIXME: Should pc be an implicit operand like PICADD, etc?
|
||||||
let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
|
let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
|
||||||
hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
|
hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
|
||||||
def LDMIA_RET : ARMPseudoInst<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
|
def LDMIA_RET : ARMPseudoExpand<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
|
||||||
reglist:$regs, variable_ops),
|
reglist:$regs, variable_ops),
|
||||||
Size4Bytes, IIC_iLoad_mBr, []>,
|
Size4Bytes, IIC_iLoad_mBr, [],
|
||||||
|
(LDMIA_UPD GPR:$wb, GPR:$Rn, pred:$p, reglist:$regs)>,
|
||||||
RegConstraint<"$Rn = $wb">;
|
RegConstraint<"$Rn = $wb">;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -2690,28 +2685,26 @@ class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin,
|
|||||||
let Inst{3-0} = Rn;
|
let Inst{3-0} = Rn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: The v5 pseudos are only necessary for the additional Constraint
|
||||||
|
// property. Remove them when it's possible to add those properties
|
||||||
|
// on an individual MachineInstr, not just an instuction description.
|
||||||
let isCommutable = 1 in {
|
let isCommutable = 1 in {
|
||||||
let Constraints = "@earlyclobber $Rd" in
|
|
||||||
def MULv5: ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
|
|
||||||
pred:$p, cc_out:$s),
|
|
||||||
Size4Bytes, IIC_iMUL32,
|
|
||||||
[(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
|
|
||||||
Requires<[IsARM, NoV6]>;
|
|
||||||
|
|
||||||
def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
|
def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm),
|
||||||
IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
|
IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm",
|
||||||
[(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
|
[(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>,
|
||||||
Requires<[IsARM, HasV6]> {
|
Requires<[IsARM, HasV6]> {
|
||||||
let Inst{15-12} = 0b0000;
|
let Inst{15-12} = 0b0000;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let Constraints = "@earlyclobber $Rd" in
|
let Constraints = "@earlyclobber $Rd" in
|
||||||
def MLAv5: ARMPseudoInst<(outs GPR:$Rd),
|
def MULv5: ARMPseudoExpand<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
|
||||||
(ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s),
|
pred:$p, cc_out:$s),
|
||||||
Size4Bytes, IIC_iMAC32,
|
Size4Bytes, IIC_iMUL32,
|
||||||
[(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
|
[(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))],
|
||||||
|
(MUL GPR:$Rd, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
|
||||||
Requires<[IsARM, NoV6]>;
|
Requires<[IsARM, NoV6]>;
|
||||||
|
}
|
||||||
|
|
||||||
def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
|
def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
|
||||||
IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
|
IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra",
|
||||||
[(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
|
[(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>,
|
||||||
@ -2720,6 +2713,14 @@ def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
|
|||||||
let Inst{15-12} = Ra;
|
let Inst{15-12} = Ra;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let Constraints = "@earlyclobber $Rd" in
|
||||||
|
def MLAv5: ARMPseudoExpand<(outs GPR:$Rd),
|
||||||
|
(ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s),
|
||||||
|
Size4Bytes, IIC_iMAC32,
|
||||||
|
[(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))],
|
||||||
|
(MLA GPR:$Rd, GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s)>,
|
||||||
|
Requires<[IsARM, NoV6]>;
|
||||||
|
|
||||||
def MLS : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
|
def MLS : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
|
||||||
IIC_iMAC32, "mls", "\t$Rd, $Rn, $Rm, $Ra",
|
IIC_iMAC32, "mls", "\t$Rd, $Rn, $Rm, $Ra",
|
||||||
[(set GPR:$Rd, (sub GPR:$Ra, (mul GPR:$Rn, GPR:$Rm)))]>,
|
[(set GPR:$Rd, (sub GPR:$Ra, (mul GPR:$Rn, GPR:$Rm)))]>,
|
||||||
@ -2735,49 +2736,34 @@ def MLS : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra),
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extra precision multiplies with low / high results
|
// Extra precision multiplies with low / high results
|
||||||
|
|
||||||
let neverHasSideEffects = 1 in {
|
let neverHasSideEffects = 1 in {
|
||||||
let isCommutable = 1 in {
|
let isCommutable = 1 in {
|
||||||
let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
|
|
||||||
def SMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
|
|
||||||
(ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
|
|
||||||
Size4Bytes, IIC_iMUL64, []>,
|
|
||||||
Requires<[IsARM, NoV6]>;
|
|
||||||
|
|
||||||
def UMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
|
|
||||||
(ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
|
|
||||||
Size4Bytes, IIC_iMUL64, []>,
|
|
||||||
Requires<[IsARM, NoV6]>;
|
|
||||||
}
|
|
||||||
|
|
||||||
def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
|
def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi),
|
||||||
(ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
|
(ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
|
||||||
"smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
|
"smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
|
||||||
Requires<[IsARM, HasV6]>;
|
Requires<[IsARM, HasV6]>;
|
||||||
|
|
||||||
def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
|
def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi),
|
||||||
(ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
|
(ins GPR:$Rn, GPR:$Rm), IIC_iMUL64,
|
||||||
"umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
|
"umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
|
||||||
Requires<[IsARM, HasV6]>;
|
Requires<[IsARM, HasV6]>;
|
||||||
|
|
||||||
|
let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
|
||||||
|
def SMULLv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
|
||||||
|
(ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
|
||||||
|
Size4Bytes, IIC_iMUL64, [],
|
||||||
|
(SMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
|
||||||
|
Requires<[IsARM, NoV6]>;
|
||||||
|
|
||||||
|
def UMULLv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
|
||||||
|
(ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
|
||||||
|
Size4Bytes, IIC_iMUL64, [],
|
||||||
|
(UMULL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
|
||||||
|
Requires<[IsARM, NoV6]>;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multiply + accumulate
|
// Multiply + accumulate
|
||||||
let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
|
|
||||||
def SMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
|
|
||||||
(ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
|
|
||||||
Size4Bytes, IIC_iMAC64, []>,
|
|
||||||
Requires<[IsARM, NoV6]>;
|
|
||||||
def UMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
|
|
||||||
(ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
|
|
||||||
Size4Bytes, IIC_iMAC64, []>,
|
|
||||||
Requires<[IsARM, NoV6]>;
|
|
||||||
def UMAALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi),
|
|
||||||
(ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
|
|
||||||
Size4Bytes, IIC_iMAC64, []>,
|
|
||||||
Requires<[IsARM, NoV6]>;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
|
def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi),
|
||||||
(ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
|
(ins GPR:$Rn, GPR:$Rm), IIC_iMAC64,
|
||||||
"smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
|
"smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>,
|
||||||
@ -2800,6 +2786,25 @@ def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi),
|
|||||||
let Inst{11-8} = Rm;
|
let Inst{11-8} = Rm;
|
||||||
let Inst{3-0} = Rn;
|
let Inst{3-0} = Rn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in {
|
||||||
|
def SMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
|
||||||
|
(ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
|
||||||
|
Size4Bytes, IIC_iMAC64, [],
|
||||||
|
(SMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
|
||||||
|
Requires<[IsARM, NoV6]>;
|
||||||
|
def UMLALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
|
||||||
|
(ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s),
|
||||||
|
Size4Bytes, IIC_iMAC64, [],
|
||||||
|
(UMLAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s)>,
|
||||||
|
Requires<[IsARM, NoV6]>;
|
||||||
|
def UMAALv5 : ARMPseudoExpand<(outs GPR:$RdLo, GPR:$RdHi),
|
||||||
|
(ins GPR:$Rn, GPR:$Rm, pred:$p),
|
||||||
|
Size4Bytes, IIC_iMAC64, [],
|
||||||
|
(UMAAL GPR:$RdLo, GPR:$RdHi, GPR:$Rn, GPR:$Rm, pred:$p)>,
|
||||||
|
Requires<[IsARM, NoV6]>;
|
||||||
|
}
|
||||||
|
|
||||||
} // neverHasSideEffects
|
} // neverHasSideEffects
|
||||||
|
|
||||||
// Most significant word multiply
|
// Most significant word multiply
|
||||||
@ -3838,6 +3843,13 @@ def Int_eh_sjlj_dispatchsetup :
|
|||||||
// Non-Instruction Patterns
|
// Non-Instruction Patterns
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// ARMv4 indirect branch using (MOVr PC, dst)
|
||||||
|
let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in
|
||||||
|
def MOVPCRX : ARMPseudoExpand<(outs), (ins GPR:$dst),
|
||||||
|
Size4Bytes, IIC_Br, [(brind GPR:$dst)],
|
||||||
|
(MOVr PC, GPR:$dst, (ops 14, zero_reg), zero_reg)>,
|
||||||
|
Requires<[IsARM, NoV4T]>;
|
||||||
|
|
||||||
// Large immediate handling.
|
// Large immediate handling.
|
||||||
|
|
||||||
// 32-bit immediate using two piece so_imms or movw + movt.
|
// 32-bit immediate using two piece so_imms or movw + movt.
|
||||||
|
@ -405,12 +405,6 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: remove when we have a way to marking a MI with these properties.
|
|
||||||
let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
|
|
||||||
hasExtraDefRegAllocReq = 1 in
|
|
||||||
def tPOP_RET : tPseudoInst<(outs), (ins pred:$p, reglist:$regs, variable_ops),
|
|
||||||
Size2Bytes, IIC_iPop_Br, []>;
|
|
||||||
|
|
||||||
// All calls clobber the non-callee saved registers. SP is marked as a use to
|
// All calls clobber the non-callee saved registers. SP is marked as a use to
|
||||||
// prevent stack-pointer assignments that appear immediately before calls from
|
// prevent stack-pointer assignments that appear immediately before calls from
|
||||||
// potentially appearing dead.
|
// potentially appearing dead.
|
||||||
@ -528,8 +522,8 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
|
|||||||
// Just a pseudo for a tBL instruction. Needed to let regalloc know about
|
// Just a pseudo for a tBL instruction. Needed to let regalloc know about
|
||||||
// the clobber of LR.
|
// the clobber of LR.
|
||||||
let Defs = [LR] in
|
let Defs = [LR] in
|
||||||
def tBfar : tPseudoInst<(outs), (ins t_bltarget:$target),
|
def tBfar : tPseudoExpand<(outs), (ins t_bltarget:$target),
|
||||||
Size4Bytes, IIC_Br, []>;
|
Size4Bytes, IIC_Br, [], (tBL t_bltarget:$target)>;
|
||||||
|
|
||||||
def tBR_JTr : tPseudoInst<(outs),
|
def tBR_JTr : tPseudoInst<(outs),
|
||||||
(ins tGPR:$target, i32imm:$jt, i32imm:$id),
|
(ins tGPR:$target, i32imm:$jt, i32imm:$id),
|
||||||
@ -1477,3 +1471,12 @@ def tLDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
|
|||||||
[(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
|
[(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
|
||||||
imm:$cp))]>,
|
imm:$cp))]>,
|
||||||
Requires<[IsThumb, IsThumb1Only]>;
|
Requires<[IsThumb, IsThumb1Only]>;
|
||||||
|
|
||||||
|
// Pseudo-instruction for merged POP and return.
|
||||||
|
// FIXME: remove when we have a way to marking a MI with these properties.
|
||||||
|
let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
|
||||||
|
hasExtraDefRegAllocReq = 1 in
|
||||||
|
def tPOP_RET : tPseudoExpand<(outs), (ins pred:$p, reglist:$regs, variable_ops),
|
||||||
|
Size2Bytes, IIC_iPop_Br, [],
|
||||||
|
(tPOP pred:$p, reglist:$regs)>;
|
||||||
|
|
||||||
|
@ -2978,9 +2978,10 @@ let Defs =
|
|||||||
// FIXME: Should pc be an implicit operand like PICADD, etc?
|
// FIXME: Should pc be an implicit operand like PICADD, etc?
|
||||||
let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
|
let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
|
||||||
hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
|
hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
|
||||||
def t2LDMIA_RET: t2PseudoInst<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
|
def t2LDMIA_RET: t2PseudoExpand<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,
|
||||||
reglist:$regs, variable_ops),
|
reglist:$regs, variable_ops),
|
||||||
Size4Bytes, IIC_iLoad_mBr, []>,
|
Size4Bytes, IIC_iLoad_mBr, [],
|
||||||
|
(t2LDMIA_UPD GPR:$wb, GPR:$Rn, pred:$p, reglist:$regs)>,
|
||||||
RegConstraint<"$Rn = $wb">;
|
RegConstraint<"$Rn = $wb">;
|
||||||
|
|
||||||
let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
|
let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
|
||||||
|
@ -23,43 +23,94 @@
|
|||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
|
||||||
static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
|
MCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO,
|
||||||
ARMAsmPrinter &Printer) {
|
const MCSymbol *Symbol) {
|
||||||
MCContext &Ctx = Printer.OutContext;
|
|
||||||
const MCExpr *Expr;
|
const MCExpr *Expr;
|
||||||
switch (MO.getTargetFlags()) {
|
switch (MO.getTargetFlags()) {
|
||||||
default: {
|
default: {
|
||||||
Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, Ctx);
|
Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
|
||||||
|
OutContext);
|
||||||
switch (MO.getTargetFlags()) {
|
switch (MO.getTargetFlags()) {
|
||||||
default:
|
default:
|
||||||
assert(0 && "Unknown target flag on symbol operand");
|
assert(0 && "Unknown target flag on symbol operand");
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case ARMII::MO_LO16:
|
case ARMII::MO_LO16:
|
||||||
Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, Ctx);
|
Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
|
||||||
Expr = ARMMCExpr::CreateLower16(Expr, Ctx);
|
OutContext);
|
||||||
|
Expr = ARMMCExpr::CreateLower16(Expr, OutContext);
|
||||||
break;
|
break;
|
||||||
case ARMII::MO_HI16:
|
case ARMII::MO_HI16:
|
||||||
Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, Ctx);
|
Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
|
||||||
Expr = ARMMCExpr::CreateUpper16(Expr, Ctx);
|
OutContext);
|
||||||
|
Expr = ARMMCExpr::CreateUpper16(Expr, OutContext);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ARMII::MO_PLT:
|
case ARMII::MO_PLT:
|
||||||
Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_PLT, Ctx);
|
Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_PLT,
|
||||||
|
OutContext);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MO.isJTI() && MO.getOffset())
|
if (!MO.isJTI() && MO.getOffset())
|
||||||
Expr = MCBinaryExpr::CreateAdd(Expr,
|
Expr = MCBinaryExpr::CreateAdd(Expr,
|
||||||
MCConstantExpr::Create(MO.getOffset(), Ctx),
|
MCConstantExpr::Create(MO.getOffset(),
|
||||||
Ctx);
|
OutContext),
|
||||||
|
OutContext);
|
||||||
return MCOperand::CreateExpr(Expr);
|
return MCOperand::CreateExpr(Expr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ARMAsmPrinter::lowerOperand(const MachineOperand &MO,
|
||||||
|
MCOperand &MCOp) {
|
||||||
|
switch (MO.getType()) {
|
||||||
|
default:
|
||||||
|
assert(0 && "unknown operand type");
|
||||||
|
return false;
|
||||||
|
case MachineOperand::MO_Register:
|
||||||
|
// Ignore all non-CPSR implicit register operands.
|
||||||
|
if (MO.isImplicit() && MO.getReg() != ARM::CPSR)
|
||||||
|
return false;
|
||||||
|
assert(!MO.getSubReg() && "Subregs should be eliminated!");
|
||||||
|
MCOp = MCOperand::CreateReg(MO.getReg());
|
||||||
|
break;
|
||||||
|
case MachineOperand::MO_Immediate:
|
||||||
|
MCOp = MCOperand::CreateImm(MO.getImm());
|
||||||
|
break;
|
||||||
|
case MachineOperand::MO_MachineBasicBlock:
|
||||||
|
MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
|
||||||
|
MO.getMBB()->getSymbol(), OutContext));
|
||||||
|
break;
|
||||||
|
case MachineOperand::MO_GlobalAddress:
|
||||||
|
MCOp = GetSymbolRef(MO, Mang->getSymbol(MO.getGlobal()));
|
||||||
|
break;
|
||||||
|
case MachineOperand::MO_ExternalSymbol:
|
||||||
|
MCOp = GetSymbolRef(MO,
|
||||||
|
GetExternalSymbolSymbol(MO.getSymbolName()));
|
||||||
|
break;
|
||||||
|
case MachineOperand::MO_JumpTableIndex:
|
||||||
|
MCOp = GetSymbolRef(MO, GetJTISymbol(MO.getIndex()));
|
||||||
|
break;
|
||||||
|
case MachineOperand::MO_ConstantPoolIndex:
|
||||||
|
MCOp = GetSymbolRef(MO, GetCPISymbol(MO.getIndex()));
|
||||||
|
break;
|
||||||
|
case MachineOperand::MO_BlockAddress:
|
||||||
|
MCOp = GetSymbolRef(MO, GetBlockAddressSymbol(MO.getBlockAddress()));
|
||||||
|
break;
|
||||||
|
case MachineOperand::MO_FPImmediate: {
|
||||||
|
APFloat Val = MO.getFPImm()->getValueAPF();
|
||||||
|
bool ignored;
|
||||||
|
Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored);
|
||||||
|
MCOp = MCOperand::CreateFPImm(Val.convertToDouble());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void llvm::LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
|
void llvm::LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
|
||||||
ARMAsmPrinter &AP) {
|
ARMAsmPrinter &AP) {
|
||||||
OutMI.setOpcode(MI->getOpcode());
|
OutMI.setOpcode(MI->getOpcode());
|
||||||
@ -68,48 +119,7 @@ void llvm::LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
|
|||||||
const MachineOperand &MO = MI->getOperand(i);
|
const MachineOperand &MO = MI->getOperand(i);
|
||||||
|
|
||||||
MCOperand MCOp;
|
MCOperand MCOp;
|
||||||
switch (MO.getType()) {
|
if (AP.lowerOperand(MO, MCOp))
|
||||||
default:
|
OutMI.addOperand(MCOp);
|
||||||
MI->dump();
|
|
||||||
assert(0 && "unknown operand type");
|
|
||||||
case MachineOperand::MO_Register:
|
|
||||||
// Ignore all non-CPSR implicit register operands.
|
|
||||||
if (MO.isImplicit() && MO.getReg() != ARM::CPSR) continue;
|
|
||||||
assert(!MO.getSubReg() && "Subregs should be eliminated!");
|
|
||||||
MCOp = MCOperand::CreateReg(MO.getReg());
|
|
||||||
break;
|
|
||||||
case MachineOperand::MO_Immediate:
|
|
||||||
MCOp = MCOperand::CreateImm(MO.getImm());
|
|
||||||
break;
|
|
||||||
case MachineOperand::MO_MachineBasicBlock:
|
|
||||||
MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
|
|
||||||
MO.getMBB()->getSymbol(), AP.OutContext));
|
|
||||||
break;
|
|
||||||
case MachineOperand::MO_GlobalAddress:
|
|
||||||
MCOp = GetSymbolRef(MO, AP.Mang->getSymbol(MO.getGlobal()), AP);
|
|
||||||
break;
|
|
||||||
case MachineOperand::MO_ExternalSymbol:
|
|
||||||
MCOp = GetSymbolRef(MO,
|
|
||||||
AP.GetExternalSymbolSymbol(MO.getSymbolName()), AP);
|
|
||||||
break;
|
|
||||||
case MachineOperand::MO_JumpTableIndex:
|
|
||||||
MCOp = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP);
|
|
||||||
break;
|
|
||||||
case MachineOperand::MO_ConstantPoolIndex:
|
|
||||||
MCOp = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP);
|
|
||||||
break;
|
|
||||||
case MachineOperand::MO_BlockAddress:
|
|
||||||
MCOp = GetSymbolRef(MO,AP.GetBlockAddressSymbol(MO.getBlockAddress()),AP);
|
|
||||||
break;
|
|
||||||
case MachineOperand::MO_FPImmediate: {
|
|
||||||
APFloat Val = MO.getFPImm()->getValueAPF();
|
|
||||||
bool ignored;
|
|
||||||
Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored);
|
|
||||||
MCOp = MCOperand::CreateFPImm(Val.convertToDouble());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OutMI.addOperand(MCOp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,8 @@ BUILT_SOURCES = ARMGenRegisterInfo.inc ARMGenInstrInfo.inc \
|
|||||||
ARMGenDAGISel.inc ARMGenSubtargetInfo.inc \
|
ARMGenDAGISel.inc ARMGenSubtargetInfo.inc \
|
||||||
ARMGenCodeEmitter.inc ARMGenCallingConv.inc \
|
ARMGenCodeEmitter.inc ARMGenCallingConv.inc \
|
||||||
ARMGenDecoderTables.inc ARMGenEDInfo.inc \
|
ARMGenDecoderTables.inc ARMGenEDInfo.inc \
|
||||||
ARMGenFastISel.inc ARMGenMCCodeEmitter.inc
|
ARMGenFastISel.inc ARMGenMCCodeEmitter.inc \
|
||||||
|
ARMGenMCPseudoLowering.inc
|
||||||
|
|
||||||
DIRS = InstPrinter AsmParser Disassembler TargetInfo MCTargetDesc
|
DIRS = InstPrinter AsmParser Disassembler TargetInfo MCTargetDesc
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user