llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: quic_hchandel (hchandel)

<details>
<summary>Changes</summary>

This extension adds two external input output instructions for a
non-memory-mapped device.

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

This patch adds assembler only support.

Co-authored-by: Sudharsan Veeravalli &lt;quic_svs@<!-- -->quicinc.com&gt;

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


13 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 (+14) 
- (modified) llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (+9-9) 
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h (+1) 
- (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+7) 
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+31) 
- (modified) llvm/lib/TargetParser/RISCVISAInfo.cpp (+3-3) 
- (modified) llvm/test/CodeGen/RISCV/attributes.ll (+2) 
- (added) llvm/test/MC/RISCV/xqciio-invalid.s (+40) 
- (added) llvm/test/MC/RISCV/xqciio-valid.s (+20) 
- (modified) llvm/unittests/TargetParser/RISCVISAInfoTest.cpp (+4-3) 


``````````diff
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c 
b/clang/test/Driver/print-supported-extensions-riscv.c
index b5533b54347b9..a4176e7a33ac9 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -206,6 +206,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.4       'Xqciint' (Qualcomm uC 
Interrupts Extension)
+// CHECK-NEXT:     xqciio               0.1       'Xqciio' (Qualcomm uC 
External Input Output Extension)
 // CHECK-NEXT:     xqcilb               0.2       'Xqcilb' (Qualcomm uC Long 
Branch Extension)
 // CHECK-NEXT:     xqcili               0.2       'Xqcili' (Qualcomm uC Load 
Large Immediate Extension)
 // CHECK-NEXT:     xqcilia              0.2       'Xqcilia' (Qualcomm uC Large 
Immediate Arithmetic Extension)
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 8735b274a805f..cda7e5fec8488 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -461,6 +461,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-Xqciio``
+  LLVM implements `version 0.1 of the Qualcomm uC External Input Output 
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-Xqciint``
   LLVM implements `version 0.4 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.
 
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 1e39f761ecdad..a388a728a13a7 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -142,6 +142,8 @@ Changes to the RISC-V Backend
   extension.
 * Adds experimental assembler support for the Qualcomm uC 'Xqcisync` (Sync 
Delay)
   extension.
+* Adds experimental assembler support for the Qualcomm uC 'Xqciio` (External 
Input Output)
+  extension.
 * Adds assembler support for the 'Zilsd` (Load/Store Pair Instructions)
   extension.
 * Adds assembler support for the 'Zclsd` (Compressed Load/Store Pair 
Instructions)
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp 
b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 05997cf78c6b1..07ed538fd01c1 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -987,6 +987,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
     return SignExtend64<32>(Imm);
   }
 
