From df3cb477a314a3c3abbbfbbfa2e88245bcfa325f Mon Sep 17 00:00:00 2001 From: Lewis Revill Date: Tue, 23 Apr 2019 14:46:13 +0000 Subject: [PATCH] [RISCV] Support assembling %tls_{ie,gd}_pcrel_hi modifiers This patch adds support for parsing and assembling the %tls_ie_pcrel_hi and %tls_gd_pcrel_hi modifiers. Differential Revision: https://reviews.llvm.org/D55342 llvm-svn: 358994 --- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 13 ++++++--- .../Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp | 6 ++++ .../Target/RISCV/MCTargetDesc/RISCVAsmBackend.h | 2 ++ .../RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp | 4 +++ .../Target/RISCV/MCTargetDesc/RISCVFixupKinds.h | 6 ++++ .../RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp | 6 ++++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp | 13 +++++++++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h | 2 ++ llvm/test/MC/RISCV/relocations.s | 32 ++++++++++++++++++++++ llvm/test/MC/RISCV/rv32i-invalid.s | 12 ++++---- 10 files changed, 86 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index a7580c5..c6b633a 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -552,11 +552,15 @@ public: if (!IsConstantImm) { IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); return IsValid && (VK == RISCVMCExpr::VK_RISCV_PCREL_HI || - VK == RISCVMCExpr::VK_RISCV_GOT_HI); + VK == RISCVMCExpr::VK_RISCV_GOT_HI || + VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI || + VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI); } else { return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None || VK == RISCVMCExpr::VK_RISCV_PCREL_HI || - VK == RISCVMCExpr::VK_RISCV_GOT_HI); + VK == RISCVMCExpr::VK_RISCV_GOT_HI || + VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI || + VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI); } } @@ -910,8 +914,9 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_InvalidUImm20AUIPC: return generateImmOutOfRangeError( Operands, ErrorInfo, 0, (1 << 20) - 1, - "operand must be a symbol with a %pcrel_hi/%got_pcrel_hi modifier " - "or an integer in the range"); + "operand must be a symbol with a " + "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or " + "an integer in the range"); case Match_InvalidSImm21Lsb0JAL: return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp index c57eb73..633ff84 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -34,6 +34,8 @@ bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm, default: break; case RISCV::fixup_riscv_got_hi20: + case RISCV::fixup_riscv_tls_got_hi20: + case RISCV::fixup_riscv_tls_gd_hi20: return true; case RISCV::fixup_riscv_pcrel_lo12_i: case RISCV::fixup_riscv_pcrel_lo12_s: @@ -51,6 +53,8 @@ bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm, llvm_unreachable("Unexpected fixup kind for pcrel_lo12"); break; case RISCV::fixup_riscv_got_hi20: + case RISCV::fixup_riscv_tls_got_hi20: + case RISCV::fixup_riscv_tls_gd_hi20: ShouldForce = true; break; case RISCV::fixup_riscv_pcrel_hi20: @@ -179,6 +183,8 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, default: llvm_unreachable("Unknown fixup kind!"); case RISCV::fixup_riscv_got_hi20: + case RISCV::fixup_riscv_tls_got_hi20: + case RISCV::fixup_riscv_tls_gd_hi20: llvm_unreachable("Relocation should be unconditionally forced\n"); case FK_Data_1: case FK_Data_2: diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h index f16bd4e..254249c 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h @@ -109,6 +109,8 @@ public: { "fixup_riscv_tprel_lo12_i", 20, 12, 0 }, { "fixup_riscv_tprel_lo12_s", 0, 32, 0 }, { "fixup_riscv_tprel_add", 0, 0, 0 }, + { "fixup_riscv_tls_got_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_riscv_tls_gd_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_riscv_jal", 12, 20, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_riscv_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_riscv_rvc_jump", 2, 11, MCFixupKindInfo::FKF_IsPCRel }, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp index e649776..c910f2c 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp @@ -93,6 +93,10 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx, return ELF::R_RISCV_TPREL_LO12_S; case RISCV::fixup_riscv_tprel_add: return ELF::R_RISCV_TPREL_ADD; + case RISCV::fixup_riscv_tls_got_hi20: + return ELF::R_RISCV_TLS_GOT_HI20; + case RISCV::fixup_riscv_tls_gd_hi20: + return ELF::R_RISCV_TLS_GD_HI20; case RISCV::fixup_riscv_jal: return ELF::R_RISCV_JAL; case RISCV::fixup_riscv_branch: diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h index e33183e..6c79333 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h @@ -49,6 +49,12 @@ enum Fixups { // fixup_riscv_tprel_add - A fixup corresponding to %tprel_add(foo) for the // add_tls instruction. Used to provide a hint to the linker. fixup_riscv_tprel_add, + // fixup_riscv_tls_got_hi20 - 20-bit fixup corresponding to + // tls_ie_pcrel_hi(foo) for instructions like auipc + fixup_riscv_tls_got_hi20, + // fixup_riscv_tls_gd_hi20 - 20-bit fixup corresponding to + // tls_gd_pcrel_hi(foo) for instructions like auipc + fixup_riscv_tls_gd_hi20, // fixup_riscv_jal - 20-bit fixup for symbol references in the jal // instruction fixup_riscv_jal, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp index f1248e5..32e9f4e 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -307,6 +307,12 @@ unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo, FixupKind = RISCV::fixup_riscv_tprel_hi20; RelaxCandidate = true; break; + case RISCVMCExpr::VK_RISCV_TLS_GOT_HI: + FixupKind = RISCV::fixup_riscv_tls_got_hi20; + break; + case RISCVMCExpr::VK_RISCV_TLS_GD_HI: + FixupKind = RISCV::fixup_riscv_tls_gd_hi20; + break; case RISCVMCExpr::VK_RISCV_CALL: FixupKind = RISCV::fixup_riscv_call; RelaxCandidate = true; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp index 6ccabee..ae25ec8 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp @@ -78,6 +78,8 @@ const MCFixup *RISCVMCExpr::getPCRelHiFixup() const { default: continue; case RISCV::fixup_riscv_got_hi20: + case RISCV::fixup_riscv_tls_got_hi20: + case RISCV::fixup_riscv_tls_gd_hi20: case RISCV::fixup_riscv_pcrel_hi20: return &F; } @@ -166,6 +168,8 @@ bool RISCVMCExpr::evaluateAsRelocatableImpl(MCValue &Res, case VK_RISCV_TPREL_LO: case VK_RISCV_TPREL_HI: case VK_RISCV_TPREL_ADD: + case VK_RISCV_TLS_GOT_HI: + case VK_RISCV_TLS_GD_HI: return false; } } @@ -187,6 +191,8 @@ RISCVMCExpr::VariantKind RISCVMCExpr::getVariantKindForName(StringRef name) { .Case("tprel_lo", VK_RISCV_TPREL_LO) .Case("tprel_hi", VK_RISCV_TPREL_HI) .Case("tprel_add", VK_RISCV_TPREL_ADD) + .Case("tls_ie_pcrel_hi", VK_RISCV_TLS_GOT_HI) + .Case("tls_gd_pcrel_hi", VK_RISCV_TLS_GD_HI) .Default(VK_RISCV_Invalid); } @@ -210,6 +216,10 @@ StringRef RISCVMCExpr::getVariantKindName(VariantKind Kind) { return "tprel_hi"; case VK_RISCV_TPREL_ADD: return "tprel_add"; + case VK_RISCV_TLS_GOT_HI: + return "tls_ie_pcrel_hi"; + case VK_RISCV_TLS_GD_HI: + return "tls_gd_pcrel_hi"; } } @@ -247,6 +257,8 @@ void RISCVMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { default: return; case VK_RISCV_TPREL_HI: + case VK_RISCV_TLS_GOT_HI: + case VK_RISCV_TLS_GD_HI: break; } @@ -259,6 +271,7 @@ bool RISCVMCExpr::evaluateAsConstant(int64_t &Res) const { if (Kind == VK_RISCV_PCREL_HI || Kind == VK_RISCV_PCREL_LO || Kind == VK_RISCV_GOT_HI || Kind == VK_RISCV_TPREL_HI || Kind == VK_RISCV_TPREL_LO || Kind == VK_RISCV_TPREL_ADD || + Kind == VK_RISCV_TLS_GOT_HI || Kind == VK_RISCV_TLS_GD_HI || Kind == VK_RISCV_CALL || Kind == VK_RISCV_CALL_PLT) return false; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h index 5846811..b5a292d 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h @@ -32,6 +32,8 @@ public: VK_RISCV_TPREL_LO, VK_RISCV_TPREL_HI, VK_RISCV_TPREL_ADD, + VK_RISCV_TLS_GOT_HI, + VK_RISCV_TLS_GD_HI, VK_RISCV_CALL, VK_RISCV_CALL_PLT, VK_RISCV_Invalid diff --git a/llvm/test/MC/RISCV/relocations.s b/llvm/test/MC/RISCV/relocations.s index 44a5d08..10a2890 100644 --- a/llvm/test/MC/RISCV/relocations.s +++ b/llvm/test/MC/RISCV/relocations.s @@ -129,6 +129,38 @@ sb t1, %pcrel_lo(.L2)(a2) # INSTR: sb t1, %pcrel_lo(.L2)(a2) # FIXUP: fixup A - offset: 0, value: %pcrel_lo(.L2), kind: fixup_riscv_pcrel_lo12_s +.L3: +auipc t1, %tls_ie_pcrel_hi(foo) +# RELOC: R_RISCV_TLS_GOT_HI20 foo 0x0 +# INSTR: auipc t1, %tls_ie_pcrel_hi(foo) +# FIXUP: fixup A - offset: 0, value: %tls_ie_pcrel_hi(foo), kind: fixup_riscv_tls_got_hi20 + +addi t1, t1, %pcrel_lo(.L3) +# RELOC: R_RISCV_PCREL_LO12_I .L3 0x0 +# INSTR: addi t1, t1, %pcrel_lo(.L3) +# FIXUP: fixup A - offset: 0, value: %pcrel_lo(.L3), kind: fixup_riscv_pcrel_lo12_i + +sb t1, %pcrel_lo(.L3)(a2) +# RELOC: R_RISCV_PCREL_LO12_S .L3 0x0 +# INSTR: sb t1, %pcrel_lo(.L3)(a2) +# FIXUP: fixup A - offset: 0, value: %pcrel_lo(.L3), kind: fixup_riscv_pcrel_lo12_s + +.L4: +auipc t1, %tls_gd_pcrel_hi(foo) +# RELOC: R_RISCV_TLS_GD_HI20 foo 0x0 +# INSTR: auipc t1, %tls_gd_pcrel_hi(foo) +# FIXUP: fixup A - offset: 0, value: %tls_gd_pcrel_hi(foo), kind: fixup_riscv_tls_gd_hi20 + +addi t1, t1, %pcrel_lo(.L4) +# RELOC: R_RISCV_PCREL_LO12_I .L4 0x0 +# INSTR: addi t1, t1, %pcrel_lo(.L4) +# FIXUP: fixup A - offset: 0, value: %pcrel_lo(.L4), kind: fixup_riscv_pcrel_lo12_i + +sb t1, %pcrel_lo(.L4)(a2) +# RELOC: R_RISCV_PCREL_LO12_S .L4 0x0 +# INSTR: sb t1, %pcrel_lo(.L4)(a2) +# FIXUP: fixup A - offset: 0, value: %pcrel_lo(.L4), kind: fixup_riscv_pcrel_lo12_s + add t1, t1, tp, %tprel_add(foo) # RELOC: R_RISCV_TPREL_ADD foo 0x0 # INSTR: add t1, t1, tp, %tprel_add(foo) diff --git a/llvm/test/MC/RISCV/rv32i-invalid.s b/llvm/test/MC/RISCV/rv32i-invalid.s index dcd9b96..e8be186 100644 --- a/llvm/test/MC/RISCV/rv32i-invalid.s +++ b/llvm/test/MC/RISCV/rv32i-invalid.s @@ -40,7 +40,7 @@ bgeu t0, t1, -13 # CHECK: :[[@LINE]]:14: error: immediate must be a multiple of ## uimm20 lui a0, -1 # CHECK: :[[@LINE]]:9: error: operand must be a symbol with %hi/%tprel_hi modifier or an integer in the range [0, 1048575] lui s0, 1048576 # CHECK: :[[@LINE]]:9: error: operand must be a symbol with %hi/%tprel_hi modifier or an integer in the range [0, 1048575] -auipc zero, -0xf # CHECK: :[[@LINE]]:13: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi modifier or an integer in the range [0, 1048575] +auipc zero, -0xf # CHECK: :[[@LINE]]:13: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or an integer in the range [0, 1048575] ## simm21_lsb0 jal gp, -1048578 # CHECK: :[[@LINE]]:9: error: immediate must be a multiple of 2 bytes in the range [-1048576, 1048574] @@ -105,7 +105,7 @@ bgeu t0, t1, %pcrel_lo(d) # CHECK: :[[@LINE]]:14: error: immediate must be a mul ## uimm20 lui a0, %lo(1) # CHECK: :[[@LINE]]:9: error: operand must be a symbol with %hi/%tprel_hi modifier or an integer in the range [0, 1048575] -auipc a1, %lo(foo) # CHECK: :[[@LINE]]:11: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi modifier or an integer in the range [0, 1048575] +auipc a1, %lo(foo) # CHECK: :[[@LINE]]:11: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or an integer in the range [0, 1048575] ## simm21_lsb0 jal gp, %lo(1) # CHECK: :[[@LINE]]:9: error: immediate must be a multiple of 2 bytes in the range [-1048576, 1048574] @@ -125,10 +125,10 @@ lui a0, %lo(foo) # CHECK: :[[@LINE]]:9: error: operand must be a symbol with %hi lui a0, %pcrel_lo(foo) # CHECK: :[[@LINE]]:9: error: operand must be a symbol with %hi/%tprel_hi modifier or an integer in the range [0, 1048575] lui a0, %pcrel_hi(foo) # CHECK: :[[@LINE]]:9: error: operand must be a symbol with %hi/%tprel_hi modifier or an integer in the range [0, 1048575] -auipc a0, foo # CHECK: :[[@LINE]]:11: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi modifier or an integer in the range [0, 1048575] -auipc a0, %lo(foo) # CHECK: :[[@LINE]]:11: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi modifier or an integer in the range [0, 1048575] -auipc a0, %hi(foo) # CHECK: :[[@LINE]]:11: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi modifier or an integer in the range [0, 1048575] -auipc a0, %pcrel_lo(foo) # CHECK: :[[@LINE]]:11: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi modifier or an integer in the range [0, 1048575] +auipc a0, foo # CHECK: :[[@LINE]]:11: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or an integer in the range [0, 1048575] +auipc a0, %lo(foo) # CHECK: :[[@LINE]]:11: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or an integer in the range [0, 1048575] +auipc a0, %hi(foo) # CHECK: :[[@LINE]]:11: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or an integer in the range [0, 1048575] +auipc a0, %pcrel_lo(foo) # CHECK: :[[@LINE]]:11: error: operand must be a symbol with a %pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or an integer in the range [0, 1048575] # TP-relative symbol names require a %tprel_add modifier. add a0, a0, tp, zero # CHECK: :[[@LINE]]:17: error: expected '%' for operand modifier -- 2.7.4