summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM
diff options
context:
space:
mode:
authorPeter Smith <peter.smith@linaro.org>2018-06-06 09:40:06 +0000
committerPeter Smith <peter.smith@linaro.org>2018-06-06 09:40:06 +0000
commit57f661bd7d20412f21ac6b7611c41a0f8b84fc01 (patch)
treea3c0558620a5a096f52d309b1d2e29fffc17c2a3 /llvm/lib/Target/ARM
parentb7c374500607486d56ae16195b57ea737fa2e5a5 (diff)
downloadbcm5719-llvm-57f661bd7d20412f21ac6b7611c41a0f8b84fc01.tar.gz
bcm5719-llvm-57f661bd7d20412f21ac6b7611c41a0f8b84fc01.zip
[MC] Pass MCSubtargetInfo to fixupNeedsRelaxation and applyFixup
On targets like Arm some relaxations may only be performed when certain architectural features are available. As functions can be compiled with differing levels of architectural support we must make a judgement on whether we can relax based on the MCSubtargetInfo for the function. This change passes through the MCSubtargetInfo for the function to fixupNeedsRelaxation so that the decision on whether to relax can be made per function. In this patch, only the ARM backend makes use of this information. We must also pass the MCSubtargetInfo to applyFixup because some fixups skip error checking on the assumption that relaxation has occurred, to prevent code-generation errors applyFixup must see the same MCSubtargetInfo as fixupNeedsRelaxation. Differential Revision: https://reviews.llvm.org/D44928 llvm-svn: 334078
Diffstat (limited to 'llvm/lib/Target/ARM')
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp41
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h16
2 files changed, 37 insertions, 20 deletions
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index 4a7bf8cc33c..f524a008130 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -173,7 +173,8 @@ void ARMAsmBackend::handleAssemblerFlag(MCAssemblerFlag Flag) {
}
}
-unsigned ARMAsmBackend::getRelaxedOpcode(unsigned Op) const {
+unsigned ARMAsmBackend::getRelaxedOpcode(unsigned Op,
+ const MCSubtargetInfo &STI) const {
bool HasThumb2 = STI.getFeatureBits()[ARM::FeatureThumb2];
bool HasV8MBaselineOps = STI.getFeatureBits()[ARM::HasV8MBaselineOps];
@@ -195,8 +196,9 @@ unsigned ARMAsmBackend::getRelaxedOpcode(unsigned Op) const {
}
}
-bool ARMAsmBackend::mayNeedRelaxation(const MCInst &Inst) const {
- if (getRelaxedOpcode(Inst.getOpcode()) != Inst.getOpcode())
+bool ARMAsmBackend::mayNeedRelaxation(const MCInst &Inst,
+ const MCSubtargetInfo &STI) const {
+ if (getRelaxedOpcode(Inst.getOpcode(), STI) != Inst.getOpcode())
return true;
return false;
}
@@ -263,7 +265,7 @@ bool ARMAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
void ARMAsmBackend::relaxInstruction(const MCInst &Inst,
const MCSubtargetInfo &STI,
MCInst &Res) const {
- unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode());
+ unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode(), STI);
// Sanity check w/ diagnostic if we get here w/ a bogus instruction.
if (RelaxedOp == Inst.getOpcode()) {
@@ -360,7 +362,8 @@ static uint32_t joinHalfWords(uint32_t FirstHalf, uint32_t SecondHalf,
unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
const MCFixup &Fixup,
const MCValue &Target, uint64_t Value,
- bool IsResolved, MCContext &Ctx) const {
+ bool IsResolved, MCContext &Ctx,
+ const MCSubtargetInfo* STI) const {
unsigned Kind = Fixup.getKind();
// MachO tries to make .o files that look vaguely pre-linked, so for MOVW/MOVT
@@ -389,7 +392,8 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
case FK_SecRel_4:
return Value;
case ARM::fixup_arm_movt_hi16:
- if (IsResolved || !STI.getTargetTriple().isOSBinFormatELF())
+ assert(STI != nullptr);
+ if (IsResolved || !STI->getTargetTriple().isOSBinFormatELF())
Value >>= 16;
LLVM_FALLTHROUGH;
case ARM::fixup_arm_movw_lo16: {
@@ -401,7 +405,8 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
return Value;
}
case ARM::fixup_t2_movt_hi16:
- if (IsResolved || !STI.getTargetTriple().isOSBinFormatELF())
+ assert(STI != nullptr);
+ if (IsResolved || !STI->getTargetTriple().isOSBinFormatELF())
Value >>= 16;
LLVM_FALLTHROUGH;
case ARM::fixup_t2_movw_lo16: {
@@ -529,9 +534,9 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
}
case ARM::fixup_arm_thumb_bl: {
if (!isInt<25>(Value - 4) ||
- (!STI.getFeatureBits()[ARM::FeatureThumb2] &&
- !STI.getFeatureBits()[ARM::HasV8MBaselineOps] &&
- !STI.getFeatureBits()[ARM::HasV6MOps] &&
+ (!STI->getFeatureBits()[ARM::FeatureThumb2] &&
+ !STI->getFeatureBits()[ARM::HasV8MBaselineOps] &&
+ !STI->getFeatureBits()[ARM::HasV6MOps] &&
!isInt<23>(Value - 4))) {
Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
return 0;
@@ -603,7 +608,8 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
case ARM::fixup_arm_thumb_cp:
// On CPUs supporting Thumb2, this will be relaxed to an ldr.w, otherwise we
// could have an error on our hands.
- if (!STI.getFeatureBits()[ARM::FeatureThumb2] && IsResolved) {
+ assert(STI != nullptr);
+ if (!STI->getFeatureBits()[ARM::FeatureThumb2] && IsResolved) {
const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
if (FixupDiagnostic) {
Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
@@ -627,8 +633,9 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
}
case ARM::fixup_arm_thumb_br:
// Offset by 4 and don't encode the lower bit, which is always 0.
- if (!STI.getFeatureBits()[ARM::FeatureThumb2] &&
- !STI.getFeatureBits()[ARM::HasV8MBaselineOps]) {
+ assert(STI != nullptr);
+ if (!STI->getFeatureBits()[ARM::FeatureThumb2] &&
+ !STI->getFeatureBits()[ARM::HasV8MBaselineOps]) {
const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
if (FixupDiagnostic) {
Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
@@ -638,7 +645,8 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
return ((Value - 4) >> 1) & 0x7ff;
case ARM::fixup_arm_thumb_bcc:
// Offset by 4 and don't encode the lower bit, which is always 0.
- if (!STI.getFeatureBits()[ARM::FeatureThumb2]) {
+ assert(STI != nullptr);
+ if (!STI->getFeatureBits()[ARM::FeatureThumb2]) {
const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
if (FixupDiagnostic) {
Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
@@ -894,10 +902,11 @@ static unsigned getFixupKindContainerSizeBytes(unsigned Kind) {
void ARMAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
- bool IsResolved) const {
+ bool IsResolved,
+ const MCSubtargetInfo* STI) const {
unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
MCContext &Ctx = Asm.getContext();
- Value = adjustFixupValue(Asm, Fixup, Target, Value, IsResolved, Ctx);
+ Value = adjustFixupValue(Asm, Fixup, Target, Value, IsResolved, Ctx, STI);
if (!Value)
return; // Doesn't change encoding.
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
index b72f45d0717..88c476bf65f 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
@@ -19,6 +19,9 @@
namespace llvm {
class ARMAsmBackend : public MCAsmBackend {
+ // The STI from the target triple the MCAsmBackend was instantiated with
+ // note that MCFragments may have a different local STI that should be
+ // used in preference.
const MCSubtargetInfo &STI;
bool isThumbMode; // Currently emitting Thumb code.
public:
@@ -31,6 +34,8 @@ public:
return ARM::NumTargetFixupKinds;
}
+ // FIXME: this should be calculated per fragment as the STI may be
+ // different.
bool hasNOP() const { return STI.getFeatureBits()[ARM::HasV6T2Ops]; }
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
@@ -40,15 +45,18 @@ public:
unsigned adjustFixupValue(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target, uint64_t Value,
- bool IsResolved, MCContext &Ctx) const;
+ bool IsResolved, MCContext &Ctx,
+ const MCSubtargetInfo *STI) const;
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target, MutableArrayRef<char> Data,
- uint64_t Value, bool IsResolved) const override;
+ uint64_t Value, bool IsResolved,
+ const MCSubtargetInfo *STI) const override;
- unsigned getRelaxedOpcode(unsigned Op) const;
+ unsigned getRelaxedOpcode(unsigned Op, const MCSubtargetInfo &STI) const;
- bool mayNeedRelaxation(const MCInst &Inst) const override;
+ bool mayNeedRelaxation(const MCInst &Inst,
+ const MCSubtargetInfo &STI) const override;
const char *reasonForFixupRelaxation(const MCFixup &Fixup,
uint64_t Value) const;
OpenPOWER on IntegriCloud