llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: Sudharsan Veeravalli (svs-quic)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/119823.diff


14 Files Affected:

- (modified) clang/test/Driver/print-supported-extensions-riscv.c (+1) 
- (modified) llvm/docs/RISCVUsage.rst (+3) 
- (modified) llvm/docs/ReleaseNotes.md (+2) 
- (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+12) 
- (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+2) 
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h (+1) 
- (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+8) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+58) 
- (modified) llvm/lib/TargetParser/RISCVISAInfo.cpp (+1-1) 
- (modified) llvm/test/CodeGen/RISCV/attributes.ll (+2) 
- (added) llvm/test/MC/RISCV/xqcilsm-aliases-valid.s (+35) 
- (added) llvm/test/MC/RISCV/xqcilsm-invalid.s (+112) 
- (added) llvm/test/MC/RISCV/xqcilsm-valid.s (+35) 
- (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+1) 


``````````diff
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c 
b/clang/test/Driver/print-supported-extensions-riscv.c
index c268f75a0fd8df..715d9e414e6114 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -191,6 +191,7 @@
 // CHECK-NEXT:     xqcia                0.2       'Xqcia' (Qualcomm uC 
Arithmetic Extension)
 // CHECK-NEXT:     xqcics               0.2       'Xqcics' (Qualcomm uC 
Conditional Select Extension)
 // CHECK-NEXT:     xqcicsr              0.2       'Xqcicsr' (Qualcomm uC CSR 
Extension)
+// CHECK-NEXT:     xqcilsm              0.2       'Xqcilsm' (Qualcomm uC Load 
Store Multiple Extension)
 // CHECK-NEXT:     xqcisls              0.2       'Xqcisls' (Qualcomm uC 
Scaled Load Store Extension)
 // CHECK-EMPTY:
 // CHECK-NEXT: Supported Profiles
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 2867dcceb84fd7..f6a0dd4bf2383c 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -435,6 +435,9 @@ The current vendor extensions supported are:
 ``experimental-Xqcicsr``
   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.
 
+``experimental-Xqcilsm``
+  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.
+
 ``experimental-Xqcisls``
   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.
 
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index ddee4ab8ce1b37..5d2ff17ee19848 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -223,6 +223,8 @@ Changes to the RISC-V Backend
   extension.
 * Adds experimental assembler support for the Qualcomm uC 'Xqcics` (Conditonal 
Select)
   extension.
+* Adds experimental assembler support for the Qualcomm uC 'Xqcilsm` (Load 
Store Multiple)
+  extension.
 
 Changes to the WebAssembly Backend
 ----------------------------------
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp 
b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 7c91dc07bbd3e5..5b9946e5132e40 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -724,6 +724,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
   bool isUImm48() const { return IsUImm<48>(); }
   bool isUImm64() const { return IsUImm<64>(); }
 
+  bool isUImm5NonZero() const {
+    if (!isImm())
+      return false;
+    int64_t Imm;
+    RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+    bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+    return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) &&
+           VK == RISCVMCExpr::VK_RISCV_None;
+  }
+
   bool isUImm8GE32() const {
     int64_t Imm;
     RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
@@ -1506,6 +1516,8 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, 
unsigned &Opcode,
     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
   case Match_InvalidUImm5:
     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
+  case Match_InvalidUImm5NonZero:
+    return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
   case Match_InvalidUImm6:
     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
   case Match_InvalidUImm7:
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp 
b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index b8ca32434aa43e..99017195185fd3 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -690,6 +690,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst 
&MI, uint64_t &Size,
                         "Qualcomm uC Arithmetic custom opcode table");
   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcics, DecoderTableXqcics32,
                         "Qualcomm uC Conditional Select custom opcode table");
+  TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcilsm, DecoderTableXqcilsm32,
+                        "Qualcomm uC Load Store Multiple custom opcode table");
   TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
 
   return MCDisassembler::Fail;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h 
