mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 21:32:10 +00:00
AArch64/ARM64: allow negative addends, at least on ELF.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207111 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
421c65b9b4
commit
d4daf1762d
@ -122,7 +122,7 @@ public:
|
|||||||
static bool classifySymbolRef(const MCExpr *Expr,
|
static bool classifySymbolRef(const MCExpr *Expr,
|
||||||
ARM64MCExpr::VariantKind &ELFRefKind,
|
ARM64MCExpr::VariantKind &ELFRefKind,
|
||||||
MCSymbolRefExpr::VariantKind &DarwinRefKind,
|
MCSymbolRefExpr::VariantKind &DarwinRefKind,
|
||||||
const MCConstantExpr *&Addend);
|
int64_t &Addend);
|
||||||
};
|
};
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
@ -587,7 +587,7 @@ public:
|
|||||||
|
|
||||||
ARM64MCExpr::VariantKind ELFRefKind;
|
ARM64MCExpr::VariantKind ELFRefKind;
|
||||||
MCSymbolRefExpr::VariantKind DarwinRefKind;
|
MCSymbolRefExpr::VariantKind DarwinRefKind;
|
||||||
const MCConstantExpr *Addend;
|
int64_t Addend;
|
||||||
if (!ARM64AsmParser::classifySymbolRef(getImm(), ELFRefKind, DarwinRefKind,
|
if (!ARM64AsmParser::classifySymbolRef(getImm(), ELFRefKind, DarwinRefKind,
|
||||||
Addend)) {
|
Addend)) {
|
||||||
return false;
|
return false;
|
||||||
@ -911,7 +911,7 @@ public:
|
|||||||
const MCExpr *Expr = Mem.OffsetImm;
|
const MCExpr *Expr = Mem.OffsetImm;
|
||||||
ARM64MCExpr::VariantKind ELFRefKind;
|
ARM64MCExpr::VariantKind ELFRefKind;
|
||||||
MCSymbolRefExpr::VariantKind DarwinRefKind;
|
MCSymbolRefExpr::VariantKind DarwinRefKind;
|
||||||
const MCConstantExpr *Addend;
|
int64_t Addend;
|
||||||
if (!ARM64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
|
if (!ARM64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
|
||||||
Addend)) {
|
Addend)) {
|
||||||
// If we don't understand the expression, assume the best and
|
// If we don't understand the expression, assume the best and
|
||||||
@ -931,8 +931,7 @@ public:
|
|||||||
// Note that we don't range-check the addend. It's adjusted modulo page
|
// 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
|
// size when converted, so there is no "out of range" condition when using
|
||||||
// @pageoff.
|
// @pageoff.
|
||||||
int64_t Value = Addend ? Addend->getValue() : 0;
|
return Addend >= 0 && (Addend % Scale) == 0;
|
||||||
return Value >= 0 && (Value % Scale) == 0;
|
|
||||||
} else if (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF ||
|
} else if (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF ||
|
||||||
DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) {
|
DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) {
|
||||||
// @gotpageoff/@tlvppageoff can only be used directly, not with an addend.
|
// @gotpageoff/@tlvppageoff can only be used directly, not with an addend.
|
||||||
@ -1482,7 +1481,7 @@ public:
|
|||||||
const MCExpr *Expr = Mem.OffsetImm;
|
const MCExpr *Expr = Mem.OffsetImm;
|
||||||
ARM64MCExpr::VariantKind ELFRefKind;
|
ARM64MCExpr::VariantKind ELFRefKind;
|
||||||
MCSymbolRefExpr::VariantKind DarwinRefKind;
|
MCSymbolRefExpr::VariantKind DarwinRefKind;
|
||||||
const MCConstantExpr *Addend;
|
int64_t Addend;
|
||||||
if (Scale > 1 &&
|
if (Scale > 1 &&
|
||||||
(!ARM64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
|
(!ARM64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
|
||||||
Addend) ||
|
Addend) ||
|
||||||
@ -2091,7 +2090,7 @@ ARM64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
|
|||||||
|
|
||||||
ARM64MCExpr::VariantKind ELFRefKind;
|
ARM64MCExpr::VariantKind ELFRefKind;
|
||||||
MCSymbolRefExpr::VariantKind DarwinRefKind;
|
MCSymbolRefExpr::VariantKind DarwinRefKind;
|
||||||
const MCConstantExpr *Addend;
|
int64_t Addend;
|
||||||
if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
|
if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
|
||||||
if (DarwinRefKind == MCSymbolRefExpr::VK_None &&
|
if (DarwinRefKind == MCSymbolRefExpr::VK_None &&
|
||||||
ELFRefKind == ARM64MCExpr::VK_INVALID) {
|
ELFRefKind == ARM64MCExpr::VK_INVALID) {
|
||||||
@ -2925,7 +2924,7 @@ bool ARM64AsmParser::parseMemory(OperandVector &Operands) {
|
|||||||
// assume it's OK and let the relocation stuff puke if it's not.
|
// assume it's OK and let the relocation stuff puke if it's not.
|
||||||
ARM64MCExpr::VariantKind ELFRefKind;
|
ARM64MCExpr::VariantKind ELFRefKind;
|
||||||
MCSymbolRefExpr::VariantKind DarwinRefKind;
|
MCSymbolRefExpr::VariantKind DarwinRefKind;
|
||||||
const MCConstantExpr *Addend;
|
int64_t Addend;
|
||||||
if (classifySymbolRef(OffsetExpr, ELFRefKind, DarwinRefKind, Addend) &&
|
if (classifySymbolRef(OffsetExpr, ELFRefKind, DarwinRefKind, Addend) &&
|
||||||
Addend == 0) {
|
Addend == 0) {
|
||||||
assert(ELFRefKind == ARM64MCExpr::VK_INVALID &&
|
assert(ELFRefKind == ARM64MCExpr::VK_INVALID &&
|
||||||
@ -3491,7 +3490,7 @@ bool ARM64AsmParser::validateInstruction(MCInst &Inst,
|
|||||||
const MCExpr *Expr = Inst.getOperand(2).getExpr();
|
const MCExpr *Expr = Inst.getOperand(2).getExpr();
|
||||||
ARM64MCExpr::VariantKind ELFRefKind;
|
ARM64MCExpr::VariantKind ELFRefKind;
|
||||||
MCSymbolRefExpr::VariantKind DarwinRefKind;
|
MCSymbolRefExpr::VariantKind DarwinRefKind;
|
||||||
const MCConstantExpr *Addend;
|
int64_t Addend;
|
||||||
if (!classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
|
if (!classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
|
||||||
return Error(Loc[2], "invalid immediate expression");
|
return Error(Loc[2], "invalid immediate expression");
|
||||||
}
|
}
|
||||||
@ -4478,9 +4477,10 @@ bool
|
|||||||
ARM64AsmParser::classifySymbolRef(const MCExpr *Expr,
|
ARM64AsmParser::classifySymbolRef(const MCExpr *Expr,
|
||||||
ARM64MCExpr::VariantKind &ELFRefKind,
|
ARM64MCExpr::VariantKind &ELFRefKind,
|
||||||
MCSymbolRefExpr::VariantKind &DarwinRefKind,
|
MCSymbolRefExpr::VariantKind &DarwinRefKind,
|
||||||
const MCConstantExpr *&Addend) {
|
int64_t &Addend) {
|
||||||
ELFRefKind = ARM64MCExpr::VK_INVALID;
|
ELFRefKind = ARM64MCExpr::VK_INVALID;
|
||||||
DarwinRefKind = MCSymbolRefExpr::VK_None;
|
DarwinRefKind = MCSymbolRefExpr::VK_None;
|
||||||
|
Addend = 0;
|
||||||
|
|
||||||
if (const ARM64MCExpr *AE = dyn_cast<ARM64MCExpr>(Expr)) {
|
if (const ARM64MCExpr *AE = dyn_cast<ARM64MCExpr>(Expr)) {
|
||||||
ELFRefKind = AE->getKind();
|
ELFRefKind = AE->getKind();
|
||||||
@ -4491,7 +4491,6 @@ ARM64AsmParser::classifySymbolRef(const MCExpr *Expr,
|
|||||||
if (SE) {
|
if (SE) {
|
||||||
// It's a simple symbol reference with no addend.
|
// It's a simple symbol reference with no addend.
|
||||||
DarwinRefKind = SE->getKind();
|
DarwinRefKind = SE->getKind();
|
||||||
Addend = 0;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4504,15 +4503,20 @@ ARM64AsmParser::classifySymbolRef(const MCExpr *Expr,
|
|||||||
return false;
|
return false;
|
||||||
DarwinRefKind = SE->getKind();
|
DarwinRefKind = SE->getKind();
|
||||||
|
|
||||||
if (BE->getOpcode() != MCBinaryExpr::Add)
|
if (BE->getOpcode() != MCBinaryExpr::Add &&
|
||||||
|
BE->getOpcode() != MCBinaryExpr::Sub)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// See if the addend is is a constant, otherwise there's more going
|
// See if the addend is is a constant, otherwise there's more going
|
||||||
// on here than we can deal with.
|
// on here than we can deal with.
|
||||||
Addend = dyn_cast<MCConstantExpr>(BE->getRHS());
|
auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
|
||||||
if (!Addend)
|
if (!AddendExpr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
Addend = AddendExpr->getValue();
|
||||||
|
if (BE->getOpcode() == MCBinaryExpr::Sub)
|
||||||
|
Addend = -Addend;
|
||||||
|
|
||||||
// It's some symbol reference + a constant addend, but really
|
// It's some symbol reference + a constant addend, but really
|
||||||
// shouldn't use both Darwin and ELF syntax.
|
// shouldn't use both Darwin and ELF syntax.
|
||||||
return ELFRefKind == ARM64MCExpr::VK_INVALID ||
|
return ELFRefKind == ARM64MCExpr::VK_INVALID ||
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
// RUN: llvm-mc -triple=aarch64-linux-gnu -filetype=obj -o - %s | llvm-objdump -triple=aarch64-linux-gnu -r - | FileCheck %s
|
// RUN: llvm-mc -triple=aarch64-linux-gnu -filetype=obj -o - %s | llvm-objdump -triple=aarch64-linux-gnu -r - | FileCheck %s
|
||||||
|
|
||||||
|
// RUN: llvm-mc -triple=arm64-linux-gnu -filetype=obj -o - %s | llvm-objdump -triple=aarch64-linux-gnu -r - | FileCheck %s
|
||||||
|
|
||||||
add x0, x4, #:lo12:sym
|
add x0, x4, #:lo12:sym
|
||||||
// CHECK: 0 R_AARCH64_ADD_ABS_LO12_NC sym
|
// CHECK: 0 R_AARCH64_ADD_ABS_LO12_NC sym
|
||||||
add x3, x5, #:lo12:sym+1
|
add x3, x5, #:lo12:sym+1
|
||||||
|
Loading…
Reference in New Issue
Block a user