[llvm] 163935a - [RISCV] Add Qualcomm uC Xqcilo (Large Offset Load Store) extension (#123881)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 22 20:44:29 PST 2025


Author: quic_hchandel
Date: 2025-01-23T10:14:25+05:30
New Revision: 163935a48df69bde944fae2b4581541dab30c730

URL: https://github.com/llvm/llvm-project/commit/163935a48df69bde944fae2b4581541dab30c730
DIFF: https://github.com/llvm/llvm-project/commit/163935a48df69bde944fae2b4581541dab30c730.diff

LOG: [RISCV] Add Qualcomm uC Xqcilo (Large Offset Load Store) extension (#123881)

This extension adds eight 48 bit load store instructions.

The current spec can be found at:
https://github.com/quic/riscv-unified-db/releases/latest

This patch adds assembler only support.

---------

Co-authored-by: Harsh Chandel <hchandel at qti.qualcomm.com>

Added: 
    llvm/test/MC/RISCV/xqcilo-aliases-valid.s
    llvm/test/MC/RISCV/xqcilo-invalid.s
    llvm/test/MC/RISCV/xqcilo-valid.s

Modified: 
    clang/test/Driver/print-supported-extensions-riscv.c
    llvm/docs/RISCVUsage.rst
    llvm/docs/ReleaseNotes.md
    llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
    llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
    llvm/lib/Target/RISCV/RISCVFeatures.td
    llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
    llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
    llvm/lib/TargetParser/RISCVISAInfo.cpp
    llvm/test/CodeGen/RISCV/attributes.ll
    llvm/unittests/TargetParser/RISCVISAInfoTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index b28e0a07dad241..ae3a1c29df3976 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -197,6 +197,7 @@
 // CHECK-NEXT:     xqcics               0.2       'Xqcics' (Qualcomm uC Conditional Select Extension)
 // CHECK-NEXT:     xqcicsr              0.2       'Xqcicsr' (Qualcomm uC CSR Extension)
 // CHECK-NEXT:     xqciint              0.2       'Xqciint' (Qualcomm uC Interrupts Extension)
+// CHECK-NEXT:     xqcilo               0.2       'Xqcilo' (Qualcomm uC Large Offset Load Store 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:

diff  --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index a1df0f7d686e62..c83fd1db0ba9b5 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -450,6 +450,9 @@ The current vendor extensions supported are:
 ``experimental-Xqciint``
   LLVM implements `version 0.2 of the Qualcomm uC Interrupts 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-Xqcilo``
+  LLVM implements `version 0.2 of the Qualcomm uC Large Offset 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.
+
 ``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.
 

diff  --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 5f9f2f7f9c329a..eb6e9c9b75beb5 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -294,6 +294,8 @@ Changes to the RISC-V Backend
   extension.
 * Adds experimental assembler support for the Qualcomm uC 'Xqciint` (Interrupts)
   extension.
+* Adds experimental assembler support for the Qualcomm uC 'Xqcilo` (Large Offset Load Store)
+  extension.
 * Added ``Sdext`` and ``Sdtrig`` extensions.
 
 Changes to the WebAssembly Backend

diff  --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 8177280044bf44..227a6361730da6 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -1036,6 +1036,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
            VK == RISCVMCExpr::VK_RISCV_None;
   }
 
+  bool isSImm26() const {
+    if (!isImm())
+      return false;
+    RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+    int64_t Imm;
+    bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+    return IsConstantImm && (VK == RISCVMCExpr::VK_RISCV_None) &&
+           isInt<26>(fixImmediateForRV32(Imm, isRV64Imm()));
+  }
+
   /// getStartLoc - Gets location of the first token of this operand
   SMLoc getStartLoc() const override { return StartLoc; }
   /// getEndLoc - Gets location of the last token of this operand
@@ -1676,6 +1686,9 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
                                       (1 << 4),
                                       "immediate must be in the range");
   }
