#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/MC/MCValue.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
return DiagnosticPredicateTy::NearMatch;
}
- bool isSymbolicUImm12Offset(const MCExpr *Expr, unsigned Scale) const {
+ bool isSymbolicUImm12Offset(const MCExpr *Expr) const {
AArch64MCExpr::VariantKind ELFRefKind;
MCSymbolRefExpr::VariantKind DarwinRefKind;
int64_t Addend;
// Note that we don't range-check the addend. It's adjusted modulo page
// size when converted, so there is no "out of range" condition when using
// @pageoff.
- return Addend >= 0 && (Addend % Scale) == 0;
+ return true;
} else if (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF ||
DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) {
// @gotpageoff/@tlvppageoff can only be used directly, not with an addend.
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
if (!MCE)
- return isSymbolicUImm12Offset(getImm(), Scale);
+ return isSymbolicUImm12Offset(getImm());
int64_t Val = MCE->getValue();
return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
for (unsigned i = 0; i != AllowedModifiers.size(); ++i) {
if (ELFRefKind == AllowedModifiers[i])
- return Addend == 0;
+ return true;
}
return false;
return true;
}
- const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
- if (!BE)
- return false;
-
- SE = dyn_cast<MCSymbolRefExpr>(BE->getLHS());
- if (!SE)
- return false;
- DarwinRefKind = SE->getKind();
-
- if (BE->getOpcode() != MCBinaryExpr::Add &&
- BE->getOpcode() != MCBinaryExpr::Sub)
- return false;
-
- // See if the addend is a constant, otherwise there's more going
- // on here than we can deal with.
- auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
- if (!AddendExpr)
+ // Check that it looks like a symbol + an addend
+ MCValue Res;
+ bool Relocatable = Expr->evaluateAsRelocatable(Res, nullptr, nullptr);
+ if (!Relocatable || !Res.getSymA() || Res.getSymB())
return false;
- Addend = AddendExpr->getValue();
- if (BE->getOpcode() == MCBinaryExpr::Sub)
- Addend = -Addend;
+ DarwinRefKind = Res.getSymA()->getKind();
+ Addend = Res.getConstant();
// It's some symbol reference + a constant addend, but really
// shouldn't use both Darwin and ELF syntax.
// RUN: FileCheck %s --check-prefix=CHECK-OBJ-LP64
add x0, x2, #:lo12:sym
+ add x0, x2, #:lo12:sym+12
+ add x0, x2, #:lo12:sym-3
// CHECK: add x0, x2, :lo12:sym
+// CHECK: add x0, x2, :lo12:sym+12
+// CHECK: add x0, x2, :lo12:sym-3
// CHECK-OBJ-LP64: 0 R_AARCH64_ADD_ABS_LO12_NC sym
+// CHECK-OBJ-LP64: 4 R_AARCH64_ADD_ABS_LO12_NC sym+12
+// CHECK-OBJ-LP64: 8 R_AARCH64_ADD_ABS_LO12_NC sym-3
add x5, x7, #:dtprel_lo12:sym
// CHECK: add x5, x7, :dtprel_lo12:sym
-// CHECK-OBJ-LP64: 4 R_AARCH64_TLSLD_ADD_DTPREL_LO12 sym
+// CHECK-OBJ-LP64: c R_AARCH64_TLSLD_ADD_DTPREL_LO12 sym
add x9, x12, #:dtprel_lo12_nc:sym
// CHECK: add x9, x12, :dtprel_lo12_nc:sym
-// CHECK-OBJ-LP64: 8 R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC sym
+// CHECK-OBJ-LP64: 10 R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC sym
add x20, x30, #:tprel_lo12:sym
// CHECK: add x20, x30, :tprel_lo12:sym
-// CHECK-OBJ-LP64: c R_AARCH64_TLSLE_ADD_TPREL_LO12 sym
+// CHECK-OBJ-LP64: 14 R_AARCH64_TLSLE_ADD_TPREL_LO12 sym
add x9, x12, #:tprel_lo12_nc:sym
// CHECK: add x9, x12, :tprel_lo12_nc:sym
-// CHECK-OBJ-LP64: 10 R_AARCH64_TLSLE_ADD_TPREL_LO12_NC sym
+// CHECK-OBJ-LP64: 18 R_AARCH64_TLSLE_ADD_TPREL_LO12_NC sym
add x5, x0, #:tlsdesc_lo12:sym
// CHECK: add x5, x0, :tlsdesc_lo12:sym
-// CHECK-OBJ-LP64: 14 R_AARCH64_TLSDESC_ADD_LO12 sym
+// CHECK-OBJ-LP64: 1c R_AARCH64_TLSDESC_ADD_LO12 sym
add x0, x2, #:lo12:sym+8
// CHECK: add x0, x2, :lo12:sym
-// CHECK-OBJ-LP64: 18 R_AARCH64_ADD_ABS_LO12_NC sym+8
+// CHECK-OBJ-LP64: 20 R_AARCH64_ADD_ABS_LO12_NC sym+8
add x5, x7, #:dtprel_lo12:sym+1
// CHECK: add x5, x7, :dtprel_lo12:sym+1
-// CHECK-OBJ-LP64: 1c R_AARCH64_TLSLD_ADD_DTPREL_LO12 sym+1
+// CHECK-OBJ-LP64: 24 R_AARCH64_TLSLD_ADD_DTPREL_LO12 sym+1
add x9, x12, #:dtprel_lo12_nc:sym+2
// CHECK: add x9, x12, :dtprel_lo12_nc:sym+2
-// CHECK-OBJ-LP64:20 R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC sym+2
+// CHECK-OBJ-LP64: 28 R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC sym+2
add x20, x30, #:tprel_lo12:sym+12
// CHECK: add x20, x30, :tprel_lo12:sym+12
-// CHECK-OBJ-LP64: 24 R_AARCH64_TLSLE_ADD_TPREL_LO12 sym+12
+// CHECK-OBJ-LP64: 2c R_AARCH64_TLSLE_ADD_TPREL_LO12 sym+12
add x9, x12, #:tprel_lo12_nc:sym+54
// CHECK: add x9, x12, :tprel_lo12_nc:sym+54
-// CHECK-OBJ-LP64: 28 R_AARCH64_TLSLE_ADD_TPREL_LO12_NC sym+54
+// CHECK-OBJ-LP64: 30 R_AARCH64_TLSLE_ADD_TPREL_LO12_NC sym+54
add x5, x0, #:tlsdesc_lo12:sym+70
// CHECK: add x5, x0, :tlsdesc_lo12:sym+70
-// CHECK-OBJ-LP64: 2c R_AARCH64_TLSDESC_ADD_LO12 sym+70
+// CHECK-OBJ-LP64: 34 R_AARCH64_TLSDESC_ADD_LO12 sym+70
.hword sym + 4 - .
-// CHECK-OBJ-LP64: 30 R_AARCH64_PREL16 sym+4
+// CHECK-OBJ-LP64: 38 R_AARCH64_PREL16 sym+4
.word sym - . + 8
-// CHECK-OBJ-LP64: 32 R_AARCH64_PREL32 sym+8
+// CHECK-OBJ-LP64: 3a R_AARCH64_PREL32 sym+8
.xword sym-.
-// CHECK-OBJ-LP64: 36 R_AARCH64_PREL64 sym{{$}}
+// CHECK-OBJ-LP64: 3e R_AARCH64_PREL64 sym{{$}}
.hword sym
-// CHECK-OBJ-LP64: 3e R_AARCH64_ABS16 sym
+// CHECK-OBJ-LP64: 46 R_AARCH64_ABS16 sym
.word sym+1
-// CHECK-OBJ-LP64: 40 R_AARCH64_ABS32 sym+1
+// CHECK-OBJ-LP64: 48 R_AARCH64_ABS32 sym+1
.xword sym+16
-// CHECK-OBJ-LP64: 44 R_AARCH64_ABS64 sym+16
+// CHECK-OBJ-LP64: 4c R_AARCH64_ABS64 sym+16
adrp x0, sym
// CHECK: adrp x0, sym
-// CHECK-OBJ-LP64: 4c R_AARCH64_ADR_PREL_PG_HI21 sym
+// CHECK-OBJ-LP64: 54 R_AARCH64_ADR_PREL_PG_HI21 sym
adrp x15, :got:sym
// CHECK: adrp x15, :got:sym
-// CHECK-OBJ-LP64: 50 R_AARCH64_ADR_GOT_PAGE sym
+// CHECK-OBJ-LP64: 58 R_AARCH64_ADR_GOT_PAGE sym
adrp x29, :gottprel:sym
// CHECK: adrp x29, :gottprel:sym
-// CHECK-OBJ-LP64: 54 R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 sym
+// CHECK-OBJ-LP64: 5c R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 sym
adrp x2, :tlsdesc:sym
// CHECK: adrp x2, :tlsdesc:sym
-// CHECK-OBJ-LP64: 58 R_AARCH64_TLSDESC_ADR_PAGE21 sym
+// CHECK-OBJ-LP64: 60 R_AARCH64_TLSDESC_ADR_PAGE21 sym
// LLVM is not competent enough to do this relocation because the
// page boundary could occur anywhere after linking. A relocation
.global trickQuestion
trickQuestion:
// CHECK: adrp x3, trickQuestion
-// CHECK-OBJ-LP64: 5c R_AARCH64_ADR_PREL_PG_HI21 trickQuestion
+// CHECK-OBJ-LP64: 64 R_AARCH64_ADR_PREL_PG_HI21 trickQuestion
ldrb w2, [x3, :lo12:sym]
ldrsb w5, [x7, #:lo12:sym]
ldrsb x11, [x13, :lo12:sym]
ldr b17, [x19, #:lo12:sym]
+ ldrb w2, [x3, :lo12:sym+15]
+ ldrsb w5, [x7, #:lo12:sym-2]
+ ldr b17, [x19, #:lo12:sym+4]
// CHECK: ldrb w2, [x3, :lo12:sym]
// CHECK: ldrsb w5, [x7, :lo12:sym]
// CHECK: ldrsb x11, [x13, :lo12:sym]
// CHECK: ldr b17, [x19, :lo12:sym]
+// CHECK: ldrb w2, [x3, :lo12:sym+15]
+// CHECK: ldrsb w5, [x7, :lo12:sym-2]
+// CHECK: ldr b17, [x19, :lo12:sym+4]
// CHECK-OBJ-LP64: R_AARCH64_LDST8_ABS_LO12_NC sym
// CHECK-OBJ-LP64: R_AARCH64_LDST8_ABS_LO12_NC sym
// CHECK-OBJ-LP64: R_AARCH64_LDST8_ABS_LO12_NC sym
// CHECK-OBJ-LP64: R_AARCH64_LDST8_ABS_LO12_NC sym
+// CHECK-OBJ-LP64: R_AARCH64_LDST8_ABS_LO12_NC sym+15
+// CHECK-OBJ-LP64: R_AARCH64_LDST8_ABS_LO12_NC sym-2
+// CHECK-OBJ-LP64: R_AARCH64_LDST8_ABS_LO12_NC sym+4
ldrb w23, [x29, #:dtprel_lo12_nc:sym]
ldrsb w23, [x19, #:dtprel_lo12:sym]
ldrsb x17, [x13, :dtprel_lo12_nc:sym]
ldr b11, [x7, #:dtprel_lo12:sym]
+ ldrb w23, [x29, #:dtprel_lo12_nc:sym+2]
// CHECK: ldrb w23, [x29, :dtprel_lo12_nc:sym]
// CHECK: ldrsb w23, [x19, :dtprel_lo12:sym]
// CHECK: ldrsb x17, [x13, :dtprel_lo12_nc:sym]
// CHECK: ldr b11, [x7, :dtprel_lo12:sym]
+// CHECK: ldrb w23, [x29, :dtprel_lo12_nc:sym+2]
// CHECK-OBJ-LP64: R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC sym
// CHECK-OBJ-LP64: R_AARCH64_TLSLD_LDST8_DTPREL_LO12 sym
// CHECK-OBJ-LP64: R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC sym
// CHECK-OBJ-LP64: R_AARCH64_TLSLD_LDST8_DTPREL_LO12 sym
+// CHECK-OBJ-LP64: R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC sym+2
ldrb w1, [x2, :tprel_lo12:sym]
ldrsb w3, [x4, #:tprel_lo12_nc:sym]
ldrsh w5, [x7, :lo12:sym]
ldrsh x11, [x13, #:lo12:sym]
ldr h17, [x19, :lo12:sym]
+ ldrh w2, [x3, #:lo12:sym+4]
// CHECK: ldrh w2, [x3, :lo12:sym]
// CHECK: ldrsh w5, [x7, :lo12:sym]
// CHECK: ldrsh x11, [x13, :lo12:sym]
// CHECK: ldr h17, [x19, :lo12:sym]
+// CHECK: ldrh w2, [x3, :lo12:sym+4]
// CHECK-OBJ-LP64: R_AARCH64_LDST16_ABS_LO12_NC sym
// CHECK-OBJ-LP64: R_AARCH64_LDST16_ABS_LO12_NC sym
// CHECK-OBJ-LP64: R_AARCH64_LDST16_ABS_LO12_NC sym
// CHECK-OBJ-LP64: R_AARCH64_LDST16_ABS_LO12_NC sym
+// CHECK-OBJ-LP64: R_AARCH64_LDST16_ABS_LO12_NC sym+4
ldrh w23, [x29, #:dtprel_lo12_nc:sym]
ldrsh w23, [x19, :dtprel_lo12:sym]
ldr x28, [x27, :lo12:sym]
ldr d26, [x25, #:lo12:sym]
+ ldr x28, [x27, :lo12:sym+10]
+ ldr x28, [x27, :lo12:sym-15]
// CHECK: ldr x28, [x27, :lo12:sym]
// CHECK: ldr d26, [x25, :lo12:sym]
+// CHECK: ldr x28, [x27, :lo12:sym+10]
+// CHECK: ldr x28, [x27, :lo12:sym-15]
// CHECK-OBJ-LP64: R_AARCH64_LDST64_ABS_LO12_NC sym
// CHECK-OBJ-LP64: R_AARCH64_LDST64_ABS_LO12_NC sym
+// CHECK-OBJ-LP64: R_AARCH64_LDST64_ABS_LO12_NC sym+10
+// CHECK-OBJ-LP64: R_AARCH64_LDST64_ABS_LO12_NC sym-15
ldr x24, [x23, #:got_lo12:sym]
ldr d22, [x21, :got_lo12:sym]
+ ldr x24, [x23, :got_lo12:sym+7]
// CHECK: ldr x24, [x23, :got_lo12:sym]
// CHECK: ldr d22, [x21, :got_lo12:sym]
+// CHECK: ldr x24, [x23, :got_lo12:sym+7]
// CHECK-OBJ-LP64: R_AARCH64_LD64_GOT_LO12_NC sym
// CHECK-OBJ-LP64: R_AARCH64_LD64_GOT_LO12_NC sym
+// CHECK-OBJ-LP64: R_AARCH64_LD64_GOT_LO12_NC sym+7
ldr x24, [x23, :dtprel_lo12_nc:sym]
ldr d22, [x21, #:dtprel_lo12:sym]