Skip to content

Commit edef028

Browse files
hchandelsvs-quic
andauthored
[RISCV] Add Qualcomm uC Xqciio (External Input Output) extension (#132721)
This extension adds two external input output instructions for 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 <[email protected]>
1 parent f8ffbae commit edef028

File tree

15 files changed

+159
-15
lines changed

15 files changed

+159
-15
lines changed

clang/test/Driver/print-supported-extensions-riscv.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@
206206
// CHECK-NEXT: xqcics 0.2 'Xqcics' (Qualcomm uC Conditional Select Extension)
207207
// CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension)
208208
// CHECK-NEXT: xqciint 0.4 'Xqciint' (Qualcomm uC Interrupts Extension)
209+
// CHECK-NEXT: xqciio 0.1 'Xqciio' (Qualcomm uC External Input Output Extension)
209210
// CHECK-NEXT: xqcilb 0.2 'Xqcilb' (Qualcomm uC Long Branch Extension)
210211
// CHECK-NEXT: xqcili 0.2 'Xqcili' (Qualcomm uC Load Large Immediate Extension)
211212
// CHECK-NEXT: xqcilia 0.2 'Xqcilia' (Qualcomm uC Large Immediate Arithmetic Extension)

llvm/docs/RISCVUsage.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,9 @@ The current vendor extensions supported are:
461461
``experimental-Xqcicsr``
462462
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.
463463

464+
``experimental-Xqciio``
465+
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.
466+
464467
``experimental-Xqciint``
465468
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.
466469

llvm/docs/ReleaseNotes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ Changes to the RISC-V Backend
142142
extension.
143143
* Adds experimental assembler support for the Qualcomm uC 'Xqcisync` (Sync Delay)
144144
extension.
145+
* Adds experimental assembler support for the Qualcomm uC 'Xqciio` (External Input Output)
146+
extension.
145147
* Adds assembler support for the 'Zilsd` (Load/Store Pair Instructions)
146148
extension.
147149
* Adds assembler support for the 'Zclsd` (Compressed Load/Store Pair Instructions)

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,8 @@ struct RISCVOperand final : public MCParsedAsmOperand {
844844

845845
bool isUImm9Lsb000() const { return isUImmShifted<6, 3>(); }
846846

847+
bool isUImm14Lsb00() const { return isUImmShifted<12, 2>(); }
848+
847849
bool isUImm10Lsb00NonZero() const {
848850
return isUImmPred(
849851
[](int64_t Imm) { return isShiftedUInt<8, 2>(Imm) && (Imm != 0); });
@@ -1521,6 +1523,10 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
15211523
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
15221524
case Match_InvalidUImm11:
15231525
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
1526+
case Match_InvalidUImm14Lsb00:
1527+
return generateImmOutOfRangeError(
1528+
Operands, ErrorInfo, 0, (1 << 14) - 4,
1529+
"immediate must be a multiple of 4 bytes in the range");
15241530
case Match_InvalidUImm16NonZero:
15251531
return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16) - 1);
15261532
case Match_InvalidSImm12:

llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -671,15 +671,15 @@ static constexpr FeatureBitset XRivosFeatureGroup = {
671671
};
672672

673673
static constexpr FeatureBitset XqciFeatureGroup = {
674-
RISCV::FeatureVendorXqcia, RISCV::FeatureVendorXqciac,
675-
RISCV::FeatureVendorXqcibi, RISCV::FeatureVendorXqcibm,
676-
RISCV::FeatureVendorXqcicli, RISCV::FeatureVendorXqcicm,
677-
RISCV::FeatureVendorXqcics, RISCV::FeatureVendorXqcicsr,
678-
RISCV::FeatureVendorXqciint, RISCV::FeatureVendorXqcilb,
679-
RISCV::FeatureVendorXqcili, RISCV::FeatureVendorXqcilia,
680-
RISCV::FeatureVendorXqcilo, RISCV::FeatureVendorXqcilsm,
681-
RISCV::FeatureVendorXqcisim, RISCV::FeatureVendorXqcisls,
682-
RISCV::FeatureVendorXqcisync,
674+
RISCV::FeatureVendorXqcia, RISCV::FeatureVendorXqciac,
675+
RISCV::FeatureVendorXqcibi, RISCV::FeatureVendorXqcibm,
676+
RISCV::FeatureVendorXqcicli, RISCV::FeatureVendorXqcicm,
677+
RISCV::FeatureVendorXqcics, RISCV::FeatureVendorXqcicsr,
678+
RISCV::FeatureVendorXqciint, RISCV::FeatureVendorXqciio,
679+
RISCV::FeatureVendorXqcilb, RISCV::FeatureVendorXqcili,
680+
RISCV::FeatureVendorXqcilia, RISCV::FeatureVendorXqcilo,
681+
RISCV::FeatureVendorXqcilsm, RISCV::FeatureVendorXqcisim,
682+
RISCV::FeatureVendorXqcisls, RISCV::FeatureVendorXqcisync,
683683
};
684684

685685
static constexpr FeatureBitset XSfVectorGroup = {

llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ enum OperandType : unsigned {
314314
OPERAND_UIMM10_LSB00_NONZERO,
315315
OPERAND_UIMM11,
316316
OPERAND_UIMM12,
317+
OPERAND_UIMM14_LSB00,
317318
OPERAND_UIMM16,
318319
OPERAND_UIMM16_NONZERO,
319320
OPERAND_UIMM20,

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,6 +1376,13 @@ def HasVendorXqcicm
13761376
AssemblerPredicate<(all_of FeatureVendorXqcicm),
13771377
"'Xqcicm' (Qualcomm uC Conditional Move Extension)">;
13781378

1379+
def FeatureVendorXqciio
1380+
: RISCVExperimentalExtension<0, 1, "Qualcomm uC External Input Output Extension">;
1381+
def HasVendorXqciio
1382+
: Predicate<"Subtarget->hasVendorXqciio()">,
1383+
AssemblerPredicate<(all_of FeatureVendorXqciio),
1384+
"'Xqciio' (Qualcomm uC External Input Output Extension)">;
1385+
13791386
def FeatureVendorXqciint
13801387
: RISCVExperimentalExtension<0, 4, "Qualcomm uC Interrupts Extension",
13811388
[FeatureStdExtZca]>;

llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,15 @@ def uimm10 : RISCVUImmLeafOp<10>;
6969

7070
def uimm11 : RISCVUImmLeafOp<11>;
7171

72+
// A 14-bit unsigned immediate where the least significant two bits are zero.
73+
def uimm14lsb00 : RISCVOp,
74+
ImmLeaf<XLenVT, [{return isShiftedUInt<12, 2>(Imm);}]> {
75+
let ParserMatchClass = UImmAsmOperand<14, "Lsb00">;
76+
let EncoderMethod = "getImmOpValue";
77+
let DecoderMethod = "decodeUImmOperand<14>";
78+
let OperandType = "OPERAND_UIMM14_LSB00";
79+
}
80+
7281
def uimm16nonzero : RISCVOp<XLenVT>,
7382
ImmLeaf<XLenVT, [{return (Imm != 0) && isUInt<16>(Imm);}]> {
7483
let ParserMatchClass = UImmAsmOperand<16, "NonZero">;
@@ -742,6 +751,28 @@ def QC_C_MILEAVERET : QCIRVInst16CI_NONE<0b10100, "qc.c.mileaveret">;
742751

743752
} // Predicates = [HasVendorXqciint, IsRV32], hasSideEffects = 1
744753

754+
let Predicates = [HasVendorXqciio, IsRV32] in {
755+
let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in {
756+
def QC_OUTW : RVInstI<0b100, OPC_CUSTOM_0, (outs),
757+
(ins GPR:$rs2, GPR:$rs1, uimm14lsb00:$imm14),
758+
"qc.outw", "$rs2, ${imm14}(${rs1})"> {
759+
bits<5> rs2;
760+
bits<14> imm14;
761+
762+
let rd = rs2;
763+
let imm12 = imm14{13-2};
764+
}
765+
766+
def QC_INW : RVInstI<0b101, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
767+
(ins GPR:$rs1, uimm14lsb00:$imm14),
768+
"qc.inw", "$rd, ${imm14}(${rs1})"> {
769+
bits<14> imm14;
770+
771+
let imm12 = imm14{13-2};
772+
}
773+
} // hasSideEffects = 1, mayLoad = 0, mayStore = 0
774+
} // Predicates = [HasVendorXqciio, IsRV32]
775+
745776
let Predicates = [HasVendorXqcilo, IsRV32] in {
746777
def QC_E_LB : QCIRVInstEILoad<0b101, 0b00, "qc.e.lb">;
747778
def QC_E_LBU : QCIRVInstEILoad<0b101, 0b01, "qc.e.lbu">;
@@ -859,6 +890,15 @@ let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in {
859890
// Aliases
860891
//===----------------------------------------------------------------------===//
861892

893+
let Predicates = [HasVendorXqciio, IsRV32] in {
894+
let EmitPriority = 0 in {
895+
def : InstAlias<"qc.outw $rs2, (${rs1})",
896+
(QC_OUTW GPR:$rs2, GPR:$rs1, 0)>;
897+
def : InstAlias<"qc.inw $rd, (${rs1})",
898+
(QC_INW GPRNoX0:$rd, GPR:$rs1, 0)>;
899+
} // EmitPriority = 0
900+
} // Predicates = [HasVendorXqciio, IsRV32]
901+
862902
let Predicates = [HasVendorXqcilsm, IsRV32] in {
863903
let EmitPriority = 0 in {
864904
def : InstAlias<"qc.swm $rs3, $rs2, (${rs1})",

llvm/lib/TargetParser/RISCVISAInfo.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -745,9 +745,9 @@ Error RISCVISAInfo::checkDependency() {
745745

746746
static constexpr StringLiteral XqciExts[] = {
747747
{"xqcia"}, {"xqciac"}, {"xqcibi"}, {"xqcibm"}, {"xqcicli"},
748-
{"xqcicm"}, {"xqcics"}, {"xqcicsr"}, {"xqciint"}, {"xqcilb"},
749-
{"xqcili"}, {"xqcilia"}, {"xqcilo"}, {"xqcilsm"}, {"xqcisim"},
750-
{"xqcisls"}, {"xqcisync"}};
748+
{"xqcicm"}, {"xqcics"}, {"xqcicsr"}, {"xqciint"}, {"xqciio"},
749+
{"xqcilb"}, {"xqcili"}, {"xqcilia"}, {"xqcilo"}, {"xqcilsm"},
750+
{"xqcisim"}, {"xqcisls"}, {"xqcisync"}};
751751
static constexpr StringLiteral ZcdOverlaps[] = {
752752
{"zcmt"}, {"zcmp"}, {"xqccmp"}, {"xqciac"}, {"xqcicm"}};
753753

llvm/test/CodeGen/RISCV/attributes.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcics %s -o - | FileCheck --check-prefix=RV32XQCICS %s
9595
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck --check-prefix=RV32XQCICSR %s
9696
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqciint %s -o - | FileCheck --check-prefix=RV32XQCIINT %s
97+
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqciio %s -o - | FileCheck --check-prefix=RV32XQCIIO %s
9798
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilb %s -o - | FileCheck --check-prefix=RV32XQCILB %s
9899
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcili %s -o - | FileCheck --check-prefix=RV32XQCILI %s
99100
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilia %s -o - | FileCheck --check-prefix=RV32XQCILIA %s
@@ -431,6 +432,7 @@
431432
; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
432433
; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
433434
; RV32XQCIINT: .attribute 5, "rv32i2p1_zca1p0_xqciint0p4"
435+
; RV32XQCIIO: .attribute 5, "rv32i2p1_xqciio0p1"
434436
; RV32XQCILB: .attribute 5, "rv32i2p1_zca1p0_xqcilb0p2"
435437
; RV32XQCILI: .attribute 5, "rv32i2p1_zca1p0_xqcili0p2"
436438
; RV32XQCILIA: .attribute 5, "rv32i2p1_zca1p0_xqcilia0p2"

llvm/test/CodeGen/RISCV/features-info.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
; CHECK-NEXT: experimental-xqcics - 'Xqcics' (Qualcomm uC Conditional Select Extension).
3232
; CHECK-NEXT: experimental-xqcicsr - 'Xqcicsr' (Qualcomm uC CSR Extension).
3333
; CHECK-NEXT: experimental-xqciint - 'Xqciint' (Qualcomm uC Interrupts Extension).
34+
; CHECK-NEXT: experimental-xqciio - 'Xqciio' (Qualcomm uC External Input Output Extension).
3435
; CHECK-NEXT: experimental-xqcilb - 'Xqcilb' (Qualcomm uC Long Branch Extension).
3536
; CHECK-NEXT: experimental-xqcili - 'Xqcili' (Qualcomm uC Load Large Immediate Extension).
3637
; CHECK-NEXT: experimental-xqcilia - 'Xqcilia' (Qualcomm uC Large Immediate Arithmetic Extension).
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Xqciio - Qualcomm uC External Input Output extension
2+
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciio -riscv-no-aliases -show-encoding \
3+
# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
4+
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciio < %s \
5+
# RUN: | llvm-objdump --mattr=+experimental-xqciio -M no-aliases --no-print-imm-hex -d - \
6+
# RUN: | FileCheck -check-prefix=CHECK-INST %s
7+
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciio -show-encoding \
8+
# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
9+
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciio < %s \
10+
# RUN: | llvm-objdump --mattr=+experimental-xqciio --no-print-imm-hex -d - \
11+
# RUN: | FileCheck -check-prefix=CHECK-INST %s
12+
13+
# CHECK-INST: qc.outw t0, 0(a0)
14+
# CHECK-ENC: encoding: [0x8b,0x42,0x05,0x00]
15+
qc.outw x5, (x10)
16+
17+
18+
# CHECK-INST: qc.inw t0, 0(a0)
19+
# CHECK-ENC: encoding: [0x8b,0x52,0x05,0x00]
20+
qc.inw x5, (x10)

llvm/test/MC/RISCV/xqciio-invalid.s

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Xqciio - Qualcomm uC External Input Output Extension
2+
# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqciio < %s 2>&1 \
3+
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s
4+
# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqciio < %s 2>&1 \
5+
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s
6+
7+
# CHECK: :[[@LINE+1]]:18: error: expected register
8+
qc.outw x5, 2048(10)
9+
10+
# CHECK-PLUS: :[[@LINE+1]]:13: error: immediate must be a multiple of 4 bytes in the range [0, 16380]
11+
qc.outw x5, x10
12+
13+
# CHECK-MINUS: :[[@LINE+1]]:13: error: invalid operand for instruction
14+
qc.outw x5, x10
15+
16+
# CHECK-PLUS: :[[@LINE+1]]:13: error: immediate must be a multiple of 4 bytes in the range [0, 16380]
17+
qc.outw x5, 4099(x10)
18+
19+
# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciio' (Qualcomm uC External Input Output Extension)
20+
qc.outw x5, 2048(x10)
21+
22+
23+
# CHECK: :[[@LINE+1]]:19: error: expected register
24+
qc.inw x23, 16380(17)
25+
26+
# CHECK-PLUS: :[[@LINE+1]]:13: error: immediate must be a multiple of 4 bytes in the range [0, 16380]
27+
qc.inw x23, x17
28+
29+
# CHECK-MINUS: :[[@LINE+1]]:13: error: invalid operand for instruction
30+
qc.inw x23, x17
31+
32+
# CHECK-PLUS: :[[@LINE+2]]:8: error: register must be a GPR excluding zero (x0)
33+
# CHECK-MINUS: :[[@LINE+1]]:8: error: invalid operand for instruction
34+
qc.inw x0, 16380(x17)
35+
36+
# CHECK-PLUS: :[[@LINE+1]]:13: error: immediate must be a multiple of 4 bytes in the range [0, 16380]
37+
qc.inw x23, 16384(x17)
38+
39+
# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciio' (Qualcomm uC External Input Output Extension)
40+
qc.inw x23, 16380(x17)

llvm/test/MC/RISCV/xqciio-valid.s

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Xqciio - Qualcomm uC External Input Output Extension
2+
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciio -riscv-no-aliases -show-encoding \
3+
# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
4+
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciio < %s \
5+
# RUN: | llvm-objdump --mattr=+experimental-xqciio -M no-aliases --no-print-imm-hex -d - \
6+
# RUN: | FileCheck -check-prefix=CHECK-INST %s
7+
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciio -show-encoding \
8+
# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
9+
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciio < %s \
10+
# RUN: | llvm-objdump --mattr=+experimental-xqciio --no-print-imm-hex -d - \
11+
# RUN: | FileCheck -check-prefix=CHECK-INST %s
12+
13+
14+
# CHECK-INST: qc.outw t0, 2048(a0)
15+
# CHECK-ENC: encoding: [0x8b,0x42,0x05,0x20]
16+
qc.outw x5, 2048(x10)
17+
18+
# CHECK-INST: qc.inw s7, 16380(a7)
19+
# CHECK-ENC: encoding: [0x8b,0xdb,0xf8,0xff]
20+
qc.inw x23, 16380(x17)

llvm/unittests/TargetParser/RISCVISAInfoTest.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -667,9 +667,9 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
667667
{"rv64i_xqcisls0p2", "rv64i_xqcia0p4", "rv64i_xqciac0p3",
668668
"rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcicm0p2",
669669
"rv64i_xqcics0p2", "rv64i_xqcicli0p2", "rv64i_xqciint0p4",
670-
"rv64i_xqcilo0p2", "rv64i_xqcilia0p2", "rv64i_xqcibm0p4",
671-
"rv64i_xqcibi0p2", "rv64i_xqcili0p2", "rv64i_xqcisim0p2",
672-
"rv64i_xqcilb0p2", "rv64i_xqcisync0p2"}) {
670+
"rv64i_xqciio0p1", "rv64i_xqcilo0p2", "rv64i_xqcilia0p2",
671+
"rv64i_xqcibm0p4", "rv64i_xqcibi0p2", "rv64i_xqcili0p2",
672+
"rv64i_xqcisim0p2", "rv64i_xqcilb0p2", "rv64i_xqcisync0p2"}) {
673673
EXPECT_THAT(
674674
toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
675675
::testing::EndsWith(" is only supported for 'rv32'"));
@@ -1159,6 +1159,7 @@ Experimental extensions
11591159
xqcics 0.2
11601160
xqcicsr 0.2
11611161
xqciint 0.4
1162+
xqciio 0.1
11621163
xqcilb 0.2
11631164
xqcili 0.2
11641165
xqcilia 0.2

0 commit comments

Comments
 (0)