Skip to content

Commit 8fcbba8

Browse files
authored
[RISCV] Add Qualcomm uC Xqcisls (Scaled Load Store) extension (#117987)
This extension adds 8 load/store instructions with a scaled index addressing mode. The current spec can be found at: https://github.com/quic/riscv-unified-db/releases/latest This patch adds assembler only support.
1 parent d83148f commit 8fcbba8

File tree

11 files changed

+238
-3
lines changed

11 files changed

+238
-3
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@
189189
// CHECK-NEXT: ssctr 1.0 'Ssctr' (Control Transfer Records Supervisor Level)
190190
// CHECK-NEXT: svukte 0.3 'Svukte' (Address-Independent Latency of User-Mode Faults to Supervisor Addresses)
191191
// CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension)
192+
// CHECK-NEXT: xqcisls 0.2 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
192193
// CHECK-EMPTY:
193194
// CHECK-NEXT: Supported Profiles
194195
// CHECK-NEXT: rva20s64

llvm/docs/RISCVUsage.rst

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

432+
``experimental-Xqcisls``
433+
LLVM implements `version 0.2 of the Qualcomm uC Scaled Load Store extension specification <https://github.com/quic/riscv-unified-db/releases/latest>`__ by Qualcomm. All instructions are prefixed with `qc.` as described in the specification. These instructions are only available for riscv32.
434+
432435
Experimental C Intrinsics
433436
=========================
434437

llvm/docs/ReleaseNotes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ Changes to the RISC-V Backend
213213
between e.g. F and Zfinx code.
214214
* Adds experimental assembler support for the Qualcomm uC 'Xqcicsr` (CSR)
215215
extension.
216+
* Adds experimental assembler support for the Qualcomm uC 'Xqcisls` (Scaled Load Store)
217+
extension.
216218

217219
Changes to the WebAssembly Backend
218220
----------------------------------

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
684684
"CORE-V Immediate Branching custom opcode table");
685685
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcicsr, DecoderTableXqcicsr32,
686686
"Qualcomm uC CSR custom opcode table");
687+
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcisls, DecoderTableXqcisls32,
688+
"Qualcomm uC Scaled Load Store custom opcode table");
687689
TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
688690

689691
return MCDisassembler::Fail;

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,6 +1351,14 @@ def HasVendorXqcicsr
13511351
AssemblerPredicate<(all_of FeatureVendorXqcicsr),
13521352
"'Xqcicsr' (Qualcomm uC CSR Extension)">;
13531353

1354+
def FeatureVendorXqcisls
1355+
: RISCVExperimentalExtension<"xqcisls", 0, 2,
1356+
"'Xqcisls' (Qualcomm uC Scaled Load Store Extension)">;
1357+
def HasVendorXqcisls
1358+
: Predicate<"Subtarget->hasVendorXqcisls()">,
1359+
AssemblerPredicate<(all_of FeatureVendorXqcisls),
1360+
"'Xqcisls' (Qualcomm uC Scaled Load Store Extension)">;
1361+
13541362
//===----------------------------------------------------------------------===//
13551363
// LLVM specific features and extensions
13561364
//===----------------------------------------------------------------------===//

llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,29 @@
2222
// Instruction Class Templates
2323
//===----------------------------------------------------------------------===//
2424

25+
let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
26+
class QCILoad_ScaleIdx<bits<4> func4, string opcodestr>
27+
: RVInstRBase<0b111, OPC_CUSTOM_0,
28+
(outs GPR:$rd), (ins GPRMem:$rs1, GPRNoX0:$rs2, uimm3:$shamt),
29+
opcodestr, "$rd, $rs1, $rs2, $shamt"> {
30+
bits<3> shamt;
31+
let Inst{31-28} = func4;
32+
let Inst{27-25} = shamt;
33+
}
34+
}
35+
36+
let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
37+
// rd corresponds to the source for the store 'rs3' described in the spec.
38+
class QCIStore_ScaleIdx<bits<4> func4, string opcodestr>
39+
: RVInstRBase<0b110, OPC_CUSTOM_1, (outs),
40+
(ins GPR:$rd, GPRMem:$rs1, GPRNoX0:$rs2, uimm3:$shamt),
41+
opcodestr, "$rd, $rs1, $rs2, $shamt"> {
42+
bits<3> shamt;
43+
let Inst{31-28} = func4;
44+
let Inst{27-25} = shamt;
45+
}
46+
}
47+
2548
//===----------------------------------------------------------------------===//
2649
// Instructions
2750
//===----------------------------------------------------------------------===//
@@ -37,3 +60,15 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
3760
"$rd, $rs1, $rs2">;
3861
} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
3962
} // Predicates = [HasVendorXqcicsr, IsRV32], DecoderNamespace = "Xqcicsr"
63+
64+
let Predicates = [HasVendorXqcisls, IsRV32], DecoderNamespace = "Xqcisls" in {
65+
def QC_LRB : QCILoad_ScaleIdx<0b1000, "qc.lrb">;
66+
def QC_LRH : QCILoad_ScaleIdx<0b1001, "qc.lrh">;
67+
def QC_LRW : QCILoad_ScaleIdx<0b1010, "qc.lrw">;
68+
def QC_LRBU : QCILoad_ScaleIdx<0b1011, "qc.lrbu">;
69+
def QC_LRHU : QCILoad_ScaleIdx<0b1100, "qc.lrhu">;
70+
71+
def QC_SRB : QCIStore_ScaleIdx<0b1101, "qc.srb">;
72+
def QC_SRH : QCIStore_ScaleIdx<0b1110, "qc.srh">;
73+
def QC_SRW : QCIStore_ScaleIdx<0b1111, "qc.srw">;
74+
} // Predicates = [HasVendorXqcisls, IsRV32], DecoderNamespace = "Xqcisls"

