Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -188,6 +188,7 @@
// CHECK-NEXT: smctr 1.0 'Smctr' (Control Transfer Records Machine Level)
// 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: xqcia 0.2 'Xqcia' (Qualcomm uC Arithmetic Extension)
// CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension)
// CHECK-NEXT: xqcisls 0.2 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
// CHECK-EMPTY:
Expand Down
3 changes: 3 additions & 0 deletions llvm/docs/RISCVUsage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,9 @@ The current vendor extensions supported are:
``Xwchc``
LLVM implements `the custom compressed opcodes present in some QingKe cores` by WCH / Nanjing Qinheng Microelectronics. The vendor refers to these opcodes by the name "XW".

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

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

Expand Down
2 changes: 2 additions & 0 deletions llvm/docs/ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ Changes to the RISC-V Backend
extension.
* Adds experimental assembler support for the Qualcomm uC 'Xqcisls` (Scaled Load Store)
extension.
* Adds experimental assembler support for the Qualcomm uC 'Xqcia` (Arithmetic)
extension.

Changes to the WebAssembly Backend
----------------------------------
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
bool isUImm6() const { return IsUImm<6>(); }
bool isUImm7() const { return IsUImm<7>(); }
bool isUImm8() const { return IsUImm<8>(); }
bool isUImm11() const { return IsUImm<11>(); }
bool isUImm16() const { return IsUImm<16>(); }
bool isUImm20() const { return IsUImm<20>(); }
bool isUImm32() const { return IsUImm<32>(); }
Expand Down Expand Up @@ -1563,6 +1564,8 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
"immediate must be a multiple of 16 bytes and non-zero in the range");
case Match_InvalidUImm11:
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
case Match_InvalidSImm12:
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
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 @@ -686,6 +686,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
"Qualcomm uC CSR custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcisls, DecoderTableXqcisls32,
"Qualcomm uC Scaled Load Store custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcia, DecoderTableXqcia32,
"Qualcomm uC Arithmetic custom opcode table");
TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");

return MCDisassembler::Fail;
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ enum OperandType : unsigned {
OPERAND_UIMM8_GE32,
OPERAND_UIMM9_LSB000,
OPERAND_UIMM10_LSB00_NONZERO,
OPERAND_UIMM11,
OPERAND_UIMM12,
OPERAND_UIMM16,
OPERAND_UIMM32,
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 @@ -1359,6 +1359,14 @@ def HasVendorXqcisls
AssemblerPredicate<(all_of FeatureVendorXqcisls),
"'Xqcisls' (Qualcomm uC Scaled Load Store Extension)">;

def FeatureVendorXqcia
: RISCVExperimentalExtension<"xqcia", 0, 2,
"'Xqcia' (Qualcomm uC Arithmetic Extension)">;
def HasVendorXqcia
: Predicate<"Subtarget->hasVendorXqcia()">,
AssemblerPredicate<(all_of FeatureVendorXqcia),
"'Xqcia' (Qualcomm uC Arithmetic Extension)">;

//===----------------------------------------------------------------------===//
// LLVM specific features and extensions
//===----------------------------------------------------------------------===//
Expand Down
36 changes: 36 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
// Operand and SDNode transformation definitions.
//===----------------------------------------------------------------------===//

def uimm11 : RISCVUImmLeafOp<11>;

//===----------------------------------------------------------------------===//
// Instruction Formats
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -45,6 +47,16 @@ class QCIStore_ScaleIdx<bits<4> func4, string opcodestr>
}
}

class QCIRVInstR<bits<4> func4, string opcodestr>
: RVInstR<{0b000, func4}, 0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
(ins GPRNoX0:$rs1), opcodestr, "$rd, $rs1"> {
let rs2 = 0;
}

class QCIRVInstRR<bits<5> func5, DAGOperand InTyRs1, string opcodestr>
: RVInstR<{0b00, func5}, 0b011, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
(ins InTyRs1:$rs1, GPRNoX0:$rs2), opcodestr, "$rd, $rs1, $rs2">;

//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -72,3 +84,27 @@ let Predicates = [HasVendorXqcisls, IsRV32], DecoderNamespace = "Xqcisls" in {
def QC_SRH : QCIStore_ScaleIdx<0b1110, "qc.srh">;
def QC_SRW : QCIStore_ScaleIdx<0b1111, "qc.srw">;
} // Predicates = [HasVendorXqcisls, IsRV32], DecoderNamespace = "Xqcisls"

