Skip to content

[RISCV] Add Qualcomm uC Xqcisim (Simulation Hint) extension #128833

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Mar 18, 2025
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 @@ -207,6 +207,7 @@
// CHECK-NEXT: xqcilia 0.2 'Xqcilia' (Qualcomm uC Large Immediate Arithmetic Extension)
// CHECK-NEXT: xqcilo 0.2 'Xqcilo' (Qualcomm uC Large Offset Load Store Extension)
// CHECK-NEXT: xqcilsm 0.2 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension)
// CHECK-NEXT: xqcisim 0.2 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
// CHECK-NEXT: xqcisls 0.2 'Xqcisls' (Qualcomm uC Scaled Load Store Extension)
// CHECK-NEXT: xrivosvisni 0.1 'XRivosVisni' (Rivos Vector Integer Small New)
// CHECK-NEXT: xrivosvizip 0.1 'XRivosVizip' (Rivos Vector Register Zips)
Expand Down
3 changes: 3 additions & 0 deletions llvm/docs/RISCVUsage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,9 @@ The current vendor extensions supported are:
``experimental-Xqcilsm``
LLVM implements `version 0.2 of the Qualcomm uC Load Store Multiple 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-Xqcisim``
LLVM implements `version 0.2 of the Qualcomm uC Simulation Hint 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.

Expand Down
2 changes: 2 additions & 0 deletions llvm/docs/ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ Changes to the RISC-V Backend
'Xqccmp' extension, which is a frame-pointer convention compatible version of
Zcmp.
* Added non-quadratic ``log-vrgather`` cost model for ``vrgather.vv`` instruction
* Adds experimental assembler support for the Qualcomm uC 'Xqcisim` (Simulation Hint)
extension.

Changes to the WebAssembly Backend
----------------------------------
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,8 @@ static constexpr FeatureBitset XqciFeatureGroup = {
RISCV::FeatureVendorXqcics, RISCV::FeatureVendorXqcicsr,
RISCV::FeatureVendorXqciint, RISCV::FeatureVendorXqcili,
RISCV::FeatureVendorXqcilia, RISCV::FeatureVendorXqcilo,
RISCV::FeatureVendorXqcilsm, RISCV::FeatureVendorXqcisls,
RISCV::FeatureVendorXqcilsm, RISCV::FeatureVendorXqcisim,
RISCV::FeatureVendorXqcisls,
};

static constexpr FeatureBitset XSfVectorGroup = {
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 @@ -1407,6 +1407,14 @@ def HasVendorXqccmp : Predicate<"Subtarget->hasVendorXqccmp()">,
AssemblerPredicate<(all_of FeatureVendorXqccmp),
"'Xqccmp' (Qualcomm 16-bit Push/Pop and Double Moves)">;

def FeatureVendorXqcisim
: RISCVExperimentalExtension<0, 2, "Qualcomm uC Simulation Hint Extension",
[FeatureStdExtZca]>;
def HasVendorXqcisim
: Predicate<"Subtarget->hasVendorXqcisim()">,
AssemblerPredicate<(all_of FeatureVendorXqcisim),
"'Xqcisim' (Qualcomm uC Simulation Hint Extension)">;

// Rivos Extension(s)

def FeatureVendorXRivosVisni
Expand Down
48 changes: 48 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,19 @@ class QCIInt_IMM<bits<1> funct1, string opcodestr>
let Inst{24-20} = imm10{9-5};
}

class QCISim_NONE<bits<4> imm11_8, string opcodestr>
: RVInstI<0b010, OPC_OP_IMM, (outs), (ins), opcodestr, ""> {
let rs1 = 0;
let rd = 0;
let imm12 = {imm11_8, 0b00000000};
}

class QCISim_RS1<bits<4> imm11_8, string opcodestr>
: RVInstI<0b010, OPC_OP_IMM, (outs), (ins GPR:$rs1), opcodestr, "$rs1"> {
let rd = 0;
let imm12 = {imm11_8, 0b00000000};
}

