Skip to content

[RISCV] Add Qualcomm uC Xqciint (Interrupts) extension #122256

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 5 commits into from
Jan 13, 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 @@ -196,6 +196,7 @@
// CHECK-NEXT: xqcicm 0.2 'Xqcicm' (Qualcomm uC Conditional Move Extension)
// CHECK-NEXT: xqcics 0.2 'Xqcics' (Qualcomm uC Conditional Select Extension)
// CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension)
// CHECK-NEXT: xqciint 0.2 'Xqciint' (Qualcomm uC Interrupts Extension)
// CHECK-NEXT: xqcilsm 0.2 'Xqcilsm' (Qualcomm uC Load Store Multiple 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 @@ -447,6 +447,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-Xqciint``
LLVM implements `version 0.2 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.

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

Expand Down
2 changes: 2 additions & 0 deletions llvm/docs/ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ Changes to the RISC-V Backend
extension.
* Adds experimental assembler support for the Qualcomm uC 'Xqcicm` (Conditonal Move)
extension.
* Adds experimental assembler support for the Qualcomm uC 'Xqciint` (Interrupts)
extension.
* Added ``Sdext`` and ``Sdtrig`` extensions.

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 isUImm10() const { return IsUImm<10>(); }
bool isUImm11() const { return IsUImm<11>(); }
bool isUImm16() const { return IsUImm<16>(); }
bool isUImm20() const { return IsUImm<20>(); }
Expand Down Expand Up @@ -1590,6 +1591,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_InvalidUImm10:
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
case Match_InvalidUImm11:
return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
case Match_InvalidSImm12:
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,8 @@ DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
"Qualcomm uC Conditional Load Immediate custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqcicm, DecoderTableXqcicm32,
"Qualcomm uC Conditional Move custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqciint, DecoderTableXqciint32,
"Qualcomm uC Interrupts custom opcode table");
TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");

return MCDisassembler::Fail;
Expand Down Expand Up @@ -732,6 +734,8 @@ DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size,
TRY_TO_DECODE_FEATURE(
RISCV::FeatureVendorXqcicm, DecoderTableXqcicm16,
"Qualcomm uC Conditional Move custom 16bit opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXqciint, DecoderTableXqciint16,
"Qualcomm uC Interrupts custom 16bit opcode table");
TRY_TO_DECODE_AND_ADD_SP(STI.hasFeature(RISCV::FeatureVendorXwchc),
DecoderTableXwchc16,
"WCH QingKe XW custom opcode table");
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 @@ -313,6 +313,7 @@ enum OperandType : unsigned {
OPERAND_UIMM8_LSB000,
OPERAND_UIMM8_GE32,
OPERAND_UIMM9_LSB000,
OPERAND_UIMM10,
OPERAND_UIMM10_LSB00_NONZERO,
OPERAND_UIMM11,
OPERAND_UIMM12,
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 @@ -1302,6 +1302,14 @@ def HasVendorXqcicm
AssemblerPredicate<(all_of FeatureVendorXqcicm),
"'Xqcicm' (Qualcomm uC Conditional Move Extension)">;

def FeatureVendorXqciint
: RISCVExperimentalExtension<0, 2, "Qualcomm uC Interrupts Extension",
[FeatureStdExtZca]>;
def HasVendorXqciint
: Predicate<"Subtarget->hasVendorXqciint()">,
AssemblerPredicate<(all_of FeatureVendorXqciint),
"'Xqciint' (Qualcomm uC Interrupts Extension)">;

//===----------------------------------------------------------------------===//
// LLVM specific features and extensions
//===----------------------------------------------------------------------===//
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2473,6 +2473,7 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
CASE_OPERAND_UIMM(6)
CASE_OPERAND_UIMM(7)
CASE_OPERAND_UIMM(8)
CASE_OPERAND_UIMM(10)
CASE_OPERAND_UIMM(12)
CASE_OPERAND_UIMM(20)
// clang-format on
Expand Down
64 changes: 64 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ def uimm5gt3 : RISCVOp<XLenVT>, ImmLeaf<XLenVT,
let OperandType = "OPERAND_UIMM5_GT3";
}

def uimm10 : RISCVUImmLeafOp<10>;

def uimm11 : RISCVUImmLeafOp<11>;

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -166,6 +168,36 @@ class QCIMVCCI<bits<3> funct3, string opcodestr, DAGOperand immType>
let rs2 = imm;
}

