Skip to content

Commit 737d6ca

Browse files
hchandelHarsh Chandel
and
Harsh Chandel
authored
[RISCV] Add Qualcomm uC Xqcicm (Conditional Move) extension (#121752)
The Qualcomm uC Xqcicm extension adds 13 conditional move instructions. 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 <hchandel@qti.qualcomm.com>
1 parent a8f3eba commit 737d6ca

File tree

11 files changed

+343
-4
lines changed

11 files changed

+343
-4
lines changed

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

+1
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@
193193
// CHECK-NEXT: xqcia 0.2 'Xqcia' (Qualcomm uC Arithmetic Extension)
194194
// CHECK-NEXT: xqciac 0.2 'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension)
195195
// CHECK-NEXT: xqcicli 0.2 'Xqcicli' (Qualcomm uC Conditional Load Immediate Extension)
196+
// CHECK-NEXT: xqcicm 0.2 'Xqcicm' (Qualcomm uC Conditional Move Extension)
196197
// CHECK-NEXT: xqcics 0.2 'Xqcics' (Qualcomm uC Conditional Select Extension)
197198
// CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension)
198199
// CHECK-NEXT: xqcilsm 0.2 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)

llvm/docs/RISCVUsage.rst

+3
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,9 @@ The current vendor extensions supported are:
438438
``experimental-Xqcicli``
439439
LLVM implements `version 0.2 of the Qualcomm uC Conditional Load Immediate 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.
440440

441+
``experimental-Xqcicm``
442+
LLVM implements `version 0.2 of the Qualcomm uC Conditional Move 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.
443+
441444
``experimental-Xqcics``
442445
LLVM implements `version 0.2 of the Qualcomm uC Conditional Select 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.
443446

llvm/docs/ReleaseNotes.md

+2
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ Changes to the RISC-V Backend
232232
extension.
233233
* Adds experimental assembler support for the Qualcomm uC 'Xqcicli` (Conditional Load Immediate)
234234
extension.
235+
* Adds experimental assembler support for the Qualcomm uC 'Xqcicm` (Conditonal Move)
236+
extension.
235237
* Added ``Sdext`` and ``Sdtrig`` extensions.
236238

237239
Changes to the WebAssembly Backend

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

+5
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
698698
TRY_TO_DECODE_FEATURE(
699699
RISCV::FeatureVendorXqcicli, DecoderTableXqcicli32,
700700
"Qualcomm uC Conditional Load Immediate custom opcode table");
701+
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcicm, DecoderTableXqcicm32,
702+
"Qualcomm uC Conditional Move custom opcode table");
701703
TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
702704

703705
return MCDisassembler::Fail;
@@ -727,6 +729,9 @@ DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size,
727729
TRY_TO_DECODE_FEATURE(
728730
RISCV::FeatureVendorXqciac, DecoderTableXqciac16,
729731
"Qualcomm uC Load-Store Address Calculation custom 16bit opcode table");
732+
TRY_TO_DECODE_FEATURE(
733+
RISCV::FeatureVendorXqcicm, DecoderTableXqcicm16,
734+
"Qualcomm uC Conditional Move custom 16bit opcode table");
730735
TRY_TO_DECODE_AND_ADD_SP(STI.hasFeature(RISCV::FeatureVendorXwchc),
731736
DecoderTableXwchc16,
732737
"WCH QingKe XW custom opcode table");

llvm/lib/Target/RISCV/RISCVFeatures.td

+8
Original file line numberDiff line numberDiff line change
@@ -1294,6 +1294,14 @@ def HasVendorXqcicli
12941294
AssemblerPredicate<(all_of FeatureVendorXqcicli),
12951295
"'Xqcicli' (Qualcomm uC Conditional Load Immediate Extension)">;
12961296

1297+
def FeatureVendorXqcicm
1298+
: RISCVExperimentalExtension<0, 2, "Qualcomm uC Conditional Move Extension",
1299+
[FeatureStdExtZca]>;
1300+
def HasVendorXqcicm
1301+
: Predicate<"Subtarget->hasVendorXqcicm()">,
1302+
AssemblerPredicate<(all_of FeatureVendorXqcicm),
1303+
"'Xqcicm' (Qualcomm uC Conditional Move Extension)">;
1304+
12971305
//===----------------------------------------------------------------------===//
12981306
// LLVM specific features and extensions
12991307
//===----------------------------------------------------------------------===//

llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td

+42
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,22 @@ class QCILICC<bits<3> funct3, bits<2> funct2, DAGOperand InTyRs2, string opcodes
150150
let Inst{31-25} = {simm, funct2};
151151
}
152152

