Author: Sudharsan Veeravalli
Date: 2024-11-29T10:26:00+05:30
New Revision: 8fcbba82d6c8038c4a0c5859275523414107b198

URL: 
https://github.com/llvm/llvm-project/commit/8fcbba82d6c8038c4a0c5859275523414107b198
DIFF: 
https://github.com/llvm/llvm-project/commit/8fcbba82d6c8038c4a0c5859275523414107b198.diff

LOG: [RISCV] Add Qualcomm uC Xqcisls (Scaled Load Store) extension (#117987)

This extension adds 8 load/store instructions with a scaled index
addressing mode.

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

This patch adds assembler only support.

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

Modified: 
    clang/test/Driver/print-supported-extensions-riscv.c
    llvm/docs/RISCVUsage.rst
    llvm/docs/ReleaseNotes.md
    llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
    llvm/lib/Target/RISCV/RISCVFeatures.td
    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 02edfc03e59cac..70b7a96daf1daf 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -189,6 +189,7 @@
 // CHECK-NEXT:     ssctr                1.0       'Ssctr' (Control Transfer 
Records Supervisor Level)
 // CHECK-NEXT:     svukte               0.3       'Svukte' 
(Address-Independent Latency of User-Mode Faults to Supervisor Addresses)
 // CHECK-NEXT:     xqcicsr              0.2       'Xqcicsr' (Qualcomm uC CSR 
Extension)
+// CHECK-NEXT:     xqcisls              0.2       'Xqcisls' (Qualcomm uC 
Scaled Load Store Extension)
 // CHECK-EMPTY:
 // CHECK-NEXT: Supported Profiles
 // CHECK-NEXT:     rva20s64

diff  --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index a7000baa69d806..230bf66fcf461b 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -429,6 +429,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-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.
+
 Experimental C Intrinsics
 =========================
 

diff  --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 8b155d77bbb397..6d50839d68953e 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -213,6 +213,8 @@ Changes to the RISC-V Backend
   between e.g. F and Zfinx code.
 * Adds experimental assembler support for the Qualcomm uC 'Xqcicsr` (CSR)
   extension.
+* Adds experimental assembler support for the Qualcomm uC 'Xqcisls` (Scaled 
Load Store)
+  extension.
 
 Changes to the WebAssembly Backend
 ----------------------------------

diff  --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp 
b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index e4f7ee323cf20b..95658f24f79e1c 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -684,6 +684,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst 
&MI, uint64_t &Size,
                         "CORE-V Immediate Branching custom opcode table");
   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcicsr, DecoderTableXqcicsr32,
                         "Qualcomm uC CSR custom opcode table");
+  TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcisls, DecoderTableXqcisls32,
+                        "Qualcomm uC Scaled Load Store custom opcode table");
   TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
 
   return MCDisassembler::Fail;

diff  --git a/llvm/lib/Target/RISCV/RISCVFeatures.td 
b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 48ae378c0e67ef..95a37a76836729 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1351,6 +1351,14 @@ def HasVendorXqcicsr
       AssemblerPredicate<(all_of FeatureVendorXqcicsr),
                          "'Xqcicsr' (Qualcomm uC CSR Extension)">;
 
+def FeatureVendorXqcisls
+    : RISCVExperimentalExtension<"xqcisls", 0, 2,
+                                 "'Xqcisls' (Qualcomm uC Scaled Load Store 
Extension)">;
+def HasVendorXqcisls
+    : Predicate<"Subtarget->hasVendorXqcisls()">,
+      AssemblerPredicate<(all_of FeatureVendorXqcisls),
+                         "'Xqcisls' (Qualcomm uC Scaled Load Store 
Extension)">;
+
 
//===----------------------------------------------------------------------===//
 // LLVM specific features and extensions
 
//===----------------------------------------------------------------------===//

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td 
b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 570fe23d744e14..5f560aa0cc7bc0 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -22,6 +22,29 @@
 // Instruction Class Templates
 
//===----------------------------------------------------------------------===//
 
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
+class QCILoad_ScaleIdx<bits<4> func4, string opcodestr>
+    : RVInstRBase<0b111, OPC_CUSTOM_0,
+                  (outs GPR:$rd), (ins GPRMem:$rs1, GPRNoX0:$rs2, 
uimm3:$shamt),
+                  opcodestr, "$rd, $rs1, $rs2, $shamt"> {
+  bits<3> shamt;
+  let Inst{31-28} = func4;
+  let Inst{27-25} = shamt;
+}
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
+// rd corresponds to the source for the store 'rs3' described in the spec.
+class QCIStore_ScaleIdx<bits<4> func4, string opcodestr>
+    : RVInstRBase<0b110, OPC_CUSTOM_1, (outs),
+                  (ins GPR:$rd, GPRMem:$rs1, GPRNoX0:$rs2, uimm3:$shamt),
+                  opcodestr, "$rd, $rs1, $rs2, $shamt"> {
+  bits<3> shamt;
+  let Inst{31-28} = func4;
+  let Inst{27-25} = shamt;
+}
+}
+
 
