Skip to content

Commit 1557eed

Browse files
hchandelHarsh Chandelsvs-quic
authored
[RISCV] Add Qualcomm uC Xqciac (Load-Store Adress calculation) extension (#121037)
This extension adds 3 instructions that perform load-store address calculation. 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]> Co-authored-by: Sudharsan Veeravalli <[email protected]>
1 parent 02e8972 commit 1557eed

File tree

13 files changed

+169
-3
lines changed

13 files changed

+169
-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: xqcia 0.2 'Xqcia' (Qualcomm uC Arithmetic Extension)
192+
// CHECK-NEXT: xqciac 0.2 'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension)
192193
// CHECK-NEXT: xqcics 0.2 'Xqcics' (Qualcomm uC Conditional Select Extension)
193194
// CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension)
194195
// 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
@@ -429,6 +429,9 @@ The current vendor extensions supported are:
429429
``experimental-Xqcia``
430430
LLVM implements `version 0.2 of the Qualcomm uC 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.
431431

432+
``experimental-Xqciac``
433+
LLVM implements `version 0.2 of the Qualcomm uC Load-Store Address Calculation 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-Xqcics``
433436
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.
434437

llvm/docs/ReleaseNotes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,8 @@ Changes to the RISC-V Backend
224224
extension.
225225
* Adds experimental assembler support for the Qualcomm uC 'Xqcia` (Arithmetic)
226226
extension.
227+
* Adds experimental assembler support for the Qualcomm uC 'Xqciac` (Load-Store Address Calculation)
228+
extension.
227229
* Adds experimental assembler support for the Qualcomm uC 'Xqcics` (Conditonal Select)
228230
extension.
229231
* Adds experimental assembler support for the Qualcomm uC 'Xqcilsm` (Load Store Multiple)

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
734734
VK == RISCVMCExpr::VK_RISCV_None;
735735
}
736736

737+
bool isUImm5GT3() const {
738+
if (!isImm())
739+
return false;
740+
RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
741+
int64_t Imm;
742+
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
743+
return IsConstantImm && isUInt<5>(Imm) && (Imm > 3) &&
744+
VK == RISCVMCExpr::VK_RISCV_None;
745+
}
746+
737747
bool isUImm8GE32() const {
738748
int64_t Imm;
739749
RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
@@ -1520,6 +1530,8 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
15201530
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
15211531
case Match_InvalidUImm5NonZero:
15221532
return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1533+
case Match_InvalidUImm5GT3:
1534+
return generateImmOutOfRangeError(Operands, ErrorInfo, 4, (1 << 5) - 1);
15231535
case Match_InvalidUImm6:
15241536
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
15251537
case Match_InvalidUImm7:

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,9 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
692692
"Qualcomm uC Conditional Select custom opcode table");
693693
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcilsm, DecoderTableXqcilsm32,
694694
"Qualcomm uC Load Store Multiple custom opcode table");
695+
TRY_TO_DECODE_FEATURE(
696+
RISCV::FeatureVendorXqciac, DecoderTableXqciac32,
697+
"Qualcomm uC Load-Store Address Calculation custom opcode table");
695698
TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
696699

697700
return MCDisassembler::Fail;
@@ -718,6 +721,9 @@ DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size,
718721
TRY_TO_DECODE_FEATURE(
719722
RISCV::FeatureStdExtZcmp, DecoderTableRVZcmp16,
720723
"Zcmp table (16-bit Push/Pop & Double Move Instructions)");
724+
TRY_TO_DECODE_FEATURE(
725+
RISCV::FeatureVendorXqciac, DecoderTableXqciac16,
726+
"Qualcomm uC Load-Store Address Calculation custom 16bit opcode table");
721727
TRY_TO_DECODE_AND_ADD_SP(STI.hasFeature(RISCV::FeatureVendorXwchc),
722728
DecoderTableXwchc16,
723729
"WCH QingKe XW custom opcode table");

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ enum OperandType : unsigned {
302302
OPERAND_UIMM4,
303303
OPERAND_UIMM5,
304304
OPERAND_UIMM5_NONZERO,
305+
OPERAND_UIMM5_GT3,
305306
OPERAND_UIMM5_LSB0,
306307
OPERAND_UIMM6,
307308
OPERAND_UIMM6_LSB0,

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,6 +1274,14 @@ def HasVendorXqcilsm
12741274
AssemblerPredicate<(all_of FeatureVendorXqcilsm),
12751275
"'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)">;
12761276

1277+
def FeatureVendorXqciac
1278+
: RISCVExperimentalExtension<0, 2, "Qualcomm uC Load-Store Address Calculation Extension",
1279+
[FeatureStdExtZca]>;
1280+
def HasVendorXqciac
1281+
: Predicate<"Subtarget->hasVendorXqciac()">,
1282+
AssemblerPredicate<(all_of FeatureVendorXqciac),
1283+
"'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension)">;
1284+
12771285
//===----------------------------------------------------------------------===//
12781286
// LLVM specific features and extensions
12791287
//===----------------------------------------------------------------------===//

llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ def uimm5nonzero : RISCVOp<XLenVT>,
2121
let OperandType = "OPERAND_UIMM5_NONZERO";
2222
}
2323

