summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp')
-rw-r--r--contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp58
1 files changed, 36 insertions, 22 deletions
diff --git a/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index 0fc7582..a58d5b3 100644
--- a/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -375,7 +375,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
case ARM::fixup_arm_movt_hi16:
if (!IsPCRel)
Value >>= 16;
- // Fallthrough
+ LLVM_FALLTHROUGH;
case ARM::fixup_arm_movw_lo16: {
unsigned Hi4 = (Value & 0xF000) >> 12;
unsigned Lo12 = Value & 0x0FFF;
@@ -387,7 +387,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
case ARM::fixup_t2_movt_hi16:
if (!IsPCRel)
Value >>= 16;
- // Fallthrough
+ LLVM_FALLTHROUGH;
case ARM::fixup_t2_movw_lo16: {
unsigned Hi4 = (Value & 0xF000) >> 12;
unsigned i = (Value & 0x800) >> 11;
@@ -403,7 +403,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
case ARM::fixup_arm_ldst_pcrel_12:
// ARM PC-relative values are offset by 8.
Value -= 4;
- // FALLTHROUGH
+ LLVM_FALLTHROUGH;
case ARM::fixup_t2_ldst_pcrel_12: {
// Offset by 4, adjusted by two due to the half-word ordering of thumb.
Value -= 4;
@@ -541,7 +541,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
//
// Note that the halfwords are stored high first, low second; so we need
// to transpose the fixup value here to map properly.
- if (Ctx && Value % 4 != 0) {
+ if (Ctx && Value % 4 != 0) {
Ctx->reportError(Fixup.getLoc(), "misaligned ARM call destination");
return 0;
}
@@ -578,6 +578,13 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
// Offset by 4, and don't encode the low two bits.
return ((Value - 4) >> 2) & 0xff;
case ARM::fixup_arm_thumb_cb: {
+ // CB instructions can only branch to offsets in [4, 126] in multiples of 2
+ // so ensure that the raw value LSB is zero and it lies in [2, 130].
+ // An offset of 2 will be relaxed to a NOP.
+ if (Ctx && ((int64_t)Value < 2 || Value > 0x82 || Value & 1)) {
+ Ctx->reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
+ return 0;
+ }
// Offset by 4 and don't encode the lower bit, which is always 0.
// FIXME: diagnose if no Thumb2
uint32_t Binary = (Value - 4) >> 1;
@@ -623,7 +630,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
case ARM::fixup_arm_pcrel_10:
Value = Value - 4; // ARM fixups offset by an additional word and don't
// need to adjust for the half-word ordering.
- // Fall through.
+ LLVM_FALLTHROUGH;
case ARM::fixup_t2_pcrel_10: {
// Offset by 4, adjusted by two due to the half-word ordering of thumb.
Value = Value - 4;
@@ -650,7 +657,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
case ARM::fixup_arm_pcrel_9:
Value = Value - 4; // ARM fixups offset by an additional word and don't
// need to adjust for the half-word ordering.
- // Fall through.
+ LLVM_FALLTHROUGH;
case ARM::fixup_t2_pcrel_9: {
// Offset by 4, adjusted by two due to the half-word ordering of thumb.
Value = Value - 4;
@@ -696,14 +703,16 @@ void ARMAsmBackend::processFixupValue(const MCAssembler &Asm,
bool &IsResolved) {
const MCSymbolRefExpr *A = Target.getSymA();
const MCSymbol *Sym = A ? &A->getSymbol() : nullptr;
- // Some fixups to thumb function symbols need the low bit (thumb bit)
- // twiddled.
- if ((unsigned)Fixup.getKind() != ARM::fixup_arm_ldst_pcrel_12 &&
- (unsigned)Fixup.getKind() != ARM::fixup_t2_ldst_pcrel_12 &&
- (unsigned)Fixup.getKind() != ARM::fixup_arm_adr_pcrel_12 &&
- (unsigned)Fixup.getKind() != ARM::fixup_thumb_adr_pcrel_10 &&
- (unsigned)Fixup.getKind() != ARM::fixup_t2_adr_pcrel_12 &&
- (unsigned)Fixup.getKind() != ARM::fixup_arm_thumb_cp) {
+ // MachO (the only user of "Value") tries to make .o files that look vaguely
+ // pre-linked, so for MOVW/MOVT and .word relocations they put the Thumb bit
+ // into the addend if possible. Other relocation types don't want this bit
+ // though (branches couldn't encode it if it *was* present, and no other
+ // relocations exist) and it can interfere with checking valid expressions.
+ if ((unsigned)Fixup.getKind() == FK_Data_4 ||
+ (unsigned)Fixup.getKind() == ARM::fixup_arm_movw_lo16 ||
+ (unsigned)Fixup.getKind() == ARM::fixup_arm_movt_hi16 ||
+ (unsigned)Fixup.getKind() == ARM::fixup_t2_movw_lo16 ||
+ (unsigned)Fixup.getKind() == ARM::fixup_t2_movt_hi16) {
if (Sym) {
if (Asm.isThumbFunc(Sym))
Value |= 1;
@@ -1111,6 +1120,7 @@ static MachO::CPUSubTypeARM getMachOSubTypeFromArch(StringRef Arch) {
MCAsmBackend *llvm::createARMAsmBackend(const Target &T,
const MCRegisterInfo &MRI,
const Triple &TheTriple, StringRef CPU,
+ const MCTargetOptions &Options,
bool isLittle) {
switch (TheTriple.getObjectFormat()) {
default:
@@ -1131,24 +1141,28 @@ MCAsmBackend *llvm::createARMAsmBackend(const Target &T,
MCAsmBackend *llvm::createARMLEAsmBackend(const Target &T,
const MCRegisterInfo &MRI,
- const Triple &TT, StringRef CPU) {
- return createARMAsmBackend(T, MRI, TT, CPU, true);
+ const Triple &TT, StringRef CPU,
+ const MCTargetOptions &Options) {
+ return createARMAsmBackend(T, MRI, TT, CPU, Options, true);
}
MCAsmBackend *llvm::createARMBEAsmBackend(const Target &T,
const MCRegisterInfo &MRI,
- const Triple &TT, StringRef CPU) {
- return createARMAsmBackend(T, MRI, TT, CPU, false);
+ const Triple &TT, StringRef CPU,
+ const MCTargetOptions &Options) {
+ return createARMAsmBackend(T, MRI, TT, CPU, Options, false);
}
MCAsmBackend *llvm::createThumbLEAsmBackend(const Target &T,
const MCRegisterInfo &MRI,
- const Triple &TT, StringRef CPU) {
- return createARMAsmBackend(T, MRI, TT, CPU, true);
+ const Triple &TT, StringRef CPU,
+ const MCTargetOptions &Options) {
+ return createARMAsmBackend(T, MRI, TT, CPU, Options, true);
}
MCAsmBackend *llvm::createThumbBEAsmBackend(const Target &T,
const MCRegisterInfo &MRI,
- const Triple &TT, StringRef CPU) {
- return createARMAsmBackend(T, MRI, TT, CPU, false);
+ const Triple &TT, StringRef CPU,
+ const MCTargetOptions &Options) {
+ return createARMAsmBackend(T, MRI, TT, CPU, Options, false);
}
OpenPOWER on IntegriCloud