//===----------------------------------------------------------------------===//
 // Instructions
 
//===----------------------------------------------------------------------===//
@@ -37,3 +60,15 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
                            "$rd, $rs1, $rs2">;
 } // hasSideEffects = 0, mayLoad = 0, mayStore = 0
 } // Predicates = [HasVendorXqcicsr, IsRV32], DecoderNamespace = "Xqcicsr"
+
+let Predicates = [HasVendorXqcisls, IsRV32], DecoderNamespace = "Xqcisls" in {
+  def  QC_LRB  : QCILoad_ScaleIdx<0b1000, "qc.lrb">;
+  def  QC_LRH  : QCILoad_ScaleIdx<0b1001, "qc.lrh">;
+  def  QC_LRW  : QCILoad_ScaleIdx<0b1010, "qc.lrw">;
+  def  QC_LRBU : QCILoad_ScaleIdx<0b1011, "qc.lrbu">;
+  def  QC_LRHU : QCILoad_ScaleIdx<0b1100, "qc.lrhu">;
+
+  def  QC_SRB  : QCIStore_ScaleIdx<0b1101, "qc.srb">;
+  def  QC_SRH  : QCIStore_ScaleIdx<0b1110, "qc.srh">;
+  def  QC_SRW  : QCIStore_ScaleIdx<0b1111, "qc.srw">;
+} // Predicates = [HasVendorXqcisls, IsRV32], DecoderNamespace = "Xqcisls"

