Skip to content

Commit e61859f

Browse files
authored
[RISCV] Add Qualcomm uC Xqcili (load large immediates) extension (llvm#130012)
The Xqcili extension includes a two instructions that load large immediates than is available with the base RISC-V ISA. 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.
1 parent c2b66ce commit e61859f

File tree

13 files changed

+132
-6
lines changed

13 files changed

+132
-6
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@
202202
// CHECK-NEXT: xqcics 0.2 'Xqcics' (Qualcomm uC Conditional Select Extension)
203203
// CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension)
204204
// CHECK-NEXT: xqciint 0.4 'Xqciint' (Qualcomm uC Interrupts Extension)
205+
// CHECK-NEXT: xqcili 0.2 'Xqcili' (Qualcomm uC Load Large Immediate Extension)
205206
// CHECK-NEXT: xqcilia 0.2 'Xqcilia' (Qualcomm uC Large Immediate Arithmetic Extension)
206207
// CHECK-NEXT: xqcilo 0.2 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
207208
// CHECK-NEXT: xqcilsm 0.2 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)

llvm/docs/RISCVUsage.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,9 @@ The current vendor extensions supported are:
456456
``experimental-Xqciint``
457457
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.
458458

459+
``experimental-Xqcili``
460+
LLVM implements `version 0.2 of the Qualcomm uC Load Large 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.
461+
459462
``experimental-Xqcilia``
460463
LLVM implements `version 0.2 of the Qualcomm uC Large Immediate Arithmetic 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.
461464

llvm/docs/ReleaseNotes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ Changes to the PowerPC Backend
107107
Changes to the RISC-V Backend
108108
-----------------------------
109109

110+
* Adds experimental assembler support for the Qualcomm uC 'Xqcili` (Load Large Immediate)
111+
extension.
110112
* Adds experimental assembler support for the Qualcomm uC 'Xqcilia` (Large Immediate Arithmetic)
111113
extension.
112114
* Adds experimental assembler support for the Qualcomm uC 'Xqcibm` (Bit Manipulation)

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
10761076
VK == RISCVMCExpr::VK_RISCV_None;
10771077
}
10781078

