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
9 changes: 9 additions & 0 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,15 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
else if (!Subtarget.hasVendorXTHeadCondMov())
setOperationAction(ISD::SELECT, XLenVT, Custom);

if (Subtarget.hasVendorXqcia() && !Subtarget.is64Bit()) {
setOperationAction(ISD::UADDSAT, MVT::i32, Legal);
setOperationAction(ISD::SADDSAT, MVT::i32, Legal);
setOperationAction(ISD::USUBSAT, MVT::i32, Legal);
setOperationAction(ISD::SSUBSAT, MVT::i32, Legal);
setOperationAction(ISD::SSHLSAT, MVT::i32, Legal);
setOperationAction(ISD::USHLSAT, MVT::i32, Legal);
}

static const unsigned FPLegalNodeTypes[] = {
ISD::FMINNUM, ISD::FMAXNUM, ISD::FMINIMUMNUM,
ISD::FMAXIMUMNUM, ISD::LRINT, ISD::LLRINT,
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
Original file line number Diff line number Diff line change
Expand Up @@ -1247,6 +1247,10 @@ class PatGprNoX0Simm32NoSimm26<SDPatternOperator OpNode, RVInst48 Inst>
: Pat<(i32 (OpNode (i32 GPRNoX0:$rs1), simm32_nosimm26:$imm)),
(Inst GPRNoX0:$rs1, simm32_nosimm26:$imm)>;

class PatGprNoX0GprNoX0<SDPatternOperator OpNode, RVInstR Inst>
: Pat<(i32 (OpNode (i32 GPRNoX0:$rs1), (i32 GPRNoX0:$rs2))),
(Inst GPRNoX0:$rs1, GPRNoX0:$rs2)>;

class QC48LdPat<PatFrag LoadOp, RVInst48 Inst>
: Pat<(i32 (LoadOp (AddLike (i32 GPR:$rs1), simm26_nosimm12:$imm26))),
(Inst GPR:$rs1, simm26_nosimm12:$imm26)>;
Expand Down Expand Up @@ -1308,5 +1312,14 @@ let Predicates = [HasVendorXqcisls, IsRV32], AddedComplexity = 1 in {
def : QCScaledStPat<store, QC_SRW>;
} // Predicates = [HasVendorXqcisls, IsRV32], AddedComplexity = 1

let Predicates = [HasVendorXqcia, IsRV32] in {
def : PatGprNoX0GprNoX0<saddsat, QC_ADDSAT>;
def : PatGprNoX0GprNoX0<uaddsat, QC_ADDUSAT>;
def : PatGprNoX0GprNoX0<ssubsat, QC_SUBSAT>;
def : PatGprNoX0GprNoX0<usubsat, QC_SUBUSAT>;
def : PatGprNoX0GprNoX0<ushlsat, QC_SHLUSAT>;
def : PatGprNoX0GprNoX0<sshlsat, QC_SHLSAT>;
} // Predicates = [HasVendorXqcia, IsRV32]

let Predicates = [HasVendorXqciint, IsRV32] in
def : Pat<(riscv_mileaveret_glue), (QC_C_MILEAVERET)>;
128 changes: 128 additions & 0 deletions llvm/test/CodeGen/RISCV/xqcia.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; Test that we are able to generate the Xqcia instructions
; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
; RUN: | FileCheck %s --check-prefixes=RV32I
; RUN: llc -mtriple=riscv32 -mattr=+experimental-xqcia -verify-machineinstrs < %s \
; RUN: | FileCheck %s --check-prefixes=RV32IXQCIA

define i32 @addsat(i32 %a, i32 %b) {
; RV32I-LABEL: addsat:
; RV32I: # %bb.0:
; RV32I-NEXT: mv a2, a0
; RV32I-NEXT: add a0, a0, a1
; RV32I-NEXT: slt a2, a0, a2
; RV32I-NEXT: slti a1, a1, 0
; RV32I-NEXT: beq a1, a2, .LBB0_2
; RV32I-NEXT: # %bb.1:
; RV32I-NEXT: srai a0, a0, 31
; RV32I-NEXT: lui a1, 524288
; RV32I-NEXT: xor a0, a0, a1
; RV32I-NEXT: .LBB0_2:
; RV32I-NEXT: ret
;
; RV32IXQCIA-LABEL: addsat:
; RV32IXQCIA: # %bb.0:
; RV32IXQCIA-NEXT: qc.addsat a0, a0, a1
; RV32IXQCIA-NEXT: ret
%saddsat = tail call i32 @llvm.sadd.sat.i32(i32 %a,i32 %b)
ret i32 %saddsat
}

define i32 @addusat(i32 %a, i32 %b) {
; RV32I-LABEL: addusat:
; RV32I: # %bb.0:
; RV32I-NEXT: add a1, a0, a1
; RV32I-NEXT: sltu a0, a1, a0
; RV32I-NEXT: neg a0, a0
; RV32I-NEXT: or a0, a0, a1
; RV32I-NEXT: ret
;
; RV32IXQCIA-LABEL: addusat:
; RV32IXQCIA: # %bb.0:
; RV32IXQCIA-NEXT: qc.addusat a0, a0, a1
; RV32IXQCIA-NEXT: ret
%uaddsat = tail call i32 @llvm.uadd.sat.i32(i32 %a,i32 %b)
ret i32 %uaddsat
}

define i32 @subsat(i32 %a, i32 %b) {
; RV32I-LABEL: subsat:
; RV32I: # %bb.0:
; RV32I-NEXT: mv a2, a0
; RV32I-NEXT: sgtz a3, a1
; RV32I-NEXT: sub a0, a0, a1
; RV32I-NEXT: slt a1, a0, a2
; RV32I-NEXT: beq a3, a1, .LBB2_2
; RV32I-NEXT: # %bb.1:
; RV32I-NEXT: srai a0, a0, 31
; RV32I-NEXT: lui a1, 524288
; RV32I-NEXT: xor a0, a0, a1
; RV32I-NEXT: .LBB2_2:
; RV32I-NEXT: ret
;
; RV32IXQCIA-LABEL: subsat:
; RV32IXQCIA: # %bb.0:
; RV32IXQCIA-NEXT: qc.subsat a0, a0, a1
; RV32IXQCIA-NEXT: ret
%ssubsat = tail call i32 @llvm.ssub.sat.i32(i32 %a,i32 %b)
ret i32 %ssubsat
}

define i32 @subusat(i32 %a, i32 %b) {
; RV32I-LABEL: subusat:
; RV32I: # %bb.0:
; RV32I-NEXT: sub a1, a0, a1
; RV32I-NEXT: sltu a0, a0, a1
; RV32I-NEXT: addi a0, a0, -1
; RV32I-NEXT: and a0, a0, a1
; RV32I-NEXT: ret
;
; RV32IXQCIA-LABEL: subusat:
; RV32IXQCIA: # %bb.0:
; RV32IXQCIA-NEXT: qc.subusat a0, a0, a1
; RV32IXQCIA-NEXT: ret
%usubsat = tail call i32 @llvm.usub.sat.i32(i32 %a,i32 %b)
ret i32 %usubsat
}

define i32 @shlusat(i32 %a, i32 %b) {
; RV32I-LABEL: shlusat:
; RV32I: # %bb.0:
; RV32I-NEXT: sll a2, a0, a1
; RV32I-NEXT: srl a1, a2, a1
; RV32I-NEXT: xor a0, a0, a1
; RV32I-NEXT: seqz a0, a0
; RV32I-NEXT: addi a0, a0, -1
; RV32I-NEXT: or a0, a0, a2
; RV32I-NEXT: ret
;
; RV32IXQCIA-LABEL: shlusat:
; RV32IXQCIA: # %bb.0:
; RV32IXQCIA-NEXT: qc.shlusat a0, a0, a1
; RV32IXQCIA-NEXT: ret
%ushlsat = tail call i32 @llvm.ushl.sat.i32(i32 %a,i32 %b)
ret i32 %ushlsat
}

define i32 @shlsat(i32 %a, i32 %b) {
; RV32I-LABEL: shlsat:
; RV32I: # %bb.0:
; RV32I-NEXT: mv a2, a0
; RV32I-NEXT: sll a0, a0, a1
; RV32I-NEXT: sra a1, a0, a1
; RV32I-NEXT: beq a2, a1, .LBB5_2
; RV32I-NEXT: # %bb.1:
; RV32I-NEXT: srai a2, a2, 31
; RV32I-NEXT: lui a0, 524288
; RV32I-NEXT: addi a0, a0, -1
; RV32I-NEXT: xor a0, a2, a0
; RV32I-NEXT: .LBB5_2:
; RV32I-NEXT: ret
;
; RV32IXQCIA-LABEL: shlsat:
; RV32IXQCIA: # %bb.0:
; RV32IXQCIA-NEXT: qc.shlsat a0, a0, a1
; RV32IXQCIA-NEXT: ret
%sshlsat = tail call i32 @llvm.sshl.sat.i32(i32 %a,i32 %b)
ret i32 %sshlsat
}
Loading