From bf48cd7c9650a885b051bbe8bed425434c88be4f Mon Sep 17 00:00:00 2001 From: Sudharsan Veeravalli Date: Thu, 3 Apr 2025 16:30:45 +0530 Subject: [PATCH] [RISCV] Add symbol support for the Xqcibi branch immediate instructions This patch adds support for parsing symbols in the Xqcibi branch immediate instructions. Vendor relocation support will be added in a later patch. --- .../RISCV/MCTargetDesc/RISCVAsmBackend.cpp | 3 ++ .../MCTargetDesc/RISCVELFObjectWriter.cpp | 2 + .../RISCV/MCTargetDesc/RISCVFixupKinds.h | 3 ++ .../RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp | 2 + llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td | 2 +- llvm/test/MC/RISCV/xqcibi-relocations.s | 44 +++++++++++++++++++ 6 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 llvm/test/MC/RISCV/xqcibi-relocations.s diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp index 37cd79e890263..10a26554ed672 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -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"); diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp index 5faeb98f0abf5..2e73ba54ae21b 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp @@ -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; } } diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h index 821372d3d39a6..df7916a4490b7 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h @@ -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, diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp index 69ad3d936fbbe..fc98859314680 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -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; } } diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td index 93eb82b012eb4..64d6f6d8f8bbf 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td @@ -550,7 +550,7 @@ class QCIBranchInst_rii funct3, DAGOperand InTyImm5, string opcodestr> class QCIBranchInst48_rii 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; diff --git a/llvm/test/MC/RISCV/xqcibi-relocations.s b/llvm/test/MC/RISCV/xqcibi-relocations.s new file mode 100644 index 0000000000000..4899e5f1eac46 --- /dev/null +++ b/llvm/test/MC/RISCV/xqcibi-relocations.s @@ -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