Skip to content

Commit 629ff2d

Browse files
authored
[RISCV][Xqcili] Implement Load Immediate Support (#132496)
This is required to support `li`, but the code is also shared with CodeGen so the compiler will now emit instructions from Xqcili when that extension is enabled during compilation. Also implemented some missed verifiers in `RISCVInstrInfo::verifyInstruction`, some of which are required for this change.
1 parent a8e168e commit 629ff2d

File tree

5 files changed

+479
-0
lines changed

5 files changed

+479
-0
lines changed

llvm/docs/ReleaseNotes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ Changes to the RISC-V Backend
150150
* Adds Support for Qualcomm's `qci-nest` and `qci-nonest` interrupt types, which
151151
use instructions from `Xqciint` to save and restore some GPRs during interrupt
152152
handlers.
153+
* When the experimental extension `Xqcili` is enabled, `qc.e.li` and `qc.li` may
154+
now be used to materialize immediates.
153155

154156
Changes to the WebAssembly Backend
155157
----------------------------------

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ static int getInstSeqCost(RISCVMatInt::InstSeq &Res, bool HasRVC) {
2222
// Assume instructions that aren't listed aren't compressible.
2323
bool Compressed = false;
2424
switch (Instr.getOpcode()) {
25+
case RISCV::QC_E_LI:
26+
// One 48-bit instruction takes the space of 1.5 regular instructions.
27+
Cost += 150;
28+
continue;
2529
case RISCV::SLLI:
2630
case RISCV::SRLI:
2731
Compressed = true;
@@ -57,6 +61,24 @@ static void generateInstSeqImpl(int64_t Val, const MCSubtargetInfo &STI,
5761
return;
5862
}
5963

64+
if (!IsRV64 && STI.hasFeature(RISCV::FeatureVendorXqcili)) {
65+
bool FitsOneStandardInst = ((Val & 0xFFF) == 0) || isInt<12>(Val);
66+
67+
// 20-bit signed immediates that don't fit into `ADDI` or `LUI` should use
68+
// `QC.LI` (a single 32-bit instruction).
69+
if (!FitsOneStandardInst && isInt<20>(Val)) {
70+
Res.emplace_back(RISCV::QC_LI, Val);
71+
return;
72+
}
73+
74+
// 32-bit signed immediates that don't fit into `ADDI`, `LUI` or `QC.LI`
75+
// should use `QC.E.LI` (a single 48-bit instruction).
76+
if (!FitsOneStandardInst && isInt<32>(Val)) {
77+
Res.emplace_back(RISCV::QC_E_LI, Val);
78+
return;
79+
}
80+
}
81+
6082
if (isInt<32>(Val)) {
6183
// Depending on the active bits in the immediate Value v, the following
6284
// instruction sequences are emitted:
@@ -523,6 +545,8 @@ OpndKind Inst::getOpndKind() const {
523545
default:
524546
llvm_unreachable("Unexpected opcode!");
525547
case RISCV::LUI:
548+
case RISCV::QC_LI:
549+
case RISCV::QC_E_LI:
526550
return RISCVMatInt::Imm;
527551
case RISCV::ADD_UW:
528552
return RISCVMatInt::RegX0;

llvm/lib/Target/RISCV/RISCVInstrInfo.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2603,8 +2603,11 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
26032603
// clang-format off
26042604
CASE_OPERAND_SIMM(5)
26052605
CASE_OPERAND_SIMM(6)
2606+
CASE_OPERAND_SIMM(11)
26062607
CASE_OPERAND_SIMM(12)
2608+
CASE_OPERAND_SIMM(20)
26072609
CASE_OPERAND_SIMM(26)
2610+
CASE_OPERAND_SIMM(32)
26082611
// clang-format on
26092612
case RISCVOp::OPERAND_SIMM5_PLUS1:
26102613
Ok = (isInt<5>(Imm) && Imm != -16) || Imm == 16;

0 commit comments

Comments
 (0)