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)
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;
}
// 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
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.
}
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)]>,
}
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,
}
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",
[]>,
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;
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 {
REG("QQQQPR");
IMM("i32imm");
+ IMM("movt_imm");
IMM("bf_inv_mask_imm");
IMM("jtblock_operand");
IMM("nohash_imm");