b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 9e36d62352ae51..8b407a9fd25505 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -301,6 +301,7 @@ enum OperandType : unsigned {
   OPERAND_UIMM3,
   OPERAND_UIMM4,
   OPERAND_UIMM5,
+  OPERAND_UIMM5_NONZERO,
   OPERAND_UIMM5_LSB0,
   OPERAND_UIMM6,
   OPERAND_UIMM6_LSB0,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td 
b/llvm/lib/Target/RISCV/RISCVFeatures.td
index d1922eb0262792..ebaf2a28ba881c 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1375,6 +1375,14 @@ def HasVendorXqcics
       AssemblerPredicate<(all_of FeatureVendorXqcics),
                          "'Xqcics' (Qualcomm uC Conditional Select 
Extension)">;
 
+def FeatureVendorXqcilsm
+    : RISCVExperimentalExtension<"xqcilsm", 0, 2,
+                                 "'Xqcilsm' (Qualcomm uC Load Store Multiple 
Extension)">;
+def HasVendorXqcilsm
+    : Predicate<"Subtarget->hasVendorXqcilsm()">,
+      AssemblerPredicate<(all_of FeatureVendorXqcilsm),
+                         "'Xqcilsm' (Qualcomm uC Load Store Multiple 
Extension)">;
+
 
//===----------------------------------------------------------------------===//
 // LLVM specific features and extensions
 
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td 
b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 3af49d7e74460c..9a61b38cfce2d8 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -14,6 +14,13 @@
 // Operand and SDNode transformation definitions.
 
//===----------------------------------------------------------------------===//
 
+def uimm5nonzero : RISCVOp<XLenVT>,
+                   ImmLeaf<XLenVT, [{return (Imm != 0) && isUInt<5>(Imm);}]> {
+  let ParserMatchClass = UImmAsmOperand<5, "NonZero">;
+  let DecoderMethod = "decodeUImmNonZeroOperand<5>";
+  let OperandType = "OPERAND_UIMM5_NONZERO";
+}
+
 def uimm11 : RISCVUImmLeafOp<11>;
 
 
//===----------------------------------------------------------------------===//
@@ -105,6 +112,26 @@ class QCISELECTICCI<bits<3> funct3, string opcodestr>
   let rs1 = imm;
 }
 
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+class QCILoadMultiple<bits<2> func2, DAGOperand InTyRs2, string opcodestr>
+    : RVInstRBase<0b111, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
+                  (ins GPR:$rs1, InTyRs2:$rs2, uimm7_lsb00:$imm),
+                  opcodestr, "$rd, $rs2, ${imm}(${rs1})"> {
+  bits<7> imm;
+  let Inst{31-25} = {func2, imm{6-2}};
+}
+
+
+// rd corresponds to the source for the store 'rs3' described in the spec.
+let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
+class QCIStoreMultiple<bits<2> func2, DAGOperand InTyRs2, string opcodestr>
+    : RVInstRBase<0b111, OPC_CUSTOM_1, (outs),
+                  (ins GPR:$rd, GPR:$rs1, InTyRs2:$rs2, uimm7_lsb00:$imm),
+                  opcodestr, "$rd, $rs2, ${imm}(${rs1})"> {
+  bits<7> imm;
+  let Inst{31-25} = {func2, imm{6-2}};
+}
+
 
//===----------------------------------------------------------------------===//
 // Instructions
 
//===----------------------------------------------------------------------===//
@@ -167,3 +194,34 @@ let Predicates = [HasVendorXqcics, IsRV32], 
DecoderNamespace = "Xqcics" in {
   def QC_SELECTIEQI : QCISELECTICCI <0b010, "qc.selectieqi">;
   def QC_SELECTINEI : QCISELECTICCI <0b011, "qc.selectinei">;
 } // Predicates = [HasVendorXqcics, IsRV32], DecoderNamespace = "Xqcics"
