Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/test/Driver/print-supported-extensions-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@
// CHECK-NEXT: ssctr 1.0 'Ssctr' (Control Transfer Records Supervisor Level)
// CHECK-NEXT: svukte 0.3 'Svukte' (Address-Independent Latency of User-Mode Faults to Supervisor Addresses)
// CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension)
// CHECK-NEXT: xqcisls 0.2 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
// CHECK-EMPTY:
// CHECK-NEXT: Supported Profiles
// CHECK-NEXT: rva20s64
Expand Down
3 changes: 3 additions & 0 deletions llvm/docs/RISCVUsage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,9 @@ The current vendor extensions supported are:
``experimental-Xqcicsr``
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.

``experimental-Xqcisls``
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.

Experimental C Intrinsics
=========================

Expand Down
2 changes: 2 additions & 0 deletions llvm/docs/ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ Changes to the RISC-V Backend
between e.g. F and Zfinx code.
* Adds experimental assembler support for the Qualcomm uC 'Xqcicsr` (CSR)
extension.
* Adds experimental assembler support for the Qualcomm uC 'Xqcisls` (Scaled Load Store)
extension.

Changes to the WebAssembly Backend
----------------------------------
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
"CORE-V Immediate Branching custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcicsr, DecoderTableXqcicsr32,
"Qualcomm uC CSR custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcisls, DecoderTableXqcisls32,
"Qualcomm uC Scaled Load Store custom opcode table");
TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");

return MCDisassembler::Fail;
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/Target/RISCV/RISCVFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -1351,6 +1351,14 @@ def HasVendorXqcicsr
AssemblerPredicate<(all_of FeatureVendorXqcicsr),
"'Xqcicsr' (Qualcomm uC CSR Extension)">;

def FeatureVendorXqcisls
: RISCVExperimentalExtension<"xqcisls", 0, 2,
"'Xqcisls' (Qualcomm uC Scaled Load Store Extension)">;
def HasVendorXqcisls
: Predicate<"Subtarget->hasVendorXqcisls()">,
AssemblerPredicate<(all_of FeatureVendorXqcisls),
"'Xqcisls' (Qualcomm uC Scaled Load Store Extension)">;

//===----------------------------------------------------------------------===//
// LLVM specific features and extensions
//===----------------------------------------------------------------------===//
Expand Down
35 changes: 35 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,29 @@
// Instruction Class Templates
//===----------------------------------------------------------------------===//

let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
class QCILoad_ScaleIdx<bits<4> func4, string opcodestr>
: RVInstRBase<0b111, OPC_CUSTOM_0,
(outs GPR:$rd), (ins GPRMem:$rs1, GPRNoX0:$rs2, uimm3:$shamt),
opcodestr, "$rd, $rs1, $rs2, $shamt"> {
bits<3> shamt;
let Inst{31-28} = func4;
let Inst{27-25} = shamt;
}
}

let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
// rd corresponds to the source for the store 'rs3' described in the spec.
class QCIStore_ScaleIdx<bits<4> func4, string opcodestr>
: RVInstRBase<0b110, OPC_CUSTOM_1, (outs),
(ins GPR:$rd, GPRMem:$rs1, GPRNoX0:$rs2, uimm3:$shamt),
opcodestr, "$rd, $rs1, $rs2, $shamt"> {
bits<3> shamt;
let Inst{31-28} = func4;
let Inst{27-25} = shamt;
}
}

//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
Expand All @@ -37,3 +60,15 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
"$rd, $rs1, $rs2">;
} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
} // Predicates = [HasVendorXqcicsr, IsRV32], DecoderNamespace = "Xqcicsr"