llvm/lib/TargetParser/RISCVISAInfo.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,7 @@ Error RISCVISAInfo::checkDependency() {
741741
bool HasVector = Exts.count("zve32x") != 0;
742742
bool HasZvl = MinVLen != 0;
743743
bool HasZcmt = Exts.count("zcmt") != 0;
744+
static constexpr StringLiteral XqciExts[] = {{"xqcicsr"}, {"xqcisls"}};
744745

745746
if (HasI && HasE)
746747
return getIncompatibleError("i", "e");
@@ -771,9 +772,9 @@ Error RISCVISAInfo::checkDependency() {
771772
return getIncompatibleError("xwchc", "zcb");
772773
}
773774

774-
if (Exts.count("xqcicsr") != 0 && (XLen != 32)) {
775-
return getError("'xqcicsr' is only supported for 'rv32'");
776-
}
775+
for (auto Ext : XqciExts)
776+
if (Exts.count(Ext.str()) && (XLen != 32))
777+
return getError("'" + Twine(Ext) + "'" + " is only supported for 'rv32'");
777778

778779
return Error::success();
779780
}

llvm/test/CodeGen/RISCV/attributes.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
; RUN: llc -mtriple=riscv32 -mattr=+xtheadsync %s -o - | FileCheck --check-prefix=RV32XTHEADSYNC %s
8383
; RUN: llc -mtriple=riscv32 -mattr=+xwchc %s -o - | FileCheck --check-prefix=RV32XWCHC %s
8484
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck --check-prefix=RV32XQCICSR %s
85+
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcisls %s -o - | FileCheck --check-prefix=RV32XQCISLS %s
8586
; RUN: llc -mtriple=riscv32 -mattr=+zaamo %s -o - | FileCheck --check-prefix=RV32ZAAMO %s
8687
; RUN: llc -mtriple=riscv32 -mattr=+zalrsc %s -o - | FileCheck --check-prefix=RV32ZALRSC %s
8788
; RUN: llc -mtriple=riscv32 -mattr=+zca %s -o - | FileCheck --check-prefixes=CHECK,RV32ZCA %s
@@ -387,6 +388,7 @@
387388
; RV32XTHEADSYNC: .attribute 5, "rv32i2p1_xtheadsync1p0"
388389
; RV32XWCHC: .attribute 5, "rv32i2p1_xwchc2p2"
389390
; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
391+
; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
390392
; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
391393
; RV32ZALRSC: .attribute 5, "rv32i2p1_zalrsc1p0"
392394
; RV32ZCA: .attribute 5, "rv32i2p1_zca1p0"
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# Xqcisls - Qualcomm uC Scaled Load Store Extension
2+
# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcisls < %s 2>&1 \
3+
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s
4+
# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcisls < %s 2>&1 \
5+
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s
6+
7+
# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
8+
qc.lrb x5, x2, x0, 4
9+
10+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
11+
qc.lrb x5, x2, x4
12+
13+
# CHECK-PLUS: :[[@LINE+1]]:20: error: immediate must be an integer in the range [0, 7]
14+
qc.lrb x5, x2, x4, 12
15+
16+
# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
17+
qc.lrb x5, 2, x4, 4
18+
19+
# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
20+
qc.lrb x5, x2, x4, 4
21+
22+
23+
# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction
24+
qc.lrh x1, x12, x0, 2
25+
26+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
27+
qc.lrh x1, x12, x6
28+
29+
# CHECK-PLUS: :[[@LINE+1]]:21: error: immediate must be an integer in the range [0, 7]
30+
qc.lrh x1, x12, x6, 22
31+
32+
# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
33+
qc.lrh x1, 12, x6, 2
34+
35+
# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
36+
qc.lrh x1, x12, x6, 2
37+
38+
39+
# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction
40+
qc.lrw x15, x7, x0, 1
41+
42+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
43+
qc.lrw x15, x7, x14
44+
45+
# CHECK-PLUS: :[[@LINE+1]]:22: error: immediate must be an integer in the range [0, 7]
46+
qc.lrw x15, x7, x14, 11
47+
48+
# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
49+
qc.lrw x15, 7, x14, 1
50+
51+
# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
52+
qc.lrw x15, x7, x14, 1
53+
54+
55+
# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
56+
qc.lrbu x9, x11, x0, 7
57+
58+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
59+
qc.lrbu x9, x11, x4
60+
61+
# CHECK-PLUS: :[[@LINE+1]]:22: error: immediate must be an integer in the range [0, 7]
62+
qc.lrbu x9, x11, x4, 37
63+
64+
# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
65+
qc.lrbu x9, 11, x4, 7
66+
67+
# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
68+
qc.lrbu x9, x11, x4, 7
69+
70+
71+
# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
72+
qc.lrhu x16, x6, x0, 4
73+
74+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
75+
qc.lrhu x16, x6, x10
76+
77+
# CHECK-PLUS: :[[@LINE+1]]:23: error: immediate must be an integer in the range [0, 7]
78+
qc.lrhu x16, x6, x10, 44
79+
80+
# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
81+
qc.lrhu x16, 6, x10, 4
82+
83+
# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
84+
qc.lrhu x16, x6, x10, 4
85+
86+
87+
# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
88+
qc.srb x0, x2, x0, 3
89+
90+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
91+
qc.srb x0, x2, x8
92+
93+
# CHECK-PLUS: :[[@LINE+1]]:20: error: immediate must be an integer in the range [0, 7]
94+
qc.srb x0, x2, x8, 93
95+
96+
# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
97+
qc.srb x0, 2, x8, 3
98+
99+
# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
100+
qc.srb x0, x2, x8, 3
101+
102+
103+
# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction
104+
qc.srh x13, x0, x0, 6
105+
106+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
107+
qc.srh x13, x0, x20
108+
109+
# CHECK-PLUS: :[[@LINE+1]]:22: error: immediate must be an integer in the range [0, 7]
110+
qc.srh x13, x0, x20, 76
111+
112+
# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
113+
qc.srh x13, 0, x20, 6
114+
115+
# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
116+
qc.srh x13, x0, x20, 6
117+
118+
119+
# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
120+
qc.srw x17, x18, x0, 0
121+
122+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
123+
qc.srw x17, x18, x19
124+
125+
# CHECK-PLUS: :[[@LINE+1]]:23: error: immediate must be an integer in the range [0, 7]
126+
qc.srw x17, x18, x19, 10
127+
128+
# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
129+
qc.srw x17, 18, x19, 0
130+
131+
# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
132+
qc.srw x17, x18, x19, 0

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Xqcisls - Qualcomm uC Scaled Load Store Extension
2+
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcisls -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-xqcisls < %s \
5+
# RUN: | llvm-objdump --mattr=+experimental-xqcisls -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-xqcisls -show-encoding \
8+
# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
9+
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcisls < %s \
10+
# RUN: | llvm-objdump --mattr=+experimental-xqcisls --no-print-imm-hex -d - \
11+
# RUN: | FileCheck -check-prefix=CHECK-INST %s
12+
13+
# CHECK-INST: qc.lrb t0, sp, tp, 4
14+
# CHECK-ENC: encoding: [0x8b,0x72,0x41,0x88]
15+
qc.lrb x5, x2, x4, 4
16+
17+
# CHECK-INST: qc.lrh ra, a2, t1, 2
18+
# CHECK-ENC: encoding: [0x8b,0x70,0x66,0x94]
19+
qc.lrh x1, x12, x6, 2
20+
21+
# CHECK-INST: qc.lrw a5, t2, a4, 1
22+
# CHECK-ENC: encoding: [0x8b,0xf7,0xe3,0xa2]
23+
qc.lrw x15, x7, x14, 1
24+
25+
# CHECK-INST: qc.lrbu s1, a1, tp, 7
26+
# CHECK-ENC: encoding: [0x8b,0xf4,0x45,0xbe]
27+
qc.lrbu x9, x11, x4, 7
28+
29+
# CHECK-INST: qc.lrhu a6, t1, a0, 4
30+
# CHECK-ENC: encoding: [0x0b,0x78,0xa3,0xc8]
31+
qc.lrhu x16, x6, x10, 4
32+
33+
# CHECK-INST: qc.srb zero, sp, s0, 3
34+
# CHECK-ENC: encoding: [0x2b,0x60,0x81,0xd6]
35+
qc.srb x0, x2, x8, 3
36+
37+
# CHECK-INST: qc.srh a3, zero, s4, 6
38+
# CHECK-ENC: encoding: [0xab,0x66,0x40,0xed]
39+
qc.srh x13, x0, x20, 6
40+
41+
# CHECK-INST: qc.srw a7, s2, s3, 0
42+
# CHECK-ENC: encoding: [0xab,0x68,0x39,0xf1]
43+
qc.srw x17, x18, x19, 0

0 commit comments

Comments
 (0)