[llvm] r350606 - [MC] [AArch64] Support resolving signed fixups for :abs_g0_s: etc.
Mandeep Singh Grang via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 7 20:48:01 PST 2019
Author: mgrang
Date: Mon Jan 7 20:48:00 2019
New Revision: 350606
URL: http://llvm.org/viewvc/llvm-project?rev=350606&view=rev
Log:
[MC] [AArch64] Support resolving signed fixups for :abs_g0_s: etc.
Summary: This patch is a follow-up to D55896.
Reviewers: efriedma, mstorsjo
Reviewed By: efriedma
Subscribers: javed.absar, kristof.beyls, llvm-commits
Differential Revision: https://reviews.llvm.org/D56029
Added:
llvm/trunk/test/MC/AArch64/fixup-absolute-signed.s
Modified:
llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
llvm/trunk/test/MC/AArch64/fixup-out-of-range.s
Modified: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp?rev=350606&r1=350605&r2=350606&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp Mon Jan 7 20:48:00 2019
@@ -218,20 +218,16 @@ static uint64_t adjustFixupValue(const M
case AArch64::fixup_aarch64_movw: {
AArch64MCExpr::VariantKind RefKind =
static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
- if (AArch64MCExpr::getSymbolLoc(RefKind) != AArch64MCExpr::VK_ABS) {
- if (AArch64MCExpr::getSymbolLoc(RefKind) != AArch64MCExpr::VK_SABS) {
- // VK_GOTTPREL, VK_TPREL, VK_DTPREL are movw fixups, but they can't
- // ever be resolved in the assembler.
- Ctx.reportError(Fixup.getLoc(),
- "relocation for a thread-local variable points to an "
- "absolute symbol");
- return Value;
- }
+ if (AArch64MCExpr::getSymbolLoc(RefKind) != AArch64MCExpr::VK_ABS &&
+ AArch64MCExpr::getSymbolLoc(RefKind) != AArch64MCExpr::VK_SABS) {
+ // VK_GOTTPREL, VK_TPREL, VK_DTPREL are movw fixups, but they can't
+ // ever be resolved in the assembler.
Ctx.reportError(Fixup.getLoc(),
- "resolvable R_AARCH64_MOVW_SABS_G* fixups are not "
- "yet implemented");
+ "relocation for a thread-local variable points to an "
+ "absolute symbol");
return Value;
}
+
if (!IsResolved) {
// FIXME: Figure out when this can actually happen, and verify our
// behavior.
@@ -239,25 +235,57 @@ static uint64_t adjustFixupValue(const M
"implemented");
return Value;
}
- switch (AArch64MCExpr::getAddressFrag(RefKind)) {
- case AArch64MCExpr::VK_G0:
- break;
- case AArch64MCExpr::VK_G1:
- Value = Value >> 16;
- break;
- case AArch64MCExpr::VK_G2:
- Value = Value >> 32;
- break;
- case AArch64MCExpr::VK_G3:
- Value = Value >> 48;
- break;
- default:
- llvm_unreachable("Variant kind doesn't correspond to fixup");
+
+ if (AArch64MCExpr::getSymbolLoc(RefKind) == AArch64MCExpr::VK_SABS) {
+ switch (AArch64MCExpr::getAddressFrag(RefKind)) {
+ case AArch64MCExpr::VK_G0:
+ break;
+ case AArch64MCExpr::VK_G1:
+ SignedValue = SignedValue >> 16;
+ break;
+ case AArch64MCExpr::VK_G2:
+ SignedValue = SignedValue >> 32;
+ break;
+ case AArch64MCExpr::VK_G3:
+ SignedValue = SignedValue >> 48;
+ break;
+ default:
+ llvm_unreachable("Variant kind doesn't correspond to fixup");
+ }
+
+ } else {
+ switch (AArch64MCExpr::getAddressFrag(RefKind)) {
+ case AArch64MCExpr::VK_G0:
+ break;
+ case AArch64MCExpr::VK_G1:
+ Value = Value >> 16;
+ break;
+ case AArch64MCExpr::VK_G2:
+ Value = Value >> 32;
+ break;
+ case AArch64MCExpr::VK_G3:
+ Value = Value >> 48;
+ break;
+ default:
+ llvm_unreachable("Variant kind doesn't correspond to fixup");
+ }
}
- if (RefKind & AArch64MCExpr::VK_NC)
+
+ if (RefKind & AArch64MCExpr::VK_NC) {
Value &= 0xFFFF;
- else if (Value > 0xFFFF)
+ }
+ else if (RefKind & AArch64MCExpr::VK_SABS) {
+ if (SignedValue > 0xFFFF || SignedValue < -0xFFFF)
+ Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
+
+ // Invert the negative immediate because it will feed into a MOVN.
+ if (SignedValue < 0)
+ SignedValue = ~SignedValue;
+ Value = static_cast<uint64_t>(SignedValue);
+ }
+ else if (Value > 0xFFFF) {
Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
+ }
return Value;
}
case AArch64::fixup_aarch64_pcrel_branch14:
@@ -336,6 +364,7 @@ void AArch64AsmBackend::applyFixup(const
return; // Doesn't change encoding.
MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
MCContext &Ctx = Asm.getContext();
+ int64_t SignedValue = static_cast<int64_t>(Value);
// Apply any target-specific value adjustments.
Value = adjustFixupValue(Fixup, Target, Value, Ctx, TheTriple, IsResolved);
@@ -364,6 +393,19 @@ void AArch64AsmBackend::applyFixup(const
Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
}
}
+
+ // FIXME: getFixupKindInfo() and getFixupKindNumBytes() could be fixed to
+ // handle this more cleanly. This may affect the output of -show-mc-encoding.
+ AArch64MCExpr::VariantKind RefKind =
+ static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
+ if (RefKind & AArch64MCExpr::VK_SABS) {
+ // If the immediate is negative, generate MOVN else MOVZ.
+ // (Bit 30 = 0) ==> MOVN, (Bit 30 = 1) ==> MOVZ.
+ if (SignedValue < 0)
+ Data[Offset + 3] &= ~(1 << 6);
+ else
+ Data[Offset + 3] |= (1 << 6);
+ }
}
bool AArch64AsmBackend::mayNeedRelaxation(const MCInst &Inst,
Added: llvm/trunk/test/MC/AArch64/fixup-absolute-signed.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AArch64/fixup-absolute-signed.s?rev=350606&view=auto
==============================================================================
--- llvm/trunk/test/MC/AArch64/fixup-absolute-signed.s (added)
+++ llvm/trunk/test/MC/AArch64/fixup-absolute-signed.s Mon Jan 7 20:48:00 2019
@@ -0,0 +1,44 @@
+// RUN: llvm-mc -triple aarch64--none-eabi -filetype obj < %s -o - | llvm-objdump -d - | FileCheck %s
+
+onepart_before = 12345
+twopart_before = -12345678
+threepart_before = -1234567890
+
+// CHECK: movn x0, #0, lsl #32
+// CHECK: movn x0, #0, lsl #32
+movz x0, #:abs_g2_s:threepart_before
+movz x0, #:abs_g2_s:threepart_after
+
+// CHECK: movk x0, #65535, lsl #32
+// CHECK: movk x0, #65535, lsl #32
+movk x0, #:abs_g2_nc:threepart_before
+movk x0, #:abs_g2_nc:threepart_after
+
+// CHECK: mov x0, #-12320769
+// CHECK: mov x0, #-12320769
+movz x0, #:abs_g1_s:twopart_before
+movz x0, #:abs_g1_s:twopart_after
+
+// CHECK: movk x0, #46697, lsl #16
+// CHECK: movk x0, #46697, lsl #16
+movk x0, #:abs_g1_nc:threepart_before
+movk x0, #:abs_g1_nc:threepart_after
+
+// CHECK: mov x0, #12345
+// CHECK: mov x0, #12345
+movz x0, #:abs_g0_s:onepart_before
+movz x0, #:abs_g0_s:onepart_after
+
+// CHECK: movk x0, #64814
+// CHECK: movk x0, #64814
+movk x0, #:abs_g0_nc:threepart_before
+movk x0, #:abs_g0_nc:threepart_after
+
+// CHECK: mov x0, #12345
+// CHECK: mov x0, #12345
+movn x0, #:abs_g0_s:onepart_before
+movn x0, #:abs_g0_s:onepart_after
+
+onepart_after = 12345
+twopart_after = -12345678
+threepart_after = -1234567890
Modified: llvm/trunk/test/MC/AArch64/fixup-out-of-range.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AArch64/fixup-out-of-range.s?rev=350606&r1=350605&r2=350606&view=diff
==============================================================================
--- llvm/trunk/test/MC/AArch64/fixup-out-of-range.s (original)
+++ llvm/trunk/test/MC/AArch64/fixup-out-of-range.s Mon Jan 7 20:48:00 2019
@@ -61,9 +61,12 @@
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: fixup value out of range
movz x0, #:abs_g1:value2
-// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: resolvable R_AARCH64_MOVW_SABS_G* fixups are not yet implemented
+// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: fixup value out of range
movz x0, #:abs_g0_s:value1
+// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: fixup value out of range
+ movz x0, #:abs_g1_s:value2
+
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: relocation for a thread-local variable points to an absolute symbol
movz x0, #:tprel_g0:value1
More information about the llvm-commits
mailing list