ARM Pseudo-ize tBR_JTr.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120310 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Grosbach 2010-11-29 19:32:47 +00:00
parent 00a035f74f
commit f1aa47dc1a
5 changed files with 19 additions and 28 deletions

View File

@ -936,23 +936,13 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
EmitJump2Table(MI); EmitJump2Table(MI);
return; return;
} }
case ARM::tBR_JTr: { case ARM::tBR_JTr:
// Lower and emit the instruction itself, then the jump table following it.
MCInst TmpInst;
// FIXME: The branch instruction is really a pseudo. We should xform it
// explicitly.
LowerARMMachineInstrToMCInst(MI, TmpInst, *this);
OutStreamer.EmitInstruction(TmpInst);
// Output the data for the jump table itself
EmitJumpTable(MI);
return;
}
case ARM::BR_JTr: { case ARM::BR_JTr: {
// Lower and emit the instruction itself, then the jump table following it. // Lower and emit the instruction itself, then the jump table following it.
// mov pc, target // mov pc, target
MCInst TmpInst; MCInst TmpInst;
TmpInst.setOpcode(ARM::MOVr); unsigned Opc = MI->getOpcode() == ARM::BR_JTr ? ARM::MOVr : ARM::tMOVr;
TmpInst.setOpcode(Opc);
TmpInst.addOperand(MCOperand::CreateReg(ARM::PC)); TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
// Add predicate operands. // Add predicate operands.
@ -960,6 +950,10 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
TmpInst.addOperand(MCOperand::CreateReg(0)); TmpInst.addOperand(MCOperand::CreateReg(0));
OutStreamer.EmitInstruction(TmpInst); OutStreamer.EmitInstruction(TmpInst);
// Make sure the Thumb jump table is 4-byte aligned.
if (Opc == ARM::tMOVr)
EmitAlignment(2);
// Output the data for the jump table itself // Output the data for the jump table itself
EmitJumpTable(MI); EmitJumpTable(MI);
return; return;

View File

@ -255,6 +255,13 @@ class ARMPseudoInst<dag oops, dag iops, InstrItinClass itin,
list<Predicate> Predicates = [IsARM]; list<Predicate> Predicates = [IsARM];
} }
// PseudoInst that's Thumb-mode only.
class tPseudoInst<dag oops, dag iops, SizeFlagVal sz, InstrItinClass itin,
list<dag> pattern>
: PseudoInst<oops, iops, itin, pattern> {
let SZ = sz;
list<Predicate> Predicates = [IsThumb];
}
// 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,
@ -816,9 +823,6 @@ class T1I<dag oops, dag iops, InstrItinClass itin,
class T1Ix2<dag oops, dag iops, InstrItinClass itin, class T1Ix2<dag oops, dag iops, InstrItinClass itin,
string asm, list<dag> pattern> string asm, list<dag> pattern>
: Thumb1I<oops, iops, AddrModeNone, Size4Bytes, itin, asm, "", pattern>; : Thumb1I<oops, iops, AddrModeNone, Size4Bytes, itin, asm, "", pattern>;
class T1JTI<dag oops, dag iops, InstrItinClass itin,
string asm, list<dag> pattern>
: Thumb1I<oops, iops, AddrModeNone, SizeSpecial, itin, asm, "", pattern>;
// Two-address instructions // Two-address instructions
class T1It<dag oops, dag iops, InstrItinClass itin, class T1It<dag oops, dag iops, InstrItinClass itin,

View File

@ -333,9 +333,6 @@ def cpinst_operand : Operand<i32> {
let PrintMethod = "printCPInstOperand"; let PrintMethod = "printCPInstOperand";
} }
def jtblock_operand : Operand<i32> {
let PrintMethod = "printJTBlockOperand";
}
def jt2block_operand : Operand<i32> { def jt2block_operand : Operand<i32> {
let PrintMethod = "printJT2BlockOperand"; let PrintMethod = "printJT2BlockOperand";
} }

View File

@ -439,14 +439,11 @@ let isBranch = 1, isTerminator = 1 in {
def tBfar : TIx2<0b11110, 0b11, 1, (outs), (ins brtarget:$target), IIC_Br, def tBfar : TIx2<0b11110, 0b11, 1, (outs), (ins brtarget:$target), IIC_Br,
"bl\t$target",[]>; "bl\t$target",[]>;
let isCodeGenOnly = 1 in def tBR_JTr : tPseudoInst<(outs),
def tBR_JTr : T1JTI<(outs), (ins tGPR:$target, i32imm:$jt, i32imm:$id),
(ins tGPR:$target, jtblock_operand:$jt, i32imm:$id), Size2Bytes, IIC_Br,
IIC_Br, "mov\tpc, $target\n\t.align\t2$jt", [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]> {
[(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>, list<Predicate> Predicates = [IsThumb, IsThumb1Only];
Encoding16 {
let Inst{15-7} = 0b010001101;
let Inst{2-0} = 0b111;
} }
} }
} }

View File

@ -96,7 +96,6 @@ public:
void printRegisterList(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printRegisterList(const MCInst *MI, unsigned OpNum, raw_ostream &O);
// The jump table instructions have custom handling in ARMAsmPrinter // The jump table instructions have custom handling in ARMAsmPrinter
// to output the jump table. Nothing further is necessary here. // to output the jump table. Nothing further is necessary here.
void printJTBlockOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O) {}
void printJT2BlockOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O) {} void printJT2BlockOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O) {}
void printTBAddrMode(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printTBAddrMode(const MCInst *MI, unsigned OpNum, raw_ostream &O);
void printNoHashImmediate(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printNoHashImmediate(const MCInst *MI, unsigned OpNum, raw_ostream &O);