forked from OSchip/llvm-project
Fix .o emission of ARM movt/movw. MCSymbolRefExpr::VK_ARM_(HI||LO)16 for the .o path now works for ARM.
Note: lo16AllZero remains in ARMInstrInfo.td - It can be factored out when Thumb movt is repaired. Existing tests cover this update. llvm-svn: 119760
This commit is contained in:
parent
4a08e563d7
commit
5a97bd873e
|
@ -214,6 +214,11 @@ namespace {
|
|||
Binary |= (Reg << 13);
|
||||
return Binary;
|
||||
}
|
||||
|
||||
unsigned getMovtImmOpValue(const MachineInstr &MI, unsigned Op) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t getAddrMode2OpValue(const MachineInstr &MI, unsigned OpIdx)
|
||||
const { return 0;}
|
||||
uint32_t getAddrMode2OffsetOpValue(const MachineInstr &MI, unsigned OpIdx)
|
||||
|
|
|
@ -27,13 +27,27 @@ using namespace llvm;
|
|||
ARMELFWriterInfo::ARMELFWriterInfo(TargetMachine &TM)
|
||||
: TargetELFWriterInfo(TM.getTargetData()->getPointerSizeInBits() == 64,
|
||||
TM.getTargetData()->isLittleEndian()) {
|
||||
// silently OK construction
|
||||
}
|
||||
|
||||
ARMELFWriterInfo::~ARMELFWriterInfo() {}
|
||||
|
||||
unsigned ARMELFWriterInfo::getRelocationType(unsigned MachineRelTy) const {
|
||||
assert(0 && "ARMELFWriterInfo::getRelocationType() not implemented");
|
||||
switch (MachineRelTy) {
|
||||
case ARM::reloc_arm_absolute:
|
||||
case ARM::reloc_arm_relative:
|
||||
case ARM::reloc_arm_cp_entry:
|
||||
case ARM::reloc_arm_vfp_cp_entry:
|
||||
case ARM::reloc_arm_machine_cp_entry:
|
||||
case ARM::reloc_arm_jt_base:
|
||||
case ARM::reloc_arm_pic_jt:
|
||||
assert(0 && "unsupported ARM relocation type"); break;
|
||||
|
||||
case ARM::reloc_arm_branch: return R_ARM_CALL; break;
|
||||
case ARM::reloc_arm_movt: return R_ARM_MOVT_ABS; break;
|
||||
case ARM::reloc_arm_movw: return R_ARM_MOVW_ABS_NC; break;
|
||||
default:
|
||||
llvm_unreachable("unknown ARM relocation type"); break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,12 @@ enum Fixups {
|
|||
// instructions.
|
||||
fixup_arm_branch,
|
||||
|
||||
// The next two are for the movt/movw pair
|
||||
// the 16bit imm field are split into imm{15-12} and imm{11-0}
|
||||
// Fixme: We need new ones for Thumb.
|
||||
fixup_arm_movt_hi16, // :upper16:
|
||||
fixup_arm_movw_lo16, // :lower16:
|
||||
|
||||
// Marker
|
||||
LastTargetFixupKind,
|
||||
NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
|
||||
|
|
|
@ -442,6 +442,13 @@ def imm0_31_m1 : Operand<i32>, PatLeaf<(imm), [{
|
|||
let EncoderMethod = "getImmMinusOneOpValue";
|
||||
}
|
||||
|
||||
// For movt/movw - sets the MC Encoder method.
|
||||
// The imm is split into imm{15-12}, imm{11-0}
|
||||
//
|
||||
def movt_imm : Operand<i32> {
|
||||
let EncoderMethod = "getMovtImmOpValue";
|
||||
}
|
||||
|
||||
// Define ARM specific addressing modes.
|
||||
|
||||
|
||||
|
@ -1970,7 +1977,7 @@ def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi,
|
|||
}
|
||||
|
||||
let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
|
||||
def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm:$imm),
|
||||
def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins movt_imm:$imm),
|
||||
DPFrm, IIC_iMOVi,
|
||||
"movw", "\t$Rd, $imm",
|
||||
[(set GPR:$Rd, imm0_65535:$imm)]>,
|
||||
|
@ -1985,7 +1992,7 @@ def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm:$imm),
|
|||
}
|
||||
|
||||
let Constraints = "$src = $Rd" in
|
||||
def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm:$imm),
|
||||
def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, movt_imm:$imm),
|
||||
DPFrm, IIC_iMOVi,
|
||||
"movt", "\t$Rd, $imm",
|
||||
[(set GPR:$Rd,
|
||||
|
@ -3056,7 +3063,7 @@ def MOVCCs : AI1<0b1101, (outs GPR:$Rd),
|
|||
}
|
||||
|
||||
let isMoveImm = 1 in
|
||||
def MOVCCi16 : AI1<0b1000, (outs GPR:$Rd), (ins GPR:$false, i32imm:$imm),
|
||||
def MOVCCi16 : AI1<0b1000, (outs GPR:$Rd), (ins GPR:$false, movt_imm:$imm),
|
||||
DPFrm, IIC_iMOVi,
|
||||
"movw", "\t$Rd, $imm",
|
||||
[]>,
|
||||
|
|
|
@ -70,6 +70,10 @@ public:
|
|||
unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
||||
/// getMovtImmOpValue - Return the encoding for the movw/movt pair
|
||||
uint32_t getMovtImmOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
||||
bool EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx,
|
||||
unsigned &Reg, unsigned &Imm,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
@ -395,6 +399,33 @@ getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
|
|||
return Binary;
|
||||
}
|
||||
|
||||
uint32_t ARMMCCodeEmitter::
|
||||
getMovtImmOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
// {20-16} = imm{15-12}
|
||||
// {11-0} = imm{11-0}
|
||||
const MCOperand &MO = MI.getOperand(OpIdx);
|
||||
if (MO.isImm()) {
|
||||
return static_cast<unsigned>(MO.getImm());
|
||||
} else if (const MCSymbolRefExpr *Expr =
|
||||
dyn_cast<MCSymbolRefExpr>(MO.getExpr())) {
|
||||
MCFixupKind Kind;
|
||||
switch (Expr->getKind()) {
|
||||
case MCSymbolRefExpr::VK_ARM_HI16:
|
||||
Kind = MCFixupKind(ARM::fixup_arm_movt_hi16);
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_ARM_LO16:
|
||||
Kind = MCFixupKind(ARM::fixup_arm_movw_lo16);
|
||||
break;
|
||||
default: assert(0 && "Unsupported ARMFixup"); break;
|
||||
}
|
||||
Fixups.push_back(MCFixup::Create(0, Expr, Kind));
|
||||
return 0;
|
||||
};
|
||||
llvm_unreachable(0 && "Unsupported MCExpr type in MCOperand");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ARMMCCodeEmitter::
|
||||
getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
|
|
|
@ -563,6 +563,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
|
|||
REG("QQQQPR");
|
||||
|
||||
IMM("i32imm");
|
||||
IMM("movt_imm");
|
||||
IMM("bf_inv_mask_imm");
|
||||
IMM("jtblock_operand");
|
||||
IMM("nohash_imm");
|
||||
|
|
Loading…
Reference in New Issue