+
+let Predicates = [HasVendorXqcilsm, IsRV32], DecoderNamespace = "Xqcilsm" in {
+    def QC_SWM : QCIStoreMultiple<0b00, GPRNoX0, "qc.swm">;
+    def QC_SWMI : QCIStoreMultiple<0b01, uimm5nonzero, "qc.swmi">;
+    def QC_SETWM : QCIStoreMultiple<0b10, GPRNoX0, "qc.setwm">;
+    def QC_SETWMI : QCIStoreMultiple<0b11, uimm5nonzero, "qc.setwmi">;
+
+    def QC_LWM : QCILoadMultiple<0b00, GPRNoX0, "qc.lwm">;
+    def QC_LWMI : QCILoadMultiple<0b01, uimm5nonzero, "qc.lwmi">;
+} // Predicates = [HasVendorXqcilsm, IsRV32], DecoderNamespace = "Xqcilsm"
+
+//===----------------------------------------------------------------------===//
+// Aliases
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasVendorXqcilsm, IsRV32] in {
+let EmitPriority = 0 in {
+  def : InstAlias<"qc.swm $rs3, $rs2, (${rs1})",
+                  (QC_SWM GPR:$rs3, GPR:$rs1, GPRNoX0:$rs2, 0)>;
+  def : InstAlias<"qc.swmi $rs3, $length, (${rs1})",
+                  (QC_SWMI GPR:$rs3, GPR:$rs1, uimm5nonzero:$length, 0)>;
+  def : InstAlias<"qc.setwm $rs3, $rs2, (${rs1})",
+                  (QC_SETWM GPR:$rs3, GPR:$rs1, GPRNoX0:$rs2, 0)>;
+  def : InstAlias<"qc.setwmi $rs3, $length, (${rs1})",
+                  (QC_SETWMI GPR:$rs3, GPR:$rs1, uimm5nonzero:$length, 0)>;
+  def : InstAlias<"qc.lwm $rd, $rs2, (${rs1})",
+                  (QC_LWM GPRNoX0:$rd, GPR:$rs1, GPRNoX0:$rs2, 0)>;
+  def : InstAlias<"qc.lwmi $rd, $length, (${rs1})",
+                  (QC_LWMI GPRNoX0:$rd, GPR:$rs1, uimm5nonzero:$length, 0)>;
+} // EmitPriority = 0
+} // Predicates = [HasVendorXqcilsm, IsRV32]
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp 
b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index de3d5564210ff4..cafc9d304e83a7 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -742,7 +742,7 @@ Error RISCVISAInfo::checkDependency() {
   bool HasZvl = MinVLen != 0;
   bool HasZcmt = Exts.count("zcmt") != 0;
   static constexpr StringLiteral XqciExts[] = {
-      {"xqcia"}, {"xqcics"}, {"xqcicsr"}, {"xqcisls"}};
+      {"xqcia"}, {"xqcics"}, {"xqcicsr"}, {"xqcilsm"}, {"xqcisls"}};
 
   if (HasI && HasE)
     return getIncompatibleError("i", "e");
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll 
b/llvm/test/CodeGen/RISCV/attributes.ll
index cdccc712a46981..f63bc944ccf22e 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -84,6 +84,7 @@
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcia %s -o - | FileCheck 
--check-prefix=RV32XQCIA %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcics %s -o - | FileCheck 
--check-prefix=RV32XQCICS %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck 
--check-prefix=RV32XQCICSR %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilsm %s -o - | FileCheck 
--check-prefix=RV32XQCILSM %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcisls %s -o - | FileCheck 
--check-prefix=RV32XQCISLS %s
 ; RUN: llc -mtriple=riscv32 -mattr=+zaamo %s -o - | FileCheck 
--check-prefix=RV32ZAAMO %s
 ; RUN: llc -mtriple=riscv32 -mattr=+zalrsc %s -o - | FileCheck 
--check-prefix=RV32ZALRSC %s
@@ -392,6 +393,7 @@
 ; RV32XQCIA: .attribute 5, "rv32i2p1_xqcia0p2"
 ; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
 ; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
+; RV32XQCILSM: .attribute 5, "rv32i2p1_xqcilsm0p2"
 ; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
 ; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
 ; RV32ZALRSC: .attribute 5, "rv32i2p1_zalrsc1p0"
