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:
Jason W Kim 2010-11-18 23:37:15 +00:00
parent 4a08e563d7
commit 5a97bd873e
6 changed files with 69 additions and 5 deletions

View File

@ -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)

View File

@ -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;
}

View File

@ -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

View File

@ -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",
[]>,

View File

@ -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 {

View File

@ -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");