let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
class QCIRVInst16CI_RS1<bits<5> funct5, string OpcodeStr>
: RVInst16CI<0b000, 0b10, (outs), (ins GPRNoX0:$rs1), OpcodeStr, "$rs1"> {
bits<5> rs1;

let Inst{12} = 0b1;
let Inst{11-7} = rs1;
let Inst{6-2} = funct5{4-0};
}

let hasSideEffects = 1 in
class QCIRVInst16CI_NONE<bits<5> funct5, string OpcodeStr>
: RVInst16CI<0b000, 0b10, (outs), (ins), OpcodeStr, ""> {
let Inst{12} = 0b1;
let Inst{11-7} = funct5;
let Inst{6-2} = 0b00100;
}

let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
class QCIInt_IMM<bits<1> funct1, string opcodestr>
: RVInstIBase<0b000, OPC_SYSTEM, (outs), (ins uimm10:$imm10), opcodestr,
"$imm10"> {
bits<10> imm10;

let rd = 0;
let rs1 = imm10{4-0};
let Inst{31-25} = {0b110011, funct1};
let Inst{24-20} = imm10{9-5};
}

//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -312,6 +344,38 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
def QC_MVGEUI : QCIMVCCI<0b111, "qc.mvgeui", uimm5>;
} // Predicates = [HasVendorXqcicm, IsRV32], DecoderNamespace = "Xqcicm"

let Predicates = [HasVendorXqciint, IsRV32], DecoderNamespace = "Xqciint" in {
let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
def QC_C_DIR : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd), (ins),
"qc.c.dir", "$rd"> {
bits<5> rd;

let Inst{12} = 0b1;
let Inst{11-7} = rd;
let Inst{6-2} = 0b00000;
}

def QC_SETINTI : QCIInt_IMM<0b0, "qc.setinti">;
def QC_CLRINTI : QCIInt_IMM<0b1, "qc.clrinti">;

def QC_C_EIR : QCIRVInst16CI_RS1<0b00001, "qc.c.eir">;
def QC_C_SETINT : QCIRVInst16CI_RS1<0b00010, "qc.c.setint">;
def QC_C_CLRINT : QCIRVInst16CI_RS1<0b00011, "qc.c.clrint">;

let mayLoad = 0, mayStore = 0 in {
def QC_C_DI : QCIRVInst16CI_NONE<0b10110, "qc.c.di">;
def QC_C_EI : QCIRVInst16CI_NONE<0b10111, "qc.c.ei">;
} // mayLoad =0, mayStore = 0

let mayLoad = 1, mayStore = 1 in {
def QC_C_MIENTER : QCIRVInst16CI_NONE<0b10000, "qc.c.mienter">;
def QC_C_MIENTER_NEST : QCIRVInst16CI_NONE<0b10001, "qc.c.mienter.nest">;
} // mayLoad = 1, mayStore = 1

let mayLoad = 1, mayStore = 1, isReturn = 1, isTerminator = 1 in
def QC_C_MILEAVERET : QCIRVInst16CI_NONE<0b10100, "qc.c.mileaveret">;
} // Predicates = [HasVendorXqciint, IsRV32], DecoderNamespace = "Xqciint"

