Index: lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -39,6 +39,7 @@ #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" @@ -5305,28 +5306,14 @@ return true; } - const MCBinaryExpr *BE = dyn_cast(Expr); - if (!BE) + // 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; - SE = dyn_cast(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(BE->getRHS()); - if (!AddendExpr) - 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. Index: test/MC/AArch64/adr-badsyms.s =================================================================== --- /dev/null +++ test/MC/AArch64/adr-badsyms.s @@ -0,0 +1,35 @@ +// RUN: not llvm-mc -triple aarch64-none-linux-gnu %s -filetype=obj -o /dev/null 2>&1 | FileCheck %s + + adr x0, -IMAGE_START +// CHECK: error: expected relocatable expression +// CHECK-NEXT: adr x0, -IMAGE_START +// CHECK-NEXT: ^ + adr x1, IMAGE_START * 10 +// CHECK: error: expected relocatable expression +// CHECK-NEXT: adr x1, IMAGE_START * 10 +// CHECK-NEXT: ^ + adr x2, 2 * (IMAGE_LOAD_START + 987136) +// CHECK: error: expected relocatable expression +// CHECK-NEXT: adr x2, 2 * (IMAGE_LOAD_START + 987136) +// CHECK-NEXT: ^ + adr x3, (IMAGE_LOAD_END + IMAGE_LOAD_START) +// CHECK: error: expected relocatable expression +// CHECK-NEXT: adr x3, (IMAGE_LOAD_END + IMAGE_LOAD_START) +// CHECK-NEXT: ^ + + adrp x0, -IMAGE_START +// CHECK: error: expected relocatable expression +// CHECK-NEXT: adrp x0, -IMAGE_START +// CHECK-NEXT: ^ + adrp x1, IMAGE_START * 10 +// CHECK: error: expected relocatable expression +// CHECK-NEXT: adrp x1, IMAGE_START * 10 +// CHECK-NEXT: ^ + adrp x2, 2 * (IMAGE_LOAD_START + 987136) +// CHECK: error: expected relocatable expression +// CHECK-NEXT: adrp x2, 2 * (IMAGE_LOAD_START + 987136) +// CHECK-NEXT: ^ + adrp x3, (IMAGE_LOAD_END + IMAGE_LOAD_START) +// CHECK: error: expected relocatable expression +// CHECK-NEXT: adrp x3, (IMAGE_LOAD_END + IMAGE_LOAD_START) +// CHECK-NEXT: ^ \ No newline at end of file Index: test/MC/AArch64/adr.s =================================================================== --- /dev/null +++ test/MC/AArch64/adr.s @@ -0,0 +1,38 @@ +// RUN: llvm-mc -triple aarch64-none-linux-gnu %s -filetype=obj -o %t.o +// RUN: llvm-objdump -d -r %t.o | FileCheck %s + + // CHECK: adr x0, #100 + // CHECK-NEXT: adr x1, #0 + // CHECK-NEXT: R_AARCH64_ADR_PREL_LO21 IMAGE_START + // CHECK-NEXT: adr x2, #0 + // CHECK-NEXT: R_AARCH64_ADR_PREL_LO21 IMAGE_START + // CHECK-NEXT: adr x3, #0 + // CHECK-NEXT: R_AARCH64_ADR_PREL_LO21 IMAGE_LOAD_START+987136 + // CHECK-NEXT: adr x4, #0 + // CHECK-NEXT: R_AARCH64_ADR_PREL_LO21 IMAGE_LOAD_START+987136 + // CHECK-NEXT: adr x5, #0 + // CHECK-NEXT: R_AARCH64_ADR_PREL_LO21 IMAGE_LOAD_START+987136 + + adr x0, 100 + adr x1, IMAGE_START + adr x2, IMAGE_START + 0 + adr x3, IMAGE_LOAD_START + 987136 + adr x4, (0xffffffff000f1000 - 0xffffffff00000000 + IMAGE_LOAD_START) + adr x5, IMAGE_LOAD_START + (0xffffffff000f1000 - 0xffffffff00000000) + + // CHECK-NEXT: adrp x1, #0 + // CHECK-NEXT: R_AARCH64_ADR_PREL_PG_HI21 IMAGE_START + // CHECK-NEXT: adrp x2, #0 + // CHECK-NEXT: R_AARCH64_ADR_PREL_PG_HI21 IMAGE_START + // CHECK-NEXT: adrp x3, #0 + // CHECK-NEXT: R_AARCH64_ADR_PREL_PG_HI21 IMAGE_LOAD_START+987136 + // CHECK-NEXT: adrp x4, #0 + // CHECK-NEXT: R_AARCH64_ADR_PREL_PG_HI21 IMAGE_LOAD_START+987136 + // CHECK-NEXT: adrp x5, #0 + // CHECK-NEXT: R_AARCH64_ADR_PREL_PG_HI21 IMAGE_LOAD_START+987136 + + adrp x1, IMAGE_START + adrp x2, IMAGE_START + 0 + adrp x3, IMAGE_LOAD_START + 987136 + adrp x4, (0xffffffff000f1000 - 0xffffffff00000000 + IMAGE_LOAD_START) + adrp x5, IMAGE_LOAD_START + (0xffffffff000f1000 - 0xffffffff00000000)