mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-30 17:33:24 +00:00
Clean up ARM tail calls a bit. They're pseudo-instructions for normal branches.
Also more cleanly separate the ARM vs. Thumb functionality. Previously, the encoding would be incorrect for some Thumb instructions (the indirect calls). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127637 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b9b80c3268
commit
5edf24efac
@ -1707,6 +1707,49 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Tail jump branches are really just branch instructions with additional
|
||||
// code-gen attributes. Convert them to the cannonical form here.
|
||||
case ARM::TAILJMPd:
|
||||
case ARM::TAILJMPdND: {
|
||||
MCInst TmpInst, TmpInst2;
|
||||
// Lower the instruction as-is to get the operands properly converted.
|
||||
LowerARMMachineInstrToMCInst(MI, TmpInst2, *this);
|
||||
TmpInst.setOpcode(ARM::Bcc);
|
||||
TmpInst.addOperand(TmpInst2.getOperand(0));
|
||||
// Add predicate operands.
|
||||
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
|
||||
TmpInst.addOperand(MCOperand::CreateReg(0));
|
||||
OutStreamer.AddComment("TAILCALL");
|
||||
OutStreamer.EmitInstruction(TmpInst);
|
||||
return;
|
||||
}
|
||||
case ARM::tTAILJMPd:
|
||||
case ARM::tTAILJMPdND: {
|
||||
MCInst TmpInst, TmpInst2;
|
||||
LowerARMMachineInstrToMCInst(MI, TmpInst2, *this);
|
||||
TmpInst.setOpcode(ARM::tB);
|
||||
TmpInst.addOperand(TmpInst2.getOperand(0));
|
||||
OutStreamer.AddComment("TAILCALL");
|
||||
OutStreamer.EmitInstruction(TmpInst);
|
||||
return;
|
||||
}
|
||||
case ARM::TAILJMPrND:
|
||||
case ARM::tTAILJMPrND:
|
||||
case ARM::TAILJMPr:
|
||||
case ARM::tTAILJMPr: {
|
||||
unsigned newOpc = (Opc == ARM::TAILJMPr || Opc == ARM::TAILJMPrND)
|
||||
? ARM::BX : ARM::tBX;
|
||||
MCInst TmpInst;
|
||||
TmpInst.setOpcode(newOpc);
|
||||
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
|
||||
// Predicate.
|
||||
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
|
||||
TmpInst.addOperand(MCOperand::CreateReg(0));
|
||||
OutStreamer.AddComment("TAILCALL");
|
||||
OutStreamer.EmitInstruction(TmpInst);
|
||||
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.
|
||||
|
@ -400,8 +400,8 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
|
||||
// Jump to label or value in register.
|
||||
if (RetOpcode == ARM::TCRETURNdi || RetOpcode == ARM::TCRETURNdiND) {
|
||||
unsigned TCOpcode = (RetOpcode == ARM::TCRETURNdi)
|
||||
? (STI.isThumb() ? ARM::TAILJMPdt : ARM::TAILJMPd)
|
||||
: (STI.isThumb() ? ARM::TAILJMPdNDt : ARM::TAILJMPdND);
|
||||
? (STI.isThumb() ? ARM::tTAILJMPd : ARM::TAILJMPd)
|
||||
: (STI.isThumb() ? ARM::tTAILJMPdND : ARM::TAILJMPdND);
|
||||
MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(TCOpcode));
|
||||
if (JumpTarget.isGlobal())
|
||||
MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(),
|
||||
@ -412,10 +412,12 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
|
||||
JumpTarget.getTargetFlags());
|
||||
}
|
||||
} else if (RetOpcode == ARM::TCRETURNri) {
|
||||
BuildMI(MBB, MBBI, dl, TII.get(ARM::TAILJMPr)).
|
||||
BuildMI(MBB, MBBI, dl,
|
||||
TII.get(STI.isThumb() ? ARM::tTAILJMPr : ARM::TAILJMPr)).
|
||||
addReg(JumpTarget.getReg(), RegState::Kill);
|
||||
} else if (RetOpcode == ARM::TCRETURNriND) {
|
||||
BuildMI(MBB, MBBI, dl, TII.get(ARM::TAILJMPrND)).
|
||||
BuildMI(MBB, MBBI, dl,
|
||||
TII.get(STI.isThumb() ? ARM::tTAILJMPrND : ARM::TAILJMPrND)).
|
||||
addReg(JumpTarget.getReg(), RegState::Kill);
|
||||
}
|
||||
|
||||
|
@ -1408,11 +1408,7 @@ let isCall = 1,
|
||||
|
||||
// Tail calls.
|
||||
|
||||
// FIXME: These should probably be xformed into the non-TC versions of the
|
||||
// instructions as part of MC lowering.
|
||||
// FIXME: These seem to be used for both Thumb and ARM instruction selection.
|
||||
// Thumb should have its own version since the instruction is actually
|
||||
// different, even though the mnemonic is the same.
|
||||
// FIXME: The Thumb versions of these should live in ARMInstrThumb.td
|
||||
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
|
||||
// Darwin versions.
|
||||
let Defs = [R0, R1, R2, R3, R9, R12,
|
||||
@ -1426,21 +1422,21 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
|
||||
def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
|
||||
IIC_Br, []>, Requires<[IsDarwin]>;
|
||||
|
||||
def TAILJMPd : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
|
||||
IIC_Br, "b\t$dst @ TAILCALL",
|
||||
def TAILJMPd : ARMPseudoInst<(outs), (ins brtarget:$dst, variable_ops),
|
||||
Size4Bytes, IIC_Br,
|
||||
[]>, Requires<[IsARM, IsDarwin]>;
|
||||
|
||||
def TAILJMPdt: ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
|
||||
IIC_Br, "b.w\t$dst @ TAILCALL",
|
||||
def tTAILJMPd: tPseudoInst<(outs), (ins brtarget:$dst, variable_ops),
|
||||
Size4Bytes, IIC_Br,
|
||||
[]>, Requires<[IsThumb, IsDarwin]>;
|
||||
|
||||
def TAILJMPr : AXI<(outs), (ins tcGPR:$dst, variable_ops),
|
||||
BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
|
||||
[]>, Requires<[IsDarwin]> {
|
||||
bits<4> dst;
|
||||
let Inst{31-4} = 0b1110000100101111111111110001;
|
||||
let Inst{3-0} = dst;
|
||||
}
|
||||
def TAILJMPr : ARMPseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
|
||||
Size4Bytes, IIC_Br,
|
||||
[]>, Requires<[IsARM, IsDarwin]>;
|
||||
|
||||
def tTAILJMPr : tPseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
|
||||
Size4Bytes, IIC_Br,
|
||||
[]>, Requires<[IsThumb, IsDarwin]>;
|
||||
}
|
||||
|
||||
// Non-Darwin versions (the difference is R9).
|
||||
@ -1455,21 +1451,20 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
|
||||
def TCRETURNriND : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
|
||||
IIC_Br, []>, Requires<[IsNotDarwin]>;
|
||||
|
||||
def TAILJMPdND : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
|
||||
IIC_Br, "b\t$dst @ TAILCALL",
|
||||
def TAILJMPdND : ARMPseudoInst<(outs), (ins brtarget:$dst, variable_ops),
|
||||
Size4Bytes, IIC_Br,
|
||||
[]>, Requires<[IsARM, IsNotDarwin]>;
|
||||
|
||||
def TAILJMPdNDt : ABXI<0b1010, (outs), (ins brtarget:$dst, variable_ops),
|
||||
IIC_Br, "b.w\t$dst @ TAILCALL",
|
||||
def tTAILJMPdND : tPseudoInst<(outs), (ins brtarget:$dst, variable_ops),
|
||||
Size4Bytes, IIC_Br,
|
||||
[]>, Requires<[IsThumb, IsNotDarwin]>;
|
||||
|
||||
def TAILJMPrND : AXI<(outs), (ins tcGPR:$dst, variable_ops),
|
||||
BrMiscFrm, IIC_Br, "bx\t$dst @ TAILCALL",
|
||||
[]>, Requires<[IsNotDarwin]> {
|
||||
bits<4> dst;
|
||||
let Inst{31-4} = 0b1110000100101111111111110001;
|
||||
let Inst{3-0} = dst;
|
||||
}
|
||||
def TAILJMPrND : ARMPseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
|
||||
Size4Bytes, IIC_Br,
|
||||
[]>, Requires<[IsARM, IsNotDarwin]>;
|
||||
def tTAILJMPrND : tPseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
|
||||
Size4Bytes, IIC_Br,
|
||||
[]>, Requires<[IsThumb, IsNotDarwin]>;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ entry:
|
||||
; CHECKT2: t7:
|
||||
; CHECKT2: blxeq _foo
|
||||
; CHECKT2-NEXT: pop.w
|
||||
; CHECKT2-NEXT: b.w _foo
|
||||
; CHECKT2-NEXT: b _foo
|
||||
br i1 undef, label %bb, label %bb1.lr.ph
|
||||
|
||||
bb1.lr.ph:
|
||||
|
Loading…
Reference in New Issue
Block a user