+  case Match_InvalidSImm26:
+    return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 25),
+                                      (1 << 25) - 1);
   case Match_InvalidRlist: {
     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
     return Error(

diff  --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 971ef90c63327d..a0b87f7c7ff257 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -45,6 +45,10 @@ class RISCVDisassembler : public MCDisassembler {
 private:
   void addSPOperands(MCInst &MI) const;
 
+  DecodeStatus getInstruction48(MCInst &Instr, uint64_t &Size,
+                                ArrayRef<uint8_t> Bytes, uint64_t Address,
+                                raw_ostream &CStream) const;
+
   DecodeStatus getInstruction32(MCInst &Instr, uint64_t &Size,
                                 ArrayRef<uint8_t> Bytes, uint64_t Address,
                                 raw_ostream &CStream) const;
@@ -745,6 +749,27 @@ DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size,
   return MCDisassembler::Fail;
 }
 
+DecodeStatus RISCVDisassembler::getInstruction48(MCInst &MI, uint64_t &Size,
+                                                 ArrayRef<uint8_t> Bytes,
+                                                 uint64_t Address,
+                                                 raw_ostream &CS) const {
+  if (Bytes.size() < 6) {
+    Size = 0;
+    return MCDisassembler::Fail;
+  }
+  Size = 6;
+
+  uint64_t Insn = 0;
+  for (size_t i = Size; i-- != 0;) {
+    Insn += (static_cast<uint64_t>(Bytes[i]) << 8 * i);
+  }
+  TRY_TO_DECODE_FEATURE(
+      RISCV::FeatureVendorXqcilo, DecoderTableXqcilo48,
+      "Qualcomm uC Large Offset Load Store custom 48bit opcode table");
+
+  return MCDisassembler::Fail;
+}
+
 DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
                                                ArrayRef<uint8_t> Bytes,
                                                uint64_t Address,
@@ -760,8 +785,7 @@ DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
 
   // 48-bit instructions are encoded as 0bxx011111.
   if ((Bytes[0] & 0b11'1111) == 0b01'1111) {
-    Size = Bytes.size() >= 6 ? 6 : 0;
-    return MCDisassembler::Fail;
+    return getInstruction48(MI, Size, Bytes, Address, CS);
   }
 
   // 64-bit instructions are encoded as 0x0111111.

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index ab04b09a7ad151..e9abc90d69a131 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -332,6 +332,7 @@ enum OperandType : unsigned {
   OPERAND_SIMM10_LSB0000_NONZERO,
   OPERAND_SIMM12,
   OPERAND_SIMM12_LSB00000,
+  OPERAND_SIMM26,
   OPERAND_CLUI_IMM,
   OPERAND_VTYPEI10,
   OPERAND_VTYPEI11,

diff  --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index f721d7148526ba..4119dd77804f1a 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1310,6 +1310,14 @@ def HasVendorXqciint
       AssemblerPredicate<(all_of FeatureVendorXqciint),
                          "'Xqciint' (Qualcomm uC Interrupts Extension)">;
 
+def FeatureVendorXqcilo
+    : RISCVExperimentalExtension<0, 2, "Qualcomm uC Large Offset Load Store Extension",
+                                 [FeatureStdExtZca]>;
+def HasVendorXqcilo
+    : Predicate<"Subtarget->hasVendorXqcilo()">,
+      AssemblerPredicate<(all_of FeatureVendorXqcilo),
+                         "'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)">;
+
 //===----------------------------------------------------------------------===//
 // LLVM specific features and extensions
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index e6678a795c807f..bd02880b0d7129 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -2513,6 +2513,7 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
         CASE_OPERAND_SIMM(5)
         CASE_OPERAND_SIMM(6)
         CASE_OPERAND_SIMM(12)
+        CASE_OPERAND_SIMM(26)
         // clang-format on
         case RISCVOp::OPERAND_SIMM5_PLUS1:
           Ok = (isInt<5>(Imm) && Imm != -16) || Imm == 16;

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index ce8c0c0a3d4e5d..f746cce8c9a0f1 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -32,6 +32,8 @@ def uimm10 : RISCVUImmLeafOp<10>;
 
 def uimm11 : RISCVUImmLeafOp<11>;
 
+def simm26 : RISCVSImmLeafOp<26>;
+
 //===----------------------------------------------------------------------===//
 // Instruction Formats
 //===----------------------------------------------------------------------===//
@@ -198,6 +200,51 @@ class QCIInt_IMM<bits<1> funct1, string opcodestr>
   let Inst{24-20} = imm10{9-5};
 }
 
+class QCIRVInstEIBase<bits<3> funct3, bits<2> funct2, dag outs,
+                      dag ins, string opcodestr, string argstr>
+    : RVInst48<outs, ins, opcodestr, argstr, [], InstFormatOther> {
+  bits<5> rd;
+  bits<5> rs1;
+  bits<26> imm;
+
+  let Inst{47-32} = imm{25-10};
+  let Inst{31-30} = funct2;
+  let Inst{29-20} = imm{9-0};
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = funct3;
+  let Inst{11-7} = rd;
+  let Inst{6-0} = 0b0011111;
+}
+
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+class QCIRVInstEILoad<bits<3> funct3, bits<2> funct2, string opcodestr>
+    : QCIRVInstEIBase<funct3, funct2, (outs GPR:$rd),
+                      (ins GPRMem:$rs1, simm26:$imm), opcodestr,
+                      "$rd, ${imm}(${rs1})">;
+
+class QCIRVInstESBase<bits<3> funct3, bits<2> funct2, dag outs,
+                      dag ins, string opcodestr, string argstr>
+    : RVInst48<outs, ins, opcodestr, argstr, [], InstFormatOther> {
+  bits<5> rs1;
+  bits<5> rs2;
+  bits<26> imm;
+
+  let Inst{47-32} = imm{25-10};
+  let Inst{31-30} = funct2;
+  let Inst{29-25} = imm{9-5};
+  let Inst{24-20} = rs2;
+  let Inst{19-15} = rs1;
+  let Inst{14-12} = funct3;
+  let Inst{11-7} = imm{4-0};
+  let Inst{6-0} = 0b0011111;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
+class QCIRVInstESStore<bits<3> funct3, bits<2> funct2, string opcodestr>
+    : QCIRVInstESBase<funct3, funct2, (outs),
+                      (ins GPRMem:$rs2, GPR:$rs1, simm26:$imm),
+                      opcodestr, "$rs2, ${imm}(${rs1})">;
+
 //===----------------------------------------------------------------------===//
 // Instructions
 //===----------------------------------------------------------------------===//
@@ -376,6 +423,18 @@ let Predicates = [HasVendorXqciint, IsRV32], DecoderNamespace = "Xqciint" in {
   def QC_C_MILEAVERET   : QCIRVInst16CI_NONE<0b10100, "qc.c.mileaveret">;
 } // Predicates = [HasVendorXqciint, IsRV32], DecoderNamespace = "Xqciint"
 
+let Predicates = [HasVendorXqcilo, IsRV32], DecoderNamespace = "Xqcilo" in {
+  def QC_E_LB    : QCIRVInstEILoad<0b101, 0b00, "qc.e.lb">;
+  def QC_E_LBU   : QCIRVInstEILoad<0b101, 0b01, "qc.e.lbu">;
+  def QC_E_LH    : QCIRVInstEILoad<0b101, 0b10, "qc.e.lh">;
+  def QC_E_LHU   : QCIRVInstEILoad<0b101, 0b11, "qc.e.lhu">;
+  def QC_E_LW    : QCIRVInstEILoad<0b110, 0b00, "qc.e.lw">;
+
+  def QC_E_SB    : QCIRVInstESStore<0b110, 0b01, "qc.e.sb">;
+  def QC_E_SH    : QCIRVInstESStore<0b110, 0b10, "qc.e.sh">;
+  def QC_E_SW    : QCIRVInstESStore<0b110, 0b11, "qc.e.sw">;
+} // Predicates = [HasVendorXqcilo, IsRV32], DecoderNamespace = "Xqcilo"
+
 //===----------------------------------------------------------------------===//
 // Aliases
 //===----------------------------------------------------------------------===//
@@ -396,3 +455,24 @@ let EmitPriority = 0 in {
                   (QC_LWMI GPRNoX0:$rd, GPR:$rs1, uimm5nonzero:$length, 0)>;
 } // EmitPriority = 0
 } // Predicates = [HasVendorXqcilsm, IsRV32]
+
+let Predicates = [HasVendorXqcilo, IsRV32] in {
+let EmitPriority = 0 in {
+  def  : InstAlias<"qc.e.lb  $rd, (${rs1})",
+                   (QC_E_LB  GPR:$rd, GPR:$rs1, 0)>;
+  def  : InstAlias<"qc.e.lbu $rd, (${rs1})",
+                   (QC_E_LBU GPR:$rd, GPR:$rs1, 0)>;
+  def  : InstAlias<"qc.e.lh  $rd, (${rs1})",
+                   (QC_E_LH  GPR:$rd, GPR:$rs1, 0)>;
+  def  : InstAlias<"qc.e.lhu $rd, (${rs1})",
+                   (QC_E_LHU GPR:$rd, GPR:$rs1, 0)>;
+  def  : InstAlias<"qc.e.lw  $rd, (${rs1})",
+                   (QC_E_LW  GPR:$rd, GPR:$rs1, 0)>;
+  def  : InstAlias<"qc.e.sb  $rs2, (${rs1})",
+                   (QC_E_SB GPR:$rs2, GPR:$rs1, 0)>;
+  def  : InstAlias<"qc.e.sh  $rs2, (${rs1})",
+                   (QC_E_SH GPR:$rs2, GPR:$rs1, 0)>;
+  def  : InstAlias<"qc.e.sw  $rs2, (${rs1})",
+                   (QC_E_SW GPR:$rs2, GPR:$rs1, 0)>;
+} // EmitPriority = 0
+} // Predicates = [HasVendorXqcilo, IsRV32]

diff  --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index 1995931abfe418..c78d60fd86b3fc 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -742,8 +742,8 @@ Error RISCVISAInfo::checkDependency() {
   bool HasZvl = MinVLen != 0;
   bool HasZcmt = Exts.count("zcmt") != 0;
   static constexpr StringLiteral XqciExts[] = {
-      {"xqcia"},   {"xqciac"},  {"xqcicli"}, {"xqcicm"}, {"xqcics"},
-      {"xqcicsr"}, {"xqciint"}, {"xqcilsm"}, {"xqcisls"}};
+      {"xqcia"},   {"xqciac"},  {"xqcicli"}, {"xqcicm"},  {"xqcics"},
+      {"xqcicsr"}, {"xqciint"}, {"xqcilo"},  {"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 a09261609d8441..caed0bdfb04984 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -88,6 +88,7 @@
 ; 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-xqciint %s -o - | FileCheck --check-prefix=RV32XQCIINT %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilo %s -o - | FileCheck --check-prefix=RV32XQCILO %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
@@ -403,6 +404,7 @@
 ; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
 ; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
 ; RV32XQCIINT: .attribute 5, "rv32i2p1_zca1p0_xqciint0p2"
+; RV32XQCILO: .attribute 5, "rv32i2p1_zca1p0_xqcilo0p2"
 ; RV32XQCILSM: .attribute 5, "rv32i2p1_xqcilsm0p2"
 ; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
 ; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"

diff  --git a/llvm/test/MC/RISCV/xqcilo-aliases-valid.s b/llvm/test/MC/RISCV/xqcilo-aliases-valid.s
new file mode 100644
index 00000000000000..dddd76260b248e
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcilo-aliases-valid.s
@@ -0,0 +1,50 @@
+# Xqcilo - Qualcomm uC Large Offset Load Store extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilo -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilo < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcilo -M no-aliases --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilo -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilo < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcilo --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.e.lb a1, 0(a0)
+# CHECK-ENC: encoding: [0x9f,0x55,0x05,0x00,0x00,0x00]
+qc.e.lb x11, (x10)
+
+
+# CHECK-INST: qc.e.lbu        a1, 0(a0)
+# CHECK-ENC: encoding: [0x9f,0x55,0x05,0x40,0x00,0x00]
+qc.e.lbu x11, (x10)
+
+
+# CHECK-INST: qc.e.lh a1, 0(a0)
+# CHECK-ENC: encoding: [0x9f,0x55,0x05,0x80,0x00,0x00]
+qc.e.lh x11, (x10)
+
+
+# CHECK-INST: qc.e.lhu        a1, 0(a0)
+# CHECK-ENC: encoding: [0x9f,0x55,0x05,0xc0,0x00,0x00]
+qc.e.lhu x11, (x10)
+
+
+# CHECK-INST: qc.e.lw a1, 0(a0)
+# CHECK-ENC: encoding: [0x9f,0x65,0x05,0x00,0x00,0x00]
+qc.e.lw x11, (x10)
+
+
+# CHECK-INST: qc.e.sb a1, 0(a0)
+# CHECK-ENC: encoding: [0x1f,0x60,0xb5,0x40,0x00,0x00]
+qc.e.sb x11, (x10)
+
+
+# CHECK-INST: qc.e.sh a1, 0(a0)
+# CHECK-ENC: encoding: [0x1f,0x60,0xb5,0x80,0x00,0x00]
+qc.e.sh x11, (x10)
+
+
+# CHECK-INST: qc.e.sw a1, 0(a0)
+# CHECK-ENC: encoding: [0x1f,0x60,0xb5,0xc0,0x00,0x00]
+qc.e.sw x11, (x10)

diff  --git a/llvm/test/MC/RISCV/xqcilo-invalid.s b/llvm/test/MC/RISCV/xqcilo-invalid.s
new file mode 100644
index 00000000000000..c298f94ece7596
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcilo-invalid.s
@@ -0,0 +1,108 @@
+# Xqcilo - Qualcomm uC Extension Large Offset Load Store extension
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcilo < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-IMM %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcilo < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-EXT %s
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.e.lb 11, 12(x10)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.e.lb x11
+
+# CHECK-IMM: :[[@LINE+1]]:14: error: immediate must be an integer in the range [-33554432, 33554431]
+qc.e.lb x11, 33445562212(x10)
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
+qc.e.lb x11, 12(x10)
+
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.e.lbu 11, 12(x10)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.e.lbu x11
+
+# CHECK-IMM: :[[@LINE+1]]:15: error: immediate must be an integer in the range [-33554432, 33554431]
+qc.e.lbu x11, 33445562212(x10)
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
+qc.e.lbu x11, 12(x10)
+
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.e.lh 11, 12(x10)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.e.lh x11
+
+# CHECK-IMM: :[[@LINE+1]]:14: error: immediate must be an integer in the range [-33554432, 33554431]
+qc.e.lh x11, 33445562212(x10)
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
+qc.e.lh x11, 12(x10)
+
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.e.lhu 11, 12(x10)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.e.lhu x11
+
+# CHECK-IMM: :[[@LINE+1]]:15: error: immediate must be an integer in the range [-33554432, 33554431]
+qc.e.lhu x11, 33445562212(x10)
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
+qc.e.lhu x11, 12(x10)
+
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.e.lw 11, 12(x10)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.e.lw x11
+
+# CHECK-IMM: :[[@LINE+1]]:14: error: immediate must be an integer in the range [-33554432, 33554431]
+qc.e.lw x11, 33445562212(x10)
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
+qc.e.lw x11, 12(x10)
+
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.e.sb 11, 12(x10)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.e.sb x11
+
+# CHECK-IMM: :[[@LINE+1]]:14: error: immediate must be an integer in the range [-33554432, 33554431]
+qc.e.sb x11, 33445562212(x10)
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
+qc.e.sb x11, 12(x10)
+
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.e.sh 11, 12(x10)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.e.sh x11
+
+# CHECK-IMM: :[[@LINE+1]]:14: error: immediate must be an integer in the range [-33554432, 33554431]
+qc.e.sh x11, 33445562212(x10)
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
+qc.e.sh x11, 12(x10)
+
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.e.sw 11, 12(x10)
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.e.sw x11
+
+# CHECK-IMM: :[[@LINE+1]]:14: error: immediate must be an integer in the range [-33554432, 33554431]
+qc.e.sw x11, 33445562212(x10)
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
+qc.e.sw x11, 12(x10)

diff  --git a/llvm/test/MC/RISCV/xqcilo-valid.s b/llvm/test/MC/RISCV/xqcilo-valid.s
new file mode 100644
index 00000000000000..ce486e39313ab8
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcilo-valid.s
@@ -0,0 +1,114 @@
+# Xqcilo - Qualcomm uC Large Offset Load Store extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilo -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilo < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcilo -M no-aliases --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcilo -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcilo < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqcilo --no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.e.lb a1, 12(a0)
+# CHECK-ENC: encoding: [0x9f,0x55,0xc5,0x00,0x00,0x00]
+qc.e.lb x11, 12(x10)
+
+# CHECK-INST: qc.e.lb a1, -33554432(a0)
+# CHECK-ENC: encoding: [0x9f,0x55,0x05,0x00,0x00,0x80]
+qc.e.lb x11, -33554432(x10)
+
+# CHECK-INST: qc.e.lb a1, 33554431(a0)
+# CHECK-ENC: encoding: [0x9f,0x55,0xf5,0x3f,0xff,0x7f]
+qc.e.lb x11, 33554431(x10)
+
+
+# CHECK-INST: qc.e.lbu        a1, 12(a0)
+# CHECK-ENC: encoding: [0x9f,0x55,0xc5,0x40,0x00,0x00]
+qc.e.lbu x11, 12(x10)
+
+# CHECK-INST: qc.e.lbu        a1, -33554432(a0)
+# CHECK-ENC: encoding: [0x9f,0x55,0x05,0x40,0x00,0x80]
+qc.e.lbu x11, -33554432(x10)
+
+# CHECK-INST: qc.e.lbu        a1, 33554431(a0)
+# CHECK-ENC: encoding: [0x9f,0x55,0xf5,0x7f,0xff,0x7f]
+qc.e.lbu x11, 33554431(x10)
+
+
+# CHECK-INST: qc.e.lh a1, 12(a0)
+# CHECK-ENC: encoding: [0x9f,0x55,0xc5,0x80,0x00,0x00]
+qc.e.lh x11, 12(x10)
+
+# CHECK-INST: qc.e.lh a1, -33554432(a0)
+# CHECK-ENC: encoding: [0x9f,0x55,0x05,0x80,0x00,0x80]
+qc.e.lh x11, -33554432(x10)
+
+# CHECK-INST: qc.e.lh a1, 33554431(a0)
+# CHECK-ENC: encoding: [0x9f,0x55,0xf5,0xbf,0xff,0x7f]
+qc.e.lh x11, 33554431(x10)
+
+
+# CHECK-INST: qc.e.lhu        a1, 12(a0)
+# CHECK-ENC: encoding: [0x9f,0x55,0xc5,0xc0,0x00,0x00]
+qc.e.lhu x11, 12(x10)
+
+# CHECK-INST: qc.e.lhu        a1, -33554432(a0)
+# CHECK-ENC: encoding: [0x9f,0x55,0x05,0xc0,0x00,0x80]
+qc.e.lhu x11, -33554432(x10)
+
+# CHECK-INST: qc.e.lhu        a1, 33554431(a0)
+# CHECK-ENC: encoding: [0x9f,0x55,0xf5,0xff,0xff,0x7f]
+qc.e.lhu x11, 33554431(x10)
+
+
+# CHECK-INST: qc.e.lw a1, 12(a0)
+# CHECK-ENC: encoding: [0x9f,0x65,0xc5,0x00,0x00,0x00]
+qc.e.lw x11, 12(x10)
+
+# CHECK-INST: qc.e.lw a1, -33554432(a0)
+# CHECK-ENC: encoding: [0x9f,0x65,0x05,0x00,0x00,0x80]
+qc.e.lw x11, -33554432(x10)
+
+# CHECK-INST: qc.e.lw a1, 33554431(a0)
+# CHECK-ENC: encoding: [0x9f,0x65,0xf5,0x3f,0xff,0x7f]
+qc.e.lw x11, 33554431(x10)
+
+
+# CHECK-INST: qc.e.sb a1, 12(a0)
+# CHECK-ENC: encoding: [0x1f,0x66,0xb5,0x40,0x00,0x00]
+qc.e.sb x11, 12(x10)
+
+# CHECK-INST: qc.e.sb a1, -33554432(a0)
+# CHECK-ENC: encoding: [0x1f,0x60,0xb5,0x40,0x00,0x80]
+qc.e.sb x11, -33554432(x10)
+
+# CHECK-INST: qc.e.sb a1, 33554431(a0)
+# CHECK-ENC: encoding: [0x9f,0x6f,0xb5,0x7e,0xff,0x7f]
+qc.e.sb x11, 33554431(x10)
+
+
+# CHECK-INST: qc.e.sh a1, 12(a0)
+# CHECK-ENC: encoding: [0x1f,0x66,0xb5,0x80,0x00,0x00]
+qc.e.sh x11, 12(x10)
+
+# CHECK-INST: qc.e.sh a1, -33554432(a0)
+# CHECK-ENC: encoding: [0x1f,0x60,0xb5,0x80,0x00,0x80]
+qc.e.sh x11, -33554432(x10)
+
+# CHECK-INST: qc.e.sh a1, 33554431(a0)
+# CHECK-ENC: encoding: [0x9f,0x6f,0xb5,0xbe,0xff,0x7f]
+qc.e.sh x11, 33554431(x10)
+
+
+# CHECK-INST: qc.e.sw a1, 12(a0)
+# CHECK-ENC: encoding: [0x1f,0x66,0xb5,0xc0,0x00,0x00]
+qc.e.sw x11, 12(x10)
+
+# CHECK-INST: qc.e.sw a1, -33554432(a0)
+# CHECK-ENC: encoding: [0x1f,0x60,0xb5,0xc0,0x00,0x80]
+qc.e.sw x11, -33554432(x10)
+
+# CHECK-INST: qc.e.sw a1, 33554431(a0)
+# CHECK-ENC: encoding: [0x9f,0x6f,0xb5,0xfe,0xff,0x7f]
+qc.e.sw x11, 33554431(x10)

diff  --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 3a7ea4550d4173..14a60c1857f24f 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -656,7 +656,8 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
   for (StringRef Input :
        {"rv64i_xqcisls0p2", "rv64i_xqcia0p2", "rv64i_xqciac0p2",
         "rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcicm0p2",
-        "rv64i_xqcics0p2", "rv64i_xqcicli0p2", "rv64i_xqciint0p2"}) {
+        "rv64i_xqcics0p2", "rv64i_xqcicli0p2", "rv64i_xqciint0p2",
+        "rv64i_xqcilo0p2"}) {
     EXPECT_THAT(
         toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
         ::testing::EndsWith(" is only supported for 'rv32'"));
@@ -1122,6 +1123,7 @@ Experimental extensions
     xqcics               0.2
     xqcicsr              0.2
     xqciint              0.2
+    xqcilo               0.2
     xqcilsm              0.2
     xqcisls              0.2
 


        


More information about the llvm-commits mailing list