diff --git a/llvm/test/MC/RISCV/xqcilsm-aliases-valid.s 
b/llvm/test/MC/RISCV/xqcilsm-aliases-valid.s
new file mode 100644
index 00000000000000..e9aec14c3c3aa0
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcilsm-aliases-valid.s
@@ -0,0 +1,35 @@
+# Xqcilsm - Qualcomm uC Load Store Multiple Extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilsm 
-riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilsm < %s 
\
+# RUN:     | llvm-objdump --mattr=+experimental-xqcilsm -M no-aliases 
--no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilsm -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilsm < %s 
\
+# RUN:     | llvm-objdump --mattr=+experimental-xqcilsm --no-print-imm-hex -d 
- \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.swm   t0, s4, 0(gp)
+# CHECK-ENC: encoding: [0xab,0xf2,0x41,0x01]
+qc.swm x5, x20, (x3)
+
+# CHECK-INST: qc.swmi  a0, 4, 0(tp)
+# CHECK-ENC: encoding: [0x2b,0x75,0x42,0x40]
+qc.swmi x10, 4, (x4)
+
+# CHECK-INST: qc.setwm tp, t5, 0(sp)
+# CHECK-ENC: encoding: [0x2b,0x72,0xe1,0x81]
+qc.setwm x4, x30, (x2)
+
+# CHECK-INST: qc.setwmi    t0, 31, 0(a2)
+# CHECK-ENC: encoding: [0xab,0x72,0xf6,0xc1]
+qc.setwmi x5, 31, (x12)
+
+# CHECK-INST: qc.lwm   t2, ra, 0(s4)
+# CHECK-ENC: encoding: [0x8b,0x73,0x1a,0x00]
+qc.lwm x7, x1, (x20)
+
+# CHECK-INST: qc.lwmi  a3, 9, 0(s7)
+# CHECK-ENC: encoding: [0x8b,0xf6,0x9b,0x40]
+qc.lwmi x13, 9, (x23)
diff --git a/llvm/test/MC/RISCV/xqcilsm-invalid.s 
b/llvm/test/MC/RISCV/xqcilsm-invalid.s
new file mode 100644
index 00000000000000..c59260b5718d0b
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcilsm-invalid.s
@@ -0,0 +1,112 @@
+# Xqcilsm - Qualcomm uC Load Store Multiple Extension
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcilsm < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcilsm < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s
+
+# CHECK: :[[@LINE+1]]:20: error: expected register
+qc.swm x5, x20, 12(20)
+
+# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+qc.swm x5, x0, 12(x3)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.swm x5, x3
+
+# CHECK-PLUS: :[[@LINE+1]]:17: error: immediate must be a multiple of 4 bytes 
in the range [0, 124]
+qc.swm x5, x20, 45(x3)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 
'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
+qc.swm x5, x20, 12(x3)
+
+
+# CHECK: :[[@LINE+1]]:20: error: expected register
+qc.swmi x10, 4, 20(4)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.swmi x10, 4, 20
+
+# CHECK-PLUS: :[[@LINE+1]]:14: error: immediate must be an integer in the 
range [1, 31]
+qc.swmi x10, 32, 20(x4)
+
+# CHECK-PLUS: :[[@LINE+1]]:14: error: immediate must be an integer in the 
range [1, 31]
+qc.swmi x10, 0, 20(x4)
+
+# CHECK-PLUS: :[[@LINE+1]]:17: error: immediate must be a multiple of 4 bytes 
in the range [0, 124]
+qc.swmi x10, 4, 45(x4)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 
'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
+qc.swmi x10, 4, 20(x4)
+
+
+# CHECK: :[[@LINE+1]]:23: error: expected register
+qc.setwm x4, x30, 124(2)
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.setwm x4, x0, 124(x2)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.setwm x4, x30, 124
+
+# CHECK-PLUS: :[[@LINE+1]]:19: error: immediate must be a multiple of 4 bytes 
in the range [0, 124]
+qc.setwm x4, x30, 128(x2)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 
'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
+qc.setwm x4, x30, 124(x2)
+
+
+# CHECK: :[[@LINE+1]]:22: error: expected register
+qc.setwmi x5, 31, 12(12)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.setwmi x5, 31, 12
+
+# CHECK-PLUS: :[[@LINE+1]]:15: error: immediate must be an integer in the 
range [1, 31]
+qc.setwmi x5, 37, 12(x12)
+
+# CHECK-PLUS: :[[@LINE+1]]:15: error: immediate must be an integer in the 
range [1, 31]
+qc.setwmi x5, 0, 12(x12)
+
+# CHECK-PLUS: :[[@LINE+1]]:19: error: immediate must be a multiple of 4 bytes 
in the range [0, 124]
+qc.setwmi x5, 31, 98(x12)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 
'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
+qc.setwmi x5, 31, 12(x12)
+
+
+# CHECK: :[[@LINE+1]]:19: error: expected register
+qc.lwm x7, x1, 24(20)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.lwm x7, x1, 24
+
+# CHECK: :[[@LINE+1]]:8: error: invalid operand for instruction
+qc.lwm x0, x1, 24(x20)
+
+# CHECK-PLUS: :[[@LINE+1]]:16: error: immediate must be a multiple of 4 bytes 
in the range [0, 124]
+qc.lwm x7, x1, 46(x20)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 
'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
+qc.lwm x7, x1, 24(x20)
+
+
+# CHECK: :[[@LINE+1]]:19: error: expected register
+qc.lwmi x13, 9, 4(23)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.lwmi x13, 9, 4
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.lwmi x0, 9, 4(x23)
+
+# CHECK-PLUS: :[[@LINE+1]]:14: error: immediate must be an integer in the 
range [1, 31]
+qc.lwmi x13, 44, 4(x23)
+
+# CHECK-PLUS: :[[@LINE+1]]:14: error: immediate must be an integer in the 
range [1, 31]
+qc.lwmi x13, 0, 4(x23)
+
+# CHECK-PLUS: :[[@LINE+1]]:17: error: immediate must be a multiple of 4 bytes 
in the range [0, 124]
+qc.lwmi x13, 9, 77(x23)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 
'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
+qc.lwmi x13, 9, 4(x23)
diff --git a/llvm/test/MC/RISCV/xqcilsm-valid.s 
b/llvm/test/MC/RISCV/xqcilsm-valid.s
new file mode 100644
index 00000000000000..4893e074df327c
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcilsm-valid.s
@@ -0,0 +1,35 @@
+# Xqcilsm - Qualcomm uC Load Store Multiple Extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilsm 
-riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilsm < %s 
\
+# RUN:     | llvm-objdump --mattr=+experimental-xqcilsm -M no-aliases 
--no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilsm -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilsm < %s 
\
+# RUN:     | llvm-objdump --mattr=+experimental-xqcilsm --no-print-imm-hex -d 
- \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.swm   t0, s4, 12(gp)
+# CHECK-ENC: encoding: [0xab,0xf2,0x41,0x07]
+qc.swm x5, x20, 12(x3)
+
+# CHECK-INST: qc.swmi  a0, 4, 20(tp)
+# CHECK-ENC: encoding: [0x2b,0x75,0x42,0x4a]
+qc.swmi x10, 4, 20(x4)
+
+# CHECK-INST: qc.setwm tp, t5, 124(sp)
+# CHECK-ENC: encoding: [0x2b,0x72,0xe1,0xbf]
+qc.setwm x4, x30, 124(x2)
+
+# CHECK-INST: qc.setwmi    t0, 31, 12(a2)
+# CHECK-ENC: encoding: [0xab,0x72,0xf6,0xc7]
+qc.setwmi x5, 31, 12(x12)
+
+# CHECK-INST: qc.lwm   t2, ra, 24(s4)
+# CHECK-ENC: encoding: [0x8b,0x73,0x1a,0x0c]
+qc.lwm x7, x1, 24(x20)
+
+# CHECK-INST: qc.lwmi  a3, 9, 4(s7)
+# CHECK-ENC: encoding: [0x8b,0xf6,0x9b,0x42]
+qc.lwmi x13, 9, 4(x23)
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp 
b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index cf06ec5670346e..bef3f571b174d3 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1117,6 +1117,7 @@ Experimental extensions
     xqcia                0.2
     xqcics               0.2
     xqcicsr              0.2
+    xqcilsm              0.2
     xqcisls              0.2
 
 Supported Profiles

``````````

</details>


https://github.com/llvm/llvm-project/pull/119823
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to