AArch64AsmParser: Restore Lsym@page-offset support

https://github.com/llvm/llvm-project/pull/134202 removed support for
`sym@page-offset` in instruction operands. This change is generally
reasonable since subtracting an offset from a symbol typically doesn’t
make sense for Mach-O due to its .subsections_via_symbols mechanism, which treats
them as separate atoms.

However, BoringSSL relies on a temporary symbol with a negative offset,
which can be meaningful when the symbol and the referenced location are
within the same atom.
```
../../third_party/boringssl/src/gen/bcm/p256-armv8-asm-apple.S:1160:25: error: unexpected token in argument list
 adrp x23,Lone_mont@PAGE-64
```

It's worth noting that expressions involving @ can be complex and
brittle in MCParser, and much of the Mach-O @ offsets remains
under-tested.

* Allow default argument for parsePrimaryExpr. The argument, used by the niche llvm-ml,
  should not require other targets to adapt.
This commit is contained in:
Fangrui Song
2025-04-09 23:13:05 -07:00
parent f819f46284
commit 3fd0d22d74
4 changed files with 54 additions and 11 deletions

View File

@@ -308,7 +308,7 @@ public:
/// on error.
/// \return - False on success.
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
AsmTypeInfo *TypeInfo) = 0;
AsmTypeInfo *TypeInfo = nullptr) = 0;
/// Parse an arbitrary expression, assuming that an initial '(' has
/// already been consumed.

View File

@@ -4483,12 +4483,16 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
if (getParser().parseAtSpecifier(ImmVal, EndLoc))
return true;
const MCExpr *Term;
if (parseOptionalToken(AsmToken::Plus)) {
if (getParser().parseExpression(Term, EndLoc))
return true;
ImmVal =
MCBinaryExpr::create(MCBinaryExpr::Add, ImmVal, Term, getContext());
}
MCBinaryExpr::Opcode Opcode;
if (parseOptionalToken(AsmToken::Plus))
Opcode = MCBinaryExpr::Add;
else if (parseOptionalToken(AsmToken::Minus))
Opcode = MCBinaryExpr::Sub;
else
return false;
if (getParser().parsePrimaryExpr(Term, EndLoc))
return true;
ImmVal = MCBinaryExpr::create(Opcode, ImmVal, Term, getContext());
}
return false;
@@ -5026,11 +5030,15 @@ bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
return true;
if (getParser().parseAtSpecifier(IdVal, E))
return true;
if (parseOptionalToken(AsmToken::Plus)) {
if (getParser().parseExpression(Term, E))
std::optional<MCBinaryExpr::Opcode> Opcode;
if (parseOptionalToken(AsmToken::Plus))
Opcode = MCBinaryExpr::Add;
else if (parseOptionalToken(AsmToken::Minus))
Opcode = MCBinaryExpr::Sub;
if (Opcode) {
if (getParser().parsePrimaryExpr(Term, E))
return true;
IdVal =
MCBinaryExpr::create(MCBinaryExpr::Add, IdVal, Term, getContext());
IdVal = MCBinaryExpr::create(*Opcode, IdVal, Term, getContext());
}
Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));

View File

@@ -366,6 +366,9 @@ subs x20, x30, sym@PAGEOFF
; CHECK-ERRORS: subs x20, x30, sym@PAGEOFF
; CHECK-ERRORS: ^
add w3, w5, sym@PAGEOFF - 3-2
; CHECK-ERRORS: [[#@LINE-1]]:28: error: unexpected token in argument list
tbl v0.8b, { v1 }, v0.8b
tbl v0.16b, { v1.8b, v2.8b, v3.8b }, v0.16b
tbx v3.16b, { v12.8b, v13.8b, v14.8b }, v6.8b

View File

@@ -17,9 +17,13 @@ _fred:
ldr w2, [x3, _data_ext@gotpageoff]
adrp x0, L_.str@PAGE
adrp x3, L1@PAGE - 5
add x3, x3, L1@pageoff - (4+1)
.data
_data:
.quad _foo
L1:
.quad _foo + 4
.quad _foo - _bar
.quad _foo - _bar + 4
@@ -36,6 +40,34 @@ L_.str:
; CHECK: Relocations [
; CHECK-NEXT: Section __text {
; CHECK-NEXT: Relocation {
; CHECK-NEXT: Offset: 0x2C
; CHECK-NEXT: PCRel: 0
; CHECK-NEXT: Length: 2
; CHECK-NEXT: Type: ARM64_RELOC_ADDEND (10)
; CHECK-NEXT: Section: __cstring (3)
; CHECK-NEXT: }
; CHECK-NEXT: Relocation {
; CHECK-NEXT: Offset: 0x2C
; CHECK-NEXT: PCRel: 0
; CHECK-NEXT: Length: 2
; CHECK-NEXT: Type: ARM64_RELOC_PAGEOFF12 (4)
; CHECK-NEXT: Symbol: _data (2)
; CHECK-NEXT: }
; CHECK-NEXT: Relocation {
; CHECK-NEXT: Offset: 0x28
; CHECK-NEXT: PCRel: 0
; CHECK-NEXT: Length: 2
; CHECK-NEXT: Type: ARM64_RELOC_ADDEND (10)
; CHECK-NEXT: Section: __cstring (3)
; CHECK-NEXT: }
; CHECK-NEXT: Relocation {
; CHECK-NEXT: Offset: 0x28
; CHECK-NEXT: PCRel: 1
; CHECK-NEXT: Length: 2
; CHECK-NEXT: Type: ARM64_RELOC_PAGE21 (3)
; CHECK-NEXT: Symbol: _data (2)
; CHECK-NEXT: }
; CHECK-NEXT: Relocation {
; CHECK-NEXT: Offset: 0x24
; CHECK-NEXT: PCRel: 1