mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-17 18:16:42 +00:00
[RISCV] Add symbol parsing support for the Xqcibi branch immediate instructions (#134233)
This patch adds support for parsing symbols in the Xqcibi branch immediate instructions. While the 32 bit branch instructions use the same instruction format and relocation as the existing branch instructions in RISCV, the 48 bit ones use the `InstFormatQC_EB` instruction format and the `R_RISCV_QC_E_BRANCH` relocation that is defined in `BinaryFormat/ELFRelocs/RISCV_nonstandard.def.` Vendor relocation support will be added in a later patch.
This commit is contained in:
parent
7d05c2326c
commit
ae5306f30e
@ -92,6 +92,7 @@ RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
|
||||
{"fixup_riscv_tlsdesc_load_lo12", 20, 12, 0},
|
||||
{"fixup_riscv_tlsdesc_add_lo12", 20, 12, 0},
|
||||
{"fixup_riscv_tlsdesc_call", 0, 0, 0},
|
||||
{"fixup_riscv_qc_e_branch", 0, 48, MCFixupKindInfo::FKF_IsPCRel},
|
||||
};
|
||||
static_assert((std::size(Infos)) == RISCV::NumTargetFixupKinds,
|
||||
"Not all fixup kinds added to Infos array");
|
||||
@ -165,6 +166,7 @@ bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(
|
||||
// in the range [-2048, 2046].
|
||||
return Offset > 2046 || Offset < -2048;
|
||||
case RISCV::fixup_riscv_branch:
|
||||
case RISCV::fixup_riscv_qc_e_branch:
|
||||
// For conditional branch instructions the immediate must be
|
||||
// in the range [-4096, 4095].
|
||||
return !isInt<13>(Offset);
|
||||
@ -464,6 +466,7 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
|
||||
Value = (Sbit << 19) | (Lo10 << 9) | (Mid1 << 8) | Hi8;
|
||||
return Value;
|
||||
}
|
||||
case RISCV::fixup_riscv_qc_e_branch:
|
||||
case RISCV::fixup_riscv_branch: {
|
||||
if (!isInt<13>(Value))
|
||||
Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
|
||||
|
@ -120,6 +120,8 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
|
||||
return ELF::R_RISCV_CALL_PLT;
|
||||
case RISCV::fixup_riscv_call_plt:
|
||||
return ELF::R_RISCV_CALL_PLT;
|
||||
case RISCV::fixup_riscv_qc_e_branch:
|
||||
return ELF::R_RISCV_QC_E_BRANCH;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,9 @@ enum Fixups {
|
||||
fixup_riscv_tlsdesc_load_lo12,
|
||||
fixup_riscv_tlsdesc_add_lo12,
|
||||
fixup_riscv_tlsdesc_call,
|
||||
// 12-bit fixup for symbol references in the 48-bit Xqcibi branch immediate
|
||||
// instructions
|
||||
fixup_riscv_qc_e_branch,
|
||||
|
||||
// Used as a sentinel, must be the last
|
||||
fixup_riscv_invalid,
|
||||
|
@ -569,6 +569,8 @@ uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
|
||||
FixupKind = RISCV::fixup_riscv_rvc_branch;
|
||||
} else if (MIFrm == RISCVII::InstFormatI) {
|
||||
FixupKind = RISCV::fixup_riscv_12_i;
|
||||
} else if (MIFrm == RISCVII::InstFormatQC_EB) {
|
||||
FixupKind = RISCV::fixup_riscv_qc_e_branch;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -550,7 +550,7 @@ class QCIBranchInst_rii<bits<3> funct3, DAGOperand InTyImm5, string opcodestr>
|
||||
class QCIBranchInst48_rii<bits<5> funct5, DAGOperand InTyImm16, string opcodestr>
|
||||
: RVInst48<(outs),
|
||||
(ins GPRNoX0:$rs1, InTyImm16:$imm16, bare_simm13_lsb0:$imm12),
|
||||
opcodestr, "$rs1, $imm16, $imm12", [], InstFormatOther> {
|
||||
opcodestr, "$rs1, $imm16, $imm12", [], InstFormatQC_EB> {
|
||||
bits<5> rs1;
|
||||
bits<16> imm16;
|
||||
bits<12> imm12;
|
||||
|
44
llvm/test/MC/RISCV/xqcibi-relocations.s
Normal file
44
llvm/test/MC/RISCV/xqcibi-relocations.s
Normal file
@ -0,0 +1,44 @@
|
||||
# RUN: llvm-mc -triple riscv32 -mattr=+experimental-xqcibi %s -show-encoding \
|
||||
# RUN: | FileCheck -check-prefix=INSTR -check-prefix=FIXUP %s
|
||||
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcibi %s -o %t.o
|
||||
# RUN: llvm-readobj -r %t.o | FileCheck -check-prefix=RELOC %s
|
||||
|
||||
# Check prefixes:
|
||||
# RELOC - Check the relocation in the object.
|
||||
# FIXUP - Check the fixup on the instruction.
|
||||
# INSTR - Check the instruction is handled properly by the ASMPrinter.
|
||||
|
||||
.text
|
||||
|
||||
# Check that branch to an undefined symbol is handled
|
||||
# FIXME: This should be relaxed to an inverse branch and jump
|
||||
qc.bnei x6, 10, foo
|
||||
# RELOC: R_RISCV_BRANCH foo 0x0
|
||||
# INSTR: qc.bnei t1, 10, foo
|
||||
# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_branch
|
||||
|
||||
# FIXME: This should be relaxed to an inverse branch and jump
|
||||
qc.e.bgeui x8, 12, foo
|
||||
# RELOC: R_RISCV_CUSTOM193 foo 0x0
|
||||
# INSTR: qc.e.bgeui s0, 12, foo
|
||||
# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_qc_e_branch
|
||||
|
||||
# Check that a label in a different section is handled similar to an undefined symbol
|
||||
# FIXME: This should be relaxed to an inverse branch and jump
|
||||
qc.e.bltui x4, 9, .bar
|
||||
# RELOC: R_RISCV_CUSTOM193 .bar 0x0
|
||||
# INSTR: qc.e.bltui tp, 9, .bar
|
||||
# FIXUP: fixup A - offset: 0, value: .bar, kind: fixup_riscv_qc_e_branch
|
||||
|
||||
# Check that branches to a defined symbol are handled correctly
|
||||
qc.e.beqi x7, 8, .L1
|
||||
# INSTR: qc.e.beqi t2, 8, .L1
|
||||
# FIXUP: fixup A - offset: 0, value: .L1, kind: fixup_riscv_qc_e_branch
|
||||
|
||||
.L1:
|
||||
ret
|
||||
|
||||
.section .t2
|
||||
|
||||
.bar:
|
||||
ret
|
Loading…
x
Reference in New Issue
Block a user