Sparc: Refactor R_SPARC_13/R_SPARC_GOT13 handling and fix a bug referencing absolute symbol https://reviews.llvm.org/D47136 did not correctly handle `ld [%i0 + abs], %o0; abs = 7` To fix it and make fixup handling less hacky, * Change TableGen MEMri to use simm13Op instead of i32imm * Emit a fixup of kind fixup_sparc_13 in SparcMCCodeEmitter::getSImm13OpValue * Convert fixup_sparc_13 to either R_SPARC_13/R_SPARC_GOT13 in getRelocType This postpones 13/GOT13 decision to relocation generation, ensuring that we suppress the relocation when referencing an absolute symbol, matching gas.
diff --git a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp index 8a73093..78fc1da 100644 --- a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +++ b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
@@ -1480,18 +1480,8 @@ if (getParser().parseExpression(EVal, E)) break; - int64_t Res; - if (!EVal->evaluateAsAbsolute(Res)) { - SparcMCExpr::Specifier Kind = SparcMCExpr::VK_13; - - if (getContext().getObjectFileInfo()->isPositionIndependent()) { - if (isCall) - Kind = SparcMCExpr::VK_WPLT30; - else - Kind = SparcMCExpr::VK_GOT13; - } - EVal = SparcMCExpr::create(Kind, EVal, getContext()); - } + if (isCall && getContext().getObjectFileInfo()->isPositionIndependent()) + EVal = SparcMCExpr::create(SparcMCExpr::VK_WPLT30, EVal, getContext()); Op = SparcOperand::CreateImm(EVal, S, E); break; }
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp index 0c0f49f..1ed5313 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
@@ -9,8 +9,10 @@ #include "MCTargetDesc/SparcFixupKinds.h" #include "MCTargetDesc/SparcMCExpr.h" #include "MCTargetDesc/SparcMCTargetDesc.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/ErrorHandling.h" @@ -110,7 +112,11 @@ case FK_Data_8: return ((Fixup.getOffset() % 8) ? ELF::R_SPARC_UA64 : ELF::R_SPARC_64); - case Sparc::fixup_sparc_13: return ELF::R_SPARC_13; + case Sparc::fixup_sparc_13: + if (Ctx.getObjectFileInfo()->isPositionIndependent()) + return ELF::R_SPARC_GOT13; + return ELF::R_SPARC_13; + case Sparc::fixup_sparc_hi22: return ELF::R_SPARC_HI22; case Sparc::fixup_sparc_lo10: return ELF::R_SPARC_LO10; case Sparc::fixup_sparc_h44: return ELF::R_SPARC_H44;
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp index b23cc16..3aaedef 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
@@ -163,10 +163,7 @@ Fixups.push_back(MCFixup::create(0, Expr, SExpr->getFixupKind())); return 0; } - uint16_t Kind = Sparc::fixup_sparc_13; - if (Ctx.getObjectFileInfo()->isPositionIndependent()) - Kind = ELF::R_SPARC_GOT13; - Fixups.push_back(MCFixup::create(0, Expr, Kind)); + Fixups.push_back(MCFixup::create(0, Expr, Sparc::fixup_sparc_13)); return 0; }
diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td index 0c89072..5617681 100644 --- a/llvm/lib/Target/Sparc/SparcInstrInfo.td +++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td
@@ -145,6 +145,12 @@ let ParserMethod = "parseMEMOperand"; } +def simm13Op : Operand<iPTR> { + let OperandType = "OPERAND_IMMEDIATE"; + let DecoderMethod = "DecodeSIMM13"; + let EncoderMethod = "getSImm13OpValue"; +} + def MEMrr : Operand<iPTR> { let PrintMethod = "printMemOperand"; let MIOperandInfo = (ops ptr_rc, ptr_rc); @@ -152,7 +158,7 @@ } def MEMri : Operand<iPTR> { let PrintMethod = "printMemOperand"; - let MIOperandInfo = (ops ptr_rc, i32imm); + let MIOperandInfo = (ops ptr_rc, simm13Op); let ParserMatchClass = SparcMEMriAsmOperand; } @@ -234,12 +240,6 @@ let ParserMatchClass = SparcCallTargetAsmOperand; } -def simm13Op : Operand<iPTR> { - let OperandType = "OPERAND_IMMEDIATE"; - let DecoderMethod = "DecodeSIMM13"; - let EncoderMethod = "getSImm13OpValue"; -} - // Operand for printing out a condition code. let PrintMethod = "printCCOperand" in { def CCOp : Operand<i32>;
diff --git a/llvm/test/MC/Sparc/sparc-fixups.s b/llvm/test/MC/Sparc/sparc-fixups.s index 18224d6..e77f56e 100644 --- a/llvm/test/MC/Sparc/sparc-fixups.s +++ b/llvm/test/MC/Sparc/sparc-fixups.s
@@ -1,34 +1,40 @@ -! RUN: llvm-mc %s -triple=sparcv9 -filetype=obj | llvm-objdump -dr - | FileCheck %s +# RUN: llvm-mc %s -triple=sparcv9 -filetype=obj | llvm-objdump -dr - | FileCheck %s --check-prefixes=NOPIC,CHECK +# RUN: llvm-mc %s -triple=sparcv9 -filetype=obj -position-independent | llvm-objdump -dr - | FileCheck %s .text -! Check that fixups are correctly applied. +# Check that fixups are correctly applied. .set sym, 0xfedcba98 -! CHECK: sethi 0x3fb72e, %o0 -! CHECK-NEXT: xor %o0, 0x298, %o0 -! CHECK-NEXT: sethi 0x3b72ea, %o1 -! CHECK-NEXT: xor %o0, 0x188, %o1 +## FIXME: Don't emit GOT relocations when -position-independent is specified. +# NOPIC: sethi 0x3fb72e, %o0 +# NOPIC-NEXT: xor %o0, 0x298, %o0 +# NOPIC-NEXT: sethi 0x3b72ea, %o1 +# NOPIC-NEXT: xor %o0, 0x188, %o1 sethi %hi(sym), %o0 xor %o0, %lo(sym), %o0 sethi %hi(-0x12345678), %o1 xor %o0, %lo(-0x12345678), %o1 -! CHECK: sethi 0x3fb, %o0 -! CHECK-NEXT: or %o0, 0x1cb, %o0 -! CHECK-NEXT: ld [%o0+0xa98], %o0 +# CHECK: ld [%i0+0x7], %o0 +ld [%i0 + abs], %o0 +abs = 7 + +# CHECK-NEXT: sethi 0x3fb, %o0 +# CHECK-NEXT: or %o0, 0x1cb, %o0 +# CHECK-NEXT: ld [%o0+0xa98], %o0 sethi %h44(sym), %o0 or %o0, %m44(sym), %o0 ld [%o0 + %l44(sym)], %o0 -! CHECK: sethi 0x0, %o0 -! CHECK-NEXT: sethi 0x3fb72e, %o0 -! CHECK-NEXT: or %o0, 0x0, %o0 +# CHECK-NEXT: sethi 0x0, %o0 +# CHECK-NEXT: sethi 0x3fb72e, %o0 +# CHECK-NEXT: or %o0, 0x0, %o0 sethi %hh(sym), %o0 sethi %lm(sym), %o0 or %o0, %hm(sym), %o0 -! CHECK: sethi 0x48d1, %o0 -! CHECK-NEXT: xor %o0, -0x168, %o0 +# CHECK-NEXT: sethi 0x48d1, %o0 +# CHECK-NEXT: xor %o0, -0x168, %o0 sethi %hix(sym), %o0 xor %o0, %lox(sym), %o0