1079+
bool isSImm20() const {
1080+
if (!isImm())
1081+
return false;
1082+
RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
1083+
int64_t Imm;
1084+
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
1085+
return IsConstantImm && (VK == RISCVMCExpr::VK_RISCV_None) &&
1086+
isInt<20>(fixImmediateForRV32(Imm, isRV64Imm()));
1087+
}
1088+
10791089
bool isSImm26() const {
10801090
if (!isImm())
10811091
return false;
@@ -1712,6 +1722,9 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
17121722
case Match_InvalidSImm26:
17131723
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 25),
17141724
(1 << 25) - 1);
1725+
case Match_InvalidSImm20:
1726+
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 19),
1727+
(1 << 19) - 1);
17151728
case Match_InvalidSImm32:
17161729
return generateImmOutOfRangeError(Operands, ErrorInfo,
17171730
std::numeric_limits<int32_t>::min(),

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -651,8 +651,9 @@ static constexpr FeatureBitset XqciFeatureGroup = {
651651
RISCV::FeatureVendorXqcibm, RISCV::FeatureVendorXqcicli,
652652
RISCV::FeatureVendorXqcicm, RISCV::FeatureVendorXqcics,
653653
RISCV::FeatureVendorXqcicsr, RISCV::FeatureVendorXqciint,
654-
RISCV::FeatureVendorXqcilia, RISCV::FeatureVendorXqcilo,
655-
RISCV::FeatureVendorXqcilsm, RISCV::FeatureVendorXqcisls,
654+
RISCV::FeatureVendorXqcili, RISCV::FeatureVendorXqcilia,
655+
RISCV::FeatureVendorXqcilo, RISCV::FeatureVendorXqcilsm,
656+
RISCV::FeatureVendorXqcisls,
656657
};
657658

658659
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
@@ -329,6 +329,7 @@ enum OperandType : unsigned {
329329
OPERAND_SIMM11,
330330
OPERAND_SIMM12,
331331
OPERAND_SIMM12_LSB00000,
332+
OPERAND_SIMM20,
332333
OPERAND_SIMM26,
333334
OPERAND_SIMM32,
334335
OPERAND_CLUI_IMM,

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,6 +1359,14 @@ def HasVendorXqciint
13591359
AssemblerPredicate<(all_of FeatureVendorXqciint),
13601360
"'Xqciint' (Qualcomm uC Interrupts Extension)">;
13611361

1362+
def FeatureVendorXqcili
1363+
: RISCVExperimentalExtension<0, 2, "Qualcomm uC Load Large Immediate Extension",
1364+
[FeatureStdExtZca]>;
1365+
1366+
def HasVendorXqcili : Predicate<"Subtarget->hasVendorXqcili()">,
1367+
AssemblerPredicate<(all_of FeatureVendorXqcili),
1368+
"'Xqcili' (Qualcomm uC Load Large Immediate Extension)">;
1369+
13621370
def FeatureVendorXqcilia
13631371
: RISCVExperimentalExtension<0, 2, "Qualcomm uC Large Immediate Arithmetic Extension",
13641372
[FeatureStdExtZca]>;

llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ def uimm11 : RISCVUImmLeafOp<11>;
5656

5757
def simm11 : RISCVSImmLeafOp<11>;
5858

59+
def simm20 : RISCVSImmLeafOp<20>;
60+
5961
def simm26 : RISCVSImmLeafOp<26>;
6062

6163
// 32-bit Immediate, used by RV32 Instructions in 32-bit operations, so no
@@ -591,6 +593,19 @@ let Predicates = [HasVendorXqcilo, IsRV32] in {
591593
def QC_E_SW : QCIRVInstESStore<0b110, 0b11, "qc.e.sw">;
592594
} // Predicates = [HasVendorXqcilo, IsRV32]
593595

596+
let Predicates = [HasVendorXqcili, IsRV32] in {
597+
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
598+
def QC_LI : RVInstU<OPC_OP_IMM_32, (outs GPRNoX0:$rd), (ins simm20:$imm20),
599+
"qc.li", "$rd, $imm20"> {
600+
let Inst{31} = imm20{19};
601+
let Inst{30-16} = imm20{14-0};
602+
let Inst{15-12} = imm20{18-15};
603+
}
604+
605+
def QC_E_LI : QCIRVInstEAI<0b000, 0b0, "qc.e.li">;
606+
} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
607+
} // Predicates = [HasVendorXqcili, IsRV32]
608+
594609
let Predicates = [HasVendorXqcilia, IsRV32] in {
595610
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
596611
def QC_E_XORAI : QCIRVInstEAI<0b001, 0b0, "qc.e.xorai">;

llvm/lib/TargetParser/RISCVISAInfo.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -744,9 +744,9 @@ Error RISCVISAInfo::checkDependency() {
744744
bool HasXqccmp = Exts.count("xqccmp") != 0;
745745

746746
static constexpr StringLiteral XqciExts[] = {
747-
{"xqcia"}, {"xqciac"}, {"xqcibm"}, {"xqcicli"},
748-
{"xqcicm"}, {"xqcics"}, {"xqcicsr"}, {"xqciint"},
749-
{"xqcilia"}, {"xqcilo"}, {"xqcilsm"}, {"xqcisls"}};
747+
{"xqcia"}, {"xqciac"}, {"xqcibm"}, {"xqcicli"}, {"xqcicm"},
748+
{"xqcics"}, {"xqcicsr"}, {"xqciint"}, {"xqcili"}, {"xqcilia"},
749+
{"xqcilo"}, {"xqcilsm"}, {"xqcisls"}};
750750
static constexpr StringLiteral ZcdOverlaps[] = {
751751
{"zcmt"}, {"zcmp"}, {"xqccmp"}, {"xqciac"}, {"xqcicm"}};
752752

llvm/test/CodeGen/RISCV/attributes.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcics %s -o - | FileCheck --check-prefix=RV32XQCICS %s
9191
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck --check-prefix=RV32XQCICSR %s
9292
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqciint %s -o - | FileCheck --check-prefix=RV32XQCIINT %s
93+
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcili %s -o - | FileCheck --check-prefix=RV32XQCILI %s
9394
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilia %s -o - | FileCheck --check-prefix=RV32XQCILIA %s
9495
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilo %s -o - | FileCheck --check-prefix=RV32XQCILO %s
9596
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilsm %s -o - | FileCheck --check-prefix=RV32XQCILSM %s
@@ -412,6 +413,7 @@
412413
; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
413414
; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
414415
; RV32XQCIINT: .attribute 5, "rv32i2p1_zca1p0_xqciint0p4"
416+
; RV32XQCILI: .attribute 5, "rv32i2p1_zca1p0_xqcili0p2"
415417
; RV32XQCILIA: .attribute 5, "rv32i2p1_zca1p0_xqcilia0p2"
416418
; RV32XQCILO: .attribute 5, "rv32i2p1_zca1p0_xqcilo0p2"
417419
; RV32XQCILSM: .attribute 5, "rv32i2p1_xqcilsm0p2"

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Xqcili - Qualcomm uC Load Large Immediate Extension
2+
# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcili < %s 2>&1 \
3+
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-PLUS,CHECK-IMM %s
4+
# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcili < %s 2>&1 \
5+
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-MINUS,CHECK-EXT %s
6+
7+
# CHECK-PLUS: :[[@LINE+2]]:9: error: register must be a GPR excluding zero (x0)
8+
# CHECK-MINUS: :[[@LINE+1]]:9: error: invalid operand for instruction
9+
qc.e.li 9, 33554432
10+
11+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
12+
qc.e.li x9
13+
14+
# CHECK-IMM: :[[@LINE+1]]:13: error: immediate must be an integer in the range [-2147483648, 4294967295]
15+
qc.e.li x9, 4294967296
16+
17+
# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcili' (Qualcomm uC Load Large Immediate Extension)
18+
qc.e.li x9, 4294967295
19+
20+
21+
# CHECK-PLUS: :[[@LINE+2]]:7: error: register must be a GPR excluding zero (x0)
22+
# CHECK-MINUS: :[[@LINE+1]]:7: error: invalid operand for instruction
23+
qc.li x0, 114514
24+
25+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
26+
qc.li x10
27+
28+
# CHECK-IMM: :[[@LINE+1]]:12: error: immediate must be an integer in the range [-524288, 524287]
29+
qc.li x10, 33554432
30+
31+
# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcili' (Qualcomm uC Load Large Immediate Extension)
32+
qc.li x10, 114514

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

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Xqcili - Qualcomm uC Load Large Immediate Extension
2+
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcili -riscv-no-aliases -show-encoding \
3+
# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
4+
5+
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcili < %s \
6+
# RUN: | llvm-objdump --mattr=+experimental-xqcili -M no-aliases --no-print-imm-hex -d - \
7+
# RUN: | FileCheck -check-prefix=CHECK-INST %s
8+
9+
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcili -show-encoding \
10+
# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
11+
12+
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcili < %s \
13+
# RUN: | llvm-objdump --mattr=+experimental-xqcili --no-print-imm-hex -d - \
14+
# RUN: | FileCheck -check-prefix=CHECK-INST %s
15+
16+
# CHECK-INST: qc.e.li a0, -1
17+
# CHECK-ENC: encoding: [0x1f,0x05,0xff,0xff,0xff,0xff]
18+
qc.e.li x10, 4294967295
19+
20+
# CHECK-INST: qc.e.li a0, -2147483648
21+
# CHECK-ENC: encoding: [0x1f,0x05,0x00,0x00,0x00,0x80]
22+
qc.e.li x10, -2147483648
23+
24+
# CHECK-INST: qc.e.li s1, -33554432
25+
# CHECK-ENC: encoding: [0x9f,0x04,0x00,0x00,0x00,0xfe]
26+
qc.e.li x9, -33554432
27+
28+
# CHECK-INST: qc.e.li s1, 33554431
29+
# CHECK-ENC: encoding: [0x9f,0x04,0xff,0xff,0xff,0x01]
30+
qc.e.li x9, 33554431
31+
32+
# CHECK-INST: qc.li s1, 524287
33+
# CHECK-ENC: encoding: [0x9b,0xf4,0xff,0x7f]
34+
qc.li x9, 524287
35+
36+
# CHECK-INST: qc.li s1, -524288
37+
# CHECK-ENC: encoding: [0x9b,0x04,0x00,0x80]
38+
qc.li x9, -524288
39+
40+
# CHECK-INST: qc.li a0, 12345
41+
# CHECK-ENC: encoding: [0x1b,0x05,0x39,0x30]
42+
qc.li x10, 12345
43+
44+
# CHECK-INST: qc.li a0, -12346
45+
# CHECK-ENC: encoding: [0x1b,0xf5,0xc6,0xcf]
46+
qc.li x10, -12346

llvm/unittests/TargetParser/RISCVISAInfoTest.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,8 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
657657
{"rv64i_xqcisls0p2", "rv64i_xqcia0p4", "rv64i_xqciac0p3",
658658
"rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcicm0p2",
659659
"rv64i_xqcics0p2", "rv64i_xqcicli0p2", "rv64i_xqciint0p4",
660-
"rv64i_xqcilo0p2", "rv64i_xqcilia0p2", "rv64i_xqcibm0p4"}) {
660+
"rv64i_xqcilo0p2", "rv64i_xqcili0p2", "rv64i_xqcilia0p2",
661+
"rv64i_xqcibm0p4"}) {
661662
EXPECT_THAT(
662663
toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
663664
::testing::EndsWith(" is only supported for 'rv32'"));
@@ -1141,6 +1142,7 @@ Experimental extensions
11411142
xqcics 0.2
11421143
xqcicsr 0.2
11431144
xqciint 0.4
1145+
xqcili 0.2
11441146
xqcilia 0.2
11451147
xqcilo 0.2
11461148
xqcilsm 0.2

0 commit comments

Comments
 (0)