Skip to content

Commit 668d968

Browse files
authored
[RISCV] Add Qualcomm uC Xqcilsm (Load Store Multiple) extension (#119823)
This extension adds 6 instructions that can do multi-word load/store. The current spec can be found at: https://github.com/quic/riscv-unified-db/releases/latest This patch adds assembler only support.
1 parent f01b62a commit 668d968

File tree

14 files changed

+273
-1
lines changed

14 files changed

+273
-1
lines changed

clang/test/Driver/print-supported-extensions-riscv.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@
191191
// CHECK-NEXT: xqcia 0.2 'Xqcia' (Qualcomm uC Arithmetic Extension)
192192
// CHECK-NEXT: xqcics 0.2 'Xqcics' (Qualcomm uC Conditional Select Extension)
193193
// CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension)
194+
// CHECK-NEXT: xqcilsm 0.2 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
194195
// CHECK-NEXT: xqcisls 0.2 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
195196
// CHECK-EMPTY:
196197
// CHECK-NEXT: Supported Profiles

llvm/docs/RISCVUsage.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,9 @@ The current vendor extensions supported are:
435435
``experimental-Xqcicsr``
436436
LLVM implements `version 0.2 of the Qualcomm uC CSR extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm. All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
437437

438+
``experimental-Xqcilsm``
439+
LLVM implements `version 0.2 of the Qualcomm uC Load Store Multiple extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm. All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
440+
438441
``experimental-Xqcisls``
439442
LLVM implements `version 0.2 of the Qualcomm uC Scaled Load Store extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm. All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
440443

llvm/docs/ReleaseNotes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ Changes to the RISC-V Backend
223223
extension.
224224
* Adds experimental assembler support for the Qualcomm uC 'Xqcics` (Conditonal Select)
225225
extension.
226+
* Adds experimental assembler support for the Qualcomm uC 'Xqcilsm` (Load Store Multiple)
227+
extension.
226228

227229
Changes to the WebAssembly Backend
228230
----------------------------------

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
724724
bool isUImm48() const { return IsUImm<48>(); }
725725
bool isUImm64() const { return IsUImm<64>(); }
726726

727+
bool isUImm5NonZero() const {
728+
if (!isImm())
729+
return false;
730+
int64_t Imm;
731+
RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
732+
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
733+
return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) &&
734+
VK == RISCVMCExpr::VK_RISCV_None;
735+
}
736+
727737
bool isUImm8GE32() const {
728738
int64_t Imm;
729739
RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
@@ -1506,6 +1516,8 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
15061516
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
15071517
case Match_InvalidUImm5:
15081518
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1519+
case Match_InvalidUImm5NonZero:
1520+
return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
15091521
case Match_InvalidUImm6:
15101522
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
15111523
case Match_InvalidUImm7:

llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
690690
"Qualcomm uC Arithmetic custom opcode table");
691691
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcics, DecoderTableXqcics32,
692692
"Qualcomm uC Conditional Select custom opcode table");
693+
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcilsm, DecoderTableXqcilsm32,
694+
"Qualcomm uC Load Store Multiple custom opcode table");
693695
TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
694696

695697
return MCDisassembler::Fail;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ enum OperandType : unsigned {
301301
OPERAND_UIMM3,
302302
OPERAND_UIMM4,
303303
OPERAND_UIMM5,
304+
OPERAND_UIMM5_NONZERO,
304305
OPERAND_UIMM5_LSB0,
305306
OPERAND_UIMM6,
306307
OPERAND_UIMM6_LSB0,

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,6 +1375,14 @@ def HasVendorXqcics
13751375
AssemblerPredicate<(all_of FeatureVendorXqcics),
13761376
"'Xqcics' (Qualcomm uC Conditional Select Extension)">;
13771377

1378+
def FeatureVendorXqcilsm
1379+
: RISCVExperimentalExtension<"xqcilsm", 0, 2,
1380+
"'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)">;
1381+
def HasVendorXqcilsm
1382+
: Predicate<"Subtarget->hasVendorXqcilsm()">,
1383+
AssemblerPredicate<(all_of FeatureVendorXqcilsm),
1384+
"'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)">;
1385+
13781386
//===----------------------------------------------------------------------===//
13791387
// LLVM specific features and extensions
13801388
//===----------------------------------------------------------------------===//

llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@
1414
// Operand and SDNode transformation definitions.
1515
//===----------------------------------------------------------------------===//
1616

17+
def uimm5nonzero : RISCVOp<XLenVT>,
18+
ImmLeaf<XLenVT, [{return (Imm != 0) && isUInt<5>(Imm);}]> {
19+
let ParserMatchClass = UImmAsmOperand<5, "NonZero">;
20+
let DecoderMethod = "decodeUImmNonZeroOperand<5>";
21+
let OperandType = "OPERAND_UIMM5_NONZERO";
22+
}
23+
1724
def uimm11 : RISCVUImmLeafOp<11>;
1825

1926
//===----------------------------------------------------------------------===//
@@ -105,6 +112,26 @@ class QCISELECTICCI<bits<3> funct3, string opcodestr>
105112
let rs1 = imm;
106113
}
107114