class QCIRVInstEIBase<bits<3> funct3, bits<2> funct2, dag outs,
dag ins, string opcodestr, string argstr>
: RVInst48<outs, ins, opcodestr, argstr, [], InstFormatOther> {
Expand Down Expand Up @@ -691,6 +704,41 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
} // Predicates = [HasVendorXqcilia, IsRV32]

let Predicates = [HasVendorXqcisim, IsRV32] in {
let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in {
def QC_PSYSCALLI : RVInstI<0b010, OPC_OP_IMM, (outs), (ins uimm10:$imm10),
"qc.psyscalli", "$imm10"> {
bits<10> imm10;

let rs1 = 0;
let rd = 0;
let imm12 = {0b00, imm10};
}

def QC_PPUTCI : RVInstI<0b010, OPC_OP_IMM, (outs), (ins uimm8:$imm8),
"qc.pputci", "$imm8"> {
bits<8> imm8;

let rs1 = 0;
let rd = 0;
let imm12 = {0b0100, imm8};
}

def QC_PCOREDUMP : QCISim_NONE<0b0110, "qc.pcoredump">;
def QC_PPREGS : QCISim_NONE<0b0111, "qc.ppregs">;
def QC_PPREG : QCISim_RS1<0b1000, "qc.ppreg">;
def QC_PPUTC : QCISim_RS1<0b1001, "qc.pputc">;
def QC_PPUTS : QCISim_RS1<0b1010, "qc.pputs">;
def QC_PEXIT : QCISim_RS1<0b1011, "qc.pexit">;
def QC_PSYSCALL : QCISim_RS1<0b1100, "qc.psyscall">;

def QC_C_PTRACE : RVInst16CI<0b000, 0b10, (outs), (ins), "qc.c.ptrace", ""> {
let rd = 0;
let imm = 0;
}
} // mayLoad = 0, mayStore = 0, hasSideEffects = 1
} // Predicates = [HasVendorXqcisim, IsRV32]

} // DecoderNamespace = "Xqci"

//===----------------------------------------------------------------------===//
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/TargetParser/RISCVISAInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,7 @@ Error RISCVISAInfo::checkDependency() {
static constexpr StringLiteral XqciExts[] = {
{"xqcia"}, {"xqciac"}, {"xqcibi"}, {"xqcibm"}, {"xqcicli"},
{"xqcicm"}, {"xqcics"}, {"xqcicsr"}, {"xqciint"}, {"xqcili"},
{"xqcilia"}, {"xqcilo"}, {"xqcilsm"}, {"xqcisls"}};
{"xqcilia"}, {"xqcilo"}, {"xqcilsm"}, {"xqcisim"}, {"xqcisls"}};
static constexpr StringLiteral ZcdOverlaps[] = {
{"zcmt"}, {"zcmp"}, {"xqccmp"}, {"xqciac"}, {"xqcicm"}};

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 @@ -95,6 +95,7 @@
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilia %s -o - | FileCheck --check-prefix=RV32XQCILIA %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilo %s -o - | FileCheck --check-prefix=RV32XQCILO %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilsm %s -o - | FileCheck --check-prefix=RV32XQCILSM %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcisim %s -o - | FileCheck --check-prefix=RV32XQCISIM %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
Expand Down Expand Up @@ -419,6 +420,7 @@
; RV32XQCILIA: .attribute 5, "rv32i2p1_zca1p0_xqcilia0p2"
; RV32XQCILO: .attribute 5, "rv32i2p1_zca1p0_xqcilo0p2"
; RV32XQCILSM: .attribute 5, "rv32i2p1_xqcilsm0p2"
; RV32XQCISIM: attribute 5, "rv32i2p1_zca1p0_xqcisim0p2"
; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
; RV32ZALRSC: .attribute 5, "rv32i2p1_zalrsc1p0"
Expand Down
125 changes: 125 additions & 0 deletions llvm/test/MC/RISCV/xqcisim-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# Xqcisim - Simulaton Hint Instructions
# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqcisim < %s 2>&1 \
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-PLUS %s
# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqcisim < %s 2>&1 \
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-MINUS %s