153+
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
154+
class QCIMVCC<bits<3> funct3, string opcodestr>
155+
: RVInstR4<0b00, funct3, OPC_CUSTOM_2, (outs GPRNoX0:$rd),
156+
(ins GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs3),
157+
opcodestr, "$rd, $rs1, $rs2, $rs3">;
158+
159+
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
160+
class QCIMVCCI<bits<3> funct3, string opcodestr, DAGOperand immType>
161+
: RVInstR4<0b10, funct3, OPC_CUSTOM_2, (outs GPRNoX0:$rd),
162+
(ins GPRNoX0:$rs1, immType:$imm, GPRNoX0:$rs3),
163+
opcodestr, "$rd, $rs1, $imm, $rs3"> {
164+
bits<5> imm;
165+
166+
let rs2 = imm;
167+
}
168+
153169
//===----------------------------------------------------------------------===//
154170
// Instructions
155171
//===----------------------------------------------------------------------===//
@@ -270,6 +286,32 @@ let Predicates = [HasVendorXqcicli, IsRV32], DecoderNamespace = "Xqcicli" in {
270286
def QC_LIGEUI : QCILICC<0b111, 0b11, uimm5, "qc.ligeui">;
271287
} // Predicates = [HasVendorXqcicli, IsRV32], DecoderNamespace = "Xqcicli"
272288

289+
let Predicates = [HasVendorXqcicm, IsRV32], DecoderNamespace = "Xqcicm" in {
290+
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
291+
def QC_C_MVEQZ : RVInst16CL<0b101, 0b10, (outs GPRC:$rd_wb),
292+
(ins GPRC:$rd, GPRC:$rs1),
293+
"qc.c.mveqz", "$rd, $rs1"> {
294+
let Constraints = "$rd = $rd_wb";
295+
296+
let Inst{12-10} = 0b011;
297+
let Inst{6-5} = 0b00;
298+
}
299+
300+
def QC_MVEQ : QCIMVCC<0b000, "qc.mveq">;
301+
def QC_MVNE : QCIMVCC<0b001, "qc.mvne">;
302+
def QC_MVLT : QCIMVCC<0b100, "qc.mvlt">;
303+
def QC_MVGE : QCIMVCC<0b101, "qc.mvge">;
304+
def QC_MVLTU : QCIMVCC<0b110, "qc.mvltu">;
305+
def QC_MVGEU : QCIMVCC<0b111, "qc.mvgeu">;
306+
307+
def QC_MVEQI : QCIMVCCI<0b000, "qc.mveqi", simm5>;
308+
def QC_MVNEI : QCIMVCCI<0b001, "qc.mvnei", simm5>;
309+
def QC_MVLTI : QCIMVCCI<0b100, "qc.mvlti", simm5>;
310+
def QC_MVGEI : QCIMVCCI<0b101, "qc.mvgei", simm5>;
311+
def QC_MVLTUI : QCIMVCCI<0b110, "qc.mvltui", uimm5>;
312+
def QC_MVGEUI : QCIMVCCI<0b111, "qc.mvgeui", uimm5>;
313+
} // Predicates = [HasVendorXqcicm, IsRV32], DecoderNamespace = "Xqcicm"
314+
273315
//===----------------------------------------------------------------------===//
274316
// Aliases
275317
//===----------------------------------------------------------------------===//

llvm/lib/TargetParser/RISCVISAInfo.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -742,8 +742,8 @@ Error RISCVISAInfo::checkDependency() {
742742
bool HasZvl = MinVLen != 0;
743743
bool HasZcmt = Exts.count("zcmt") != 0;
744744
static constexpr StringLiteral XqciExts[] = {
745-
{"xqcia"}, {"xqciac"}, {"xqcicli"}, {"xqcics"},
746-
{"xqcicsr"}, {"xqcilsm"}, {"xqcisls"}};
745+
{"xqcia"}, {"xqciac"}, {"xqcicli"}, {"xqcicm"},
746+
{"xqcics"}, {"xqcicsr"}, {"xqcilsm"}, {"xqcisls"}};
747747

748748
if (HasI && HasE)
749749
return getIncompatibleError("i", "e");

llvm/test/CodeGen/RISCV/attributes.ll

