mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
50b0b8da35
This patch extends the SDNode ISel support for RVV from only the vector/vector instructions to include the vector/scalar and vector/immediate forms. It uses splat_vector to carry the scalar in each case, except when XLEN<SEW (RV32 SEW=64) when a custom node `SPLAT_VECTOR_I64` is used for type-legalization and to encode the fact that the value is sign-extended to SEW. When the scalar is a full 64-bit value we use a sequence to materialize the constant into the vector register. The non-intrinsic ISel patterns have also been split into their own file. Authored-by: Roger Ferrer Ibanez <rofirrim@gmail.com> Co-Authored-by: Fraser Cormack <fraser@codeplay.com> Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D93312
167 lines
6.7 KiB
TableGen
167 lines
6.7 KiB
TableGen
//===- RISCVInstrInfoVSDPatterns.td - RVV SDNode patterns --*- tablegen -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// This file contains the required infrastructure and SDNode patterns to
|
|
/// support code generation for the standard 'V' (Vector) extension, version
|
|
/// 0.9. This version is still experimental as the 'V' extension hasn't been
|
|
/// ratified yet.
|
|
///
|
|
/// This file is included from and depends upon RISCVInstrInfoVPseudos.td
|
|
///
|
|
/// Note: the patterns for RVV intrinsics are found in
|
|
/// RISCVInstrInfoVPseudos.td.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Helpers to define the SDNode patterns.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
def SDTSplatI64 : SDTypeProfile<1, 1, [
|
|
SDTCVecEltisVT<0, i64>, SDTCisVT<1, i32>
|
|
]>;
|
|
|
|
def rv32_splat_i64 : SDNode<"RISCVISD::SPLAT_VECTOR_I64", SDTSplatI64>;
|
|
|
|
// Penalize the generic form with Complexity=1 to give the simm5/uimm5 variants
|
|
// precedence
|
|
def SplatPat : ComplexPattern<vAny, 1, "selectVSplat", [], [], 1>;
|
|
|
|
def SplatPat_simm5 : ComplexPattern<vAny, 1, "selectVSplatSimm5", []>;
|
|
def SplatPat_uimm5 : ComplexPattern<vAny, 1, "selectVSplatUimm5", []>;
|
|
|
|
multiclass VPatUSLoadStoreSDNode<LLVMType type,
|
|
LLVMType mask_type,
|
|
int sew,
|
|
LMULInfo vlmul,
|
|
RegisterClass reg_rs1,
|
|
VReg reg_class>
|
|
{
|
|
defvar load_instr = !cast<Instruction>("PseudoVLE"#sew#"_V_"#vlmul.MX);
|
|
defvar store_instr = !cast<Instruction>("PseudoVSE"#sew#"_V_"#vlmul.MX);
|
|
// Load
|
|
def : Pat<(type (load reg_rs1:$rs1)),
|
|
(load_instr reg_rs1:$rs1, VLMax, sew)>;
|
|
// Store
|
|
def : Pat<(store type:$rs2, reg_rs1:$rs1),
|
|
(store_instr reg_class:$rs2, reg_rs1:$rs1, VLMax, sew)>;
|
|
}
|
|
|
|
multiclass VPatUSLoadStoreSDNodes<RegisterClass reg_rs1> {
|
|
foreach vti = AllVectors in
|
|
defm "" : VPatUSLoadStoreSDNode<vti.Vector, vti.Mask, vti.SEW, vti.LMul,
|
|
reg_rs1, vti.RegClass>;
|
|
}
|
|
|
|
class VPatBinarySDNode_VV<SDNode vop,
|
|
string instruction_name,
|
|
ValueType result_type,
|
|
ValueType op_type,
|
|
ValueType mask_type,
|
|
int sew,
|
|
LMULInfo vlmul,
|
|
VReg RetClass,
|
|
VReg op_reg_class> :
|
|
Pat<(result_type (vop
|
|
(op_type op_reg_class:$rs1),
|
|
(op_type op_reg_class:$rs2))),
|
|
(!cast<Instruction>(instruction_name#"_VV_"# vlmul.MX)
|
|
op_reg_class:$rs1,
|
|
op_reg_class:$rs2,
|
|
VLMax, sew)>;
|
|
|
|
class VPatBinarySDNode_XI<SDNode vop,
|
|
string instruction_name,
|
|
string suffix,
|
|
ValueType result_type,
|
|
ValueType vop_type,
|
|
ValueType xop_type,
|
|
ValueType mask_type,
|
|
int sew,
|
|
LMULInfo vlmul,
|
|
VReg RetClass,
|
|
VReg vop_reg_class,
|
|
ComplexPattern SplatPatKind,
|
|
DAGOperand xop_kind> :
|
|
Pat<(result_type (vop
|
|
(vop_type vop_reg_class:$rs1),
|
|
(vop_type (SplatPatKind xop_kind:$rs2)))),
|
|
(!cast<Instruction>(instruction_name#_#suffix#_# vlmul.MX)
|
|
vop_reg_class:$rs1,
|
|
xop_kind:$rs2,
|
|
VLMax, sew)>;
|
|
|
|
multiclass VPatBinarySDNode_VV_VX_VI<SDNode vop, string instruction_name,
|
|
Operand ImmType = simm5>
|
|
{
|
|
foreach vti = AllIntegerVectors in {
|
|
def : VPatBinarySDNode_VV<vop, instruction_name,
|
|
vti.Vector, vti.Vector, vti.Mask, vti.SEW,
|
|
vti.LMul, vti.RegClass, vti.RegClass>;
|
|
def : VPatBinarySDNode_XI<vop, instruction_name, "VX",
|
|
vti.Vector, vti.Vector, XLenVT, vti.Mask, vti.SEW,
|
|
vti.LMul, vti.RegClass, vti.RegClass,
|
|
SplatPat, GPR>;
|
|
def : VPatBinarySDNode_XI<vop, instruction_name, "VI",
|
|
vti.Vector, vti.Vector, XLenVT, vti.Mask, vti.SEW,
|
|
vti.LMul, vti.RegClass, vti.RegClass,
|
|
!cast<ComplexPattern>(SplatPat#_#ImmType),
|
|
ImmType>;
|
|
}
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Patterns.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
let Predicates = [HasStdExtV] in {
|
|
|
|
// 7.4. Vector Unit-Stride Instructions
|
|
defm "" : VPatUSLoadStoreSDNodes<GPR>;
|
|
defm "" : VPatUSLoadStoreSDNodes<AddrFI>;
|
|
|
|
// 12.1. Vector Single-Width Integer Add and Subtract
|
|
defm "" : VPatBinarySDNode_VV_VX_VI<add, "PseudoVADD">;
|
|
|
|
// 12.5. Vector Bitwise Logical Instructions
|
|
defm "" : VPatBinarySDNode_VV_VX_VI<or, "PseudoVOR">;
|
|
|
|
// 12.6. Vector Single-Width Bit Shift Instructions
|
|
defm "" : VPatBinarySDNode_VV_VX_VI<shl, "PseudoVSLL", uimm5>;
|
|
defm "" : VPatBinarySDNode_VV_VX_VI<srl, "PseudoVSRL", uimm5>;
|
|
|
|
} // Predicates = [HasStdExtV]
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Vector Splats
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
let Predicates = [HasStdExtV] in {
|
|
foreach vti = AllIntegerVectors in {
|
|
def : Pat<(vti.Vector (splat_vector GPR:$rs1)),
|
|
(!cast<Instruction>("PseudoVMV_V_X_" # vti.LMul.MX)
|
|
GPR:$rs1, VLMax, vti.SEW)>;
|
|
def : Pat<(vti.Vector (splat_vector simm5:$rs1)),
|
|
(!cast<Instruction>("PseudoVMV_V_I_" # vti.LMul.MX)
|
|
simm5:$rs1, VLMax, vti.SEW)>;
|
|
}
|
|
} // Predicates = [HasStdExtV]
|
|
|
|
let Predicates = [HasStdExtV, IsRV32] in {
|
|
foreach vti = AllIntegerVectors in {
|
|
if !eq(vti.SEW, 64) then {
|
|
def : Pat<(vti.Vector (rv32_splat_i64 GPR:$rs1)),
|
|
(!cast<Instruction>("PseudoVMV_V_X_" # vti.LMul.MX)
|
|
GPR:$rs1, VLMax, vti.SEW)>;
|
|
def : Pat<(vti.Vector (rv32_splat_i64 simm5:$rs1)),
|
|
(!cast<Instruction>("PseudoVMV_V_I_" # vti.LMul.MX)
|
|
simm5:$rs1, VLMax, vti.SEW)>;
|
|
}
|
|
}
|
|
} // Predicates = [HasStdExtV, IsRV32]
|