115+
let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
116+
class QCILoadMultiple<bits<2> funct2, DAGOperand InTyRs2, string opcodestr>
117+
: RVInstRBase<0b111, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
118+
(ins GPR:$rs1, InTyRs2:$rs2, uimm7_lsb00:$imm),
119+
opcodestr, "$rd, $rs2, ${imm}(${rs1})"> {
120+
bits<7> imm;
121+
let Inst{31-25} = {funct2, imm{6-2}};
122+
}
123+
124+
125+
// rd corresponds to the source for the store 'rs3' described in the spec.
126+
let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
127+
class QCIStoreMultiple<bits<2> funct2, DAGOperand InTyRs2, string opcodestr>
128+
: RVInstRBase<0b111, OPC_CUSTOM_1, (outs),
129+
(ins GPR:$rd, GPR:$rs1, InTyRs2:$rs2, uimm7_lsb00:$imm),
130+
opcodestr, "$rd, $rs2, ${imm}(${rs1})"> {
131+
bits<7> imm;
132+
let Inst{31-25} = {funct2, imm{6-2}};
133+
}
134+
108135
//===----------------------------------------------------------------------===//
109136
// Instructions
110137
//===----------------------------------------------------------------------===//
@@ -167,3 +194,34 @@ let Predicates = [HasVendorXqcics, IsRV32], DecoderNamespace = "Xqcics" in {
167194
def QC_SELECTIEQI : QCISELECTICCI <0b010, "qc.selectieqi">;
168195
def QC_SELECTINEI : QCISELECTICCI <0b011, "qc.selectinei">;
169196
} // Predicates = [HasVendorXqcics, IsRV32], DecoderNamespace = "Xqcics"
197+
198+
let Predicates = [HasVendorXqcilsm, IsRV32], DecoderNamespace = "Xqcilsm" in {
199+
def QC_SWM : QCIStoreMultiple<0b00, GPRNoX0, "qc.swm">;
200+
def QC_SWMI : QCIStoreMultiple<0b01, uimm5nonzero, "qc.swmi">;
201+
def QC_SETWM : QCIStoreMultiple<0b10, GPRNoX0, "qc.setwm">;
202+
def QC_SETWMI : QCIStoreMultiple<0b11, uimm5nonzero, "qc.setwmi">;
203+
204+
def QC_LWM : QCILoadMultiple<0b00, GPRNoX0, "qc.lwm">;
205+
def QC_LWMI : QCILoadMultiple<0b01, uimm5nonzero, "qc.lwmi">;
206+
} // Predicates = [HasVendorXqcilsm, IsRV32], DecoderNamespace = "Xqcilsm"
207+
208+
//===----------------------------------------------------------------------===//
209+
// Aliases
210+
//===----------------------------------------------------------------------===//
211+
212+
let Predicates = [HasVendorXqcilsm, IsRV32] in {
213+
let EmitPriority = 0 in {
214+
def : InstAlias<"qc.swm $rs3, $rs2, (${rs1})",
215+
(QC_SWM GPR:$rs3, GPR:$rs1, GPRNoX0:$rs2, 0)>;
216+
def : InstAlias<"qc.swmi $rs3, $length, (${rs1})",
217+
(QC_SWMI GPR:$rs3, GPR:$rs1, uimm5nonzero:$length, 0)>;
218+
def : InstAlias<"qc.setwm $rs3, $rs2, (${rs1})",
219+
(QC_SETWM GPR:$rs3, GPR:$rs1, GPRNoX0:$rs2, 0)>;
220+
def : InstAlias<"qc.setwmi $rs3, $length, (${rs1})",
221+
(QC_SETWMI GPR:$rs3, GPR:$rs1, uimm5nonzero:$length, 0)>;
222+
def : InstAlias<"qc.lwm $rd, $rs2, (${rs1})",
223+
(QC_LWM GPRNoX0:$rd, GPR:$rs1, GPRNoX0:$rs2, 0)>;
224+
def : InstAlias<"qc.lwmi $rd, $length, (${rs1})",
225+
(QC_LWMI GPRNoX0:$rd, GPR:$rs1, uimm5nonzero:$length, 0)>;
226+
} // EmitPriority = 0
227+
} // Predicates = [HasVendorXqcilsm, IsRV32]

llvm/lib/TargetParser/RISCVISAInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ Error RISCVISAInfo::checkDependency() {
742742
bool HasZvl = MinVLen != 0;
743743
bool HasZcmt = Exts.count("zcmt") != 0;
744744
static constexpr StringLiteral XqciExts[] = {
745-
{"xqcia"}, {"xqcics"}, {"xqcicsr"}, {"xqcisls"}};
745+
{"xqcia"}, {"xqcics"}, {"xqcicsr"}, {"xqcilsm"}, {"xqcisls"}};
746746

747747
if (HasI && HasE)
748748
return getIncompatibleError("i", "e");

llvm/test/CodeGen/RISCV/attributes.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcia %s -o - | FileCheck --check-prefix=RV32XQCIA %s
8585
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcics %s -o - | FileCheck --check-prefix=RV32XQCICS %s
8686
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck --check-prefix=RV32XQCICSR %s
87+
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilsm %s -o - | FileCheck --check-prefix=RV32XQCILSM %s
8788
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcisls %s -o - | FileCheck --check-prefix=RV32XQCISLS %s
8889
; RUN: llc -mtriple=riscv32 -mattr=+zaamo %s -o - | FileCheck --check-prefix=RV32ZAAMO %s
8990
; RUN: llc -mtriple=riscv32 -mattr=+zalrsc %s -o - | FileCheck --check-prefix=RV32ZALRSC %s
@@ -392,6 +393,7 @@
392393
; RV32XQCIA: .attribute 5, "rv32i2p1_xqcia0p2"
393394
; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
394395
; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
396+
; RV32XQCILSM: .attribute 5, "rv32i2p1_xqcilsm0p2"
395397
; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
396398
; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
397399
; RV32ZALRSC: .attribute 5, "rv32i2p1_zalrsc1p0"

0 commit comments

Comments
 (0)