+2
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcia %s -o - | FileCheck --check-prefix=RV32XQCIA %s
8585
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqciac %s -o - | FileCheck --check-prefix=RV32XQCIAC %s
8686
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicli %s -o - | FileCheck --check-prefix=RV32XQCICLI %s
87+
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm %s -o - | FileCheck --check-prefix=RV32XQCICM %s
8788
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcics %s -o - | FileCheck --check-prefix=RV32XQCICS %s
8889
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck --check-prefix=RV32XQCICSR %s
8990
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilsm %s -o - | FileCheck --check-prefix=RV32XQCILSM %s
@@ -397,6 +398,7 @@
397398
; RV32XQCIA: .attribute 5, "rv32i2p1_xqcia0p2"
398399
; RV32XQCIAC: .attribute 5, "rv32i2p1_zca1p0_xqciac0p2"
399400
; RV32XQCICLI: .attribute 5, "rv32i2p1_xqcicli0p2"
401+
; RV32XQCICM: .attribute 5, "rv32i2p1_zca1p0_xqcicm0p2"
400402
; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
401403
; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
402404
; RV32XQCILSM: .attribute 5, "rv32i2p1_xqcilsm0p2"

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

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# Xqcicm - Qualcomm uC Conditional Move Extension
2+
# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcicm < %s 2>&1 \
3+
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-IMM %s
4+
# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcicm < %s 2>&1 \
5+
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-EXT %s
6+
7+
# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
8+
qc.c.mveqz 9, x10
9+
10+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
11+
qc.c.mveqz x9
12+
13+
# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcicm' (Qualcomm uC Conditional Move Extension)
14+
qc.c.mveqz x9, x10
15+
16+
17+
# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
18+
qc.mveq 9, x10, x11, x12
19+
20+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
21+
qc.mveq x9
22+
23+
# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcicm' (Qualcomm uC Conditional Move Extension)
24+
qc.mveq x9, x10, x11, x12
25+
26+
27+
# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
28+
qc.mvge 9, x10, x11, x12
29+
30+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
31+
qc.mvge x9
32+
33+
# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcicm' (Qualcomm uC Conditional Move Extension)
34+
qc.mvge x9, x10, x11, x12
35+
36+
37+
# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
38+
qc.mvgeu 9, x10, x11, x12
39+
40+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
41+
qc.mvgeu x9
42+
43+
# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcicm' (Qualcomm uC Conditional Move Extension)
44+
qc.mvgeu x9, x10, x11, x12
45+
46+
47+
# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
48+
qc.mvlt 9, x10, x11, x12
49+
50+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
51+
qc.mvlt x9
52+
53+
# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcicm' (Qualcomm uC Conditional Move Extension)
54+
qc.mvlt x9, x10, x11, x12
55+
56+
57+
# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
58+
qc.mvltu 9, x10, x11, x12
59+
60+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
61+
qc.mvltu x9
62+
63+
# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcicm' (Qualcomm uC Conditional Move Extension)
64+
qc.mvltu x9, x10, x11, x12
65+
66+
67+
# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
68+
qc.mvne 9, x10, x11, x12
69+
70+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
71+
qc.mvne x9
72+
73+
# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcicm' (Qualcomm uC Conditional Move Extension)
74+
qc.mvne x9, x10, x11, x12
75+
76+
77+
# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
78+
qc.mveqi 9, x10, 5, x12
79+
80+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
81+
qc.mveqi x9
82+
83+
# CHECK-IMM: :[[@LINE+1]]:19: error: immediate must be an integer in the range [-16, 15]
84+
qc.mveqi x9, x10, 17, x12
85+
86+
# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcicm' (Qualcomm uC Conditional Move Extension)
87+
qc.mveqi x9, x10, 5, x12
88+
89+
90+
# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
91+
qc.mvgei 9, x10, 5, x12
92+
93+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
94+
qc.mvgei x9
95+
96+
# CHECK-IMM: :[[@LINE+1]]:19: error: immediate must be an integer in the range [-16, 15]
97+
qc.mvgei x9, x10, 17, x12
98+
99+
# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcicm' (Qualcomm uC Conditional Move Extension)
100+
qc.mvgei x9, x10, 5, x12
101+
102+
103+
# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
104+
qc.mvlti 9, x10, 5, x12
105+
106+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
107+
qc.mvlti x9
108+
109+
# CHECK-IMM: :[[@LINE+1]]:19: error: immediate must be an integer in the range [-16, 15]
110+
qc.mvlti x9, x10, 17, x12
111+
112+
# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcicm' (Qualcomm uC Conditional Move Extension)
113+
qc.mvlti x9, x10, 5, x12
114+
115+
116+
# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
117+
qc.mvnei 9, x10, 5, x12
118+
119+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
120+
qc.mvnei x9
121+
122+
# CHECK-IMM: :[[@LINE+1]]:19: error: immediate must be an integer in the range [-16, 15]
123+
qc.mvnei x9, x10, 17, x12
124+
125+
# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcicm' (Qualcomm uC Conditional Move Extension)
126+
qc.mvnei x9, x10, 5, x12
127+
128+
129+
# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
130+
qc.mvltui 9, x10, 5, x12
131+
132+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
133+
qc.mvltui x9
134+
135+
# CHECK-IMM: :[[@LINE+1]]:20: error: immediate must be an integer in the range [0, 31]
136+
qc.mvltui x9, x10, 37, x12
137+
138+
# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcicm' (Qualcomm uC Conditional Move Extension)
139+
qc.mvltui x9, x10, 5, x12
140+
141+
142+
# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
143+
qc.mvgeui 9, x10, 5, x12
144+
145+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
146+
qc.mvgeui x9
147+
148+
# CHECK-IMM: :[[@LINE+1]]:20: error: immediate must be an integer in the range [0, 31]
149+
qc.mvgeui x9, x10, 37, x12
150+
151+
# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcicm' (Qualcomm uC Conditional Move Extension)
152+
qc.mvgeui x9, x10, 5, x12

0 commit comments

Comments
 (0)