-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[RISCV] Add Qualcomm uC Xqciint (Interrupts) extension #122256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This extension adds eleven instructions to accelerate interrupt servicing. The current spec can be found at: https://github.com/quic/riscv-unified-db/releases/latest This patch adds assembler only support. Change-Id: Ic3381f98709e947a8dd8c9e40cfe6bb42c359f77
Change-Id: I9d9c98493788b139a3c95cf0b22066312ccd131e
@llvm/pr-subscribers-clang @llvm/pr-subscribers-mc Author: quic_hchandel (hchandel) ChangesThis extension adds eleven instructions to accelerate interrupt servicing. The current spec can be found at: This patch adds assembler only support. Full diff: https://github.com/llvm/llvm-project/pull/122256.diff 13 Files Affected:
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index a8d9fcd8569cfb..b28e0a07dad241 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -196,6 +196,7 @@
// CHECK-NEXT: xqcicm 0.2 'Xqcicm' (Qualcomm uC Conditional Move Extension)
// 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: 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 0dc63f34806b4c..a1df0f7d686e62 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -447,6 +447,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-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-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 159bd5cea973f8..22ef03427963af 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -234,6 +234,8 @@ Changes to the RISC-V Backend
extension.
* Adds experimental assembler support for the Qualcomm uC 'Xqcicm` (Conditonal Move)
extension.
+* Adds experimental assembler support for the Qualcomm uC 'Xqciint` (Interrupts)
+ 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 2205c67c2d21ba..8177280044bf44 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -717,6 +717,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
bool isUImm6() const { return IsUImm<6>(); }
bool isUImm7() const { return IsUImm<7>(); }
bool isUImm8() const { return IsUImm<8>(); }
+ bool isUImm10() const { return IsUImm<10>(); }
bool isUImm11() const { return IsUImm<11>(); }
bool isUImm16() const { return IsUImm<16>(); }
bool isUImm20() const { return IsUImm<20>(); }
@@ -1590,6 +1591,8 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
"immediate must be a multiple of 16 bytes and non-zero in the range");
+ case Match_InvalidUImm10:
+ return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
case Match_InvalidUImm11:
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
case Match_InvalidSImm12:
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index a490910154eb4d..971ef90c63327d 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -700,6 +700,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
"Qualcomm uC Conditional Load Immediate custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcicm, DecoderTableXqcicm32,
"Qualcomm uC Conditional Move custom opcode table");
+ TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqciint, DecoderTableXqciint32,
+ "Qualcomm uC Interrupts custom opcode table");
TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
return MCDisassembler::Fail;
@@ -732,6 +734,8 @@ DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size,
TRY_TO_DECODE_FEATURE(
RISCV::FeatureVendorXqcicm, DecoderTableXqcicm16,
"Qualcomm uC Conditional Move custom 16bit opcode table");
+ TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqciint, DecoderTableXqciint16,
+ "Qualcomm uC Interrupts custom 16bit opcode table");
TRY_TO_DECODE_AND_ADD_SP(STI.hasFeature(RISCV::FeatureVendorXwchc),
DecoderTableXwchc16,
"WCH QingKe XW custom opcode table");
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 7048e40822342f..ab04b09a7ad151 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -313,6 +313,7 @@ enum OperandType : unsigned {
OPERAND_UIMM8_LSB000,
OPERAND_UIMM8_GE32,
OPERAND_UIMM9_LSB000,
+ OPERAND_UIMM10,
OPERAND_UIMM10_LSB00_NONZERO,
OPERAND_UIMM11,
OPERAND_UIMM12,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 01bc5387e672ec..f721d7148526ba 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1302,6 +1302,14 @@ def HasVendorXqcicm
AssemblerPredicate<(all_of FeatureVendorXqcicm),
"'Xqcicm' (Qualcomm uC Conditional Move Extension)">;
+def FeatureVendorXqciint
+ : RISCVExperimentalExtension<0, 2, "Qualcomm uC Interrupts Extension",
+ [FeatureStdExtZca]>;
+def HasVendorXqciint
+ : Predicate<"Subtarget->hasVendorXqciint()">,
+ AssemblerPredicate<(all_of FeatureVendorXqciint),
+ "'Xqciint' (Qualcomm uC Interrupts Extension)">;
+
//===----------------------------------------------------------------------===//
// LLVM specific features and extensions
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 6f15646852f91b..95e30c07410da0 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -28,6 +28,8 @@ def uimm5gt3 : RISCVOp<XLenVT>, ImmLeaf<XLenVT,
let OperandType = "OPERAND_UIMM5_GT3";
}
+def uimm10 : RISCVUImmLeafOp<10>;
+
def uimm11 : RISCVUImmLeafOp<11>;
//===----------------------------------------------------------------------===//
@@ -166,6 +168,36 @@ class QCIMVCCI<bits<3> funct3, string opcodestr, DAGOperand immType>
let rs2 = imm;
}
+let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
+class QCIRVInst16CI_RS1<bits<5> imm5, string OpcodeStr>
+ : RVInst16CI<0b000, 0b10, (outs), (ins GPRNoX0:$rs1), OpcodeStr, "$rs1"> {
+ bits<5> rs1;
+
+ let Inst{12} = 0b1;
+ let Inst{11-7} = rs1;
+ let Inst{6-2} = imm5{4-0};
+}
+
+let hasSideEffects = 1 in
+class QCIRVInst16CI_NONE<bits<5> funct5, string OpcodeStr>
+ : RVInst16CI<0b000, 0b10, (outs), (ins), OpcodeStr, ""> {
+ let Inst{12} = 0b1;
+ let Inst{11-7} = funct5;
+ let Inst{6-2} = 0b00100;
+}
+
+let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
+class QCIInt_IMM<bits<1> funct1, string opcodestr>
+ : RVInstIBase<0b000, OPC_SYSTEM, (outs), (ins uimm10:$imm10), opcodestr,
+ "$imm10"> {
+ bits<10> imm10;
+
+ let rd = 0;
+ let rs1 = imm10{4-0};
+ let Inst{31-25} = {0b110011, funct1};
+ let Inst{24-20} = imm10{9-5};
+}
+
//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
@@ -312,6 +344,38 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
def QC_MVGEUI : QCIMVCCI<0b111, "qc.mvgeui", uimm5>;
} // Predicates = [HasVendorXqcicm, IsRV32], DecoderNamespace = "Xqcicm"
+let Predicates = [HasVendorXqciint, IsRV32], DecoderNamespace = "Xqciint" in {
+let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
+ def QC_C_DIR : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd), (ins),
+ "qc.c.dir", "$rd"> {
+ bits<5> rd;
+
+ let Inst{12} = 0b1;
+ let Inst{11-7} = rd;
+ let Inst{6-2} = 0b00000;
+ }
+
+ def QC_SETINTI : QCIInt_IMM<0b0, "qc.setinti">;
+ def QC_CLRINTI : QCIInt_IMM<0b1, "qc.clrinti">;
+
+ def QC_C_EIR : QCIRVInst16CI_RS1<0b00001, "qc.c.eir">;
+ def QC_C_SETINT : QCIRVInst16CI_RS1<0b00010, "qc.c.setint">;
+ def QC_C_CLRINT : QCIRVInst16CI_RS1<0b00011, "qc.c.clrint">;
+
+let mayLoad = 0, mayStore = 0 in {
+ def QC_C_DI : QCIRVInst16CI_NONE<0b10110, "qc.c.di">;
+ def QC_C_EI : QCIRVInst16CI_NONE<0b10111, "qc.c.ei">;
+}
+
+let mayLoad = 1, mayStore = 1 in {
+ def QC_C_MIENTER : QCIRVInst16CI_NONE<0b10000, "qc.c.mienter">;
+ def QC_C_MIENTER_NEST : QCIRVInst16CI_NONE<0b10001, "qc.c.mienter.nest">;
+}
+
+let mayLoad = 1, mayStore = 1, isReturn = 1, isTerminator = 1 in
+ def QC_C_MILEAVERET : QCIRVInst16CI_NONE<0b10100, "qc.c.mileaveret">;
+} // Predicates = [HasVendorXqciint, IsRV32], DecoderNamespace = "Xqciint"
+
//===----------------------------------------------------------------------===//
// Aliases
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index d6e1eac0d85af4..1995931abfe418 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"}, {"xqcilsm"}, {"xqcisls"}};
+ {"xqcia"}, {"xqciac"}, {"xqcicli"}, {"xqcicm"}, {"xqcics"},
+ {"xqcicsr"}, {"xqciint"}, {"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 c0fcc6f6111118..a09261609d8441 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -87,6 +87,7 @@
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm %s -o - | FileCheck --check-prefix=RV32XQCICM %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-xqciint %s -o - | FileCheck --check-prefix=RV32XQCIINT %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
@@ -401,6 +402,7 @@
; RV32XQCICM: .attribute 5, "rv32i2p1_zca1p0_xqcicm0p2"
; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
+; RV32XQCIINT: .attribute 5, "rv32i2p1_zca1p0_xqciint0p2"
; RV32XQCILSM: .attribute 5, "rv32i2p1_xqcilsm0p2"
; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
diff --git a/llvm/test/MC/RISCV/xqciint-invalid.s b/llvm/test/MC/RISCV/xqciint-invalid.s
new file mode 100644
index 00000000000000..e748109f41d82f
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqciint-invalid.s
@@ -0,0 +1,105 @@
+# Xqciint - Qualcomm uC Interrupts extension
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqciint < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-IMM %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqciint < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-EXT %s
+
+# CHECK-IMM: :[[@LINE+1]]:12: error: immediate must be an integer in the range [0, 1023]
+qc.setinti 1025
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.setinti 11, 12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.setinti
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.setinti 10
+
+
+# CHECK-IMM: :[[@LINE+1]]:12: error: immediate must be an integer in the range [0, 1023]
+qc.clrinti 2000
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.clrinti 22, x4
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.clrinti
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.clrinti 8
+
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.c.clrint 22
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.c.clrint
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.clrint x8
+
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.c.di 22
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.di
+
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.c.dir 22
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.c.dir
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.dir x8
+
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.c.ei 22
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.ei
+
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.c.eir 22
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.c.eir
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.eir x8
+
+
+# CHECK: :[[@LINE+1]]:19: error: invalid operand for instruction
+qc.c.mienter.nest 22
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.mienter.nest
+
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.c.mienter 22
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.mienter
+
+
+# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction
+qc.c.mileaveret 22
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.mileaveret
+
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.c.setint 22
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.c.setint
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.setint x8
diff --git a/llvm/test/MC/RISCV/xqciint-valid.s b/llvm/test/MC/RISCV/xqciint-valid.s
new file mode 100644
index 00000000000000..c05a402b5b14a8
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqciint-valid.s
@@ -0,0 +1,81 @@
+# Xqciint - Qualcomm uC Interrupts extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciint -riscv-no-aliases -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciint < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqciint -M no-aliases --no-print-imm-hex -d - \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciint -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciint < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqciint --no-print-imm-hex -d - \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.setinti 500
+# CHECK-ENC: encoding: [0x73,0x00,0xfa,0xcc]
+qc.setinti 500
+
+# CHECK-INST: qc.setinti 0
+# CHECK-ENC: encoding: [0x73,0x00,0x00,0xcc]
+qc.setinti 0
+
+# CHECK-INST: qc.setinti 1023
+# CHECK-ENC: encoding: [0x73,0x80,0xff,0xcd]
+qc.setinti 1023
+
+
+# CHECK-INST: qc.clrinti 500
+# CHECK-ENC: encoding: [0x73,0x00,0xfa,0xce]
+qc.clrinti 500
+
+# CHECK-INST: qc.clrinti 1023
+# CHECK-ENC: encoding: [0x73,0x80,0xff,0xcf]
+qc.clrinti 1023
+
+# CHECK-INST: qc.clrinti 0
+# CHECK-ENC: encoding: [0x73,0x00,0x00,0xce]
+qc.clrinti 0
+
+
+# CHECK-INST: qc.c.clrint a0
+# CHECK-ENC: encoding: [0x0e,0x15]
+qc.c.clrint x10
+
+
+# CHECK-INST: qc.c.di
+# CHECK-ENC: encoding: [0x12,0x1b]
+qc.c.di
+
+
+# CHECK-INST: qc.c.dir a0
+# CHECK-ENC: encoding: [0x02,0x15]
+qc.c.dir x10
+
+
+# CHECK-INST: qc.c.ei
+# CHECK-ENC: encoding: [0x92,0x1b]
+qc.c.ei
+
+
+# CHECK-INST: qc.c.eir a0
+# CHECK-ENC: encoding: [0x06,0x15]
+qc.c.eir x10
+
+
+# CHECK-INST: qc.c.mienter.nest
+# CHECK-ENC: encoding: [0x92,0x18]
+qc.c.mienter.nest
+
+
+# CHECK-INST: qc.c.mienter
+# CHECK-ENC: encoding: [0x12,0x18]
+qc.c.mienter
+
+
+# CHECK-INST: qc.c.mileaveret
+# CHECK-ENC: encoding: [0x12,0x1a]
+qc.c.mileaveret
+
+
+# CHECK-INST: qc.c.setint a0
+# CHECK-ENC: encoding: [0x0a,0x15]
+qc.c.setint x10
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 3955d36fce896a..3a7ea4550d4173 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -656,7 +656,7 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
for (StringRef Input :
{"rv64i_xqcisls0p2", "rv64i_xqcia0p2", "rv64i_xqciac0p2",
"rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcicm0p2",
- "rv64i_xqcics0p2", "rv64i_xqcicli0p2"}) {
+ "rv64i_xqcics0p2", "rv64i_xqcicli0p2", "rv64i_xqciint0p2"}) {
EXPECT_THAT(
toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
::testing::EndsWith(" is only supported for 'rv32'"));
@@ -1121,6 +1121,7 @@ Experimental extensions
xqcicm 0.2
xqcics 0.2
xqcicsr 0.2
+ xqciint 0.2
xqcilsm 0.2
xqcisls 0.2
|
@llvm/pr-subscribers-backend-risc-v Author: quic_hchandel (hchandel) ChangesThis extension adds eleven instructions to accelerate interrupt servicing. The current spec can be found at: This patch adds assembler only support. Full diff: https://github.com/llvm/llvm-project/pull/122256.diff 13 Files Affected:
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index a8d9fcd8569cfb..b28e0a07dad241 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -196,6 +196,7 @@
// CHECK-NEXT: xqcicm 0.2 'Xqcicm' (Qualcomm uC Conditional Move Extension)
// 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: 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 0dc63f34806b4c..a1df0f7d686e62 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -447,6 +447,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-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-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 159bd5cea973f8..22ef03427963af 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -234,6 +234,8 @@ Changes to the RISC-V Backend
extension.
* Adds experimental assembler support for the Qualcomm uC 'Xqcicm` (Conditonal Move)
extension.
+* Adds experimental assembler support for the Qualcomm uC 'Xqciint` (Interrupts)
+ 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 2205c67c2d21ba..8177280044bf44 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -717,6 +717,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
bool isUImm6() const { return IsUImm<6>(); }
bool isUImm7() const { return IsUImm<7>(); }
bool isUImm8() const { return IsUImm<8>(); }
+ bool isUImm10() const { return IsUImm<10>(); }
bool isUImm11() const { return IsUImm<11>(); }
bool isUImm16() const { return IsUImm<16>(); }
bool isUImm20() const { return IsUImm<20>(); }
@@ -1590,6 +1591,8 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
"immediate must be a multiple of 16 bytes and non-zero in the range");
+ case Match_InvalidUImm10:
+ return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
case Match_InvalidUImm11:
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
case Match_InvalidSImm12:
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index a490910154eb4d..971ef90c63327d 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -700,6 +700,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
"Qualcomm uC Conditional Load Immediate custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcicm, DecoderTableXqcicm32,
"Qualcomm uC Conditional Move custom opcode table");
+ TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqciint, DecoderTableXqciint32,
+ "Qualcomm uC Interrupts custom opcode table");
TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
return MCDisassembler::Fail;
@@ -732,6 +734,8 @@ DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size,
TRY_TO_DECODE_FEATURE(
RISCV::FeatureVendorXqcicm, DecoderTableXqcicm16,
"Qualcomm uC Conditional Move custom 16bit opcode table");
+ TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqciint, DecoderTableXqciint16,
+ "Qualcomm uC Interrupts custom 16bit opcode table");
TRY_TO_DECODE_AND_ADD_SP(STI.hasFeature(RISCV::FeatureVendorXwchc),
DecoderTableXwchc16,
"WCH QingKe XW custom opcode table");
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 7048e40822342f..ab04b09a7ad151 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -313,6 +313,7 @@ enum OperandType : unsigned {
OPERAND_UIMM8_LSB000,
OPERAND_UIMM8_GE32,
OPERAND_UIMM9_LSB000,
+ OPERAND_UIMM10,
OPERAND_UIMM10_LSB00_NONZERO,
OPERAND_UIMM11,
OPERAND_UIMM12,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 01bc5387e672ec..f721d7148526ba 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1302,6 +1302,14 @@ def HasVendorXqcicm
AssemblerPredicate<(all_of FeatureVendorXqcicm),
"'Xqcicm' (Qualcomm uC Conditional Move Extension)">;
+def FeatureVendorXqciint
+ : RISCVExperimentalExtension<0, 2, "Qualcomm uC Interrupts Extension",
+ [FeatureStdExtZca]>;
+def HasVendorXqciint
+ : Predicate<"Subtarget->hasVendorXqciint()">,
+ AssemblerPredicate<(all_of FeatureVendorXqciint),
+ "'Xqciint' (Qualcomm uC Interrupts Extension)">;
+
//===----------------------------------------------------------------------===//
// LLVM specific features and extensions
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 6f15646852f91b..95e30c07410da0 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -28,6 +28,8 @@ def uimm5gt3 : RISCVOp<XLenVT>, ImmLeaf<XLenVT,
let OperandType = "OPERAND_UIMM5_GT3";
}
+def uimm10 : RISCVUImmLeafOp<10>;
+
def uimm11 : RISCVUImmLeafOp<11>;
//===----------------------------------------------------------------------===//
@@ -166,6 +168,36 @@ class QCIMVCCI<bits<3> funct3, string opcodestr, DAGOperand immType>
let rs2 = imm;
}
+let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
+class QCIRVInst16CI_RS1<bits<5> imm5, string OpcodeStr>
+ : RVInst16CI<0b000, 0b10, (outs), (ins GPRNoX0:$rs1), OpcodeStr, "$rs1"> {
+ bits<5> rs1;
+
+ let Inst{12} = 0b1;
+ let Inst{11-7} = rs1;
+ let Inst{6-2} = imm5{4-0};
+}
+
+let hasSideEffects = 1 in
+class QCIRVInst16CI_NONE<bits<5> funct5, string OpcodeStr>
+ : RVInst16CI<0b000, 0b10, (outs), (ins), OpcodeStr, ""> {
+ let Inst{12} = 0b1;
+ let Inst{11-7} = funct5;
+ let Inst{6-2} = 0b00100;
+}
+
+let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
+class QCIInt_IMM<bits<1> funct1, string opcodestr>
+ : RVInstIBase<0b000, OPC_SYSTEM, (outs), (ins uimm10:$imm10), opcodestr,
+ "$imm10"> {
+ bits<10> imm10;
+
+ let rd = 0;
+ let rs1 = imm10{4-0};
+ let Inst{31-25} = {0b110011, funct1};
+ let Inst{24-20} = imm10{9-5};
+}
+
//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
@@ -312,6 +344,38 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
def QC_MVGEUI : QCIMVCCI<0b111, "qc.mvgeui", uimm5>;
} // Predicates = [HasVendorXqcicm, IsRV32], DecoderNamespace = "Xqcicm"
+let Predicates = [HasVendorXqciint, IsRV32], DecoderNamespace = "Xqciint" in {
+let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
+ def QC_C_DIR : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd), (ins),
+ "qc.c.dir", "$rd"> {
+ bits<5> rd;
+
+ let Inst{12} = 0b1;
+ let Inst{11-7} = rd;
+ let Inst{6-2} = 0b00000;
+ }
+
+ def QC_SETINTI : QCIInt_IMM<0b0, "qc.setinti">;
+ def QC_CLRINTI : QCIInt_IMM<0b1, "qc.clrinti">;
+
+ def QC_C_EIR : QCIRVInst16CI_RS1<0b00001, "qc.c.eir">;
+ def QC_C_SETINT : QCIRVInst16CI_RS1<0b00010, "qc.c.setint">;
+ def QC_C_CLRINT : QCIRVInst16CI_RS1<0b00011, "qc.c.clrint">;
+
+let mayLoad = 0, mayStore = 0 in {
+ def QC_C_DI : QCIRVInst16CI_NONE<0b10110, "qc.c.di">;
+ def QC_C_EI : QCIRVInst16CI_NONE<0b10111, "qc.c.ei">;
+}
+
+let mayLoad = 1, mayStore = 1 in {
+ def QC_C_MIENTER : QCIRVInst16CI_NONE<0b10000, "qc.c.mienter">;
+ def QC_C_MIENTER_NEST : QCIRVInst16CI_NONE<0b10001, "qc.c.mienter.nest">;
+}
+
+let mayLoad = 1, mayStore = 1, isReturn = 1, isTerminator = 1 in
+ def QC_C_MILEAVERET : QCIRVInst16CI_NONE<0b10100, "qc.c.mileaveret">;
+} // Predicates = [HasVendorXqciint, IsRV32], DecoderNamespace = "Xqciint"
+
//===----------------------------------------------------------------------===//
// Aliases
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index d6e1eac0d85af4..1995931abfe418 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"}, {"xqcilsm"}, {"xqcisls"}};
+ {"xqcia"}, {"xqciac"}, {"xqcicli"}, {"xqcicm"}, {"xqcics"},
+ {"xqcicsr"}, {"xqciint"}, {"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 c0fcc6f6111118..a09261609d8441 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -87,6 +87,7 @@
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm %s -o - | FileCheck --check-prefix=RV32XQCICM %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-xqciint %s -o - | FileCheck --check-prefix=RV32XQCIINT %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
@@ -401,6 +402,7 @@
; RV32XQCICM: .attribute 5, "rv32i2p1_zca1p0_xqcicm0p2"
; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
+; RV32XQCIINT: .attribute 5, "rv32i2p1_zca1p0_xqciint0p2"
; RV32XQCILSM: .attribute 5, "rv32i2p1_xqcilsm0p2"
; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
diff --git a/llvm/test/MC/RISCV/xqciint-invalid.s b/llvm/test/MC/RISCV/xqciint-invalid.s
new file mode 100644
index 00000000000000..e748109f41d82f
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqciint-invalid.s
@@ -0,0 +1,105 @@
+# Xqciint - Qualcomm uC Interrupts extension
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqciint < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-IMM %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqciint < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-EXT %s
+
+# CHECK-IMM: :[[@LINE+1]]:12: error: immediate must be an integer in the range [0, 1023]
+qc.setinti 1025
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.setinti 11, 12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.setinti
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.setinti 10
+
+
+# CHECK-IMM: :[[@LINE+1]]:12: error: immediate must be an integer in the range [0, 1023]
+qc.clrinti 2000
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.clrinti 22, x4
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.clrinti
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.clrinti 8
+
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.c.clrint 22
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.c.clrint
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.clrint x8
+
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.c.di 22
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.di
+
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.c.dir 22
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.c.dir
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.dir x8
+
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.c.ei 22
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.ei
+
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.c.eir 22
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.c.eir
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.eir x8
+
+
+# CHECK: :[[@LINE+1]]:19: error: invalid operand for instruction
+qc.c.mienter.nest 22
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.mienter.nest
+
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.c.mienter 22
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.mienter
+
+
+# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction
+qc.c.mileaveret 22
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.mileaveret
+
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.c.setint 22
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.c.setint
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.setint x8
diff --git a/llvm/test/MC/RISCV/xqciint-valid.s b/llvm/test/MC/RISCV/xqciint-valid.s
new file mode 100644
index 00000000000000..c05a402b5b14a8
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqciint-valid.s
@@ -0,0 +1,81 @@
+# Xqciint - Qualcomm uC Interrupts extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciint -riscv-no-aliases -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciint < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqciint -M no-aliases --no-print-imm-hex -d - \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciint -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciint < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqciint --no-print-imm-hex -d - \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.setinti 500
+# CHECK-ENC: encoding: [0x73,0x00,0xfa,0xcc]
+qc.setinti 500
+
+# CHECK-INST: qc.setinti 0
+# CHECK-ENC: encoding: [0x73,0x00,0x00,0xcc]
+qc.setinti 0
+
+# CHECK-INST: qc.setinti 1023
+# CHECK-ENC: encoding: [0x73,0x80,0xff,0xcd]
+qc.setinti 1023
+
+
+# CHECK-INST: qc.clrinti 500
+# CHECK-ENC: encoding: [0x73,0x00,0xfa,0xce]
+qc.clrinti 500
+
+# CHECK-INST: qc.clrinti 1023
+# CHECK-ENC: encoding: [0x73,0x80,0xff,0xcf]
+qc.clrinti 1023
+
+# CHECK-INST: qc.clrinti 0
+# CHECK-ENC: encoding: [0x73,0x00,0x00,0xce]
+qc.clrinti 0
+
+
+# CHECK-INST: qc.c.clrint a0
+# CHECK-ENC: encoding: [0x0e,0x15]
+qc.c.clrint x10
+
+
+# CHECK-INST: qc.c.di
+# CHECK-ENC: encoding: [0x12,0x1b]
+qc.c.di
+
+
+# CHECK-INST: qc.c.dir a0
+# CHECK-ENC: encoding: [0x02,0x15]
+qc.c.dir x10
+
+
+# CHECK-INST: qc.c.ei
+# CHECK-ENC: encoding: [0x92,0x1b]
+qc.c.ei
+
+
+# CHECK-INST: qc.c.eir a0
+# CHECK-ENC: encoding: [0x06,0x15]
+qc.c.eir x10
+
+
+# CHECK-INST: qc.c.mienter.nest
+# CHECK-ENC: encoding: [0x92,0x18]
+qc.c.mienter.nest
+
+
+# CHECK-INST: qc.c.mienter
+# CHECK-ENC: encoding: [0x12,0x18]
+qc.c.mienter
+
+
+# CHECK-INST: qc.c.mileaveret
+# CHECK-ENC: encoding: [0x12,0x1a]
+qc.c.mileaveret
+
+
+# CHECK-INST: qc.c.setint a0
+# CHECK-ENC: encoding: [0x0a,0x15]
+qc.c.setint x10
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 3955d36fce896a..3a7ea4550d4173 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -656,7 +656,7 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
for (StringRef Input :
{"rv64i_xqcisls0p2", "rv64i_xqcia0p2", "rv64i_xqciac0p2",
"rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcicm0p2",
- "rv64i_xqcics0p2", "rv64i_xqcicli0p2"}) {
+ "rv64i_xqcics0p2", "rv64i_xqcicli0p2", "rv64i_xqciint0p2"}) {
EXPECT_THAT(
toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
::testing::EndsWith(" is only supported for 'rv32'"));
@@ -1121,6 +1121,7 @@ Experimental extensions
xqcicm 0.2
xqcics 0.2
xqcicsr 0.2
+ xqciint 0.2
xqcilsm 0.2
xqcisls 0.2
|
@llvm/pr-subscribers-clang-driver Author: quic_hchandel (hchandel) ChangesThis extension adds eleven instructions to accelerate interrupt servicing. The current spec can be found at: This patch adds assembler only support. Full diff: https://github.com/llvm/llvm-project/pull/122256.diff 13 Files Affected:
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index a8d9fcd8569cfb..b28e0a07dad241 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -196,6 +196,7 @@
// CHECK-NEXT: xqcicm 0.2 'Xqcicm' (Qualcomm uC Conditional Move Extension)
// 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: 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 0dc63f34806b4c..a1df0f7d686e62 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -447,6 +447,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-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-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 159bd5cea973f8..22ef03427963af 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -234,6 +234,8 @@ Changes to the RISC-V Backend
extension.
* Adds experimental assembler support for the Qualcomm uC 'Xqcicm` (Conditonal Move)
extension.
+* Adds experimental assembler support for the Qualcomm uC 'Xqciint` (Interrupts)
+ 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 2205c67c2d21ba..8177280044bf44 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -717,6 +717,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
bool isUImm6() const { return IsUImm<6>(); }
bool isUImm7() const { return IsUImm<7>(); }
bool isUImm8() const { return IsUImm<8>(); }
+ bool isUImm10() const { return IsUImm<10>(); }
bool isUImm11() const { return IsUImm<11>(); }
bool isUImm16() const { return IsUImm<16>(); }
bool isUImm20() const { return IsUImm<20>(); }
@@ -1590,6 +1591,8 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
"immediate must be a multiple of 16 bytes and non-zero in the range");
+ case Match_InvalidUImm10:
+ return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
case Match_InvalidUImm11:
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
case Match_InvalidSImm12:
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index a490910154eb4d..971ef90c63327d 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -700,6 +700,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
"Qualcomm uC Conditional Load Immediate custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcicm, DecoderTableXqcicm32,
"Qualcomm uC Conditional Move custom opcode table");
+ TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqciint, DecoderTableXqciint32,
+ "Qualcomm uC Interrupts custom opcode table");
TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
return MCDisassembler::Fail;
@@ -732,6 +734,8 @@ DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size,
TRY_TO_DECODE_FEATURE(
RISCV::FeatureVendorXqcicm, DecoderTableXqcicm16,
"Qualcomm uC Conditional Move custom 16bit opcode table");
+ TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqciint, DecoderTableXqciint16,
+ "Qualcomm uC Interrupts custom 16bit opcode table");
TRY_TO_DECODE_AND_ADD_SP(STI.hasFeature(RISCV::FeatureVendorXwchc),
DecoderTableXwchc16,
"WCH QingKe XW custom opcode table");
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 7048e40822342f..ab04b09a7ad151 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -313,6 +313,7 @@ enum OperandType : unsigned {
OPERAND_UIMM8_LSB000,
OPERAND_UIMM8_GE32,
OPERAND_UIMM9_LSB000,
+ OPERAND_UIMM10,
OPERAND_UIMM10_LSB00_NONZERO,
OPERAND_UIMM11,
OPERAND_UIMM12,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 01bc5387e672ec..f721d7148526ba 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1302,6 +1302,14 @@ def HasVendorXqcicm
AssemblerPredicate<(all_of FeatureVendorXqcicm),
"'Xqcicm' (Qualcomm uC Conditional Move Extension)">;
+def FeatureVendorXqciint
+ : RISCVExperimentalExtension<0, 2, "Qualcomm uC Interrupts Extension",
+ [FeatureStdExtZca]>;
+def HasVendorXqciint
+ : Predicate<"Subtarget->hasVendorXqciint()">,
+ AssemblerPredicate<(all_of FeatureVendorXqciint),
+ "'Xqciint' (Qualcomm uC Interrupts Extension)">;
+
//===----------------------------------------------------------------------===//
// LLVM specific features and extensions
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 6f15646852f91b..95e30c07410da0 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -28,6 +28,8 @@ def uimm5gt3 : RISCVOp<XLenVT>, ImmLeaf<XLenVT,
let OperandType = "OPERAND_UIMM5_GT3";
}
+def uimm10 : RISCVUImmLeafOp<10>;
+
def uimm11 : RISCVUImmLeafOp<11>;
//===----------------------------------------------------------------------===//
@@ -166,6 +168,36 @@ class QCIMVCCI<bits<3> funct3, string opcodestr, DAGOperand immType>
let rs2 = imm;
}
+let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
+class QCIRVInst16CI_RS1<bits<5> imm5, string OpcodeStr>
+ : RVInst16CI<0b000, 0b10, (outs), (ins GPRNoX0:$rs1), OpcodeStr, "$rs1"> {
+ bits<5> rs1;
+
+ let Inst{12} = 0b1;
+ let Inst{11-7} = rs1;
+ let Inst{6-2} = imm5{4-0};
+}
+
+let hasSideEffects = 1 in
+class QCIRVInst16CI_NONE<bits<5> funct5, string OpcodeStr>
+ : RVInst16CI<0b000, 0b10, (outs), (ins), OpcodeStr, ""> {
+ let Inst{12} = 0b1;
+ let Inst{11-7} = funct5;
+ let Inst{6-2} = 0b00100;
+}
+
+let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
+class QCIInt_IMM<bits<1> funct1, string opcodestr>
+ : RVInstIBase<0b000, OPC_SYSTEM, (outs), (ins uimm10:$imm10), opcodestr,
+ "$imm10"> {
+ bits<10> imm10;
+
+ let rd = 0;
+ let rs1 = imm10{4-0};
+ let Inst{31-25} = {0b110011, funct1};
+ let Inst{24-20} = imm10{9-5};
+}
+
//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
@@ -312,6 +344,38 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
def QC_MVGEUI : QCIMVCCI<0b111, "qc.mvgeui", uimm5>;
} // Predicates = [HasVendorXqcicm, IsRV32], DecoderNamespace = "Xqcicm"
+let Predicates = [HasVendorXqciint, IsRV32], DecoderNamespace = "Xqciint" in {
+let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
+ def QC_C_DIR : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd), (ins),
+ "qc.c.dir", "$rd"> {
+ bits<5> rd;
+
+ let Inst{12} = 0b1;
+ let Inst{11-7} = rd;
+ let Inst{6-2} = 0b00000;
+ }
+
+ def QC_SETINTI : QCIInt_IMM<0b0, "qc.setinti">;
+ def QC_CLRINTI : QCIInt_IMM<0b1, "qc.clrinti">;
+
+ def QC_C_EIR : QCIRVInst16CI_RS1<0b00001, "qc.c.eir">;
+ def QC_C_SETINT : QCIRVInst16CI_RS1<0b00010, "qc.c.setint">;
+ def QC_C_CLRINT : QCIRVInst16CI_RS1<0b00011, "qc.c.clrint">;
+
+let mayLoad = 0, mayStore = 0 in {
+ def QC_C_DI : QCIRVInst16CI_NONE<0b10110, "qc.c.di">;
+ def QC_C_EI : QCIRVInst16CI_NONE<0b10111, "qc.c.ei">;
+}
+
+let mayLoad = 1, mayStore = 1 in {
+ def QC_C_MIENTER : QCIRVInst16CI_NONE<0b10000, "qc.c.mienter">;
+ def QC_C_MIENTER_NEST : QCIRVInst16CI_NONE<0b10001, "qc.c.mienter.nest">;
+}
+
+let mayLoad = 1, mayStore = 1, isReturn = 1, isTerminator = 1 in
+ def QC_C_MILEAVERET : QCIRVInst16CI_NONE<0b10100, "qc.c.mileaveret">;
+} // Predicates = [HasVendorXqciint, IsRV32], DecoderNamespace = "Xqciint"
+
//===----------------------------------------------------------------------===//
// Aliases
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index d6e1eac0d85af4..1995931abfe418 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"}, {"xqcilsm"}, {"xqcisls"}};
+ {"xqcia"}, {"xqciac"}, {"xqcicli"}, {"xqcicm"}, {"xqcics"},
+ {"xqcicsr"}, {"xqciint"}, {"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 c0fcc6f6111118..a09261609d8441 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -87,6 +87,7 @@
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm %s -o - | FileCheck --check-prefix=RV32XQCICM %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-xqciint %s -o - | FileCheck --check-prefix=RV32XQCIINT %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
@@ -401,6 +402,7 @@
; RV32XQCICM: .attribute 5, "rv32i2p1_zca1p0_xqcicm0p2"
; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
+; RV32XQCIINT: .attribute 5, "rv32i2p1_zca1p0_xqciint0p2"
; RV32XQCILSM: .attribute 5, "rv32i2p1_xqcilsm0p2"
; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
diff --git a/llvm/test/MC/RISCV/xqciint-invalid.s b/llvm/test/MC/RISCV/xqciint-invalid.s
new file mode 100644
index 00000000000000..e748109f41d82f
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqciint-invalid.s
@@ -0,0 +1,105 @@
+# Xqciint - Qualcomm uC Interrupts extension
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqciint < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-IMM %s
+# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqciint < %s 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-EXT %s
+
+# CHECK-IMM: :[[@LINE+1]]:12: error: immediate must be an integer in the range [0, 1023]
+qc.setinti 1025
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.setinti 11, 12
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.setinti
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.setinti 10
+
+
+# CHECK-IMM: :[[@LINE+1]]:12: error: immediate must be an integer in the range [0, 1023]
+qc.clrinti 2000
+
+# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
+qc.clrinti 22, x4
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.clrinti
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.clrinti 8
+
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.c.clrint 22
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.c.clrint
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.clrint x8
+
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.c.di 22
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.di
+
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.c.dir 22
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.c.dir
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.dir x8
+
+
+# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
+qc.c.ei 22
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.ei
+
+
+# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
+qc.c.eir 22
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.c.eir
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.eir x8
+
+
+# CHECK: :[[@LINE+1]]:19: error: invalid operand for instruction
+qc.c.mienter.nest 22
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.mienter.nest
+
+
+# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
+qc.c.mienter 22
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.mienter
+
+
+# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction
+qc.c.mileaveret 22
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.mileaveret
+
+
+# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
+qc.c.setint 22
+
+# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
+qc.c.setint
+
+# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
+qc.c.setint x8
diff --git a/llvm/test/MC/RISCV/xqciint-valid.s b/llvm/test/MC/RISCV/xqciint-valid.s
new file mode 100644
index 00000000000000..c05a402b5b14a8
--- /dev/null
+++ b/llvm/test/MC/RISCV/xqciint-valid.s
@@ -0,0 +1,81 @@
+# Xqciint - Qualcomm uC Interrupts extension
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciint -riscv-no-aliases -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciint < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqciint -M no-aliases --no-print-imm-hex -d - \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciint -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciint < %s \
+# RUN: | llvm-objdump --mattr=+experimental-xqciint --no-print-imm-hex -d - \
+# RUN: | FileCheck -check-prefix=CHECK-INST %s
+
+# CHECK-INST: qc.setinti 500
+# CHECK-ENC: encoding: [0x73,0x00,0xfa,0xcc]
+qc.setinti 500
+
+# CHECK-INST: qc.setinti 0
+# CHECK-ENC: encoding: [0x73,0x00,0x00,0xcc]
+qc.setinti 0
+
+# CHECK-INST: qc.setinti 1023
+# CHECK-ENC: encoding: [0x73,0x80,0xff,0xcd]
+qc.setinti 1023
+
+
+# CHECK-INST: qc.clrinti 500
+# CHECK-ENC: encoding: [0x73,0x00,0xfa,0xce]
+qc.clrinti 500
+
+# CHECK-INST: qc.clrinti 1023
+# CHECK-ENC: encoding: [0x73,0x80,0xff,0xcf]
+qc.clrinti 1023
+
+# CHECK-INST: qc.clrinti 0
+# CHECK-ENC: encoding: [0x73,0x00,0x00,0xce]
+qc.clrinti 0
+
+
+# CHECK-INST: qc.c.clrint a0
+# CHECK-ENC: encoding: [0x0e,0x15]
+qc.c.clrint x10
+
+
+# CHECK-INST: qc.c.di
+# CHECK-ENC: encoding: [0x12,0x1b]
+qc.c.di
+
+
+# CHECK-INST: qc.c.dir a0
+# CHECK-ENC: encoding: [0x02,0x15]
+qc.c.dir x10
+
+
+# CHECK-INST: qc.c.ei
+# CHECK-ENC: encoding: [0x92,0x1b]
+qc.c.ei
+
+
+# CHECK-INST: qc.c.eir a0
+# CHECK-ENC: encoding: [0x06,0x15]
+qc.c.eir x10
+
+
+# CHECK-INST: qc.c.mienter.nest
+# CHECK-ENC: encoding: [0x92,0x18]
+qc.c.mienter.nest
+
+
+# CHECK-INST: qc.c.mienter
+# CHECK-ENC: encoding: [0x12,0x18]
+qc.c.mienter
+
+
+# CHECK-INST: qc.c.mileaveret
+# CHECK-ENC: encoding: [0x12,0x1a]
+qc.c.mileaveret
+
+
+# CHECK-INST: qc.c.setint a0
+# CHECK-ENC: encoding: [0x0a,0x15]
+qc.c.setint x10
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 3955d36fce896a..3a7ea4550d4173 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -656,7 +656,7 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
for (StringRef Input :
{"rv64i_xqcisls0p2", "rv64i_xqcia0p2", "rv64i_xqciac0p2",
"rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcicm0p2",
- "rv64i_xqcics0p2", "rv64i_xqcicli0p2"}) {
+ "rv64i_xqcics0p2", "rv64i_xqcicli0p2", "rv64i_xqciint0p2"}) {
EXPECT_THAT(
toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
::testing::EndsWith(" is only supported for 'rv32'"));
@@ -1121,6 +1121,7 @@ Experimental extensions
xqcicm 0.2
xqcics 0.2
xqcicsr 0.2
+ xqciint 0.2
xqcilsm 0.2
xqcisls 0.2
|
Change-Id: I86fe70060baec52926132082edea067561ba536d
Change-Id: Ibc5b0e59e1ff081466c8eeb1a9660de0e95a0a0c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Change-Id: Iff961f7d7122687c5b6e4861c27e8f747c066938
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks!
This extension adds eleven instructions to accelerate interrupt servicing. 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 <[email protected]>
This extension adds eleven instructions to accelerate interrupt servicing.
The current spec can be found at:
https://github.com/quic/riscv-unified-db/releases/latest
This patch adds assembler only support.