diff  --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp 
b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index cc5be59572e040..5673866f9d9d9d 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -741,6 +741,7 @@ Error RISCVISAInfo::checkDependency() {
   bool HasVector = Exts.count("zve32x") != 0;
   bool HasZvl = MinVLen != 0;
   bool HasZcmt = Exts.count("zcmt") != 0;
+  static constexpr StringLiteral XqciExts[] = {{"xqcicsr"}, {"xqcisls"}};
 
   if (HasI && HasE)
     return getIncompatibleError("i", "e");
@@ -771,9 +772,9 @@ Error RISCVISAInfo::checkDependency() {
       return getIncompatibleError("xwchc", "zcb");
   }
 
-  if (Exts.count("xqcicsr") != 0 && (XLen != 32)) {
-    return getError("'xqcicsr' is only supported for 'rv32'");
-  }
+  for (auto Ext : XqciExts)
+    if (Exts.count(Ext.str()) && (XLen != 32))
+      return getError("'" + Twine(Ext) + "'" + " is only supported for 
'rv32'");
 
   return Error::success();
 }

diff  --git a/llvm/test/CodeGen/RISCV/attributes.ll 
b/llvm/test/CodeGen/RISCV/attributes.ll
index 554ae89357f72c..8a3d5e5cfe6216 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -82,6 +82,7 @@
 ; RUN: llc -mtriple=riscv32 -mattr=+xtheadsync %s -o - | FileCheck 
--check-prefix=RV32XTHEADSYNC %s
 ; RUN: llc -mtriple=riscv32 -mattr=+xwchc %s -o - | FileCheck 
--check-prefix=RV32XWCHC %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck 
--check-prefix=RV32XQCICSR %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
 ; RUN: llc -mtriple=riscv32 -mattr=+zca %s -o - | FileCheck 
--check-prefixes=CHECK,RV32ZCA %s
@@ -387,6 +388,7 @@
 ; RV32XTHEADSYNC: .attribute 5, "rv32i2p1_xtheadsync1p0"
 ; RV32XWCHC: .attribute 5, "rv32i2p1_xwchc2p2"
 ; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
+; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
 ; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
 ; RV32ZALRSC: .attribute 5, "rv32i2p1_zalrsc1p0"
 ; RV32ZCA: .attribute 5, "rv32i2p1_zca1p0"

diff  --git a/llvm/test/MC/RISCV/xqcisls-invalid.s 
b/llvm/test/MC/RISCV/xqcisls-invalid.s
new file mode 100644
index 00000000000000..4cd2a14975a946
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcisls-invalid.s
@@ -0,0 +1,132 @@
+# Xqcisls - Qualcomm uC Scaled Load Store Extension
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcisls < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcisls < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.lrb x5, x2, x0, 4
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.lrb x5, x2, x4
+
+# CHECK-PLUS: :[[@LINE+1]]:20: error: immediate must be an integer in the 
range [0, 7]
+qc.lrb x5, x2, x4, 12
+
+# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+qc.lrb x5, 2, x4, 4
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 
'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
+qc.lrb x5, x2, x4, 4
+
+
+# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction
+qc.lrh x1, x12, x0, 2
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.lrh x1, x12, x6
+
+# CHECK-PLUS: :[[@LINE+1]]:21: error: immediate must be an integer in the 
range [0, 7]
+qc.lrh x1, x12, x6, 22
+
+# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+qc.lrh x1, 12, x6, 2
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 
'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
+qc.lrh x1, x12, x6, 2
+
+
+# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction
+qc.lrw x15, x7, x0, 1
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.lrw x15, x7, x14
+
+# CHECK-PLUS: :[[@LINE+1]]:22: error: immediate must be an integer in the 
range [0, 7]
+qc.lrw x15, x7, x14, 11
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.lrw x15, 7, x14, 1
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 
'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
+qc.lrw x15, x7, x14, 1
+
+
+# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
+qc.lrbu x9, x11, x0, 7
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.lrbu x9, x11, x4
+
+# CHECK-PLUS: :[[@LINE+1]]:22: error: immediate must be an integer in the 
range [0, 7]
+qc.lrbu x9, x11, x4, 37
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.lrbu x9, 11, x4, 7
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 
'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
+qc.lrbu x9, x11, x4, 7
+
+
+# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
+qc.lrhu x16, x6, x0, 4
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.lrhu x16, x6, x10
+
+# CHECK-PLUS: :[[@LINE+1]]:23: error: immediate must be an integer in the 
range [0, 7]
+qc.lrhu x16, x6, x10, 44
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.lrhu x16, 6, x10, 4
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 
'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
+qc.lrhu x16, x6, x10, 4
+
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.srb x0, x2, x0, 3
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.srb x0, x2, x8
+
+# CHECK-PLUS: :[[@LINE+1]]:20: error: immediate must be an integer in the 
range [0, 7]
+qc.srb x0, x2, x8, 93
+
+# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
+qc.srb x0, 2, x8, 3
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 
'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
+qc.srb x0, x2, x8, 3
+
+
+# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction
+qc.srh x13, x0, x0, 6
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.srh x13, x0, x20
+
+# CHECK-PLUS: :[[@LINE+1]]:22: error: immediate must be an integer in the 
range [0, 7]
+qc.srh x13, x0, x20, 76
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.srh x13, 0, x20, 6
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 
'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
+qc.srh x13, x0, x20, 6
+
+
+# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
+qc.srw x17, x18, x0, 0
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.srw x17, x18, x19
+
+# CHECK-PLUS: :[[@LINE+1]]:23: error: immediate must be an integer in the 
range [0, 7]
+qc.srw x17, x18, x19, 10
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.srw x17, 18, x19, 0
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 
'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
+qc.srw x17, x18, x19, 0

diff  --git a/llvm/test/MC/RISCV/xqcisls-valid.s 
b/llvm/test/MC/RISCV/xqcisls-valid.s
new file mode 100644
index 00000000000000..ae8370afc6c6e2
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqcisls-valid.s
@@ -0,0 +1,43 @@
+# Xqcisls - Qualcomm uC Scaled Load Store Extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcisls 
-riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcisls < %s 
\
+# RUN:     | llvm-objdump --mattr=+experimental-xqcisls -M no-aliases 
--no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcisls -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcisls < %s 
\
+# RUN:     | llvm-objdump --mattr=+experimental-xqcisls --no-print-imm-hex -d 
- \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.lrb    t0, sp, tp, 4
+# CHECK-ENC: encoding: [0x8b,0x72,0x41,0x88]
+qc.lrb x5, x2, x4, 4
+
+# CHECK-INST: qc.lrh    ra, a2, t1, 2
+# CHECK-ENC: encoding: [0x8b,0x70,0x66,0x94]
+qc.lrh x1, x12, x6, 2
+
+# CHECK-INST: qc.lrw    a5, t2, a4, 1
+# CHECK-ENC: encoding: [0x8b,0xf7,0xe3,0xa2]
+qc.lrw x15, x7, x14, 1
+
+# CHECK-INST: qc.lrbu    s1, a1, tp, 7
+# CHECK-ENC: encoding: [0x8b,0xf4,0x45,0xbe]
+qc.lrbu x9, x11, x4, 7
+
+# CHECK-INST: qc.lrhu    a6, t1, a0, 4
+# CHECK-ENC: encoding: [0x0b,0x78,0xa3,0xc8]
+qc.lrhu x16, x6, x10, 4
+
+# CHECK-INST: qc.srb    zero, sp, s0, 3
+# CHECK-ENC: encoding: [0x2b,0x60,0x81,0xd6]
+qc.srb x0, x2, x8, 3
+
+# CHECK-INST: qc.srh    a3, zero, s4, 6
+# CHECK-ENC: encoding: [0xab,0x66,0x40,0xed]
+qc.srh x13, x0, x20, 6
+
+# CHECK-INST: qc.srw    a7, s2, s3, 0
+# CHECK-ENC: encoding: [0xab,0x68,0x39,0xf1]
+qc.srw x17, x18, x19, 0

diff  --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp 
b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 4b450e23627168..23f1d832773ccf 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -652,6 +652,11 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
     EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
               "'xwchc' and 'zcb' extensions are incompatible");
   }
+
+  for (StringRef Input : {"rv64i_xqcisls0p2"}) {
+    EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
+              "'xqcisls' is only supported for 'rv32'");
+  }
 }
 
 TEST(ParseArchString, MissingDepency) {
@@ -1105,6 +1110,7 @@ Experimental extensions
     ssctr                1.0
     svukte               0.3
     xqcicsr              0.2
+    xqcisls              0.2
 
 Supported Profiles
     rva20s64


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to