//===----------------------------------------------------------------------===//
// Aliases
//===----------------------------------------------------------------------===//
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/TargetParser/RISCVISAInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -742,8 +742,8 @@ Error RISCVISAInfo::checkDependency() {
bool HasZvl = MinVLen != 0;
bool HasZcmt = Exts.count("zcmt") != 0;
static constexpr StringLiteral XqciExts[] = {
{"xqcia"}, {"xqciac"}, {"xqcicli"}, {"xqcicm"},
{"xqcics"}, {"xqcicsr"}, {"xqcilsm"}, {"xqcisls"}};
{"xqcia"}, {"xqciac"}, {"xqcicli"}, {"xqcicm"}, {"xqcics"},
{"xqcicsr"}, {"xqciint"}, {"xqcilsm"}, {"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 @@ -87,6 +87,7 @@
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicm %s -o - | FileCheck --check-prefix=RV32XQCICM %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcics %s -o - | FileCheck --check-prefix=RV32XQCICS %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcicsr %s -o - | FileCheck --check-prefix=RV32XQCICSR %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqciint %s -o - | FileCheck --check-prefix=RV32XQCIINT %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcilsm %s -o - | FileCheck --check-prefix=RV32XQCILSM %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 @@ -401,6 +402,7 @@
; RV32XQCICM: .attribute 5, "rv32i2p1_zca1p0_xqcicm0p2"
; RV32XQCICS: .attribute 5, "rv32i2p1_xqcics0p2"
; RV32XQCICSR: .attribute 5, "rv32i2p1_xqcicsr0p2"
; RV32XQCIINT: .attribute 5, "rv32i2p1_zca1p0_xqciint0p2"
; RV32XQCILSM: .attribute 5, "rv32i2p1_xqcilsm0p2"
; RV32XQCISLS: .attribute 5, "rv32i2p1_xqcisls0p2"
; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo1p0"
Expand Down
105 changes: 105 additions & 0 deletions llvm/test/MC/RISCV/xqciint-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Xqciint - Qualcomm uC Interrupts extension
# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-xqciint < %s 2>&1 \
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-IMM %s
# RUN: not llvm-mc -triple riscv32 -mattr=-experimental-xqciint < %s 2>&1 \
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-EXT %s

# CHECK-IMM: :[[@LINE+1]]:12: error: immediate must be an integer in the range [0, 1023]
qc.setinti 1025

# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
qc.setinti 11, 12

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

# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
qc.setinti 10


# CHECK-IMM: :[[@LINE+1]]:12: error: immediate must be an integer in the range [0, 1023]
qc.clrinti 2000

# CHECK: :[[@LINE+1]]:16: error: invalid operand for instruction
qc.clrinti 22, x4

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

# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
qc.clrinti 8


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

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

# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
qc.c.clrint x8


# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
qc.c.di 22

# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
qc.c.di


# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
qc.c.dir 22

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

# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
qc.c.dir x8


# CHECK: :[[@LINE+1]]:9: error: invalid operand for instruction
qc.c.ei 22

# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
qc.c.ei


# CHECK: :[[@LINE+1]]:10: error: invalid operand for instruction
qc.c.eir 22

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

# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
qc.c.eir x8


# CHECK: :[[@LINE+1]]:19: error: invalid operand for instruction
qc.c.mienter.nest 22

# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
qc.c.mienter.nest


# CHECK: :[[@LINE+1]]:14: error: invalid operand for instruction
qc.c.mienter 22

# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
qc.c.mienter


# CHECK: :[[@LINE+1]]:17: error: invalid operand for instruction
qc.c.mileaveret 22

# CHECK-EXT: :[[@LINE+1]]:1: error: instruction requires the following: 'Xqciint' (Qualcomm uC Interrupts Extension)
qc.c.mileaveret


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

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

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

# CHECK-INST: qc.setinti 500
# CHECK-ENC: encoding: [0x73,0x00,0xfa,0xcc]
qc.setinti 500

# CHECK-INST: qc.setinti 0
# CHECK-ENC: encoding: [0x73,0x00,0x00,0xcc]
qc.setinti 0

# CHECK-INST: qc.setinti 1023
# CHECK-ENC: encoding: [0x73,0x80,0xff,0xcd]
qc.setinti 1023


# CHECK-INST: qc.clrinti 500
# CHECK-ENC: encoding: [0x73,0x00,0xfa,0xce]
qc.clrinti 500

# CHECK-INST: qc.clrinti 1023
# CHECK-ENC: encoding: [0x73,0x80,0xff,0xcf]
qc.clrinti 1023

# CHECK-INST: qc.clrinti 0
# CHECK-ENC: encoding: [0x73,0x00,0x00,0xce]
qc.clrinti 0


# CHECK-INST: qc.c.clrint a0
# CHECK-ENC: encoding: [0x0e,0x15]
qc.c.clrint x10


# CHECK-INST: qc.c.di
# CHECK-ENC: encoding: [0x12,0x1b]
qc.c.di


# CHECK-INST: qc.c.dir a0
# CHECK-ENC: encoding: [0x02,0x15]
qc.c.dir x10


# CHECK-INST: qc.c.ei
# CHECK-ENC: encoding: [0x92,0x1b]
qc.c.ei


# CHECK-INST: qc.c.eir a0
# CHECK-ENC: encoding: [0x06,0x15]
qc.c.eir x10


# CHECK-INST: qc.c.mienter.nest
# CHECK-ENC: encoding: [0x92,0x18]
qc.c.mienter.nest


# CHECK-INST: qc.c.mienter
# CHECK-ENC: encoding: [0x12,0x18]
qc.c.mienter


# CHECK-INST: qc.c.mileaveret
# CHECK-ENC: encoding: [0x12,0x1a]
qc.c.mileaveret


# CHECK-INST: qc.c.setint a0
# CHECK-ENC: encoding: [0x0a,0x15]
qc.c.setint x10
Loading
Loading