let Predicates = [HasVendorXqcia, IsRV32], DecoderNamespace = "Xqcia" in {
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
def QC_SLASAT : QCIRVInstRR<0b01010, GPRNoX0, "qc.slasat">;
def QC_SLLSAT : QCIRVInstRR<0b01100, GPRNoX0, "qc.sllsat">;
def QC_ADDSAT : QCIRVInstRR<0b01110, GPRNoX0, "qc.addsat">;
def QC_ADDUSAT : QCIRVInstRR<0b01111, GPRNoX0, "qc.addusat">;
def QC_SUBSAT : QCIRVInstRR<0b10000, GPRNoX0, "qc.subsat">;
def QC_SUBUSAT : QCIRVInstRR<0b10001, GPRNoX0, "qc.subusat">;

def QC_WRAP : QCIRVInstRR<0b10010, GPR, "qc.wrap">;
def QC_WRAPI : RVInstI<0b000, OPC_CUSTOM_0, (outs GPRNoX0:$rd),
(ins GPRNoX0:$rs1, uimm11:$imm11), "qc.wrapi",
"$rd, $rs1, $imm11"> {
bits<11> imm11;

let imm12 = {0b0, imm11};
}

def QC_NORM : QCIRVInstR<0b0111, "qc.norm">;
def QC_NORMU : QCIRVInstR<0b1000, "qc.normu">;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I have a question about the semantics of qc.normu in the spec

XReg clz = (xlen() - 1) - $signed(highest_set_bit(X[rs1]));
XReg exp = (X[rs1] << clz);
XReg mnt = (-clz);
X[rd] = {mnt[23:0], exp[7:0]};

Are the assignments of mnt and exp swapped? Unless I'm misunderstanding, I would expect exp to be based only on clz and mnt to be baed on (X[rs1] << clz).

Also the assignment of X[rd] = {mnt[23:0], exp[7:0]}; seems like it should be taking the upper 24 bits of mnt not the lower 24 bits? But maybe I've misunderstood?

def QC_NORMEU : QCIRVInstR<0b1001, "qc.normeu">;
} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
} // Predicates = [HasVendorXqcia, IsRV32], DecoderNamespace = "Xqcia"
3 changes: 2 additions & 1 deletion llvm/lib/TargetParser/RISCVISAInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -741,7 +741,8 @@ 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"}};
static constexpr StringLiteral XqciExts[] = {
{"xqcia"}, {"xqcicsr"}, {"xqcisls"}};

if (HasI && HasE)
return getIncompatibleError("i", "e");
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 @@ -81,6 +81,7 @@
; RUN: llc -mtriple=riscv32 -mattr=+xtheadmempair %s -o - | FileCheck --check-prefix=RV32XTHEADMEMPAIR %s
; 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-xqcia %s -o - | FileCheck --check-prefix=RV32XQCIA %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
Expand Down Expand Up @@ -387,6 +388,7 @@
; RV32XTHEADMEMPAIR: .attribute 5, "rv32i2p1_xtheadmempair1p0"
; RV32XTHEADSYNC: .attribute 5, "rv32i2p1_xtheadsync1p0"
; RV32XWCHC: .attribute 5, "rv32i2p1_xwchc2p2"
; RV32XQCIA: .attribute 5, "rv32i2p1_xqcia0p2"
; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
Expand Down
201 changes: 201 additions & 0 deletions llvm/test/MC/RISCV/xqcia-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
# Xqcia - Qualcomm uC Arithmetic Extension
# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcia < %s 2>&1 \
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s
# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcia < %s 2>&1 \
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s

# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
qc.slasat x10, x3, 17

# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
qc.slasat x10, x3

# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
qc.slasat x0, x3, x17

# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
qc.slasat x10, x0, x17

# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
qc.slasat x10, x3, x0

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
qc.slasat x10, x3, x17


# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
qc.sllsat x23, x25, 27

# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
qc.sllsat x23, x25

# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
qc.sllsat x0, x25, x27

# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
qc.sllsat x23, x0, x27

# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
qc.sllsat x23, x25, x0

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
qc.sllsat x23, x25, x27


# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
qc.addsat x17, x14, 7

# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
qc.addsat x17, x14

# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
qc.addsat x0, x14, x7

# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
qc.addsat x17, x0, x7

# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
qc.addsat x17, x14, x0

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
qc.addsat x17, x14, x7


# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
qc.addusat x8, x18, 28

# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
qc.addusat x8, x18

# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
qc.addusat x0, x18, x28

# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
qc.addusat x8, x0, x28

# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
qc.addusat x8, x18, x0

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
qc.addusat x8, x18, x28


# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
qc.subsat x22, x2, 12

# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
qc.subsat x22, x2

# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
qc.subsat x0, x2, x12

# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
qc.subsat x22, x0, x12

# CHECK: :[[@LINE+1]]:20: error: invalid operand for instruction
qc.subsat x22, x2, x0

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
qc.subsat x22, x2, x12


# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
qc.subusat x9, x14, 17

# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
qc.subusat x9, x14

# CHECK: :[[@LINE+1]]:12: error: invalid operand for instruction
qc.subusat x0, x14, x17

# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
qc.subusat x9, x0, x17

# CHECK: :[[@LINE+1]]:21: error: invalid operand for instruction
qc.subusat x9, x14, x0

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
qc.subusat x9, x14, x17


# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
qc.wrap x3, x30, 23

# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
qc.wrap x3, x30

# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
qc.wrap x0, x30, x23

# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
qc.wrap x3, x30, x0

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
qc.wrap x3, x30, x23


# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
qc.wrapi x0, 12, 2047

# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
qc.wrapi x0, x12, 2047

# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
qc.wrapi x6, x0, 2047

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

# CHECK-PLUS: :[[@LINE+1]]:19: error: immediate must be an integer in the range [0, 2047]
qc.wrapi x6, x12, 2048

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
qc.wrapi x6, x12, 2047


# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
qc.norm x3, 7

# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
qc.norm x3

# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
qc.norm x0, x7

# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
qc.norm x3, x0

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
qc.norm x3, x7


# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
qc.normu x11, 17

# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
qc.normu x11

# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
qc.normu x0, x17

# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
qc.normu x11, x0

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
qc.normu x11, x17


# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
qc.normeu x26, 31

# CHECK: :[[@LINE+1]]:1: error: too few operands for instruction
qc.normeu x26

# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
qc.normeu x0, x31

# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
qc.normeu x26, x0

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcia' (Qualcomm uC Arithmetic Extension)
qc.normeu x26, x31
Loading