1e8d8bef9SDimitry Andric//===-- VEInstrPatternsVec.td - VEC_-type SDNodes and isel for VE Target --===//
2e8d8bef9SDimitry Andric//
3e8d8bef9SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e8d8bef9SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
5e8d8bef9SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e8d8bef9SDimitry Andric//
7e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
8e8d8bef9SDimitry Andric//
9e8d8bef9SDimitry Andric// This file describes the VEC_* prefixed intermediate SDNodes and their
10e8d8bef9SDimitry Andric// isel patterns.
11e8d8bef9SDimitry Andric//
12e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
13e8d8bef9SDimitry Andric
14e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
15e8d8bef9SDimitry Andric// Instruction format superclass
16e8d8bef9SDimitry Andric//===----------------------------------------------------------------------===//
17e8d8bef9SDimitry Andric
1804eeddc0SDimitry Andric// Sub-register replication for packed broadcast.
1904eeddc0SDimitry Andricdef: Pat<(i64 (repl_f32 f32:$val)),
2004eeddc0SDimitry Andric            (ORrr
2104eeddc0SDimitry Andric              (SRLri (f2l $val), 32),
2204eeddc0SDimitry Andric              (zero_i32 (f2l $val)))>;
2304eeddc0SDimitry Andricdef: Pat<(i64 (repl_i32 i32:$val)),
2404eeddc0SDimitry Andric            (ORrr
2504eeddc0SDimitry Andric              (zero_f32 (i2l $val)),
2604eeddc0SDimitry Andric              (SLLri (i2l $val), 32))>;
2704eeddc0SDimitry Andric
28*fcaf7f86SDimitry Andric///// Mask Load & Store /////
29*fcaf7f86SDimitry Andric
30*fcaf7f86SDimitry Andric// Store for v256i1, v512i1 are implemented in 2 ways.  These STVM/STVM512
31*fcaf7f86SDimitry Andric// pseudo instruction is used for frameindex related load/store instructions.
32*fcaf7f86SDimitry Andric// Custom Lowering is used for other load/store instructions.
33*fcaf7f86SDimitry Andric
34*fcaf7f86SDimitry Andricdef : Pat<(v256i1 (load ADDRrii:$addr)),
35*fcaf7f86SDimitry Andric          (LDVMrii ADDRrii:$addr)>;
36*fcaf7f86SDimitry Andricdef : Pat<(v512i1 (load ADDRrii:$addr)),
37*fcaf7f86SDimitry Andric          (LDVM512rii ADDRrii:$addr)>;
38*fcaf7f86SDimitry Andricdef : Pat<(store v256i1:$vx, ADDRrii:$addr),
39*fcaf7f86SDimitry Andric          (STVMrii ADDRrii:$addr, $vx)>;
40*fcaf7f86SDimitry Andricdef : Pat<(store v512i1:$vx, ADDRrii:$addr),
41*fcaf7f86SDimitry Andric          (STVM512rii ADDRrii:$addr, $vx)>;
4204eeddc0SDimitry Andric
43e8d8bef9SDimitry Andricmulticlass vbrd_elem32<ValueType v32, ValueType s32, SDPatternOperator ImmOp,
44fe6060f1SDimitry Andric                       SDNodeXForm ImmCast, OutPatFrag SuperRegCast> {
45e8d8bef9SDimitry Andric  // VBRDil
46e8d8bef9SDimitry Andric  def : Pat<(v32 (vec_broadcast (s32 ImmOp:$sy), i32:$vl)),
47e8d8bef9SDimitry Andric            (VBRDil (ImmCast $sy), i32:$vl)>;
48e8d8bef9SDimitry Andric
49e8d8bef9SDimitry Andric  // VBRDrl
50e8d8bef9SDimitry Andric  def : Pat<(v32 (vec_broadcast s32:$sy, i32:$vl)),
51e8d8bef9SDimitry Andric            (VBRDrl (SuperRegCast $sy), i32:$vl)>;
52e8d8bef9SDimitry Andric}
53e8d8bef9SDimitry Andric
54e8d8bef9SDimitry Andricmulticlass vbrd_elem64<ValueType v64, ValueType s64,
55e8d8bef9SDimitry Andric                       SDPatternOperator ImmOp, SDNodeXForm ImmCast> {
56e8d8bef9SDimitry Andric  // VBRDil
57e8d8bef9SDimitry Andric  def : Pat<(v64 (vec_broadcast (s64 ImmOp:$sy), i32:$vl)),
58e8d8bef9SDimitry Andric            (VBRDil (ImmCast $sy), i32:$vl)>;
59e8d8bef9SDimitry Andric
60e8d8bef9SDimitry Andric  // VBRDrl
61e8d8bef9SDimitry Andric  def : Pat<(v64 (vec_broadcast s64:$sy, i32:$vl)),
62e8d8bef9SDimitry Andric            (VBRDrl s64:$sy, i32:$vl)>;
63e8d8bef9SDimitry Andric}
64e8d8bef9SDimitry Andric
65e8d8bef9SDimitry Andricmulticlass extract_insert_elem32<ValueType v32, ValueType s32,
66fe6060f1SDimitry Andric                                 OutPatFrag SubRegCast,
67fe6060f1SDimitry Andric                                 OutPatFrag SuperRegCast> {
68e8d8bef9SDimitry Andric  // LVSvi
69e8d8bef9SDimitry Andric  def: Pat<(s32 (extractelt v32:$vec, uimm7:$idx)),
70e8d8bef9SDimitry Andric           (SubRegCast (LVSvi v32:$vec, (ULO7 $idx)))>;
71e8d8bef9SDimitry Andric  // LVSvr
72e8d8bef9SDimitry Andric  def: Pat<(s32 (extractelt v32:$vec, i64:$idx)),
73e8d8bef9SDimitry Andric           (SubRegCast (LVSvr v32:$vec, $idx))>;
74e8d8bef9SDimitry Andric
75e8d8bef9SDimitry Andric  // LSVir
76e8d8bef9SDimitry Andric  def: Pat<(v32 (insertelt v32:$vec, s32:$val, uimm7:$idx)),
77e8d8bef9SDimitry Andric           (LSVir_v (ULO7 $idx), (SuperRegCast $val), $vec)>;
78e8d8bef9SDimitry Andric  // LSVrr
79e8d8bef9SDimitry Andric  def: Pat<(v32 (insertelt v32:$vec, s32:$val, i64:$idx)),
80e8d8bef9SDimitry Andric           (LSVrr_v $idx, (SuperRegCast $val), $vec)>;
81e8d8bef9SDimitry Andric}
82e8d8bef9SDimitry Andric
83e8d8bef9SDimitry Andricmulticlass extract_insert_elem64<ValueType v64, ValueType s64> {
84e8d8bef9SDimitry Andric  // LVSvi
85e8d8bef9SDimitry Andric  def: Pat<(s64 (extractelt v64:$vec, uimm7:$idx)),
86e8d8bef9SDimitry Andric           (LVSvi v64:$vec, (ULO7 $idx))>;
87e8d8bef9SDimitry Andric  // LVSvr
88e8d8bef9SDimitry Andric  def: Pat<(s64 (extractelt v64:$vec, i64:$idx)),
89e8d8bef9SDimitry Andric           (LVSvr v64:$vec, $idx)>;
90e8d8bef9SDimitry Andric
91e8d8bef9SDimitry Andric  // LSVir
92e8d8bef9SDimitry Andric  def: Pat<(v64 (insertelt v64:$vec, s64:$val, uimm7:$idx)),
93e8d8bef9SDimitry Andric           (LSVir_v (ULO7 $idx), $val, $vec)>;
94e8d8bef9SDimitry Andric  // LSVrr
95e8d8bef9SDimitry Andric  def: Pat<(v64 (insertelt v64:$vec, s64:$val, i64:$idx)),
96e8d8bef9SDimitry Andric           (LSVrr_v $idx, $val, $vec)>;
97e8d8bef9SDimitry Andric}
98e8d8bef9SDimitry Andric
99e8d8bef9SDimitry Andricmulticlass patterns_elem32<ValueType v32, ValueType s32,
100e8d8bef9SDimitry Andric                           SDPatternOperator ImmOp, SDNodeXForm ImmCast,
101fe6060f1SDimitry Andric                           OutPatFrag SubRegCast, OutPatFrag SuperRegCast> {
102e8d8bef9SDimitry Andric  defm : vbrd_elem32<v32, s32, ImmOp, ImmCast, SuperRegCast>;
103e8d8bef9SDimitry Andric  defm : extract_insert_elem32<v32, s32, SubRegCast, SuperRegCast>;
104e8d8bef9SDimitry Andric}
105e8d8bef9SDimitry Andric
106e8d8bef9SDimitry Andricmulticlass patterns_elem64<ValueType v64, ValueType s64,
107e8d8bef9SDimitry Andric                           SDPatternOperator ImmOp, SDNodeXForm ImmCast> {
108e8d8bef9SDimitry Andric  defm : vbrd_elem64<v64, s64, ImmOp, ImmCast>;
109e8d8bef9SDimitry Andric  defm : extract_insert_elem64<v64, s64>;
110e8d8bef9SDimitry Andric}
111e8d8bef9SDimitry Andric
112e8d8bef9SDimitry Andricdefm : patterns_elem32<v256i32, i32, simm7, LO7, l2i, i2l>;
113e8d8bef9SDimitry Andricdefm : patterns_elem32<v256f32, f32, simm7fp, LO7FP, l2f, f2l>;
114e8d8bef9SDimitry Andric
115e8d8bef9SDimitry Andricdefm : patterns_elem64<v256i64, i64, simm7, LO7>;
116e8d8bef9SDimitry Andricdefm : patterns_elem64<v256f64, f64, simm7fp, LO7FP>;
11704eeddc0SDimitry Andric
11804eeddc0SDimitry Andricdefm : vbrd_elem64<v512i32, i64, simm7, LO7>;
11904eeddc0SDimitry Andricdefm : vbrd_elem64<v512f32, i64, simm7, LO7>;
12004eeddc0SDimitry Andricdefm : vbrd_elem64<v512i32, f64, simm7fp, LO7FP>;
12104eeddc0SDimitry Andricdefm : vbrd_elem64<v512f32, f64, simm7fp, LO7FP>;
12281ad6265SDimitry Andric
12381ad6265SDimitry Andricclass Mask_Binary<ValueType MaskVT, SDPatternOperator MaskOp, string InstName> :
12481ad6265SDimitry Andric  Pat<(MaskVT (MaskOp MaskVT:$ma, MaskVT:$mb)), (!cast<Instruction>(InstName#"mm") $ma, $mb)>;
12581ad6265SDimitry Andric
12681ad6265SDimitry Andricdef: Mask_Binary<v256i1, and, "ANDM">;
12781ad6265SDimitry Andricdef: Mask_Binary<v256i1, or,  "ORM">;
12881ad6265SDimitry Andricdef: Mask_Binary<v256i1, xor, "XORM">;
12981ad6265SDimitry Andric
13081ad6265SDimitry Andric///// Packing support /////
13181ad6265SDimitry Andric
13281ad6265SDimitry Andric// v256i1 <> v512i1
13381ad6265SDimitry Andricdef : Pat<(v256i1 (vec_unpack_lo v512i1:$vm, (i32 srcvalue))),
13481ad6265SDimitry Andric          (EXTRACT_SUBREG $vm, sub_vm_odd)>;
13581ad6265SDimitry Andricdef : Pat<(v256i1 (vec_unpack_hi v512i1:$vm, (i32 srcvalue))),
13681ad6265SDimitry Andric          (EXTRACT_SUBREG $vm, sub_vm_even)>;
13781ad6265SDimitry Andricdef : Pat<(v512i1 (vec_pack v256i1:$vlo, v256i1:$vhi, (i32 srcvalue))),
13881ad6265SDimitry Andric          (INSERT_SUBREG (INSERT_SUBREG
13981ad6265SDimitry Andric                         (v512i1 (IMPLICIT_DEF)),
14081ad6265SDimitry Andric                         $vlo, sub_vm_odd),
14181ad6265SDimitry Andric                         $vhi, sub_vm_even)>;
14281ad6265SDimitry Andric
14381ad6265SDimitry Andric// v256.32 <> v512.32
14481ad6265SDimitry Andricmulticlass Packing<ValueType PackVT> {
14581ad6265SDimitry Andric  // no-op unpacks
14681ad6265SDimitry Andric  def : Pat<(v256i32 (vec_unpack_lo PackVT:$vp, (i32 srcvalue))),
14781ad6265SDimitry Andric            (COPY_TO_REGCLASS $vp, V64)>;
14881ad6265SDimitry Andric  def : Pat<(v256f32 (vec_unpack_hi PackVT:$vp, (i32 srcvalue))),
14981ad6265SDimitry Andric            (COPY_TO_REGCLASS $vp, V64)>;
15081ad6265SDimitry Andric
15181ad6265SDimitry Andric  // shuffle unpacks
15281ad6265SDimitry Andric  def : Pat<(v256f32 (vec_unpack_lo PackVT:$vp, i32:$avl)),
15381ad6265SDimitry Andric            (VSHFvvil $vp, $vp, 4, $avl)>; // always pick lo
15481ad6265SDimitry Andric  def : Pat<(v256i32 (vec_unpack_hi PackVT:$vp, i32:$avl)),
15581ad6265SDimitry Andric            (VSHFvvil $vp, $vp, 0, $avl)>; // always pick hi
15681ad6265SDimitry Andric}
15781ad6265SDimitry Andric
15881ad6265SDimitry Andricdefm : Packing<v512i32>;
15981ad6265SDimitry Andricdefm : Packing<v512f32>;
16081ad6265SDimitry Andric
16181ad6265SDimitry Andricdef : Pat<(v512i32 (vec_pack v256i32:$vlo, v256i32:$vhi, i32:$avl)),
16281ad6265SDimitry Andric          (VSHFvvil $vlo, $vhi, 13, $avl)>;
16381ad6265SDimitry Andricdef : Pat<(v512f32 (vec_pack v256f32:$vlo, v256f32:$vhi, i32:$avl)),
16481ad6265SDimitry Andric          (VSHFvvil $vlo, $vhi, 8, $avl)>;
165