+  bool isUImm14Lsb00() const {
+    if (!isImm())
+      return false;
+    int64_t Imm;
+    RISCVMCExpr::Specifier VK = RISCVMCExpr::VK_None;
+    bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+    return IsConstantImm && isShiftedUInt<12, 2>(Imm) &&
+           VK == RISCVMCExpr::VK_None;
+  }
+
   bool isSImm11() const {
     if (!isImm())
       return false;
@@ -1741,6 +1751,10 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc 
IDLoc, unsigned &Opcode,
     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
   case Match_InvalidUImm11:
     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
+  case Match_InvalidUImm14Lsb00:
+    return generateImmOutOfRangeError(
+        Operands, ErrorInfo, 0, (1 << 14) - 4,
+        "immediate must be a multiple of 4 bytes in the range");
   case Match_InvalidUImm16NonZero:
     return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16) - 1);
   case Match_InvalidSImm12:
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp 
b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 93cbf662bfa32..49dc46d0b0918 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -672,15 +672,15 @@ static constexpr FeatureBitset XRivosFeatureGroup = {
 };
 
 static constexpr FeatureBitset XqciFeatureGroup = {
-    RISCV::FeatureVendorXqcia,    RISCV::FeatureVendorXqciac,
-    RISCV::FeatureVendorXqcibi,   RISCV::FeatureVendorXqcibm,
-    RISCV::FeatureVendorXqcicli,  RISCV::FeatureVendorXqcicm,
-    RISCV::FeatureVendorXqcics,   RISCV::FeatureVendorXqcicsr,
-    RISCV::FeatureVendorXqciint,  RISCV::FeatureVendorXqcilb,
-    RISCV::FeatureVendorXqcili,   RISCV::FeatureVendorXqcilia,
-    RISCV::FeatureVendorXqcilo,   RISCV::FeatureVendorXqcilsm,
-    RISCV::FeatureVendorXqcisim,  RISCV::FeatureVendorXqcisls,
-    RISCV::FeatureVendorXqcisync,
+    RISCV::FeatureVendorXqcia,   RISCV::FeatureVendorXqciac,
+    RISCV::FeatureVendorXqcibi,  RISCV::FeatureVendorXqcibm,
+    RISCV::FeatureVendorXqcicli, RISCV::FeatureVendorXqcicm,
+    RISCV::FeatureVendorXqcics,  RISCV::FeatureVendorXqcicsr,
+    RISCV::FeatureVendorXqciint, RISCV::FeatureVendorXqciio,
+    RISCV::FeatureVendorXqcilb,  RISCV::FeatureVendorXqcili,
+    RISCV::FeatureVendorXqcilia, RISCV::FeatureVendorXqcilo,
+    RISCV::FeatureVendorXqcilsm, RISCV::FeatureVendorXqcisim,
+    RISCV::FeatureVendorXqcisls, RISCV::FeatureVendorXqcisync,
 };
 
 static constexpr FeatureBitset XSfVectorGroup = {
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h 
b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index db305b0083415..b4c61779e8f50 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -314,6 +314,7 @@ enum OperandType : unsigned {
   OPERAND_UIMM10_LSB00_NONZERO,
   OPERAND_UIMM11,
   OPERAND_UIMM12,
+  OPERAND_UIMM14_LSB00,
   OPERAND_UIMM16,
   OPERAND_UIMM16_NONZERO,
   OPERAND_UIMM20,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td 
b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 85e3675beb80e..385d490b1fc14 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1376,6 +1376,13 @@ def HasVendorXqcicm
       AssemblerPredicate<(all_of FeatureVendorXqcicm),
                          "'Xqcicm' (Qualcomm uC Conditional Move Extension)">;
 
+def FeatureVendorXqciio
+    : RISCVExperimentalExtension<0, 1, "Qualcomm uC External Input Output 
Extension">;
+def HasVendorXqciio
+    : Predicate<"Subtarget->hasVendorXqciio()">,
+      AssemblerPredicate<(all_of FeatureVendorXqciio),
+                         "'Xqciio' (Qualcomm uC External Input Output 
Extension)">;
+
 def FeatureVendorXqciint
     : RISCVExperimentalExtension<0, 4, "Qualcomm uC Interrupts Extension",
                                  [FeatureStdExtZca]>;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td 
b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 69290c0da1824..22cfbd95f72ef 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -69,6 +69,15 @@ def uimm10 : RISCVUImmLeafOp<10>;
 
 def uimm11 : RISCVUImmLeafOp<11>;
 
+// A 14-bit unsigned immediate where the least significant two bits are zero.
+def uimm14lsb00 : RISCVOp,
+                  ImmLeaf<XLenVT, [{return isShiftedUInt<12, 2>(Imm);}]> {
+  let ParserMatchClass = UImmAsmOperand<14, "Lsb00">;
+  let EncoderMethod = "getImmOpValue";
+  let DecoderMethod = "decodeUImmOperand<14>";
+  let OperandType = "OPERAND_UIMM14_LSB00";
+}
+
 def uimm16nonzero : RISCVOp<XLenVT>,
                     ImmLeaf<XLenVT, [{return (Imm != 0) && isUInt<16>(Imm);}]> 
{
   let ParserMatchClass = UImmAsmOperand<16, "NonZero">;
@@ -741,6 +750,28 @@ def QC_C_MILEAVERET   : QCIRVInst16CI_NONE<0b10100, 
"qc.c.mileaveret">;
 
 } // Predicates = [HasVendorXqciint, IsRV32], hasSideEffects = 1
 
+let Predicates = [HasVendorXqciio, IsRV32] in {
+let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in {
+  def QC_OUTW : RVInstI<0b100, OPC_CUSTOM_0, (outs),
+                        (ins GPR:$rs3, GPR:$rs1, uimm14lsb00:$imm14),
+                        "qc.outw", "$rs3, ${imm14}(${rs1})"> {
+    bits<5> rs3;
+    bits<14> imm14;
+
+    let rd = rs3;
+    let imm12 = imm14{13-2};
+  }
+
+  def QC_INW : RVInstI<0b101, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
+                       (ins GPR:$rs1, uimm14lsb00:$imm14),
+                       "qc.inw", "$rd, ${imm14}(${rs1})"> {
+    bits<14> imm14;
+
+    let imm12 = imm14{13-2};
+  }
+} // hasSideEffects = 1, mayLoad = 0, mayStore = 0
+} // Predicates = [HasVendorXqciio, IsRV32]
+
 let Predicates = [HasVendorXqcilo, IsRV32] in {
   def QC_E_LB    : QCIRVInstEILoad<0b101, 0b00, "qc.e.lb">;
   def QC_E_LBU   : QCIRVInstEILoad<0b101, 0b01, "qc.e.lbu">;
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp 
b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index 0f7673c624c92..713da131e52dc 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -745,9 +745,9 @@ Error RISCVISAInfo::checkDependency() {
 
   static constexpr StringLiteral XqciExts[] = {
       {"xqcia"},   {"xqciac"},  {"xqcibi"},  {"xqcibm"},  {"xqcicli"},
-      {"xqcicm"},  {"xqcics"},  {"xqcicsr"}, {"xqciint"}, {"xqcilb"},
-      {"xqcili"},  {"xqcilia"}, {"xqcilo"},  {"xqcilsm"}, {"xqcisim"},
-      {"xqcisls"}, {"xqcisync"}};
+      {"xqcicm"},  {"xqcics"},  {"xqcicsr"}, {"xqciint"}, {"xqciio"},
+      {"xqcilb"},  {"xqcili"},  {"xqcilia"}, {"xqcilo"},  {"xqcilsm"},
+      {"xqcisim"}, {"xqcisls"}, {"xqcisync"}};
   static constexpr StringLiteral ZcdOverlaps[] = {
       {"zcmt"}, {"zcmp"}, {"xqccmp"}, {"xqciac"}, {"xqcicm"}};
 
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll 
b/llvm/test/CodeGen/RISCV/attributes.ll
index b1793233339de..bff3bbf53b01e 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -93,6 +93,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-xqciio %s -o - | FileCheck 
--check-prefix=RV32XQCIIO %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilb %s -o - | FileCheck 
--check-prefix=RV32XQCILB %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcili %s -o - | FileCheck 
--check-prefix=RV32XQCILI %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilia %s -o - | FileCheck 
--check-prefix=RV32XQCILIA %s
@@ -428,6 +429,7 @@
 ; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
 ; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
 ; RV32XQCIINT: .attribute 5, "rv32i2p1_zca1p0_xqciint0p4"
+; RV32XQCIIO: .attribute 5, "rv32i2p1_xqciio0p1"
 ; RV32XQCILB: .attribute 5, "rv32i2p1_zca1p0_xqcilb0p2"
 ; RV32XQCILI: .attribute 5, "rv32i2p1_zca1p0_xqcili0p2"
 ; RV32XQCILIA: .attribute 5, "rv32i2p1_zca1p0_xqcilia0p2"
diff --git a/llvm/test/MC/RISCV/xqciio-invalid.s 
b/llvm/test/MC/RISCV/xqciio-invalid.s
new file mode 100644
index 0000000000000..f37e58023c7e1
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqciio-invalid.s
@@ -0,0 +1,40 @@
+# Xqciio - Qualcomm uC External Input Output Extension
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqciio < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqciio < %s 2>&1 \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s
+
+# CHECK: :[[@LINE+1]]:18: error: expected register
+qc.outw x5, 2048(10)
+
+# CHECK-PLUS: :[[@LINE+1]]:13: error: immediate must be a multiple of 4 bytes 
in the range [0, 16380]
+qc.outw x5, x10
+
+# CHECK-MINUS: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.outw x5, x10
+
+# CHECK-PLUS: :[[@LINE+1]]:13: error: immediate must be a multiple of 4 bytes 
in the range [0, 16380]
+qc.outw x5, 4099(x10)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 
'Xqciio' (Qualcomm uC External Input Output Extension)
+qc.outw x5, 2048(x10)
+
+
+# CHECK: :[[@LINE+1]]:19: error: expected register
+qc.inw x23, 16380(17)
+
+# CHECK-PLUS: :[[@LINE+1]]:13: error: immediate must be a multiple of 4 bytes 
in the range [0, 16380]
+qc.inw x23, x17
+
+# CHECK-MINUS: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.inw x23, x17
+
+# CHECK-PLUS: :[[@LINE+2]]:8: error: register must be a GPR excluding zero (x0)
+# CHECK-MINUS: :[[@LINE+1]]:8: error: invalid operand for instruction
+qc.inw x0, 16380(x17)
+
+# CHECK-PLUS: :[[@LINE+1]]:13: error: immediate must be a multiple of 4 bytes 
in the range [0, 16380]
+qc.inw x23, 16384(x17)
+
+# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 
'Xqciio' (Qualcomm uC External Input Output Extension)
+qc.inw x23, 16380(x17)
diff --git a/llvm/test/MC/RISCV/xqciio-valid.s 
b/llvm/test/MC/RISCV/xqciio-valid.s
new file mode 100644
index 0000000000000..912db65966de9
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqciio-valid.s
@@ -0,0 +1,20 @@
+# Xqciio - Qualcomm uC External Input Output Extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciio 
-riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciio < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqciio -M no-aliases 
--no-print-imm-hex -d - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciio -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciio < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-xqciio --no-print-imm-hex -d - 
\
+# RUN:     | FileCheck -check-prefix=CHECK-INST %s
+
+
+# CHECK-INST: qc.outw    t0, 2048(a0)
+# CHECK-ENC: encoding: [0x8b,0x42,0x05,0x20]
+qc.outw x5, 2048(x10)
+
+# CHECK-INST: qc.inw    s7, 16380(a7)
+# CHECK-ENC: encoding: [0x8b,0xdb,0xf8,0xff]
+qc.inw x23, 16380(x17)
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp 
b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index cf510995afa07..c03e786af51c1 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -667,9 +667,9 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
        {"rv64i_xqcisls0p2", "rv64i_xqcia0p4", "rv64i_xqciac0p3",
         "rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcicm0p2",
         "rv64i_xqcics0p2", "rv64i_xqcicli0p2", "rv64i_xqciint0p4",
-        "rv64i_xqcilo0p2", "rv64i_xqcilia0p2", "rv64i_xqcibm0p4",
-        "rv64i_xqcibi0p2", "rv64i_xqcili0p2", "rv64i_xqcisim0p2",
-        "rv64i_xqcilb0p2", "rv64i_xqcisync0p2"}) {
+        "rv64i_xqciio0p1", "rv64i_xqcilo0p2", "rv64i_xqcilia0p2",
+        "rv64i_xqcibm0p4", "rv64i_xqcibi0p2", "rv64i_xqcili0p2",
+        "rv64i_xqcisim0p2", "rv64i_xqcilb0p2", "rv64i_xqcisync0p2"}) {
     EXPECT_THAT(
         toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
         ::testing::EndsWith(" is only supported for 'rv32'"));
@@ -1159,6 +1159,7 @@ Experimental extensions
     xqcics               0.2
     xqcicsr              0.2
     xqciint              0.4
+    xqciio               0.1
     xqcilb               0.2
     xqcili               0.2
     xqcilia              0.2

``````````

</details>


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

Reply via email to