summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/ARM/ARMCodeEmitter.cpp5
-rw-r--r--lib/Target/ARM/ARMELFWriterInfo.cpp18
-rw-r--r--lib/Target/ARM/ARMFixupKinds.h6
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td13
-rw-r--r--lib/Target/ARM/ARMMCCodeEmitter.cpp31
-rw-r--r--utils/TableGen/EDEmitter.cpp1
6 files changed, 69 insertions, 5 deletions
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index 14b0acc037..8888420d2a 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -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)
diff --git a/lib/Target/ARM/ARMELFWriterInfo.cpp b/lib/Target/ARM/ARMELFWriterInfo.cpp
index 85b690fd7a..776727500d 100644
--- a/lib/Target/ARM/ARMELFWriterInfo.cpp
+++ b/lib/Target/ARM/ARMELFWriterInfo.cpp
@@ -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;
}
diff --git a/lib/Target/ARM/ARMFixupKinds.h b/lib/Target/ARM/ARMFixupKinds.h
index 8d26f213e6..2da0619955 100644
--- a/lib/Target/ARM/ARMFixupKinds.h
+++ b/lib/Target/ARM/ARMFixupKinds.h
@@ -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
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index 0ef1e3c653..fc542ea060 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -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",
[]>,
diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp
index cbb41021dd..6592dcfebe 100644
--- a/lib/Target/ARM/ARMMCCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp
@@ -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;
@@ -396,6 +400,33 @@ getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
}
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 {
const MCOperand &MO = MI.getOperand(OpIdx);
diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp
index dd09174c20..ab52e8bd26 100644
--- a/utils/TableGen/EDEmitter.cpp
+++ b/utils/TableGen/EDEmitter.cpp
@@ -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");