[llvm] [RISCV] Add symbol parsing support for Xqcili load large immediate instructions (PR #134581)
Sudharsan Veeravalli via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 8 20:51:12 PDT 2025
https://github.com/svs-quic updated https://github.com/llvm/llvm-project/pull/134581
>From 2e0d42c525af51a956e97e46aca09982ec6332b8 Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <quic_svs at quicinc.com>
Date: Mon, 7 Apr 2025 10:57:02 +0530
Subject: [PATCH 1/4] [RISCV] Add symbol parsing support for Xqcili load larget
immediate instructions
This patch adds support for parsing symbols in the Xqcili load larget immediate
instructions. The 32 bit qc.li instructions uses the R_RISCV_QC_ABS20_U relocation
while the 48 bit qc.e.li instruction uses the R_RISCV_QC_E_32 relocation and the
InstFormatQC_EAI instruction format.
Vendor relocation support will be added in a later patch.
---
.../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 36 ++++++++++++--
.../RISCV/MCTargetDesc/RISCVAsmBackend.cpp | 17 ++++++-
.../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 2 +-
.../MCTargetDesc/RISCVELFObjectWriter.cpp | 4 ++
.../RISCV/MCTargetDesc/RISCVFixupKinds.h | 4 ++
.../RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp | 5 ++
.../Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp | 3 ++
.../Target/RISCV/MCTargetDesc/RISCVMCExpr.h | 1 +
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 4 +-
llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td | 19 +++++--
llvm/test/MC/RISCV/xqcili-invalid.s | 2 +-
llvm/test/MC/RISCV/xqcili-relocations.s | 49 +++++++++++++++++++
12 files changed, 133 insertions(+), 13 deletions(-)
create mode 100644 llvm/test/MC/RISCV/xqcili-relocations.s
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index dba78fef0bad8..c682722cdb701 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -794,9 +794,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
bool isSImm6() const { return isSImm<6>(); }
bool isSImm11() const { return isSImm<11>(); }
bool isSImm16() const { return isSImm<16>(); }
- bool isSImm20() const { return isSImm<20>(); }
bool isSImm26() const { return isSImm<26>(); }
- bool isSImm32() const { return isSImm<32>(); }
bool isSImm5NonZero() const {
return isSImmPred([](int64_t Imm) { return Imm != 0 && isInt<5>(Imm); });
@@ -876,6 +874,32 @@ struct RISCVOperand final : public MCParsedAsmOperand {
return isUImmPred([](int64_t Imm) { return isUInt<16>(Imm) && Imm != 0; });
}
+ bool isSImm20LI() const {
+ if (!isImm())
+ return false;
+
+ int64_t Imm;
+ if (evaluateConstantImm(getImm(), Imm))
+ return isInt<20>(fixImmediateForRV32(Imm, isRV64Imm()));
+
+ RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
+ return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
+ VK == RISCVMCExpr::VK_QC_ABS20;
+ }
+
+ bool isSImm32() const {
+ if (!isImm())
+ return false;
+
+ int64_t Imm;
+ if (evaluateConstantImm(getImm(), Imm))
+ return isInt<32>(fixImmediateForRV32(Imm, isRV64Imm()));
+
+ RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
+ return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
+ VK == RISCVMCExpr::VK_None;
+ }
+
bool isUImm20LUI() const {
if (!isImm())
return false;
@@ -1519,6 +1543,11 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1,
"immediate must be non-zero in the range");
+ case Match_InvalidSImm20LI:
+ return generateImmOutOfRangeError(
+ Operands, ErrorInfo, -(1 << 19), (1 << 19) - 1,
+ "operand must be a symbol with a %qc.abs20 specifier or an integer "
+ " in the range");
case Match_InvalidUImm20LUI:
return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 20) - 1,
@@ -1555,9 +1584,6 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidSImm26:
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 25),
(1 << 25) - 1);
- case Match_InvalidSImm20:
- return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 19),
- (1 << 19) - 1);
case Match_InvalidSImm32:
return generateImmOutOfRangeError(Operands, ErrorInfo,
std::numeric_limits<int32_t>::min(),
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index 6641116db9a19..9ae6ba04f262e 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -93,6 +93,8 @@ RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
{"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},
+ {"fixup_riscv_qc_e_32", 16, 32, 0},
+ {"fixup_riscv_qc_abs20_u", 12, 20, 0},
};
static_assert((std::size(Infos)) == RISCV::NumTargetFixupKinds,
"Not all fixup kinds added to Infos array");
@@ -559,7 +561,20 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
(Bit5 << 2);
return Value;
}
-
+ case RISCV::fixup_riscv_qc_e_32: {
+ if (!isInt<32>(Value))
+ Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
+ return ((Value & 0xffffffff) << 16);
+ }
+ case RISCV::fixup_riscv_qc_abs20_u: {
+ if (!isInt<20>(Value))
+ Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
+ uint64_t Bit20 = (Value >> 20) & 0x1;
+ uint64_t Bit15_1 = (Value >> 1) & 0x7fff;
+ uint64_t Bit19_16 = (Value >> 16) & 0xf;
+ Value = (Bit20 << 31) | (Bit15_1 << 16) | (Bit19_16 << 12);
+ return Value;
+ }
}
}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 506c638c83a72..17b99f26a1b8c 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -340,7 +340,7 @@ enum OperandType : unsigned {
OPERAND_SIMM12_LSB00000,
OPERAND_SIMM16,
OPERAND_SIMM16_NONZERO,
- OPERAND_SIMM20,
+ OPERAND_SIMM20_LI,
OPERAND_SIMM26,
OPERAND_SIMM32,
OPERAND_CLUI_IMM,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
index 5fdf8e23d1214..9859bf39bcc5e 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
@@ -173,6 +173,10 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
return ELF::R_RISCV_RELAX;
case RISCV::fixup_riscv_align:
return ELF::R_RISCV_ALIGN;
+ case RISCV::fixup_riscv_qc_e_32:
+ return ELF::R_RISCV_QC_E_32;
+ case RISCV::fixup_riscv_qc_abs20_u:
+ return ELF::R_RISCV_QC_ABS20_U;
}
}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
index df7916a4490b7..a4f5673fca225 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
@@ -80,6 +80,10 @@ enum Fixups {
// 12-bit fixup for symbol references in the 48-bit Xqcibi branch immediate
// instructions
fixup_riscv_qc_e_branch,
+ // 32-bit fixup for symbol references in the 48-bit qc.e.li instruction
+ fixup_riscv_qc_e_32,
+ // 20-bit fixup for symbol references in the 32-bit qc.li instruction
+ fixup_riscv_qc_abs20_u,
// 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 37a2ac336d20c..95858da45f202 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
@@ -653,6 +653,9 @@ uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
case RISCVMCExpr::VK_TLSDESC_CALL:
FixupKind = RISCV::fixup_riscv_tlsdesc_call;
break;
+ case RISCVMCExpr::VK_QC_ABS20:
+ FixupKind = RISCV::fixup_riscv_qc_abs20_u;
+ break;
}
} else if (Kind == MCExpr::SymbolRef || Kind == MCExpr::Binary) {
// FIXME: Sub kind binary exprs have chance of underflow.
@@ -668,6 +671,8 @@ uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
FixupKind = RISCV::fixup_riscv_12_i;
} else if (MIFrm == RISCVII::InstFormatQC_EB) {
FixupKind = RISCV::fixup_riscv_qc_e_branch;
+ } else if (MIFrm == RISCVII::InstFormatQC_EAI) {
+ FixupKind = RISCV::fixup_riscv_qc_e_32;
}
}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp
index a48dca7be0d28..d6650e156c8b3 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp
@@ -116,6 +116,7 @@ RISCVMCExpr::getSpecifierForName(StringRef name) {
.Case("tlsdesc_load_lo", VK_TLSDESC_LOAD_LO)
.Case("tlsdesc_add_lo", VK_TLSDESC_ADD_LO)
.Case("tlsdesc_call", VK_TLSDESC_CALL)
+ .Case("qc.abs20", VK_QC_ABS20)
// Used in data directives
.Case("pltpcrel", VK_PLTPCREL)
.Case("gotpcrel", VK_GOTPCREL)
@@ -164,6 +165,8 @@ StringRef RISCVMCExpr::getSpecifierName(Specifier S) {
return "gotpcrel";
case VK_PLTPCREL:
return "pltpcrel";
+ case VK_QC_ABS20:
+ return "qc.abs20";
}
llvm_unreachable("Invalid ELF symbol kind");
}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h
index fd6993c18d820..e0aa7ff244521 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h
@@ -43,6 +43,7 @@ class RISCVMCExpr : public MCTargetExpr {
VK_TLSDESC_LOAD_LO,
VK_TLSDESC_ADD_LO,
VK_TLSDESC_CALL,
+ VK_QC_ABS20,
};
private:
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 44894365b6d41..3eca78bb063f3 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -2654,7 +2654,6 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
CASE_OPERAND_SIMM(6)
CASE_OPERAND_SIMM(11)
CASE_OPERAND_SIMM(12)
- CASE_OPERAND_SIMM(20)
CASE_OPERAND_SIMM(26)
CASE_OPERAND_SIMM(32)
// clang-format on
@@ -2673,6 +2672,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
case RISCVOp::OPERAND_SIMM12_LSB00000:
Ok = isShiftedInt<7, 5>(Imm);
break;
+ case RISCVOp::OPERAND_SIMM20_LI:
+ Ok = isInt<20>(Imm);
+ break;
case RISCVOp::OPERAND_UIMMLOG2XLEN:
Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
break;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index f762c4943f630..5368aa63fea6c 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -103,7 +103,18 @@ def simm16nonzero : RISCVOp<XLenVT>,
let OperandType = "OPERAND_SIMM16_NONZERO";
}
-def simm20 : RISCVSImmLeafOp<20>;
+def simm20_li : RISCVOp<XLenVT> {
+ let ParserMatchClass = SImmAsmOperand<20, "LI">;
+ let EncoderMethod = "getImmOpValue";
+ let DecoderMethod = "decodeSImmOperand<20>";
+ let OperandType = "OPERAND_SIMM20_LI";
+ let MCOperandPredicate = [{
+ int64_t Imm;
+ if (MCOp.evaluateAsConstantImm(Imm))
+ return isInt<20>(Imm);
+ return MCOp.isBareSymbolRef();
+ }];
+}
def simm26 : RISCVSImmLeafOp<26>;
@@ -118,7 +129,7 @@ def simm32 : RISCVOp<XLenVT> {
int64_t Imm;
if (MCOp.evaluateAsConstantImm(Imm))
return isInt<32>(Imm);
- return false;
+ return MCOp.isBareSymbolRef();
}];
}
@@ -1009,7 +1020,7 @@ let Predicates = [HasVendorXqcilb, IsRV32] in {
let Predicates = [HasVendorXqcili, IsRV32] in {
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
- def QC_LI : RVInstU<OPC_OP_IMM_32, (outs GPRNoX0:$rd), (ins simm20:$imm20),
+ def QC_LI : RVInstU<OPC_OP_IMM_32, (outs GPRNoX0:$rd), (ins simm20_li:$imm20),
"qc.li", "$rd, $imm20"> {
let Inst{31} = imm20{19};
let Inst{30-16} = imm20{14-0};
@@ -1017,7 +1028,7 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
}
def QC_E_LI : RVInst48<(outs GPRNoX0:$rd), (ins simm32:$imm),
- "qc.e.li", "$rd, $imm", [], InstFormatOther> {
+ "qc.e.li", "$rd, $imm", [], InstFormatQC_EAI> {
bits<5> rd;
bits<32> imm;
diff --git a/llvm/test/MC/RISCV/xqcili-invalid.s b/llvm/test/MC/RISCV/xqcili-invalid.s
index 0c4b4f04e86e9..567ed8ba89736 100644
--- a/llvm/test/MC/RISCV/xqcili-invalid.s
+++ b/llvm/test/MC/RISCV/xqcili-invalid.s
@@ -25,7 +25,7 @@ qc.li x0, 114514
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
qc.li x10
-# CHECK-IMM: :[[@LINE+1]]:12: error: immediate must be an integer in the range [-524288, 524287]
+# CHECK-IMM: :[[@LINE+1]]:12: error: operand must be a symbol with a %qc.abs20 specifier or an integer in the range [-524288, 524287]
qc.li x10, 33554432
# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcili' (Qualcomm uC Load Large Immediate Extension)
diff --git a/llvm/test/MC/RISCV/xqcili-relocations.s b/llvm/test/MC/RISCV/xqcili-relocations.s
new file mode 100644
index 0000000000000..b0a3f3bae11d5
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcili-relocations.s
@@ -0,0 +1,49 @@
+# RUN: llvm-mc -triple riscv32 -mattr=+experimental-xqcili %s -show-encoding \
+# RUN: | FileCheck -check-prefix=INSTR -check-prefix=FIXUP %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcili %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
+
+qc.li x4, %qc.abs20(foo)
+# RELOC: R_RISCV_CUSTOM192 foo 0x0
+# INSTR: qc.li tp, %qc.abs20(foo)
+# FIXUP: fixup A - offset: 0, value: %qc.abs20(foo), kind: fixup_riscv_qc_abs20_u
+
+qc.e.li x5, foo
+# RELOC: R_RISCV_CUSTOM194 foo 0x0
+# INSTR: qc.e.li t0, foo
+# FIXUP: fixup A - offset: 0, value: foo, kind: fixup_riscv_qc_e_32
+
+# Check that a label in a different section is handled similar to an undefined symbol
+qc.li x9, %qc.abs20(.bar)
+# RELOC: R_RISCV_CUSTOM192 .bar 0x0
+# INSTR: qc.li s1, %qc.abs20(.bar)
+# FIXUP: fixup A - offset: 0, value: %qc.abs20(.bar), kind: fixup_riscv_qc_abs20_u
+
+qc.e.li x8, .bar
+# RELOC: R_RISCV_CUSTOM194 .bar 0x0
+# INSTR: qc.e.li s0, .bar
+# FIXUP: fixup A - offset: 0, value: .bar, kind: fixup_riscv_qc_e_32
+
+# Check that branches to a defined symbol are handled correctly
+qc.li x7, %qc.abs20(.L1)
+# INSTR: qc.li t2, %qc.abs20(.L1)
+# FIXUP: fixup A - offset: 0, value: %qc.abs20(.L1), kind: fixup_riscv_qc_abs20_u
+
+qc.e.li x6, .L1
+# INSTR: qc.e.li t1, .L1
+# FIXUP: fixup A - offset: 0, value: .L1, kind: fixup_riscv_qc_e_32
+
+.L1:
+ ret
+
+.section .t2
+
+.bar:
+ ret
>From e44320f16cbf1fb4b005dfd8cdde64e79eddaf1d Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <quic_svs at quicinc.com>
Date: Tue, 8 Apr 2025 07:46:57 +0530
Subject: [PATCH 2/4] Change name
---
.../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 30 ++++++++++---------
.../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 2 +-
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 4 ++-
llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td | 19 +++++++-----
4 files changed, 32 insertions(+), 23 deletions(-)
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index c682722cdb701..1221ea07815b4 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -551,6 +551,21 @@ struct RISCVOperand final : public MCParsedAsmOperand {
return IsValid && VK == RISCVMCExpr::VK_None;
}
+ // True if operand is a symbol with no modifiers, or a constant with no
+ // modifiers and isInt<N>(Op).
+ template <int N> bool isBareSimmN() const {
+ if (!isImm())
+ return false;
+
+ int64_t Imm;
+ if (evaluateConstantImm(getImm(), Imm))
+ return isInt<N>(fixImmediateForRV32(Imm, isRV64Imm()));
+
+ RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
+ return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
+ VK == RISCVMCExpr::VK_None;
+ }
+
// Predicate methods for AsmOperands defined in RISCVInstrInfo.td
bool isBareSymbol() const {
@@ -887,19 +902,6 @@ struct RISCVOperand final : public MCParsedAsmOperand {
VK == RISCVMCExpr::VK_QC_ABS20;
}
- bool isSImm32() const {
- if (!isImm())
- return false;
-
- int64_t Imm;
- if (evaluateConstantImm(getImm(), Imm))
- return isInt<32>(fixImmediateForRV32(Imm, isRV64Imm()));
-
- RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
- return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
- VK == RISCVMCExpr::VK_None;
- }
-
bool isUImm20LUI() const {
if (!isImm())
return false;
@@ -1584,7 +1586,7 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidSImm26:
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 25),
(1 << 25) - 1);
- case Match_InvalidSImm32:
+ case Match_InvalidBareSImm32:
return generateImmOutOfRangeError(Operands, ErrorInfo,
std::numeric_limits<int32_t>::min(),
std::numeric_limits<uint32_t>::max());
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 17b99f26a1b8c..84a23de6b1995 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -342,7 +342,7 @@ enum OperandType : unsigned {
OPERAND_SIMM16_NONZERO,
OPERAND_SIMM20_LI,
OPERAND_SIMM26,
- OPERAND_SIMM32,
+ OPERAND_BARE_SIMM32,
OPERAND_CLUI_IMM,
OPERAND_VTYPEI10,
OPERAND_VTYPEI11,
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 3eca78bb063f3..f8a35533ba952 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -2655,7 +2655,6 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
CASE_OPERAND_SIMM(11)
CASE_OPERAND_SIMM(12)
CASE_OPERAND_SIMM(26)
- CASE_OPERAND_SIMM(32)
// clang-format on
case RISCVOp::OPERAND_SIMM5_PLUS1:
Ok = (isInt<5>(Imm) && Imm != -16) || Imm == 16;
@@ -2675,6 +2674,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
case RISCVOp::OPERAND_SIMM20_LI:
Ok = isInt<20>(Imm);
break;
+ case RISCVOp::OPERAND_BARE_SIMM32:
+ Ok = isInt<32>(Imm);
+ break;
case RISCVOp::OPERAND_UIMMLOG2XLEN:
Ok = STI.is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
break;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 5368aa63fea6c..b5e6e06cc8c3c 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -118,13 +118,18 @@ def simm20_li : RISCVOp<XLenVT> {
def simm26 : RISCVSImmLeafOp<26>;
+class BareSImmNAsmOperand<int width>
+ : ImmAsmOperand<"BareS", width, ""> {
+ let PredicateMethod = "isBareSimmN<" # width # ">";
+}
+
// 32-bit Immediate, used by RV32 Instructions in 32-bit operations, so no
// sign-/zero-extension. This is represented internally as a signed 32-bit value.
-def simm32 : RISCVOp<XLenVT> {
- let ParserMatchClass = SImmAsmOperand<32, "">;
+def bare_simm32 : RISCVOp<XLenVT> {
+ let ParserMatchClass = BareSImmNAsmOperand<32>;
let EncoderMethod = "getImmOpValue";
let DecoderMethod = "decodeSImmOperand<32>";
- let OperandType = "OPERAND_SIMM32";
+ let OperandType = "OPERAND_BARE_SIMM32";
let MCOperandPredicate = [{
int64_t Imm;
if (MCOp.evaluateAsConstantImm(Imm))
@@ -267,7 +272,7 @@ def InsnQC_EAI : DirectiveInsnQC_EAI<(outs AnyReg:$rd),
(ins uimm7_opcode:$opcode,
uimm3:$func3,
uimm1:$func1,
- simm32:$imm32),
+ bare_simm32:$imm32),
"$opcode, $func3, $func1, $rd, $imm32">;
def InsnQC_EI : DirectiveInsnQC_EI<(outs AnyReg:$rd),
(ins uimm7_opcode:$opcode,
@@ -314,7 +319,7 @@ def : InstAlias<".insn_qc.eai $opcode, $func3, $func1, $rd, $imm32",
uimm7_opcode:$opcode,
uimm3:$func3,
uimm1:$func1,
- simm32:$imm32)>;
+ bare_simm32:$imm32)>;
def : InstAlias<".insn_qc.ei $opcode, $func3, $func2, $rd, $rs1, $imm26",
(InsnQC_EI AnyReg:$rd,
uimm7_opcode:$opcode,
@@ -682,7 +687,7 @@ class QCIRVInstESStore<bits<3> funct3, bits<2> funct2, string opcodestr>
opcodestr, "$rs2, ${imm}(${rs1})">;
class QCIRVInstEAI<bits<3> funct3, bits<1> funct1, string opcodestr>
- : RVInst48<(outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd, simm32:$imm),
+ : RVInst48<(outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd, bare_simm32:$imm),
opcodestr, "$rd, $imm", [], InstFormatOther> {
bits<5> rd;
bits<32> imm;
@@ -1027,7 +1032,7 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
let Inst{15-12} = imm20{18-15};
}
- def QC_E_LI : RVInst48<(outs GPRNoX0:$rd), (ins simm32:$imm),
+ def QC_E_LI : RVInst48<(outs GPRNoX0:$rd), (ins bare_simm32:$imm),
"qc.e.li", "$rd, $imm", [], InstFormatQC_EAI> {
bits<5> rd;
bits<32> imm;
>From ba4f9500a5527384b731b256791ebbf9330a904f Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <quic_svs at quicinc.com>
Date: Wed, 9 Apr 2025 09:13:58 +0530
Subject: [PATCH 3/4] Fix AsmBackend code
---
llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index 9ae6ba04f262e..c43a506d3f147 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -569,10 +569,10 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
case RISCV::fixup_riscv_qc_abs20_u: {
if (!isInt<20>(Value))
Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
- uint64_t Bit20 = (Value >> 20) & 0x1;
- uint64_t Bit15_1 = (Value >> 1) & 0x7fff;
- uint64_t Bit19_16 = (Value >> 16) & 0xf;
- Value = (Bit20 << 31) | (Bit15_1 << 16) | (Bit19_16 << 12);
+ uint64_t Bit19 = (Value >> 19) & 0x1;
+ uint64_t Bit14_0 = (Value) & 0x7fff;
+ uint64_t Bit18_15 = (Value >> 15) & 0xf;
+ Value = (Bit19 << 31) | (Bit14_0 << 16) | (Bit18_15 << 12);
return Value;
}
}
>From 576405f2ce626eebe4a79337976e9166cdf6c1c6 Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <quic_svs at quicinc.com>
Date: Wed, 9 Apr 2025 09:20:43 +0530
Subject: [PATCH 4/4] Use unsigned
---
llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index c43a506d3f147..c6c2e0810b75e 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -569,9 +569,9 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
case RISCV::fixup_riscv_qc_abs20_u: {
if (!isInt<20>(Value))
Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
- uint64_t Bit19 = (Value >> 19) & 0x1;
- uint64_t Bit14_0 = (Value) & 0x7fff;
- uint64_t Bit18_15 = (Value >> 15) & 0xf;
+ unsigned Bit19 = (Value >> 19) & 0x1;
+ unsigned Bit14_0 = Value & 0x7fff;
+ unsigned Bit18_15 = (Value >> 15) & 0xf;
Value = (Bit19 << 31) | (Bit14_0 << 16) | (Bit18_15 << 12);
return Value;
}
More information about the llvm-commits
mailing list