Completed :lower16: / :upper16: support for movw / movt pairs on Darwin.
- Fixed :upper16: fix up routine. It should be shifting down the top 16 bits first.
- Added support for Thumb2 :lower16: and :upper16: fix up.
- Added :upper16: and :lower16: relocation support to mach-o object writer.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123424 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp
index 542d24d..3aa40db 100644
--- a/lib/Target/ARM/ARMMCCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp
@@ -17,6 +17,7 @@
#include "ARMFixupKinds.h"
#include "ARMInstrInfo.h"
#include "ARMMCExpr.h"
+#include "ARMSubtarget.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
@@ -33,11 +34,13 @@
void operator=(const ARMMCCodeEmitter &); // DO NOT IMPLEMENT
const TargetMachine &TM;
const TargetInstrInfo &TII;
+ const ARMSubtarget *Subtarget;
MCContext &Ctx;
public:
ARMMCCodeEmitter(TargetMachine &tm, MCContext &ctx)
- : TM(tm), TII(*TM.getInstrInfo()), Ctx(ctx) {
+ : TM(tm), TII(*TM.getInstrInfo()),
+ Subtarget(&TM.getSubtarget<ARMSubtarget>()), Ctx(ctx) {
}
~ARMMCCodeEmitter() {}
@@ -306,8 +309,7 @@
/// Thumb2 mode.
unsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI,
unsigned EncodedValue) const {
- const ARMSubtarget &Subtarget = TM.getSubtarget<ARMSubtarget>();
- if (Subtarget.isThumb2()) {
+ if (Subtarget->isThumb2()) {
// NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved
// to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are
// set to 1111.
@@ -326,8 +328,7 @@
/// Thumb2 mode.
unsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI,
unsigned EncodedValue) const {
- const ARMSubtarget &Subtarget = TM.getSubtarget<ARMSubtarget>();
- if (Subtarget.isThumb2()) {
+ if (Subtarget->isThumb2()) {
EncodedValue &= 0xF0FFFFFF;
EncodedValue |= 0x09000000;
}
@@ -340,8 +341,7 @@
/// Thumb2 mode.
unsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI,
unsigned EncodedValue) const {
- const ARMSubtarget &Subtarget = TM.getSubtarget<ARMSubtarget>();
- if (Subtarget.isThumb2()) {
+ if (Subtarget->isThumb2()) {
EncodedValue &= 0x00FFFFFF;
EncodedValue |= 0xEE000000;
}
@@ -353,7 +353,7 @@
/// them to their Thumb2 form if we are currently in Thumb2 mode.
unsigned ARMMCCodeEmitter::
VFPThumb2PostEncoder(const MCInst &MI, unsigned EncodedValue) const {
- if (TM.getSubtarget<ARMSubtarget>().isThumb2()) {
+ if (Subtarget->isThumb2()) {
EncodedValue &= 0x0FFFFFFF;
EncodedValue |= 0xE0000000;
}
@@ -477,8 +477,7 @@
SmallVectorImpl<MCFixup> &Fixups) const {
// FIXME: This really, really shouldn't use TargetMachine. We don't want
// coupling between MC and TM anywhere we can help it.
- const ARMSubtarget &Subtarget = TM.getSubtarget<ARMSubtarget>();
- if (Subtarget.isThumb2())
+ if (Subtarget->isThumb2())
return
::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups);
return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_branch, Fixups);
@@ -575,9 +574,8 @@
else
Expr = MO2.getExpr();
- const ARMSubtarget &Subtarget = TM.getSubtarget<ARMSubtarget>();
MCFixupKind Kind;
- if (Subtarget.isThumb2())
+ if (Subtarget->isThumb2())
Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12);
else
Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12);
@@ -662,14 +660,24 @@
switch (ARM16Expr->getKind()) {
default: assert(0 && "Unsupported ARMFixup");
case ARMMCExpr::VK_ARM_HI16:
- Kind = MCFixupKind(ARM::fixup_arm_movt_hi16);
- if (EvaluateAsPCRel(E))
- Kind = MCFixupKind(ARM::fixup_arm_movt_hi16_pcrel);
+ if (!Subtarget->isTargetDarwin() && EvaluateAsPCRel(E))
+ Kind = MCFixupKind(Subtarget->isThumb2()
+ ? ARM::fixup_t2_movt_hi16_pcrel
+ : ARM::fixup_arm_movt_hi16_pcrel);
+ else
+ Kind = MCFixupKind(Subtarget->isThumb2()
+ ? ARM::fixup_t2_movt_hi16
+ : ARM::fixup_arm_movt_hi16);
break;
case ARMMCExpr::VK_ARM_LO16:
- Kind = MCFixupKind(ARM::fixup_arm_movw_lo16);
- if (EvaluateAsPCRel(E))
- Kind = MCFixupKind(ARM::fixup_arm_movw_lo16_pcrel);
+ if (!Subtarget->isTargetDarwin() && EvaluateAsPCRel(E))
+ Kind = MCFixupKind(Subtarget->isThumb2()
+ ? ARM::fixup_t2_movw_lo16_pcrel
+ : ARM::fixup_arm_movw_lo16_pcrel);
+ else
+ Kind = MCFixupKind(Subtarget->isThumb2()
+ ? ARM::fixup_t2_movw_lo16
+ : ARM::fixup_arm_movw_lo16);
break;
}
Fixups.push_back(MCFixup::Create(0, E, Kind));
@@ -841,8 +849,7 @@
assert(MO.isExpr() && "Unexpected machine operand type!");
const MCExpr *Expr = MO.getExpr();
MCFixupKind Kind;
- const ARMSubtarget &Subtarget = TM.getSubtarget<ARMSubtarget>();
- if (Subtarget.isThumb2())
+ if (Subtarget->isThumb2())
Kind = MCFixupKind(ARM::fixup_t2_pcrel_10);
else
Kind = MCFixupKind(ARM::fixup_arm_pcrel_10);
@@ -1151,7 +1158,6 @@
void ARMMCCodeEmitter::
EncodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups) const {
- const ARMSubtarget &Subtarget = TM.getSubtarget<ARMSubtarget>();
// Pseudo instructions don't get encoded.
const TargetInstrDesc &Desc = TII.get(MI.getOpcode());
uint64_t TSFlags = Desc.TSFlags;
@@ -1167,7 +1173,7 @@
uint32_t Binary = getBinaryCodeForInstr(MI, Fixups);
// Thumb 32-bit wide instructions need to emit the high order halfword
// first.
- if (Subtarget.isThumb() && Size == 4) {
+ if (Subtarget->isThumb() && Size == 4) {
EmitConstant(Binary >> 16, 2, OS);
EmitConstant(Binary & 0xffff, 2, OS);
} else