let Predicates = [HasVendorXqcisls, IsRV32], DecoderNamespace = "Xqcisls" in {
def QC_LRB : QCILoad_ScaleIdx<0b1000, "qc.lrb">;
def QC_LRH : QCILoad_ScaleIdx<0b1001, "qc.lrh">;
def QC_LRW : QCILoad_ScaleIdx<0b1010, "qc.lrw">;
def QC_LRBU : QCILoad_ScaleIdx<0b1011, "qc.lrbu">;
def QC_LRHU : QCILoad_ScaleIdx<0b1100, "qc.lrhu">;

def QC_SRB : QCIStore_ScaleIdx<0b1101, "qc.srb">;
def QC_SRH : QCIStore_ScaleIdx<0b1110, "qc.srh">;
def QC_SRW : QCIStore_ScaleIdx<0b1111, "qc.srw">;
} // Predicates = [HasVendorXqcisls, IsRV32], DecoderNamespace = "Xqcisls"
9 changes: 6 additions & 3 deletions llvm/lib/TargetParser/RISCVISAInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,7 @@ Error RISCVISAInfo::checkDependency() {
bool HasVector = Exts.count("zve32x") != 0;
bool HasZvl = MinVLen != 0;
bool HasZcmt = Exts.count("zcmt") != 0;
static constexpr StringLiteral XqciExts[] = {{"xqcicsr"}, {"xqcisls"}};

if (HasI && HasE)
return getIncompatibleError("i", "e");
Expand Down Expand Up @@ -771,9 +772,11 @@ Error RISCVISAInfo::checkDependency() {
return getIncompatibleError("xwchc", "zcb");
}

if (Exts.count("xqcicsr") != 0 && (XLen != 32)) {
return getError("'xqcicsr' is only supported for 'rv32'");
}
for (auto Ext : XqciExts)
if (Exts.count(Ext.str()) && (XLen != 32))
return createStringError(errc::invalid_argument,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use getError instead of createStringError?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I've made the change.

"'" + Twine(Ext) + "'" +
" is only supported for 'rv32'");

return Error::success();
}
Expand Down
2 changes: 2 additions & 0 deletions llvm/test/CodeGen/RISCV/attributes.ll
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
; RUN: llc -mtriple=riscv32 -mattr=+xtheadsync %s -o - | FileCheck --check-prefix=RV32XTHEADSYNC %s
; RUN: llc -mtriple=riscv32 -mattr=+xwchc %s -o - | FileCheck --check-prefix=RV32XWCHC %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck --check-prefix=RV32XQCICSR %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcisls %s -o - | FileCheck --check-prefix=RV32XQCISLS %s
; RUN: llc -mtriple=riscv32 -mattr=+zaamo %s -o - | FileCheck --check-prefix=RV32ZAAMO %s
; RUN: llc -mtriple=riscv32 -mattr=+zalrsc %s -o - | FileCheck --check-prefix=RV32ZALRSC %s
; RUN: llc -mtriple=riscv32 -mattr=+zca %s -o - | FileCheck --check-prefixes=CHECK,RV32ZCA %s
Expand Down Expand Up @@ -387,6 +388,7 @@
; RV32XTHEADSYNC: .attribute 5, "rv32i2p1_xtheadsync1p0"
; RV32XWCHC: .attribute 5, "rv32i2p1_xwchc2p2"
; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
; RV32ZALRSC: .attribute 5, "rv32i2p1_zalrsc1p0"
; RV32ZCA: .attribute 5, "rv32i2p1_zca1p0"
Expand Down
132 changes: 132 additions & 0 deletions llvm/test/MC/RISCV/xqcisls-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Xqcisls - Qualcomm uC Scaled Load Store Extension
# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcisls < %s 2>&1 \
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s
# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcisls < %s 2>&1 \
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s

# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
qc.lrb x5, x2, x0, 4

# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
qc.lrb x5, x2, x4

# CHECK-PLUS: :[[@LINE+1]]:20: error: immediate must be an integer in the range [0, 7]
qc.lrb x5, x2, x4, 12

# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
qc.lrb x5, 2, x4, 4

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
qc.lrb x5, x2, x4, 4


# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction
qc.lrh x1, x12, x0, 2

# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
qc.lrh x1, x12, x6

# CHECK-PLUS: :[[@LINE+1]]:21: error: immediate must be an integer in the range [0, 7]
qc.lrh x1, x12, x6, 22

# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
qc.lrh x1, 12, x6, 2

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
qc.lrh x1, x12, x6, 2


# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction
qc.lrw x15, x7, x0, 1

# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
qc.lrw x15, x7, x14

# CHECK-PLUS: :[[@LINE+1]]:22: error: immediate must be an integer in the range [0, 7]
qc.lrw x15, x7, x14, 11

# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
qc.lrw x15, 7, x14, 1

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
qc.lrw x15, x7, x14, 1


# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
qc.lrbu x9, x11, x0, 7

# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
qc.lrbu x9, x11, x4

# CHECK-PLUS: :[[@LINE+1]]:22: error: immediate must be an integer in the range [0, 7]
qc.lrbu x9, x11, x4, 37

# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
qc.lrbu x9, 11, x4, 7

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
qc.lrbu x9, x11, x4, 7


# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
qc.lrhu x16, x6, x0, 4

# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
qc.lrhu x16, x6, x10

# CHECK-PLUS: :[[@LINE+1]]:23: error: immediate must be an integer in the range [0, 7]
qc.lrhu x16, x6, x10, 44

# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
qc.lrhu x16, 6, x10, 4

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
qc.lrhu x16, x6, x10, 4


# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
qc.srb x0, x2, x0, 3

# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
qc.srb x0, x2, x8

# CHECK-PLUS: :[[@LINE+1]]:20: error: immediate must be an integer in the range [0, 7]
qc.srb x0, x2, x8, 93

# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
qc.srb x0, 2, x8, 3

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
qc.srb x0, x2, x8, 3


# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction
qc.srh x13, x0, x0, 6

# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
qc.srh x13, x0, x20

# CHECK-PLUS: :[[@LINE+1]]:22: error: immediate must be an integer in the range [0, 7]
qc.srh x13, x0, x20, 76

# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
qc.srh x13, 0, x20, 6

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
qc.srh x13, x0, x20, 6


# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
qc.srw x17, x18, x0, 0

# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
qc.srw x17, x18, x19

# CHECK-PLUS: :[[@LINE+1]]:23: error: immediate must be an integer in the range [0, 7]
qc.srw x17, x18, x19, 10

# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
qc.srw x17, 18, x19, 0

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
qc.srw x17, x18, x19, 0
43 changes: 43 additions & 0 deletions llvm/test/MC/RISCV/xqcisls-valid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Xqcisls - Qualcomm uC Scaled Load Store Extension
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcisls -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcisls < %s \
# RUN: | llvm-objdump --mattr=+experimental-xqcisls -M no-aliases --no-print-imm-hex -d - \
# RUN: | FileCheck -check-prefix=CHECK-INST %s
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-xqcisls -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-xqcisls < %s \
# RUN: | llvm-objdump --mattr=+experimental-xqcisls --no-print-imm-hex -d - \
# RUN: | FileCheck -check-prefix=CHECK-INST %s

# CHECK-INST: qc.lrb t0, sp, tp, 4
# CHECK-ENC: encoding: [0x8b,0x72,0x41,0x88]
qc.lrb x5, x2, x4, 4

# CHECK-INST: qc.lrh ra, a2, t1, 2
# CHECK-ENC: encoding: [0x8b,0x70,0x66,0x94]
qc.lrh x1, x12, x6, 2

# CHECK-INST: qc.lrw a5, t2, a4, 1
# CHECK-ENC: encoding: [0x8b,0xf7,0xe3,0xa2]
qc.lrw x15, x7, x14, 1

# CHECK-INST: qc.lrbu s1, a1, tp, 7
# CHECK-ENC: encoding: [0x8b,0xf4,0x45,0xbe]
qc.lrbu x9, x11, x4, 7

# CHECK-INST: qc.lrhu a6, t1, a0, 4
# CHECK-ENC: encoding: [0x0b,0x78,0xa3,0xc8]
qc.lrhu x16, x6, x10, 4

# CHECK-INST: qc.srb zero, sp, s0, 3
# CHECK-ENC: encoding: [0x2b,0x60,0x81,0xd6]
qc.srb x0, x2, x8, 3

# CHECK-INST: qc.srh a3, zero, s4, 6
# CHECK-ENC: encoding: [0xab,0x66,0x40,0xed]
qc.srh x13, x0, x20, 6

# CHECK-INST: qc.srw a7, s2, s3, 0
# CHECK-ENC: encoding: [0xab,0x68,0x39,0xf1]
qc.srw x17, x18, x19, 0
6 changes: 6 additions & 0 deletions llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,11 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
"'xwchc' and 'zcb' extensions are incompatible");
}

for (StringRef Input : {"rv64i_xqcisls0p2"}) {
EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
"'xqcisls' is only supported for 'rv32'");
}
}

TEST(ParseArchString, MissingDepency) {
Expand Down Expand Up @@ -1105,6 +1110,7 @@ Experimental extensions
ssctr 1.0
svukte 0.3
xqcicsr 0.2
xqcisls 0.2

Supported Profiles
rva20s64
Expand Down