[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
This commit is contained in:
parent
9fc422830a
commit
df3cb477a3
@ -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,
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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 },
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user