Skip to content

Commit ae5306f

Browse files
authored
[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.
1 parent 7d05c23 commit ae5306f

File tree

6 files changed

+55
-1
lines changed

6 files changed

+55
-1
lines changed

llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
9292
{"fixup_riscv_tlsdesc_load_lo12", 20, 12, 0},
9393
{"fixup_riscv_tlsdesc_add_lo12", 20, 12, 0},
9494
{"fixup_riscv_tlsdesc_call", 0, 0, 0},
95+
{"fixup_riscv_qc_e_branch", 0, 48, MCFixupKindInfo::FKF_IsPCRel},
9596
};
9697
static_assert((std::size(Infos)) == RISCV::NumTargetFixupKinds,
9798
"Not all fixup kinds added to Infos array");
@@ -165,6 +166,7 @@ bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(
165166
// in the range [-2048, 2046].
166167
return Offset > 2046 || Offset < -2048;
167168
case RISCV::fixup_riscv_branch:
169+
case RISCV::fixup_riscv_qc_e_branch:
168170
// For conditional branch instructions the immediate must be
169171
// in the range [-4096, 4095].
170172
return !isInt<13>(Offset);
@@ -464,6 +466,7 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
464466
Value = (Sbit << 19) | (Lo10 << 9) | (Mid1 << 8) | Hi8;
465467
return Value;
466468
}
469+
case RISCV::fixup_riscv_qc_e_branch:
467470
case RISCV::fixup_riscv_branch: {
468471
if (!isInt<13>(Value))
469472
Ctx.reportError(Fixup.getLoc(), "fixup value out of range");

llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
120120
return ELF::R_RISCV_CALL_PLT;
121121
case RISCV::fixup_riscv_call_plt:
122122
return ELF::R_RISCV_CALL_PLT;
123+
case RISCV::fixup_riscv_qc_e_branch:
124+
return ELF::R_RISCV_QC_E_BRANCH;
123125
}
124126
}
125127

llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ enum Fixups {
7777
fixup_riscv_tlsdesc_load_lo12,
7878
fixup_riscv_tlsdesc_add_lo12,
7979
fixup_riscv_tlsdesc_call,
80+
// 12-bit fixup for symbol references in the 48-bit Xqcibi branch immediate
81+
// instructions
82+
fixup_riscv_qc_e_branch,
8083

8184
// Used as a sentinel, must be the last
8285
fixup_riscv_invalid,

llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,8 @@ uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
569569
FixupKind = RISCV::fixup_riscv_rvc_branch;
570570
} else if (MIFrm == RISCVII::InstFormatI) {
571571
FixupKind = RISCV::fixup_riscv_12_i;
572+
} else if (MIFrm == RISCVII::InstFormatQC_EB) {
573+
FixupKind = RISCV::fixup_riscv_qc_e_branch;
572574
}
573575
}
574576

llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ class QCIBranchInst_rii<bits<3> funct3, DAGOperand InTyImm5, string opcodestr>
550550
class QCIBranchInst48_rii<bits<5> funct5, DAGOperand InTyImm16, string opcodestr>
551551
: RVInst48<(outs),
552552
(ins GPRNoX0:$rs1, InTyImm16:$imm16, bare_simm13_lsb0:$imm12),
553-
opcodestr, "$rs1, $imm16, $imm12", [], InstFormatOther> {
553+
opcodestr, "$rs1, $imm16, $imm12", [], InstFormatQC_EB> {
554554
bits<5> rs1;
555555
bits<16> imm16;
556556
bits<12> imm12;
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# RUN: llvm-mc -triple riscv32 -mattr=+experimental-xqcibi %s -show-encoding \
2+
# RUN: | FileCheck -check-prefix=INSTR -check-prefix=FIXUP %s
3+
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcibi %s -o %t.o
4+
# RUN: llvm-readobj -r %t.o | FileCheck -check-prefix=RELOC %s
5+
6+
# Check prefixes:
7+
# RELOC - Check the relocation in the object.
8+
# FIXUP - Check the fixup on the instruction.
9+
# INSTR - Check the instruction is handled properly by the ASMPrinter.
10+
11+
.text
12+
13+
# Check that branch to an undefined symbol is handled
14+
# FIXME: This should be relaxed to an inverse branch and jump
15+
qc.bnei x6, 10, foo
16+
# RELOC: R_RISCV_BRANCH foo 0x0
17+
# INSTR: qc.bnei t1, 10, foo
18+
# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_branch
19+
20+
# FIXME: This should be relaxed to an inverse branch and jump
21+
qc.e.bgeui x8, 12, foo
22+
# RELOC: R_RISCV_CUSTOM193 foo 0x0
23+
# INSTR: qc.e.bgeui s0, 12, foo
24+
# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_qc_e_branch
25+
26+
# Check that a label in a different section is handled similar to an undefined symbol
27+
# FIXME: This should be relaxed to an inverse branch and jump
28+
qc.e.bltui x4, 9, .bar
29+
# RELOC: R_RISCV_CUSTOM193 .bar 0x0
30+
# INSTR: qc.e.bltui tp, 9, .bar
31+
# FIXUP: fixup A - offset: 0, value: .bar, kind: fixup_riscv_qc_e_branch
32+
33+
# Check that branches to a defined symbol are handled correctly
34+
qc.e.beqi x7, 8, .L1
35+
# INSTR: qc.e.beqi t2, 8, .L1
36+
# FIXUP: fixup A - offset: 0, value: .L1, kind: fixup_riscv_qc_e_branch
37+
38+
.L1:
39+
ret
40+
41+
.section .t2
42+
43+
.bar:
44+
ret

0 commit comments

Comments
 (0)