# CHECK-PLUS: :[[@LINE+1]]:14: error: immediate must be an integer in the range [0, 1023]
qc.psyscalli 1024

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

# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
qc.psyscalli 23, x0

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
qc.psyscalli 1023


# CHECK-PLUS: :[[@LINE+1]]:11: error: immediate must be an integer in the range [0, 255]
qc.pputci 256

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

# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
qc.pputci 200, x8

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
qc.pputci 255


# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
qc.c.ptrace x0

# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
qc.c.ptrace 1

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
qc.c.ptrace


# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
qc.pcoredump 12

# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
qc.pcoredump x4

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
qc.pcoredump


# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
qc.ppregs x1

# CHECK: :[[@LINE+1]]:11: error: invalid operand for instruction
qc.ppregs 23

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
qc.ppregs


# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
qc.ppreg x10, x2

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

# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
qc.ppreg 23

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
qc.ppreg a0


# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
qc.pputc x7, x3

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

# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
qc.pputc 34

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
qc.pputc t2


# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
qc.pputs x15, x18

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

# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
qc.pputs 45

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
qc.pputs a5


# CHECK: :[[@LINE+1]]:15: error: invalid operand for instruction
qc.pexit x26, x23

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

# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
qc.pexit 78

# CHECK-MINUS: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqcisim' (Qualcomm uC Simulation Hint Extension)
qc.pexit s10


# CHECK: :[[@LINE+1]]:18: error: invalid operand for instruction
qc.psyscall x11, x5

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

# CHECK: :[[@LINE+1]]:13: error: invalid operand for instruction
qc.psyscall 98

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


# CHECK-INST: qc.psyscalli 1023
# CHECK-ENC: encoding: [0x13,0x20,0xf0,0x3f]
qc.psyscalli 1023

# CHECK-INST: qc.pputci 255
# CHECK-ENC: encoding: [0x13,0x20,0xf0,0x4f]
qc.pputci 255

# CHECK-INST: qc.c.ptrace
# CHECK-ENC: encoding: [0x02,0x00]
qc.c.ptrace

# CHECK-INST: qc.pcoredump
# CHECK-ENC: encoding: [0x13,0x20,0x00,0x60]
qc.pcoredump

# CHECK-INST: qc.ppregs
# CHECK-ENC: encoding: [0x13,0x20,0x00,0x70]
qc.ppregs

# CHECK-INST: qc.ppreg a0
# CHECK-ENC: encoding: [0x13,0x20,0x05,0x80]
qc.ppreg x10

# CHECK-INST: qc.pputc t2
# CHECK-ENC: encoding: [0x13,0xa0,0x03,0x90]
qc.pputc x7

# CHECK-INST: qc.pputs a5
# CHECK-ENC: encoding: [0x13,0xa0,0x07,0xa0]
qc.pputs x15

# CHECK-INST: qc.pexit s10
# CHECK-ENC: encoding: [0x13,0x20,0x0d,0xb0]
qc.pexit x26

# CHECK-INST: qc.psyscall a1
# CHECK-ENC: encoding: [0x13,0xa0,0x05,0xc0]
qc.psyscall x11
3 changes: 2 additions & 1 deletion llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,7 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
"rv64i_xqcicsr0p2", "rv64i_xqcilsm0p2", "rv64i_xqcicm0p2",
"rv64i_xqcics0p2", "rv64i_xqcicli0p2", "rv64i_xqciint0p4",
"rv64i_xqcilo0p2", "rv64i_xqcilia0p2", "rv64i_xqcibm0p4",
"rv64i_xqcibi0p2", "rv64i_xqcili0p2"}) {
"rv64i_xqcibi0p2", "rv64i_xqcili0p2", "rv64i_xqcisim0p2"}) {
EXPECT_THAT(
toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
::testing::EndsWith(" is only supported for 'rv32'"));
Expand Down Expand Up @@ -1147,6 +1147,7 @@ Experimental extensions
xqcilia 0.2
xqcilo 0.2
xqcilsm 0.2
xqcisim 0.2
xqcisls 0.2
xrivosvisni 0.1
xrivosvizip 0.1
Expand Down
Loading