mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
Refactor LEApcrelJT as a pseudo-instructionlowered to a cannonical ADR
instruction at MC lowering. Add binary encoding information for the ADR, including fixup data for the label operand. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120594 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
bee0c38f59
commit
5d14f9be7b
@ -726,6 +726,21 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
case ARM::LEApcrelJT: {
|
||||
unsigned JTI = MI->getOperand(1).getIndex();
|
||||
unsigned Id = MI->getOperand(2).getImm();
|
||||
MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, Id);
|
||||
const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(JTISymbol, OutContext);
|
||||
MCInst TmpInst;
|
||||
TmpInst.setOpcode(ARM::ADRadd);
|
||||
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
|
||||
TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr));
|
||||
// Add predicate operands.
|
||||
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
|
||||
TmpInst.addOperand(MCOperand::CreateReg(0));
|
||||
OutStreamer.EmitInstruction(TmpInst);
|
||||
return;
|
||||
}
|
||||
case ARM::MOVPCRX: {
|
||||
MCInst TmpInst;
|
||||
TmpInst.setOpcode(ARM::MOVr);
|
||||
|
@ -167,6 +167,8 @@ namespace {
|
||||
const { return 0; }
|
||||
unsigned NEONThumb2DupPostEncoder(const MachineInstr &MI,unsigned Val)
|
||||
const { return 0; }
|
||||
unsigned getAdrLabelOpValue(const MachineInstr &MI, unsigned Op)
|
||||
const { return 0; }
|
||||
unsigned getBranchTargetOpValue(const MachineInstr &MI, unsigned Op)
|
||||
const { return 0; }
|
||||
unsigned getCCOutOpValue(const MachineInstr &MI, unsigned Op)
|
||||
|
@ -338,6 +338,11 @@ def pclabel : Operand<i32> {
|
||||
let PrintMethod = "printPCLabel";
|
||||
}
|
||||
|
||||
// ADR instruction labels.
|
||||
def adrlabel : Operand<i32> {
|
||||
let EncoderMethod = "getAdrLabelOpValue";
|
||||
}
|
||||
|
||||
def neon_vcvt_imm32 : Operand<i32> {
|
||||
let EncoderMethod = "getNEONVcvtImm32OpValue";
|
||||
}
|
||||
@ -1178,28 +1183,39 @@ def PICSTRB : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
|
||||
// LEApcrel - Load a pc-relative address into a register without offending the
|
||||
// assembler.
|
||||
let neverHasSideEffects = 1, isReMaterializable = 1 in
|
||||
// FIXME: We want one cannonical LEApcrel instruction and to express one or
|
||||
// both of these as pseudo-instructions that get expanded to it. In particular,
|
||||
// the cannonical "adr" pattern should take a single label operand, and the
|
||||
// JT version should be a pseudo that when lowered to MC, xforms the insn
|
||||
// to the canonical form referencing the correct symbol.
|
||||
def LEApcrel : AXI1<0, (outs GPR:$Rd), (ins i32imm:$label, pred:$p),
|
||||
MiscFrm, IIC_iALUi,
|
||||
"adr${p}\t$Rd, #$label", []>;
|
||||
|
||||
def LEApcrelJT : AXI1<0b0100, (outs GPR:$Rd),
|
||||
(ins i32imm:$label, nohash_imm:$id, pred:$p),
|
||||
MiscFrm, IIC_iALUi,
|
||||
"adr${p}\t$Rd, #${label}_${id}", []> {
|
||||
bits<4> p;
|
||||
// The 'adr' mnemonic encodes differently if the label is before or after
|
||||
// the instruction.
|
||||
def ADRadd : AI1<0b0100, (outs GPR:$Rd), (ins adrlabel:$label),
|
||||
MiscFrm, IIC_iALUi, "adr", "\t$Rd, #$label", []> {
|
||||
bits<4> Rd;
|
||||
let Inst{31-28} = p;
|
||||
bits<12> label;
|
||||
let Inst{27-25} = 0b001;
|
||||
let Inst{20} = 0;
|
||||
let Inst{19-16} = 0b1111;
|
||||
let Inst{15-12} = Rd;
|
||||
// FIXME: Add label encoding/fixup
|
||||
let Inst{11-0} = label;
|
||||
}
|
||||
def ADRsub : AI1<0b0010, (outs GPR:$Rd), (ins adrlabel:$label),
|
||||
MiscFrm, IIC_iALUi, "adr", "\t$Rd, #$label", []> {
|
||||
bits<4> Rd;
|
||||
bits<12> label;
|
||||
let Inst{27-25} = 0b001;
|
||||
let Inst{20} = 0;
|
||||
let Inst{19-16} = 0b1111;
|
||||
let Inst{15-12} = Rd;
|
||||
let Inst{11-0} = label;
|
||||
}
|
||||
|
||||
// FIXME: This should be a pseudo lowered to one of the above at MC lowering
|
||||
// time. It may be interesting determining which of the two. Perhaps a fixup
|
||||
// will be needed to do so? That would be kinda fugly.
|
||||
def LEApcrel : AXI1<0, (outs GPR:$Rd), (ins i32imm:$label, pred:$p),
|
||||
MiscFrm, IIC_iALUi,
|
||||
"adr${p}\t$Rd, #$label", []>;
|
||||
|
||||
def LEApcrelJT : ARMPseudoInst<(outs GPR:$Rd),
|
||||
(ins i32imm:$label, nohash_imm:$id, pred:$p),
|
||||
Size4Bytes, IIC_iALUi, []>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Control Flow Instructions.
|
||||
|
@ -85,6 +85,11 @@ public:
|
||||
uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
||||
/// getAdrLabelOpValue - Return encoding info for 12-bit immediate
|
||||
/// ADR label target.
|
||||
uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
||||
/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12'
|
||||
/// operand.
|
||||
uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
|
||||
@ -395,6 +400,24 @@ getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// getAdrLabelOpValue - Return encoding info for 12-bit immediate
|
||||
/// ADR label target.
|
||||
uint32_t ARMMCCodeEmitter::
|
||||
getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
const MCOperand &MO = MI.getOperand(OpIdx);
|
||||
|
||||
// If the destination is an immediate, we have nothing to do.
|
||||
if (MO.isImm()) return MO.getImm();
|
||||
assert (MO.isExpr() && "Unexpected branch target type!");
|
||||
const MCExpr *Expr = MO.getExpr();
|
||||
MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_12);
|
||||
Fixups.push_back(MCFixup::Create(0, Expr, Kind));
|
||||
|
||||
// All of the information is in the fixup.
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand.
|
||||
uint32_t ARMMCCodeEmitter::
|
||||
getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
|
||||
|
@ -582,6 +582,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
|
||||
IMM("jt2block_operand");
|
||||
IMM("t_imm_s4");
|
||||
IMM("pclabel");
|
||||
IMM("adrlabel");
|
||||
IMM("shift_imm");
|
||||
IMM("neon_vcvt_imm32");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user