forked from OSchip/llvm-project
[MC] [AArch64] Support resolving fixups for abs_g0 etc.
This requires a bit more code than other fixups, to distingush between abs_g0/abs_g1/etc. Actually, I think some of the other fixups are missing some checks, but I won't try to address that here. I haven't seen any real-world code that uses a construct like this, but it clearly should work, and we're considering using it in the implementation of localescape/localrecover on Windows (see https://reviews.llvm.org/D53540). I've verified that binutils produces the same code as llvm-mc for the testcase. This currently doesn't include support for the *_s variants (that requires a bit more work to set the opcode). Differential Revision: https://reviews.llvm.org/D55896 llvm-svn: 349799
This commit is contained in:
parent
b40e99af08
commit
4648209e16
|
@ -110,11 +110,11 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
|
|||
case FK_Data_1:
|
||||
return 1;
|
||||
|
||||
case AArch64::fixup_aarch64_movw:
|
||||
case FK_Data_2:
|
||||
case FK_SecRel_2:
|
||||
return 2;
|
||||
|
||||
case AArch64::fixup_aarch64_movw:
|
||||
case AArch64::fixup_aarch64_pcrel_branch14:
|
||||
case AArch64::fixup_aarch64_add_imm12:
|
||||
case AArch64::fixup_aarch64_ldst_imm12_scale1:
|
||||
|
@ -145,9 +145,9 @@ static unsigned AdrImmBits(unsigned Value) {
|
|||
return (hi19 << 5) | (lo2 << 29);
|
||||
}
|
||||
|
||||
static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
|
||||
MCContext &Ctx, const Triple &TheTriple,
|
||||
bool IsResolved) {
|
||||
static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target,
|
||||
uint64_t Value, MCContext &Ctx,
|
||||
const Triple &TheTriple, bool IsResolved) {
|
||||
unsigned Kind = Fixup.getKind();
|
||||
int64_t SignedValue = static_cast<int64_t>(Value);
|
||||
switch (Kind) {
|
||||
|
@ -215,10 +215,51 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
|
|||
if (Value & 0xf)
|
||||
Ctx.reportError(Fixup.getLoc(), "fixup must be 16-byte aligned");
|
||||
return Value >> 4;
|
||||
case AArch64::fixup_aarch64_movw:
|
||||
Ctx.reportError(Fixup.getLoc(),
|
||||
"no resolvable MOVZ/MOVK fixups supported yet");
|
||||
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;
|
||||
}
|
||||
Ctx.reportError(Fixup.getLoc(),
|
||||
"resolvable R_AARCH64_MOVW_SABS_G* fixups are not "
|
||||
"yet implemented");
|
||||
return Value;
|
||||
}
|
||||
if (!IsResolved) {
|
||||
// FIXME: Figure out when this can actually happen, and verify our
|
||||
// behavior.
|
||||
Ctx.reportError(Fixup.getLoc(), "unresolved movw fixup not yet "
|
||||
"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 (RefKind & AArch64MCExpr::VK_NC)
|
||||
Value &= 0xFFFF;
|
||||
else if (Value > 0xFFFF)
|
||||
Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
|
||||
return Value;
|
||||
}
|
||||
case AArch64::fixup_aarch64_pcrel_branch14:
|
||||
// Signed 16-bit immediate
|
||||
if (SignedValue > 32767 || SignedValue < -32768)
|
||||
|
@ -296,7 +337,7 @@ void AArch64AsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
|||
MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
|
||||
MCContext &Ctx = Asm.getContext();
|
||||
// Apply any target-specific value adjustments.
|
||||
Value = adjustFixupValue(Fixup, Value, Ctx, TheTriple, IsResolved);
|
||||
Value = adjustFixupValue(Fixup, Target, Value, Ctx, TheTriple, IsResolved);
|
||||
|
||||
// Shift the value into position.
|
||||
Value <<= Info.TargetOffset;
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
// RUN: llvm-mc -triple aarch64--none-eabi -filetype obj < %s -o - | llvm-objdump -d - | FileCheck %s
|
||||
|
||||
// CHECK: mov x0, #1311673391471656960
|
||||
movz x0, #:abs_g3:fourpart
|
||||
// CHECK: mov x0, #20014547599360
|
||||
movz x0, #:abs_g2:threepart
|
||||
// CHECK: movk x0, #22136, lsl #32
|
||||
movk x0, #:abs_g2_nc:fourpart
|
||||
// CHECK: mov x0, #305397760
|
||||
movz x0, #:abs_g1:twopart
|
||||
// CHECK: movk x0, #37035, lsl #16
|
||||
movk x0, #:abs_g1_nc:fourpart
|
||||
// CHECK: mov x0, #4660
|
||||
movz x0, #:abs_g0:onepart
|
||||
// CHECK: movk x0, #52719
|
||||
movk x0, #:abs_g0_nc:fourpart
|
||||
|
||||
onepart = 0x1234
|
||||
twopart = 0x12345678
|
||||
threepart = 0x1234567890AB
|
||||
fourpart = 0x1234567890ABCDEF
|
|
@ -55,6 +55,19 @@
|
|||
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: fixup not sufficiently aligned
|
||||
b unaligned
|
||||
|
||||
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: fixup value out of range
|
||||
movz x0, #:abs_g0:value1
|
||||
|
||||
// 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
|
||||
movz x0, #:abs_g0_s:value1
|
||||
|
||||
// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: relocation for a thread-local variable points to an absolute symbol
|
||||
movz x0, #:tprel_g0:value1
|
||||
|
||||
|
||||
.byte 0
|
||||
unaligned:
|
||||
.byte 0
|
||||
|
@ -63,3 +76,5 @@ unaligned:
|
|||
.balign 8
|
||||
distant:
|
||||
.word 0
|
||||
value1 = 0x12345678
|
||||
value2 = 0x123456789
|
||||
|
|
Loading…
Reference in New Issue