24+
def uimm5gt3 : RISCVOp<XLenVT>, ImmLeaf<XLenVT,
25+
[{return (Imm > 3) && isUInt<5>(Imm);}]> {
26+
let ParserMatchClass = UImmAsmOperand<5, "GT3">;
27+
let DecoderMethod = "decodeUImmOperand<5>";
28+
let OperandType = "OPERAND_UIMM5_GT3";
29+
}
30+
2431
def uimm11 : RISCVUImmLeafOp<11>;
2532

2633
//===----------------------------------------------------------------------===//
@@ -184,6 +191,37 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
184191
} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
185192
} // Predicates = [HasVendorXqcia, IsRV32], DecoderNamespace = "Xqcia"
186193

194+
let Predicates = [HasVendorXqciac, IsRV32], DecoderNamespace = "Xqciac" in {
195+
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
196+
def QC_C_MULADDI : RVInst16CL<0b001, 0b10, (outs GPRC:$rd_wb),
197+
(ins GPRC:$rd, GPRC:$rs1, uimm5:$uimm),
198+
"qc.c.muladdi", "$rd, $rs1, $uimm"> {
199+
let Constraints = "$rd = $rd_wb";
200+
bits<5> uimm;
201+
202+
let Inst{12-10} = uimm{3-1};
203+
let Inst{6} = uimm{0};
204+
let Inst{5} = uimm{4};
205+
}
206+
207+
def QC_MULADDI : RVInstI<0b110, OPC_CUSTOM_0, (outs GPRNoX0:$rd_wb),
208+
(ins GPRNoX0:$rd, GPRNoX0:$rs1, simm12:$imm12),
209+
"qc.muladdi", "$rd, $rs1, $imm12"> {
210+
let Constraints = "$rd = $rd_wb";
211+
}
212+
213+
def QC_SHLADD : RVInstRBase<0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
214+
(ins GPRNoX0:$rs1, GPRNoX0:$rs2, uimm5gt3:$shamt),
215+
"qc.shladd", "$rd, $rs1, $rs2, $shamt"> {
216+
bits<5> shamt;
217+
218+
let Inst{31-30} = 0b01;
219+
let Inst{29-25} = shamt;
220+
}
221+
222+
} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
223+
} // Predicates = [HasVendorXqciac, IsRV32], DecoderNamespace = "Xqciac"
224+
187225
let Predicates = [HasVendorXqcics, IsRV32], DecoderNamespace = "Xqcics" in {
188226
def QC_SELECTIIEQ : QCISELECTIICC <0b010, "qc.selectiieq">;
189227
def QC_SELECTIINE : QCISELECTIICC <0b011, "qc.selectiine">;

llvm/lib/TargetParser/RISCVISAInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ Error RISCVISAInfo::checkDependency() {
742742
bool HasZvl = MinVLen != 0;
743743
bool HasZcmt = Exts.count("zcmt") != 0;
744744
static constexpr StringLiteral XqciExts[] = {
745-
{"xqcia"}, {"xqcics"}, {"xqcicsr"}, {"xqcilsm"}, {"xqcisls"}};
745+
{"xqcia"}, {"xqciac"}, {"xqcics"}, {"xqcicsr"}, {"xqcilsm"}, {"xqcisls"}};
746746

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

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-xqcia %s -o - | FileCheck --check-prefix=RV32XQCIA %s
85+
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqciac %s -o - | FileCheck --check-prefix=RV32XQCIAC %s
8586
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcics %s -o - | FileCheck --check-prefix=RV32XQCICS %s
8687
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck --check-prefix=RV32XQCICSR %s
8788
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilsm %s -o - | FileCheck --check-prefix=RV32XQCILSM %s
@@ -391,6 +392,7 @@
391392
; RV32XTHEADSYNC: .attribute 5, "rv32i2p1_xtheadsync1p0"
392393
; RV32XWCHC: .attribute 5, "rv32i2p1_xwchc2p2"
393394
; RV32XQCIA: .attribute 5, "rv32i2p1_xqcia0p2"
395+
; RV32XQCIAC: .attribute 5, "rv32i2p1_zca1p0_xqciac0p2"
394396
; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
395397
; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
396398
; RV32XQCILSM: .attribute 5, "rv32i2p1_xqcilsm0p2"

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Xqciac - Qualcomm uC Load-Store Address Calculation Extension
2+
# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqciac < %s 2>&1 \
3+
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-IMM %s
4+
# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqciac < %s 2>&1 \
5+
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-EXT %s
6+
7+
# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
8+
qc.c.muladdi x5, x10, 4
9+
10+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
11+
qc.c.muladdi x15
12+
13+
# CHECK-IMM: :[[@LINE+1]]:24: error: immediate must be an integer in the range [0, 31]
14+
qc.c.muladdi x10, x15, 32
15+
16+
# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension)
17+
qc.c.muladdi x10, x15, 20
18+
19+
20+
# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
21+
qc.muladdi x0, x10, 1048577
22+
23+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
24+
qc.muladdi x10
25+
26+
# CHECK-IMM: :[[@LINE+1]]:22: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
27+
qc.muladdi x10, x15, 8589934592
28+
29+
# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension)
30+
qc.muladdi x10, x15, 577
31+
32+
33+
# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
34+
qc.shladd 0, x10, 1048577
35+
36+
# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
37+
qc.shladd x10
38+
39+
# CHECK-IMM: :[[@LINE+1]]:26: error: immediate must be an integer in the range [4, 31]
40+
qc.shladd x10, x15, x11, 2
41+
42+
# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension)
43+
qc.shladd x10, x15, x11, 5

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Xqciac - Qualcomm uC Load-Store Address Calculation Extension
2+
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqciac -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-xqciac < %s \
5+
# RUN: | llvm-objdump --mattr=+experimental-xqciac -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-xqciac -show-encoding \
8+
# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
9+
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqciac < %s \
10+
# RUN: | llvm-objdump --mattr=+experimental-xqciac --no-print-imm-hex -d - \
11+
# RUN: | FileCheck -check-prefix=CHECK-INST %s
12+
13+
# CHECK-INST: qc.c.muladdi a0, a1, 0
14+
# CHECK-ENC: encoding: [0x8a,0x21]
15+
qc.c.muladdi x10, x11, 0
16+
17+
# CHECK-INST: qc.c.muladdi a0, a1, 31
18+
# CHECK-ENC: encoding: [0xea,0x3d]
19+
qc.c.muladdi x10, x11, 31
20+
21+
# CHECK-INST: qc.c.muladdi a0, a1, 16
22+
# CHECK-ENC: encoding: [0xaa,0x21]
23+
qc.c.muladdi x10, x11, 16
24+
25+
26+
# CHECK-INST: qc.muladdi tp, t0, 1234
27+
# CHECK-ENC: encoding: [0x0b,0xe2,0x22,0x4d]
28+
qc.muladdi x4, x5, 1234
29+
30+
# CHECK-INST: qc.muladdi a0, a1, -2048
31+
# CHECK-ENC: encoding: [0x0b,0xe5,0x05,0x80]
32+
qc.muladdi x10, x11, -2048
33+
34+
# CHECK-INST: qc.muladdi a0, a1, 2047
35+
# CHECK-ENC: encoding: [0x0b,0xe5,0xf5,0x7f]
36+
qc.muladdi x10, x11, 2047
37+
38+
39+
# CHECK-INST: qc.shladd tp, t0, t1, 12
40+
# CHECK-ENC: encoding: [0x0b,0xb2,0x62,0x58]
41+
qc.shladd x4, x5, x6, 12
42+
43+
# CHECK-INST: qc.shladd a0, a1, a2, 4
44+
# CHECK-ENC: encoding: [0x0b,0xb5,0xc5,0x48]
45+
qc.shladd x10, x11, x12, 4
46+
47+
# CHECK-INST: qc.shladd a0, a1, a2, 31
48+
# CHECK-ENC: encoding: [0x0b,0xb5,0xc5,0x7e]
49+
qc.shladd x10, x11, x12, 31

llvm/unittests/TargetParser/RISCVISAInfoTest.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -654,8 +654,8 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
654654
}
655655

656656
for (StringRef Input :
657-
{"rv64i_xqcisls0p2", "rv64i_xqcia0p2", "rv64i_xqcicsr0p2",
658-
"rv64i_xqcilsm0p2", "rv64i_xqcics0p2"}) {
657+
{"rv64i_xqcisls0p2", "rv64i_xqcia0p2", "rv64i_xqciac0p2",
658+
"rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcics0p2"}) {
659659
EXPECT_THAT(
660660
toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
661661
::testing::EndsWith(" is only supported for 'rv32'"));
@@ -1113,6 +1113,7 @@ Experimental extensions
11131113
ssctr 1.0
11141114
svukte 0.3
11151115
xqcia 0.2
1116+
xqciac 0.2
11161117
xqcics 0.2
11171118
xqcicsr 0.2
11181119
xqcilsm 0.2

0 commit comments

Comments
 (0)