1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-21 03:53:04 +02:00
llvm-mirror/lib/Target/Hexagon/HexagonIntrinsics.td
Krzysztof Parzyszek 275ca43ee3 [Hexagon] Handle operand type differences for A2_tfrpi
The instruction A2_tfrpi has a 64-bit operand, while the corresponding
intrinsic takes a 32-bit value. The actual value has only 8 significant
bits, so the difference is only in the type used to represent it.
In order to map the intrinsic to the instruction, the operand needs to
be extended to the correct type.

llvm-svn: 268635
2016-05-05 15:29:47 +00:00

1347 lines
58 KiB
TableGen

//===-- HexagonIntrinsics.td - Instruction intrinsics ------*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// This is populated based on the following specs:
// Hexagon V2 Architecture
// Application-Level Specification
// 80-V9418-8 Rev. B
// March 4, 2008
//===----------------------------------------------------------------------===//
class T_I_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID imm:$Is),
(MI imm:$Is)>;
class T_R_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I32:$Rs),
(MI I32:$Rs)>;
class T_P_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I64:$Rs),
(MI I64:$Rs)>;
class T_II_pat <InstHexagon MI, Intrinsic IntID, PatFrag Imm1, PatFrag Imm2>
: Pat<(IntID Imm1:$Is, Imm2:$It),
(MI Imm1:$Is, Imm2:$It)>;
class T_RI_pat <InstHexagon MI, Intrinsic IntID,
PatLeaf ImmPred = PatLeaf<(i32 imm)>>
: Pat<(IntID I32:$Rs, ImmPred:$It),
(MI I32:$Rs, ImmPred:$It)>;
class T_IR_pat <InstHexagon MI, Intrinsic IntID,
PatFrag ImmPred = PatLeaf<(i32 imm)>>
: Pat<(IntID ImmPred:$Is, I32:$Rt),
(MI ImmPred:$Is, I32:$Rt)>;
class T_PI_pat <InstHexagon MI, Intrinsic IntID>
: Pat<(IntID I64:$Rs, imm:$It),
(MI I64:$Rs, imm:$It)>;
class T_RP_pat <InstHexagon MI, Intrinsic IntID>
: Pat<(IntID I32:$Rs, I64:$Rt),
(MI I32:$Rs, I64:$Rt)>;
class T_RR_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I32:$Rs, I32:$Rt),
(MI I32:$Rs, I32:$Rt)>;
class T_PP_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I64:$Rs, I64:$Rt),
(MI I64:$Rs, I64:$Rt)>;
class T_QQ_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I32:$Rs, I32:$Rt),
(MI (C2_tfrrp I32:$Rs), (C2_tfrrp I32:$Rt))>;
class T_QII_pat <InstHexagon MI, Intrinsic IntID, PatFrag Imm1, PatFrag Imm2>
: Pat <(IntID I32:$Rp, Imm1:$Is, Imm2:$It),
(MI (C2_tfrrp I32:$Rp), Imm1:$Is, Imm2:$It)>;
class T_QRR_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I32:$Rp, I32:$Rs, I32:$Rt),
(MI (C2_tfrrp I32:$Rp), I32:$Rs, I32:$Rt)>;
class T_QRI_pat <InstHexagon MI, Intrinsic IntID, PatFrag ImmPred>
: Pat <(IntID I32:$Rp, I32:$Rs, ImmPred:$Is),
(MI (C2_tfrrp I32:$Rp), I32:$Rs, ImmPred:$Is)>;
class T_QIR_pat <InstHexagon MI, Intrinsic IntID, PatFrag ImmPred>
: Pat <(IntID I32:$Rp, ImmPred:$Is, I32:$Rs),
(MI (C2_tfrrp I32:$Rp), ImmPred:$Is, I32:$Rs)>;
class T_QPP_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I32:$Rp, I64:$Rs, I64:$Rt),
(MI (C2_tfrrp I32:$Rp), I64:$Rs, I64:$Rt)>;
class T_RRI_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I32:$Rs, I32:$Rt, imm:$Iu),
(MI I32:$Rs, I32:$Rt, imm:$Iu)>;
class T_RII_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I32:$Rs, imm:$It, imm:$Iu),
(MI I32:$Rs, imm:$It, imm:$Iu)>;
class T_IRI_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID imm:$It, I32:$Rs, imm:$Iu),
(MI imm:$It, I32:$Rs, imm:$Iu)>;
class T_IRR_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID imm:$Is, I32:$Rs, I32:$Rt),
(MI imm:$Is, I32:$Rs, I32:$Rt)>;
class T_RIR_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I32:$Rs, imm:$Is, I32:$Rt),
(MI I32:$Rs, imm:$Is, I32:$Rt)>;
class T_RRR_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I32:$Rs, I32:$Rt, I32:$Ru),
(MI I32:$Rs, I32:$Rt, I32:$Ru)>;
class T_PPI_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I64:$Rs, I64:$Rt, imm:$Iu),
(MI I64:$Rs, I64:$Rt, imm:$Iu)>;
class T_PII_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I64:$Rs, imm:$It, imm:$Iu),
(MI I64:$Rs, imm:$It, imm:$Iu)>;
class T_PPP_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I64:$Rs, I64:$Rt, I64:$Ru),
(MI I64:$Rs, I64:$Rt, I64:$Ru)>;
class T_PPR_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I64:$Rs, I64:$Rt, I32:$Ru),
(MI I64:$Rs, I64:$Rt, I32:$Ru)>;
class T_PRR_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I64:$Rs, I32:$Rt, I32:$Ru),
(MI I64:$Rs, I32:$Rt, I32:$Ru)>;
class T_PPQ_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I64:$Rs, I64:$Rt, I32:$Rp),
(MI I64:$Rs, I64:$Rt, (C2_tfrrp I32:$Rp))>;
class T_PR_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I64:$Rs, I32:$Rt),
(MI I64:$Rs, I32:$Rt)>;
class T_D_pat <InstHexagon MI, Intrinsic IntID>
: Pat<(IntID (F64:$Rs)),
(MI (F64:$Rs))>;
class T_DI_pat <InstHexagon MI, Intrinsic IntID,
PatLeaf ImmPred = PatLeaf<(i32 imm)>>
: Pat<(IntID F64:$Rs, ImmPred:$It),
(MI F64:$Rs, ImmPred:$It)>;
class T_F_pat <InstHexagon MI, Intrinsic IntID>
: Pat<(IntID F32:$Rs),
(MI F32:$Rs)>;
class T_FI_pat <InstHexagon MI, Intrinsic IntID,
PatLeaf ImmPred = PatLeaf<(i32 imm)>>
: Pat<(IntID F32:$Rs, ImmPred:$It),
(MI F32:$Rs, ImmPred:$It)>;
class T_FF_pat <InstHexagon MI, Intrinsic IntID>
: Pat<(IntID F32:$Rs, F32:$Rt),
(MI F32:$Rs, F32:$Rt)>;
class T_DD_pat <InstHexagon MI, Intrinsic IntID>
: Pat<(IntID F64:$Rs, F64:$Rt),
(MI F64:$Rs, F64:$Rt)>;
class T_FFF_pat <InstHexagon MI, Intrinsic IntID>
: Pat<(IntID F32:$Rs, F32:$Rt, F32:$Ru),
(MI F32:$Rs, F32:$Rt, F32:$Ru)>;
class T_FFFQ_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID F32:$Rs, F32:$Rt, F32:$Ru, I32:$Rp),
(MI F32:$Rs, F32:$Rt, F32:$Ru, (C2_tfrrp I32:$Rp))>;
class T_Q_RI_pat <InstHexagon MI, Intrinsic IntID,
PatLeaf ImmPred = PatLeaf<(i32 imm)>>
: Pat<(IntID I32:$Rs, ImmPred:$It),
(C2_tfrpr (MI I32:$Rs, ImmPred:$It))>;
class T_Q_RR_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I32:$Rs, I32:$Rt),
(C2_tfrpr (MI I32:$Rs, I32:$Rt))>;
class T_Q_RP_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I32:$Rs, I64:$Rt),
(C2_tfrpr (MI I32:$Rs, I64:$Rt))>;
class T_Q_PR_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I64:$Rs, I32:$Rt),
(C2_tfrpr (MI I64:$Rs, I32:$Rt))>;
class T_Q_PI_pat <InstHexagon MI, Intrinsic IntID>
: Pat<(IntID I64:$Rs, imm:$It),
(C2_tfrpr (MI I64:$Rs, imm:$It))>;
class T_Q_PP_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I64:$Rs, I64:$Rt),
(C2_tfrpr (MI I64:$Rs, I64:$Rt))>;
class T_Q_Q_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I32:$Rp),
(C2_tfrpr (MI (C2_tfrrp I32:$Rp)))>;
class T_Q_QQ_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I32:$Rp, I32:$Rq),
(C2_tfrpr (MI (C2_tfrrp I32:$Rp), (C2_tfrrp I32:$Rq)))>;
class T_Q_FF_pat <InstHexagon MI, Intrinsic IntID>
: Pat<(IntID F32:$Rs, F32:$Rt),
(C2_tfrpr (MI F32:$Rs, F32:$Rt))>;
class T_Q_DD_pat <InstHexagon MI, Intrinsic IntID>
: Pat<(IntID F64:$Rs, F64:$Rt),
(C2_tfrpr (MI F64:$Rs, F64:$Rt))>;
class T_Q_FI_pat <InstHexagon MI, Intrinsic IntID>
: Pat<(IntID F32:$Rs, imm:$It),
(C2_tfrpr (MI F32:$Rs, imm:$It))>;
class T_Q_DI_pat <InstHexagon MI, Intrinsic IntID>
: Pat<(IntID F64:$Rs, imm:$It),
(C2_tfrpr (MI F64:$Rs, imm:$It))>;
class T_Q_QQQ_pat <InstHexagon MI, Intrinsic IntID>
: Pat <(IntID I32:$Rp, I32:$Rq, I32:$Rs),
(C2_tfrpr (MI (C2_tfrrp I32:$Rp), (C2_tfrrp I32:$Rq),
(C2_tfrrp I32:$Rs)))>;
//===----------------------------------------------------------------------===//
// MPYS / Multipy signed/unsigned halfwords
//Rd=mpy[u](Rs.[H|L],Rt.[H|L])[:<<1][:rnd][:sat]
//===----------------------------------------------------------------------===//
def : T_RR_pat <M2_mpy_ll_s1, int_hexagon_M2_mpy_ll_s1>;
def : T_RR_pat <M2_mpy_ll_s0, int_hexagon_M2_mpy_ll_s0>;
def : T_RR_pat <M2_mpy_lh_s1, int_hexagon_M2_mpy_lh_s1>;
def : T_RR_pat <M2_mpy_lh_s0, int_hexagon_M2_mpy_lh_s0>;
def : T_RR_pat <M2_mpy_hl_s1, int_hexagon_M2_mpy_hl_s1>;
def : T_RR_pat <M2_mpy_hl_s0, int_hexagon_M2_mpy_hl_s0>;
def : T_RR_pat <M2_mpy_hh_s1, int_hexagon_M2_mpy_hh_s1>;
def : T_RR_pat <M2_mpy_hh_s0, int_hexagon_M2_mpy_hh_s0>;
def : T_RR_pat <M2_mpyu_ll_s1, int_hexagon_M2_mpyu_ll_s1>;
def : T_RR_pat <M2_mpyu_ll_s0, int_hexagon_M2_mpyu_ll_s0>;
def : T_RR_pat <M2_mpyu_lh_s1, int_hexagon_M2_mpyu_lh_s1>;
def : T_RR_pat <M2_mpyu_lh_s0, int_hexagon_M2_mpyu_lh_s0>;
def : T_RR_pat <M2_mpyu_hl_s1, int_hexagon_M2_mpyu_hl_s1>;
def : T_RR_pat <M2_mpyu_hl_s0, int_hexagon_M2_mpyu_hl_s0>;
def : T_RR_pat <M2_mpyu_hh_s1, int_hexagon_M2_mpyu_hh_s1>;
def : T_RR_pat <M2_mpyu_hh_s0, int_hexagon_M2_mpyu_hh_s0>;
def : T_RR_pat <M2_mpy_sat_ll_s1, int_hexagon_M2_mpy_sat_ll_s1>;
def : T_RR_pat <M2_mpy_sat_ll_s0, int_hexagon_M2_mpy_sat_ll_s0>;
def : T_RR_pat <M2_mpy_sat_lh_s1, int_hexagon_M2_mpy_sat_lh_s1>;
def : T_RR_pat <M2_mpy_sat_lh_s0, int_hexagon_M2_mpy_sat_lh_s0>;
def : T_RR_pat <M2_mpy_sat_hl_s1, int_hexagon_M2_mpy_sat_hl_s1>;
def : T_RR_pat <M2_mpy_sat_hl_s0, int_hexagon_M2_mpy_sat_hl_s0>;
def : T_RR_pat <M2_mpy_sat_hh_s1, int_hexagon_M2_mpy_sat_hh_s1>;
def : T_RR_pat <M2_mpy_sat_hh_s0, int_hexagon_M2_mpy_sat_hh_s0>;
def : T_RR_pat <M2_mpy_rnd_ll_s1, int_hexagon_M2_mpy_rnd_ll_s1>;
def : T_RR_pat <M2_mpy_rnd_ll_s0, int_hexagon_M2_mpy_rnd_ll_s0>;
def : T_RR_pat <M2_mpy_rnd_lh_s1, int_hexagon_M2_mpy_rnd_lh_s1>;
def : T_RR_pat <M2_mpy_rnd_lh_s0, int_hexagon_M2_mpy_rnd_lh_s0>;
def : T_RR_pat <M2_mpy_rnd_hl_s1, int_hexagon_M2_mpy_rnd_hl_s1>;
def : T_RR_pat <M2_mpy_rnd_hl_s0, int_hexagon_M2_mpy_rnd_hl_s0>;
def : T_RR_pat <M2_mpy_rnd_hh_s1, int_hexagon_M2_mpy_rnd_hh_s1>;
def : T_RR_pat <M2_mpy_rnd_hh_s0, int_hexagon_M2_mpy_rnd_hh_s0>;
def : T_RR_pat <M2_mpy_sat_rnd_ll_s1, int_hexagon_M2_mpy_sat_rnd_ll_s1>;
def : T_RR_pat <M2_mpy_sat_rnd_ll_s0, int_hexagon_M2_mpy_sat_rnd_ll_s0>;
def : T_RR_pat <M2_mpy_sat_rnd_lh_s1, int_hexagon_M2_mpy_sat_rnd_lh_s1>;
def : T_RR_pat <M2_mpy_sat_rnd_lh_s0, int_hexagon_M2_mpy_sat_rnd_lh_s0>;
def : T_RR_pat <M2_mpy_sat_rnd_hl_s1, int_hexagon_M2_mpy_sat_rnd_hl_s1>;
def : T_RR_pat <M2_mpy_sat_rnd_hl_s0, int_hexagon_M2_mpy_sat_rnd_hl_s0>;
def : T_RR_pat <M2_mpy_sat_rnd_hh_s1, int_hexagon_M2_mpy_sat_rnd_hh_s1>;
def : T_RR_pat <M2_mpy_sat_rnd_hh_s0, int_hexagon_M2_mpy_sat_rnd_hh_s0>;
//===----------------------------------------------------------------------===//
// MPYS / Multipy signed/unsigned halfwords and add/subtract the
// result from the accumulator.
//Rx [-+]= mpy[u](Rs.[H|L],Rt.[H|L])[:<<1][:sat]
//===----------------------------------------------------------------------===//
def : T_RRR_pat <M2_mpy_acc_ll_s1, int_hexagon_M2_mpy_acc_ll_s1>;
def : T_RRR_pat <M2_mpy_acc_ll_s0, int_hexagon_M2_mpy_acc_ll_s0>;
def : T_RRR_pat <M2_mpy_acc_lh_s1, int_hexagon_M2_mpy_acc_lh_s1>;
def : T_RRR_pat <M2_mpy_acc_lh_s0, int_hexagon_M2_mpy_acc_lh_s0>;
def : T_RRR_pat <M2_mpy_acc_hl_s1, int_hexagon_M2_mpy_acc_hl_s1>;
def : T_RRR_pat <M2_mpy_acc_hl_s0, int_hexagon_M2_mpy_acc_hl_s0>;
def : T_RRR_pat <M2_mpy_acc_hh_s1, int_hexagon_M2_mpy_acc_hh_s1>;
def : T_RRR_pat <M2_mpy_acc_hh_s0, int_hexagon_M2_mpy_acc_hh_s0>;
def : T_RRR_pat <M2_mpyu_acc_ll_s1, int_hexagon_M2_mpyu_acc_ll_s1>;
def : T_RRR_pat <M2_mpyu_acc_ll_s0, int_hexagon_M2_mpyu_acc_ll_s0>;
def : T_RRR_pat <M2_mpyu_acc_lh_s1, int_hexagon_M2_mpyu_acc_lh_s1>;
def : T_RRR_pat <M2_mpyu_acc_lh_s0, int_hexagon_M2_mpyu_acc_lh_s0>;
def : T_RRR_pat <M2_mpyu_acc_hl_s1, int_hexagon_M2_mpyu_acc_hl_s1>;
def : T_RRR_pat <M2_mpyu_acc_hl_s0, int_hexagon_M2_mpyu_acc_hl_s0>;
def : T_RRR_pat <M2_mpyu_acc_hh_s1, int_hexagon_M2_mpyu_acc_hh_s1>;
def : T_RRR_pat <M2_mpyu_acc_hh_s0, int_hexagon_M2_mpyu_acc_hh_s0>;
def : T_RRR_pat <M2_mpy_nac_ll_s1, int_hexagon_M2_mpy_nac_ll_s1>;
def : T_RRR_pat <M2_mpy_nac_ll_s0, int_hexagon_M2_mpy_nac_ll_s0>;
def : T_RRR_pat <M2_mpy_nac_lh_s1, int_hexagon_M2_mpy_nac_lh_s1>;
def : T_RRR_pat <M2_mpy_nac_lh_s0, int_hexagon_M2_mpy_nac_lh_s0>;
def : T_RRR_pat <M2_mpy_nac_hl_s1, int_hexagon_M2_mpy_nac_hl_s1>;
def : T_RRR_pat <M2_mpy_nac_hl_s0, int_hexagon_M2_mpy_nac_hl_s0>;
def : T_RRR_pat <M2_mpy_nac_hh_s1, int_hexagon_M2_mpy_nac_hh_s1>;
def : T_RRR_pat <M2_mpy_nac_hh_s0, int_hexagon_M2_mpy_nac_hh_s0>;
def : T_RRR_pat <M2_mpyu_nac_ll_s1, int_hexagon_M2_mpyu_nac_ll_s1>;
def : T_RRR_pat <M2_mpyu_nac_ll_s0, int_hexagon_M2_mpyu_nac_ll_s0>;
def : T_RRR_pat <M2_mpyu_nac_lh_s1, int_hexagon_M2_mpyu_nac_lh_s1>;
def : T_RRR_pat <M2_mpyu_nac_lh_s0, int_hexagon_M2_mpyu_nac_lh_s0>;
def : T_RRR_pat <M2_mpyu_nac_hl_s1, int_hexagon_M2_mpyu_nac_hl_s1>;
def : T_RRR_pat <M2_mpyu_nac_hl_s0, int_hexagon_M2_mpyu_nac_hl_s0>;
def : T_RRR_pat <M2_mpyu_nac_hh_s1, int_hexagon_M2_mpyu_nac_hh_s1>;
def : T_RRR_pat <M2_mpyu_nac_hh_s0, int_hexagon_M2_mpyu_nac_hh_s0>;
def : T_RRR_pat <M2_mpy_acc_sat_ll_s1, int_hexagon_M2_mpy_acc_sat_ll_s1>;
def : T_RRR_pat <M2_mpy_acc_sat_ll_s0, int_hexagon_M2_mpy_acc_sat_ll_s0>;
def : T_RRR_pat <M2_mpy_acc_sat_lh_s1, int_hexagon_M2_mpy_acc_sat_lh_s1>;
def : T_RRR_pat <M2_mpy_acc_sat_lh_s0, int_hexagon_M2_mpy_acc_sat_lh_s0>;
def : T_RRR_pat <M2_mpy_acc_sat_hl_s1, int_hexagon_M2_mpy_acc_sat_hl_s1>;
def : T_RRR_pat <M2_mpy_acc_sat_hl_s0, int_hexagon_M2_mpy_acc_sat_hl_s0>;
def : T_RRR_pat <M2_mpy_acc_sat_hh_s1, int_hexagon_M2_mpy_acc_sat_hh_s1>;
def : T_RRR_pat <M2_mpy_acc_sat_hh_s0, int_hexagon_M2_mpy_acc_sat_hh_s0>;
def : T_RRR_pat <M2_mpy_nac_sat_ll_s1, int_hexagon_M2_mpy_nac_sat_ll_s1>;
def : T_RRR_pat <M2_mpy_nac_sat_ll_s0, int_hexagon_M2_mpy_nac_sat_ll_s0>;
def : T_RRR_pat <M2_mpy_nac_sat_lh_s1, int_hexagon_M2_mpy_nac_sat_lh_s1>;
def : T_RRR_pat <M2_mpy_nac_sat_lh_s0, int_hexagon_M2_mpy_nac_sat_lh_s0>;
def : T_RRR_pat <M2_mpy_nac_sat_hl_s1, int_hexagon_M2_mpy_nac_sat_hl_s1>;
def : T_RRR_pat <M2_mpy_nac_sat_hl_s0, int_hexagon_M2_mpy_nac_sat_hl_s0>;
def : T_RRR_pat <M2_mpy_nac_sat_hh_s1, int_hexagon_M2_mpy_nac_sat_hh_s1>;
def : T_RRR_pat <M2_mpy_nac_sat_hh_s0, int_hexagon_M2_mpy_nac_sat_hh_s0>;
//===----------------------------------------------------------------------===//
// Multiply signed/unsigned halfwords with and without saturation and rounding
// into a 64-bits destination register.
//===----------------------------------------------------------------------===//
def : T_RR_pat <M2_mpyd_hh_s0, int_hexagon_M2_mpyd_hh_s0>;
def : T_RR_pat <M2_mpyd_hl_s0, int_hexagon_M2_mpyd_hl_s0>;
def : T_RR_pat <M2_mpyd_lh_s0, int_hexagon_M2_mpyd_lh_s0>;
def : T_RR_pat <M2_mpyd_ll_s0, int_hexagon_M2_mpyd_ll_s0>;
def : T_RR_pat <M2_mpyd_hh_s1, int_hexagon_M2_mpyd_hh_s1>;
def : T_RR_pat <M2_mpyd_hl_s1, int_hexagon_M2_mpyd_hl_s1>;
def : T_RR_pat <M2_mpyd_lh_s1, int_hexagon_M2_mpyd_lh_s1>;
def : T_RR_pat <M2_mpyd_ll_s1, int_hexagon_M2_mpyd_ll_s1>;
def : T_RR_pat <M2_mpyd_rnd_hh_s0, int_hexagon_M2_mpyd_rnd_hh_s0>;
def : T_RR_pat <M2_mpyd_rnd_hl_s0, int_hexagon_M2_mpyd_rnd_hl_s0>;
def : T_RR_pat <M2_mpyd_rnd_lh_s0, int_hexagon_M2_mpyd_rnd_lh_s0>;
def : T_RR_pat <M2_mpyd_rnd_ll_s0, int_hexagon_M2_mpyd_rnd_ll_s0>;
def : T_RR_pat <M2_mpyd_rnd_hh_s1, int_hexagon_M2_mpyd_rnd_hh_s1>;
def : T_RR_pat <M2_mpyd_rnd_hl_s1, int_hexagon_M2_mpyd_rnd_hl_s1>;
def : T_RR_pat <M2_mpyd_rnd_lh_s1, int_hexagon_M2_mpyd_rnd_lh_s1>;
def : T_RR_pat <M2_mpyd_rnd_ll_s1, int_hexagon_M2_mpyd_rnd_ll_s1>;
def : T_RR_pat <M2_mpyud_hh_s0, int_hexagon_M2_mpyud_hh_s0>;
def : T_RR_pat <M2_mpyud_hl_s0, int_hexagon_M2_mpyud_hl_s0>;
def : T_RR_pat <M2_mpyud_lh_s0, int_hexagon_M2_mpyud_lh_s0>;
def : T_RR_pat <M2_mpyud_ll_s0, int_hexagon_M2_mpyud_ll_s0>;
def : T_RR_pat <M2_mpyud_hh_s1, int_hexagon_M2_mpyud_hh_s1>;
def : T_RR_pat <M2_mpyud_hl_s1, int_hexagon_M2_mpyud_hl_s1>;
def : T_RR_pat <M2_mpyud_lh_s1, int_hexagon_M2_mpyud_lh_s1>;
def : T_RR_pat <M2_mpyud_ll_s1, int_hexagon_M2_mpyud_ll_s1>;
//===----------------------------------------------------------------------===//
// MPYS / Multipy signed/unsigned halfwords and add/subtract the
// result from the 64-bit destination register.
//Rxx [-+]= mpy[u](Rs.[H|L],Rt.[H|L])[:<<1][:sat]
//===----------------------------------------------------------------------===//
def : T_PRR_pat <M2_mpyd_acc_hh_s0, int_hexagon_M2_mpyd_acc_hh_s0>;
def : T_PRR_pat <M2_mpyd_acc_hl_s0, int_hexagon_M2_mpyd_acc_hl_s0>;
def : T_PRR_pat <M2_mpyd_acc_lh_s0, int_hexagon_M2_mpyd_acc_lh_s0>;
def : T_PRR_pat <M2_mpyd_acc_ll_s0, int_hexagon_M2_mpyd_acc_ll_s0>;
def : T_PRR_pat <M2_mpyd_acc_hh_s1, int_hexagon_M2_mpyd_acc_hh_s1>;
def : T_PRR_pat <M2_mpyd_acc_hl_s1, int_hexagon_M2_mpyd_acc_hl_s1>;
def : T_PRR_pat <M2_mpyd_acc_lh_s1, int_hexagon_M2_mpyd_acc_lh_s1>;
def : T_PRR_pat <M2_mpyd_acc_ll_s1, int_hexagon_M2_mpyd_acc_ll_s1>;
def : T_PRR_pat <M2_mpyd_nac_hh_s0, int_hexagon_M2_mpyd_nac_hh_s0>;
def : T_PRR_pat <M2_mpyd_nac_hl_s0, int_hexagon_M2_mpyd_nac_hl_s0>;
def : T_PRR_pat <M2_mpyd_nac_lh_s0, int_hexagon_M2_mpyd_nac_lh_s0>;
def : T_PRR_pat <M2_mpyd_nac_ll_s0, int_hexagon_M2_mpyd_nac_ll_s0>;
def : T_PRR_pat <M2_mpyd_nac_hh_s1, int_hexagon_M2_mpyd_nac_hh_s1>;
def : T_PRR_pat <M2_mpyd_nac_hl_s1, int_hexagon_M2_mpyd_nac_hl_s1>;
def : T_PRR_pat <M2_mpyd_nac_lh_s1, int_hexagon_M2_mpyd_nac_lh_s1>;
def : T_PRR_pat <M2_mpyd_nac_ll_s1, int_hexagon_M2_mpyd_nac_ll_s1>;
def : T_PRR_pat <M2_mpyud_acc_hh_s0, int_hexagon_M2_mpyud_acc_hh_s0>;
def : T_PRR_pat <M2_mpyud_acc_hl_s0, int_hexagon_M2_mpyud_acc_hl_s0>;
def : T_PRR_pat <M2_mpyud_acc_lh_s0, int_hexagon_M2_mpyud_acc_lh_s0>;
def : T_PRR_pat <M2_mpyud_acc_ll_s0, int_hexagon_M2_mpyud_acc_ll_s0>;
def : T_PRR_pat <M2_mpyud_acc_hh_s1, int_hexagon_M2_mpyud_acc_hh_s1>;
def : T_PRR_pat <M2_mpyud_acc_hl_s1, int_hexagon_M2_mpyud_acc_hl_s1>;
def : T_PRR_pat <M2_mpyud_acc_lh_s1, int_hexagon_M2_mpyud_acc_lh_s1>;
def : T_PRR_pat <M2_mpyud_acc_ll_s1, int_hexagon_M2_mpyud_acc_ll_s1>;
def : T_PRR_pat <M2_mpyud_nac_hh_s0, int_hexagon_M2_mpyud_nac_hh_s0>;
def : T_PRR_pat <M2_mpyud_nac_hl_s0, int_hexagon_M2_mpyud_nac_hl_s0>;
def : T_PRR_pat <M2_mpyud_nac_lh_s0, int_hexagon_M2_mpyud_nac_lh_s0>;
def : T_PRR_pat <M2_mpyud_nac_ll_s0, int_hexagon_M2_mpyud_nac_ll_s0>;
def : T_PRR_pat <M2_mpyud_nac_hh_s1, int_hexagon_M2_mpyud_nac_hh_s1>;
def : T_PRR_pat <M2_mpyud_nac_hl_s1, int_hexagon_M2_mpyud_nac_hl_s1>;
def : T_PRR_pat <M2_mpyud_nac_lh_s1, int_hexagon_M2_mpyud_nac_lh_s1>;
def : T_PRR_pat <M2_mpyud_nac_ll_s1, int_hexagon_M2_mpyud_nac_ll_s1>;
// Vector complex multiply imaginary: Rdd=vcmpyi(Rss,Rtt)[:<<1]:sat
def : T_PP_pat <M2_vcmpy_s1_sat_i, int_hexagon_M2_vcmpy_s1_sat_i>;
def : T_PP_pat <M2_vcmpy_s0_sat_i, int_hexagon_M2_vcmpy_s0_sat_i>;
// Vector complex multiply real: Rdd=vcmpyr(Rss,Rtt)[:<<1]:sat
def : T_PP_pat <M2_vcmpy_s1_sat_r, int_hexagon_M2_vcmpy_s1_sat_r>;
def : T_PP_pat <M2_vcmpy_s0_sat_r, int_hexagon_M2_vcmpy_s0_sat_r>;
// Vector dual multiply: Rdd=vdmpy(Rss,Rtt)[:<<1]:sat
def : T_PP_pat <M2_vdmpys_s1, int_hexagon_M2_vdmpys_s1>;
def : T_PP_pat <M2_vdmpys_s0, int_hexagon_M2_vdmpys_s0>;
// Vector multiply even halfwords: Rdd=vmpyeh(Rss,Rtt)[:<<1]:sat
def : T_PP_pat <M2_vmpy2es_s1, int_hexagon_M2_vmpy2es_s1>;
def : T_PP_pat <M2_vmpy2es_s0, int_hexagon_M2_vmpy2es_s0>;
//Rdd=vmpywoh(Rss,Rtt)[:<<1][:rnd]:sat
def : T_PP_pat <M2_mmpyh_s0, int_hexagon_M2_mmpyh_s0>;
def : T_PP_pat <M2_mmpyh_s1, int_hexagon_M2_mmpyh_s1>;
def : T_PP_pat <M2_mmpyh_rs0, int_hexagon_M2_mmpyh_rs0>;
def : T_PP_pat <M2_mmpyh_rs1, int_hexagon_M2_mmpyh_rs1>;
//Rdd=vmpyweh(Rss,Rtt)[:<<1][:rnd]:sat
def : T_PP_pat <M2_mmpyl_s0, int_hexagon_M2_mmpyl_s0>;
def : T_PP_pat <M2_mmpyl_s1, int_hexagon_M2_mmpyl_s1>;
def : T_PP_pat <M2_mmpyl_rs0, int_hexagon_M2_mmpyl_rs0>;
def : T_PP_pat <M2_mmpyl_rs1, int_hexagon_M2_mmpyl_rs1>;
//Rdd=vmpywouh(Rss,Rtt)[:<<1][:rnd]:sat
def : T_PP_pat <M2_mmpyuh_s0, int_hexagon_M2_mmpyuh_s0>;
def : T_PP_pat <M2_mmpyuh_s1, int_hexagon_M2_mmpyuh_s1>;
def : T_PP_pat <M2_mmpyuh_rs0, int_hexagon_M2_mmpyuh_rs0>;
def : T_PP_pat <M2_mmpyuh_rs1, int_hexagon_M2_mmpyuh_rs1>;
//Rdd=vmpyweuh(Rss,Rtt)[:<<1][:rnd]:sat
def : T_PP_pat <M2_mmpyul_s0, int_hexagon_M2_mmpyul_s0>;
def : T_PP_pat <M2_mmpyul_s1, int_hexagon_M2_mmpyul_s1>;
def : T_PP_pat <M2_mmpyul_rs0, int_hexagon_M2_mmpyul_rs0>;
def : T_PP_pat <M2_mmpyul_rs1, int_hexagon_M2_mmpyul_rs1>;
// Vector reduce add unsigned bytes: Rdd32[+]=vrmpybu(Rss32,Rtt32)
def : T_PP_pat <A2_vraddub, int_hexagon_A2_vraddub>;
def : T_PPP_pat <A2_vraddub_acc, int_hexagon_A2_vraddub_acc>;
// Vector sum of absolute differences unsigned bytes: Rdd=vrsadub(Rss,Rtt)
def : T_PP_pat <A2_vrsadub, int_hexagon_A2_vrsadub>;
def : T_PPP_pat <A2_vrsadub_acc, int_hexagon_A2_vrsadub_acc>;
// Vector absolute difference: Rdd=vabsdiffh(Rtt,Rss)
def : T_PP_pat <M2_vabsdiffh, int_hexagon_M2_vabsdiffh>;
// Vector absolute difference words: Rdd=vabsdiffw(Rtt,Rss)
def : T_PP_pat <M2_vabsdiffw, int_hexagon_M2_vabsdiffw>;
// Vector reduce complex multiply real or imaginary:
// Rdd[+]=vrcmpy[ir](Rss,Rtt[*])
def : T_PP_pat <M2_vrcmpyi_s0, int_hexagon_M2_vrcmpyi_s0>;
def : T_PP_pat <M2_vrcmpyi_s0c, int_hexagon_M2_vrcmpyi_s0c>;
def : T_PPP_pat <M2_vrcmaci_s0, int_hexagon_M2_vrcmaci_s0>;
def : T_PPP_pat <M2_vrcmaci_s0c, int_hexagon_M2_vrcmaci_s0c>;
def : T_PP_pat <M2_vrcmpyr_s0, int_hexagon_M2_vrcmpyr_s0>;
def : T_PP_pat <M2_vrcmpyr_s0c, int_hexagon_M2_vrcmpyr_s0c>;
def : T_PPP_pat <M2_vrcmacr_s0, int_hexagon_M2_vrcmacr_s0>;
def : T_PPP_pat <M2_vrcmacr_s0c, int_hexagon_M2_vrcmacr_s0c>;
// Vector reduce halfwords
// Rdd[+]=vrmpyh(Rss,Rtt)
def : T_PP_pat <M2_vrmpy_s0, int_hexagon_M2_vrmpy_s0>;
def : T_PPP_pat <M2_vrmac_s0, int_hexagon_M2_vrmac_s0>;
//===----------------------------------------------------------------------===//
// Vector Multipy with accumulation
//===----------------------------------------------------------------------===//
// Vector multiply word by signed half with accumulation
// Rxx+=vmpyw[eo]h(Rss,Rtt)[:<<1][:rnd]:sat
def : T_PPP_pat <M2_mmacls_s1, int_hexagon_M2_mmacls_s1>;
def : T_PPP_pat <M2_mmacls_s0, int_hexagon_M2_mmacls_s0>;
def : T_PPP_pat <M2_mmacls_rs1, int_hexagon_M2_mmacls_rs1>;
def : T_PPP_pat <M2_mmacls_rs0, int_hexagon_M2_mmacls_rs0>;
def : T_PPP_pat <M2_mmachs_s1, int_hexagon_M2_mmachs_s1>;
def : T_PPP_pat <M2_mmachs_s0, int_hexagon_M2_mmachs_s0>;
def : T_PPP_pat <M2_mmachs_rs1, int_hexagon_M2_mmachs_rs1>;
def : T_PPP_pat <M2_mmachs_rs0, int_hexagon_M2_mmachs_rs0>;
// Vector multiply word by unsigned half with accumulation
// Rxx+=vmpyw[eo]uh(Rss,Rtt)[:<<1][:rnd]:sat
def : T_PPP_pat <M2_mmaculs_s1, int_hexagon_M2_mmaculs_s1>;
def : T_PPP_pat <M2_mmaculs_s0, int_hexagon_M2_mmaculs_s0>;
def : T_PPP_pat <M2_mmaculs_rs1, int_hexagon_M2_mmaculs_rs1>;
def : T_PPP_pat <M2_mmaculs_rs0, int_hexagon_M2_mmaculs_rs0>;
def : T_PPP_pat <M2_mmacuhs_s1, int_hexagon_M2_mmacuhs_s1>;
def : T_PPP_pat <M2_mmacuhs_s0, int_hexagon_M2_mmacuhs_s0>;
def : T_PPP_pat <M2_mmacuhs_rs1, int_hexagon_M2_mmacuhs_rs1>;
def : T_PPP_pat <M2_mmacuhs_rs0, int_hexagon_M2_mmacuhs_rs0>;
// Vector multiply even halfwords with accumulation
// Rxx+=vmpyeh(Rss,Rtt)[:<<1][:sat]
def : T_PPP_pat <M2_vmac2es, int_hexagon_M2_vmac2es>;
def : T_PPP_pat <M2_vmac2es_s1, int_hexagon_M2_vmac2es_s1>;
def : T_PPP_pat <M2_vmac2es_s0, int_hexagon_M2_vmac2es_s0>;
// Vector dual multiply with accumulation
// Rxx+=vdmpy(Rss,Rtt)[:sat]
def : T_PPP_pat <M2_vdmacs_s1, int_hexagon_M2_vdmacs_s1>;
def : T_PPP_pat <M2_vdmacs_s0, int_hexagon_M2_vdmacs_s0>;
// Vector complex multiply real or imaginary with accumulation
// Rxx+=vcmpy[ir](Rss,Rtt):sat
def : T_PPP_pat <M2_vcmac_s0_sat_r, int_hexagon_M2_vcmac_s0_sat_r>;
def : T_PPP_pat <M2_vcmac_s0_sat_i, int_hexagon_M2_vcmac_s0_sat_i>;
//===----------------------------------------------------------------------===//
// Add/Subtract halfword
// Rd=add(Rt.L,Rs.[HL])[:sat]
// Rd=sub(Rt.L,Rs.[HL])[:sat]
// Rd=add(Rt.[LH],Rs.[HL])[:sat][:<16]
// Rd=sub(Rt.[LH],Rs.[HL])[:sat][:<16]
//===----------------------------------------------------------------------===//
//Rd=add(Rt.L,Rs.[LH])
def : T_RR_pat <A2_addh_l16_ll, int_hexagon_A2_addh_l16_ll>;
def : T_RR_pat <A2_addh_l16_hl, int_hexagon_A2_addh_l16_hl>;
//Rd=add(Rt.L,Rs.[LH]):sat
def : T_RR_pat <A2_addh_l16_sat_ll, int_hexagon_A2_addh_l16_sat_ll>;
def : T_RR_pat <A2_addh_l16_sat_hl, int_hexagon_A2_addh_l16_sat_hl>;
//Rd=sub(Rt.L,Rs.[LH])
def : T_RR_pat <A2_subh_l16_ll, int_hexagon_A2_subh_l16_ll>;
def : T_RR_pat <A2_subh_l16_hl, int_hexagon_A2_subh_l16_hl>;
//Rd=sub(Rt.L,Rs.[LH]):sat
def : T_RR_pat <A2_subh_l16_sat_ll, int_hexagon_A2_subh_l16_sat_ll>;
def : T_RR_pat <A2_subh_l16_sat_hl, int_hexagon_A2_subh_l16_sat_hl>;
//Rd=add(Rt.[LH],Rs.[LH]):<<16
def : T_RR_pat <A2_addh_h16_ll, int_hexagon_A2_addh_h16_ll>;
def : T_RR_pat <A2_addh_h16_lh, int_hexagon_A2_addh_h16_lh>;
def : T_RR_pat <A2_addh_h16_hl, int_hexagon_A2_addh_h16_hl>;
def : T_RR_pat <A2_addh_h16_hh, int_hexagon_A2_addh_h16_hh>;
//Rd=sub(Rt.[LH],Rs.[LH]):<<16
def : T_RR_pat <A2_subh_h16_ll, int_hexagon_A2_subh_h16_ll>;
def : T_RR_pat <A2_subh_h16_lh, int_hexagon_A2_subh_h16_lh>;
def : T_RR_pat <A2_subh_h16_hl, int_hexagon_A2_subh_h16_hl>;
def : T_RR_pat <A2_subh_h16_hh, int_hexagon_A2_subh_h16_hh>;
//Rd=add(Rt.[LH],Rs.[LH]):sat:<<16
def : T_RR_pat <A2_addh_h16_sat_ll, int_hexagon_A2_addh_h16_sat_ll>;
def : T_RR_pat <A2_addh_h16_sat_lh, int_hexagon_A2_addh_h16_sat_lh>;
def : T_RR_pat <A2_addh_h16_sat_hl, int_hexagon_A2_addh_h16_sat_hl>;
def : T_RR_pat <A2_addh_h16_sat_hh, int_hexagon_A2_addh_h16_sat_hh>;
//Rd=sub(Rt.[LH],Rs.[LH]):sat:<<16
def : T_RR_pat <A2_subh_h16_sat_ll, int_hexagon_A2_subh_h16_sat_ll>;
def : T_RR_pat <A2_subh_h16_sat_lh, int_hexagon_A2_subh_h16_sat_lh>;
def : T_RR_pat <A2_subh_h16_sat_hl, int_hexagon_A2_subh_h16_sat_hl>;
def : T_RR_pat <A2_subh_h16_sat_hh, int_hexagon_A2_subh_h16_sat_hh>;
// ALU64 / ALU / min max
def : T_RR_pat<A2_max, int_hexagon_A2_max>;
def : T_RR_pat<A2_min, int_hexagon_A2_min>;
def : T_RR_pat<A2_maxu, int_hexagon_A2_maxu>;
def : T_RR_pat<A2_minu, int_hexagon_A2_minu>;
// Shift and accumulate
def : T_RRI_pat <S2_asr_i_r_nac, int_hexagon_S2_asr_i_r_nac>;
def : T_RRI_pat <S2_lsr_i_r_nac, int_hexagon_S2_lsr_i_r_nac>;
def : T_RRI_pat <S2_asl_i_r_nac, int_hexagon_S2_asl_i_r_nac>;
def : T_RRI_pat <S2_asr_i_r_acc, int_hexagon_S2_asr_i_r_acc>;
def : T_RRI_pat <S2_lsr_i_r_acc, int_hexagon_S2_lsr_i_r_acc>;
def : T_RRI_pat <S2_asl_i_r_acc, int_hexagon_S2_asl_i_r_acc>;
def : T_RRI_pat <S2_asr_i_r_and, int_hexagon_S2_asr_i_r_and>;
def : T_RRI_pat <S2_lsr_i_r_and, int_hexagon_S2_lsr_i_r_and>;
def : T_RRI_pat <S2_asl_i_r_and, int_hexagon_S2_asl_i_r_and>;
def : T_RRI_pat <S2_asr_i_r_or, int_hexagon_S2_asr_i_r_or>;
def : T_RRI_pat <S2_lsr_i_r_or, int_hexagon_S2_lsr_i_r_or>;
def : T_RRI_pat <S2_asl_i_r_or, int_hexagon_S2_asl_i_r_or>;
def : T_RRI_pat <S2_lsr_i_r_xacc, int_hexagon_S2_lsr_i_r_xacc>;
def : T_RRI_pat <S2_asl_i_r_xacc, int_hexagon_S2_asl_i_r_xacc>;
def : T_PPI_pat <S2_asr_i_p_nac, int_hexagon_S2_asr_i_p_nac>;
def : T_PPI_pat <S2_lsr_i_p_nac, int_hexagon_S2_lsr_i_p_nac>;
def : T_PPI_pat <S2_asl_i_p_nac, int_hexagon_S2_asl_i_p_nac>;
def : T_PPI_pat <S2_asr_i_p_acc, int_hexagon_S2_asr_i_p_acc>;
def : T_PPI_pat <S2_lsr_i_p_acc, int_hexagon_S2_lsr_i_p_acc>;
def : T_PPI_pat <S2_asl_i_p_acc, int_hexagon_S2_asl_i_p_acc>;
def : T_PPI_pat <S2_asr_i_p_and, int_hexagon_S2_asr_i_p_and>;
def : T_PPI_pat <S2_lsr_i_p_and, int_hexagon_S2_lsr_i_p_and>;
def : T_PPI_pat <S2_asl_i_p_and, int_hexagon_S2_asl_i_p_and>;
def : T_PPI_pat <S2_asr_i_p_or, int_hexagon_S2_asr_i_p_or>;
def : T_PPI_pat <S2_lsr_i_p_or, int_hexagon_S2_lsr_i_p_or>;
def : T_PPI_pat <S2_asl_i_p_or, int_hexagon_S2_asl_i_p_or>;
def : T_PPI_pat <S2_lsr_i_p_xacc, int_hexagon_S2_lsr_i_p_xacc>;
def : T_PPI_pat <S2_asl_i_p_xacc, int_hexagon_S2_asl_i_p_xacc>;
def : T_RRR_pat <S2_asr_r_r_nac, int_hexagon_S2_asr_r_r_nac>;
def : T_RRR_pat <S2_lsr_r_r_nac, int_hexagon_S2_lsr_r_r_nac>;
def : T_RRR_pat <S2_asl_r_r_nac, int_hexagon_S2_asl_r_r_nac>;
def : T_RRR_pat <S2_lsl_r_r_nac, int_hexagon_S2_lsl_r_r_nac>;
def : T_RRR_pat <S2_asr_r_r_acc, int_hexagon_S2_asr_r_r_acc>;
def : T_RRR_pat <S2_lsr_r_r_acc, int_hexagon_S2_lsr_r_r_acc>;
def : T_RRR_pat <S2_asl_r_r_acc, int_hexagon_S2_asl_r_r_acc>;
def : T_RRR_pat <S2_lsl_r_r_acc, int_hexagon_S2_lsl_r_r_acc>;
def : T_RRR_pat <S2_asr_r_r_and, int_hexagon_S2_asr_r_r_and>;
def : T_RRR_pat <S2_lsr_r_r_and, int_hexagon_S2_lsr_r_r_and>;
def : T_RRR_pat <S2_asl_r_r_and, int_hexagon_S2_asl_r_r_and>;
def : T_RRR_pat <S2_lsl_r_r_and, int_hexagon_S2_lsl_r_r_and>;
def : T_RRR_pat <S2_asr_r_r_or, int_hexagon_S2_asr_r_r_or>;
def : T_RRR_pat <S2_lsr_r_r_or, int_hexagon_S2_lsr_r_r_or>;
def : T_RRR_pat <S2_asl_r_r_or, int_hexagon_S2_asl_r_r_or>;
def : T_RRR_pat <S2_lsl_r_r_or, int_hexagon_S2_lsl_r_r_or>;
def : T_PPR_pat <S2_asr_r_p_nac, int_hexagon_S2_asr_r_p_nac>;
def : T_PPR_pat <S2_lsr_r_p_nac, int_hexagon_S2_lsr_r_p_nac>;
def : T_PPR_pat <S2_asl_r_p_nac, int_hexagon_S2_asl_r_p_nac>;
def : T_PPR_pat <S2_lsl_r_p_nac, int_hexagon_S2_lsl_r_p_nac>;
def : T_PPR_pat <S2_asr_r_p_acc, int_hexagon_S2_asr_r_p_acc>;
def : T_PPR_pat <S2_lsr_r_p_acc, int_hexagon_S2_lsr_r_p_acc>;
def : T_PPR_pat <S2_asl_r_p_acc, int_hexagon_S2_asl_r_p_acc>;
def : T_PPR_pat <S2_lsl_r_p_acc, int_hexagon_S2_lsl_r_p_acc>;
def : T_PPR_pat <S2_asr_r_p_and, int_hexagon_S2_asr_r_p_and>;
def : T_PPR_pat <S2_lsr_r_p_and, int_hexagon_S2_lsr_r_p_and>;
def : T_PPR_pat <S2_asl_r_p_and, int_hexagon_S2_asl_r_p_and>;
def : T_PPR_pat <S2_lsl_r_p_and, int_hexagon_S2_lsl_r_p_and>;
def : T_PPR_pat <S2_asr_r_p_or, int_hexagon_S2_asr_r_p_or>;
def : T_PPR_pat <S2_lsr_r_p_or, int_hexagon_S2_lsr_r_p_or>;
def : T_PPR_pat <S2_asl_r_p_or, int_hexagon_S2_asl_r_p_or>;
def : T_PPR_pat <S2_lsl_r_p_or, int_hexagon_S2_lsl_r_p_or>;
def : T_RRI_pat <S2_asr_i_r_nac, int_hexagon_S2_asr_i_r_nac>;
def : T_RRI_pat <S2_lsr_i_r_nac, int_hexagon_S2_lsr_i_r_nac>;
def : T_RRI_pat <S2_asl_i_r_nac, int_hexagon_S2_asl_i_r_nac>;
def : T_RRI_pat <S2_asr_i_r_acc, int_hexagon_S2_asr_i_r_acc>;
def : T_RRI_pat <S2_lsr_i_r_acc, int_hexagon_S2_lsr_i_r_acc>;
def : T_RRI_pat <S2_asl_i_r_acc, int_hexagon_S2_asl_i_r_acc>;
def : T_RRI_pat <S2_asr_i_r_and, int_hexagon_S2_asr_i_r_and>;
def : T_RRI_pat <S2_lsr_i_r_and, int_hexagon_S2_lsr_i_r_and>;
def : T_RRI_pat <S2_asl_i_r_and, int_hexagon_S2_asl_i_r_and>;
def : T_RRI_pat <S2_asr_i_r_or, int_hexagon_S2_asr_i_r_or>;
def : T_RRI_pat <S2_lsr_i_r_or, int_hexagon_S2_lsr_i_r_or>;
def : T_RRI_pat <S2_asl_i_r_or, int_hexagon_S2_asl_i_r_or>;
def : T_RRI_pat <S2_lsr_i_r_xacc, int_hexagon_S2_lsr_i_r_xacc>;
def : T_RRI_pat <S2_asl_i_r_xacc, int_hexagon_S2_asl_i_r_xacc>;
def : T_PPI_pat <S2_asr_i_p_nac, int_hexagon_S2_asr_i_p_nac>;
def : T_PPI_pat <S2_lsr_i_p_nac, int_hexagon_S2_lsr_i_p_nac>;
def : T_PPI_pat <S2_asl_i_p_nac, int_hexagon_S2_asl_i_p_nac>;
def : T_PPI_pat <S2_asr_i_p_acc, int_hexagon_S2_asr_i_p_acc>;
def : T_PPI_pat <S2_lsr_i_p_acc, int_hexagon_S2_lsr_i_p_acc>;
def : T_PPI_pat <S2_asl_i_p_acc, int_hexagon_S2_asl_i_p_acc>;
def : T_PPI_pat <S2_asr_i_p_and, int_hexagon_S2_asr_i_p_and>;
def : T_PPI_pat <S2_lsr_i_p_and, int_hexagon_S2_lsr_i_p_and>;
def : T_PPI_pat <S2_asl_i_p_and, int_hexagon_S2_asl_i_p_and>;
def : T_PPI_pat <S2_asr_i_p_or, int_hexagon_S2_asr_i_p_or>;
def : T_PPI_pat <S2_lsr_i_p_or, int_hexagon_S2_lsr_i_p_or>;
def : T_PPI_pat <S2_asl_i_p_or, int_hexagon_S2_asl_i_p_or>;
def : T_PPI_pat <S2_lsr_i_p_xacc, int_hexagon_S2_lsr_i_p_xacc>;
def : T_PPI_pat <S2_asl_i_p_xacc, int_hexagon_S2_asl_i_p_xacc>;
def : T_RRR_pat <S2_asr_r_r_nac, int_hexagon_S2_asr_r_r_nac>;
def : T_RRR_pat <S2_lsr_r_r_nac, int_hexagon_S2_lsr_r_r_nac>;
def : T_RRR_pat <S2_asl_r_r_nac, int_hexagon_S2_asl_r_r_nac>;
def : T_RRR_pat <S2_lsl_r_r_nac, int_hexagon_S2_lsl_r_r_nac>;
def : T_RRR_pat <S2_asr_r_r_acc, int_hexagon_S2_asr_r_r_acc>;
def : T_RRR_pat <S2_lsr_r_r_acc, int_hexagon_S2_lsr_r_r_acc>;
def : T_RRR_pat <S2_asl_r_r_acc, int_hexagon_S2_asl_r_r_acc>;
def : T_RRR_pat <S2_lsl_r_r_acc, int_hexagon_S2_lsl_r_r_acc>;
def : T_RRR_pat <S2_asr_r_r_and, int_hexagon_S2_asr_r_r_and>;
def : T_RRR_pat <S2_lsr_r_r_and, int_hexagon_S2_lsr_r_r_and>;
def : T_RRR_pat <S2_asl_r_r_and, int_hexagon_S2_asl_r_r_and>;
def : T_RRR_pat <S2_lsl_r_r_and, int_hexagon_S2_lsl_r_r_and>;
def : T_RRR_pat <S2_asr_r_r_or, int_hexagon_S2_asr_r_r_or>;
def : T_RRR_pat <S2_lsr_r_r_or, int_hexagon_S2_lsr_r_r_or>;
def : T_RRR_pat <S2_asl_r_r_or, int_hexagon_S2_asl_r_r_or>;
def : T_RRR_pat <S2_lsl_r_r_or, int_hexagon_S2_lsl_r_r_or>;
def : T_PPR_pat <S2_asr_r_p_nac, int_hexagon_S2_asr_r_p_nac>;
def : T_PPR_pat <S2_lsr_r_p_nac, int_hexagon_S2_lsr_r_p_nac>;
def : T_PPR_pat <S2_asl_r_p_nac, int_hexagon_S2_asl_r_p_nac>;
def : T_PPR_pat <S2_lsl_r_p_nac, int_hexagon_S2_lsl_r_p_nac>;
def : T_PPR_pat <S2_asr_r_p_acc, int_hexagon_S2_asr_r_p_acc>;
def : T_PPR_pat <S2_lsr_r_p_acc, int_hexagon_S2_lsr_r_p_acc>;
def : T_PPR_pat <S2_asl_r_p_acc, int_hexagon_S2_asl_r_p_acc>;
def : T_PPR_pat <S2_lsl_r_p_acc, int_hexagon_S2_lsl_r_p_acc>;
def : T_PPR_pat <S2_asr_r_p_and, int_hexagon_S2_asr_r_p_and>;
def : T_PPR_pat <S2_lsr_r_p_and, int_hexagon_S2_lsr_r_p_and>;
def : T_PPR_pat <S2_asl_r_p_and, int_hexagon_S2_asl_r_p_and>;
def : T_PPR_pat <S2_lsl_r_p_and, int_hexagon_S2_lsl_r_p_and>;
def : T_PPR_pat <S2_asr_r_p_or, int_hexagon_S2_asr_r_p_or>;
def : T_PPR_pat <S2_lsr_r_p_or, int_hexagon_S2_lsr_r_p_or>;
def : T_PPR_pat <S2_asl_r_p_or, int_hexagon_S2_asl_r_p_or>;
def : T_PPR_pat <S2_lsl_r_p_or, int_hexagon_S2_lsl_r_p_or>;
//*******************************************************************
// ALU32/ALU
//*******************************************************************
def : T_RR_pat<A2_add, int_hexagon_A2_add>;
def : T_RI_pat<A2_addi, int_hexagon_A2_addi>;
def : T_RR_pat<A2_sub, int_hexagon_A2_sub>;
def : T_IR_pat<A2_subri, int_hexagon_A2_subri>;
def : T_RR_pat<A2_and, int_hexagon_A2_and>;
def : T_RI_pat<A2_andir, int_hexagon_A2_andir>;
def : T_RR_pat<A2_or, int_hexagon_A2_or>;
def : T_RI_pat<A2_orir, int_hexagon_A2_orir>;
def : T_RR_pat<A2_xor, int_hexagon_A2_xor>;
def : T_RR_pat<A2_combinew, int_hexagon_A2_combinew>;
// Assembler mapped from Rd32=not(Rs32) to Rd32=sub(#-1,Rs32)
def : Pat <(int_hexagon_A2_not I32:$Rs),
(A2_subri -1, I32:$Rs)>;
// Assembler mapped from Rd32=neg(Rs32) to Rd32=sub(#0,Rs32)
def : Pat <(int_hexagon_A2_neg I32:$Rs),
(A2_subri 0, I32:$Rs)>;
// Transfer immediate
def : Pat <(int_hexagon_A2_tfril I32:$Rs, u16_0ImmPred:$Is),
(A2_tfril I32:$Rs, u16_0ImmPred:$Is)>;
def : Pat <(int_hexagon_A2_tfrih I32:$Rs, u16_0ImmPred:$Is),
(A2_tfrih I32:$Rs, u16_0ImmPred:$Is)>;
// Transfer Register/immediate.
def : T_R_pat <A2_tfr, int_hexagon_A2_tfr>;
def : T_I_pat <A2_tfrsi, int_hexagon_A2_tfrsi>;
def ImmExt64: SDNodeXForm<imm, [{
int64_t V = N->getSExtValue();
return CurDAG->getTargetConstant(V, SDLoc(N), MVT::i64);
}]>;
// A2_tfrpi has an operand of type i64. This is necessary, since it is
// generated from "(set I64:$Rd, imm)". That pattern would not appear
// in the DAG, if the immediate was not a 64-bit value.
// The builtin for A2_tfrpi, on the other hand, takes a 32-bit value,
// which makes it impossible to simply replace it with the instruction.
// To connect the builtin with the instruction, the builtin's operand
// needs to be extended to the right type.
def : Pat<(int_hexagon_A2_tfrpi imm:$Is),
(A2_tfrpi (ImmExt64 $Is))>;
// Assembler mapped from Rdd32=Rss32 to Rdd32=combine(Rss.H32,Rss.L32)
def : Pat<(int_hexagon_A2_tfrp I64:$src),
(A2_combinew (HiReg I64:$src), (LoReg I64:$src))>;
//*******************************************************************
// ALU32/PERM
//*******************************************************************
// Combine
def: T_RR_pat<A2_combine_hh, int_hexagon_A2_combine_hh>;
def: T_RR_pat<A2_combine_hl, int_hexagon_A2_combine_hl>;
def: T_RR_pat<A2_combine_lh, int_hexagon_A2_combine_lh>;
def: T_RR_pat<A2_combine_ll, int_hexagon_A2_combine_ll>;
def: T_II_pat<A2_combineii, int_hexagon_A2_combineii, s32ImmPred, s8ImmPred>;
// Mux
def : T_QRR_pat<C2_mux, int_hexagon_C2_mux>;
def : T_QRI_pat<C2_muxir, int_hexagon_C2_muxir, s32ImmPred>;
def : T_QIR_pat<C2_muxri, int_hexagon_C2_muxri, s32ImmPred>;
def : T_QII_pat<C2_muxii, int_hexagon_C2_muxii, s32ImmPred, s8ImmPred>;
// Shift halfword
def : T_R_pat<A2_aslh, int_hexagon_A2_aslh>;
def : T_R_pat<A2_asrh, int_hexagon_A2_asrh>;
def : T_R_pat<A2_asrh, int_hexagon_SI_to_SXTHI_asrh>;
// Sign/zero extend
def : T_R_pat<A2_sxth, int_hexagon_A2_sxth>;
def : T_R_pat<A2_sxtb, int_hexagon_A2_sxtb>;
def : T_R_pat<A2_zxth, int_hexagon_A2_zxth>;
def : T_R_pat<A2_zxtb, int_hexagon_A2_zxtb>;
//*******************************************************************
// ALU32/PRED
//*******************************************************************
// Compare
def : T_Q_RR_pat<C2_cmpeq, int_hexagon_C2_cmpeq>;
def : T_Q_RR_pat<C2_cmpgt, int_hexagon_C2_cmpgt>;
def : T_Q_RR_pat<C2_cmpgtu, int_hexagon_C2_cmpgtu>;
def : T_Q_RI_pat<C2_cmpeqi, int_hexagon_C2_cmpeqi, s32ImmPred>;
def : T_Q_RI_pat<C2_cmpgti, int_hexagon_C2_cmpgti, s32ImmPred>;
def : T_Q_RI_pat<C2_cmpgtui, int_hexagon_C2_cmpgtui, u32ImmPred>;
def : Pat <(int_hexagon_C2_cmpgei I32:$src1, s32ImmPred:$src2),
(C2_tfrpr (C2_cmpgti I32:$src1,
(DEC_CONST_SIGNED s32ImmPred:$src2)))>;
def : Pat <(int_hexagon_C2_cmpgeui I32:$src1, u32ImmPred:$src2),
(C2_tfrpr (C2_cmpgtui I32:$src1,
(DEC_CONST_UNSIGNED u32ImmPred:$src2)))>;
def : Pat <(int_hexagon_C2_cmpgeui I32:$src, 0),
(C2_tfrpr (C2_cmpeq I32:$src, I32:$src))>;
def : Pat <(int_hexagon_C2_cmplt I32:$src1, I32:$src2),
(C2_tfrpr (C2_cmpgt I32:$src2, I32:$src1))>;
def : Pat <(int_hexagon_C2_cmpltu I32:$src1, I32:$src2),
(C2_tfrpr (C2_cmpgtu I32:$src2, I32:$src1))>;
//*******************************************************************
// ALU32/VH
//*******************************************************************
// Vector add, subtract, average halfwords
def: T_RR_pat<A2_svaddh, int_hexagon_A2_svaddh>;
def: T_RR_pat<A2_svaddhs, int_hexagon_A2_svaddhs>;
def: T_RR_pat<A2_svadduhs, int_hexagon_A2_svadduhs>;
def: T_RR_pat<A2_svsubh, int_hexagon_A2_svsubh>;
def: T_RR_pat<A2_svsubhs, int_hexagon_A2_svsubhs>;
def: T_RR_pat<A2_svsubuhs, int_hexagon_A2_svsubuhs>;
def: T_RR_pat<A2_svavgh, int_hexagon_A2_svavgh>;
def: T_RR_pat<A2_svavghs, int_hexagon_A2_svavghs>;
def: T_RR_pat<A2_svnavgh, int_hexagon_A2_svnavgh>;
//*******************************************************************
// ALU64/ALU
//*******************************************************************
def: T_RR_pat<A2_addsat, int_hexagon_A2_addsat>;
def: T_RR_pat<A2_subsat, int_hexagon_A2_subsat>;
def: T_PP_pat<A2_addp, int_hexagon_A2_addp>;
def: T_PP_pat<A2_subp, int_hexagon_A2_subp>;
def: T_PP_pat<A2_andp, int_hexagon_A2_andp>;
def: T_PP_pat<A2_orp, int_hexagon_A2_orp>;
def: T_PP_pat<A2_xorp, int_hexagon_A2_xorp>;
def: T_Q_PP_pat<C2_cmpeqp, int_hexagon_C2_cmpeqp>;
def: T_Q_PP_pat<C2_cmpgtp, int_hexagon_C2_cmpgtp>;
def: T_Q_PP_pat<C2_cmpgtup, int_hexagon_C2_cmpgtup>;
def: T_PP_pat<S2_parityp, int_hexagon_S2_parityp>;
def: T_RR_pat<S2_packhl, int_hexagon_S2_packhl>;
//*******************************************************************
// ALU64/VB
//*******************************************************************
// ALU64 - Vector add
def : T_PP_pat <A2_vaddub, int_hexagon_A2_vaddub>;
def : T_PP_pat <A2_vaddubs, int_hexagon_A2_vaddubs>;
def : T_PP_pat <A2_vaddh, int_hexagon_A2_vaddh>;
def : T_PP_pat <A2_vaddhs, int_hexagon_A2_vaddhs>;
def : T_PP_pat <A2_vadduhs, int_hexagon_A2_vadduhs>;
def : T_PP_pat <A2_vaddw, int_hexagon_A2_vaddw>;
def : T_PP_pat <A2_vaddws, int_hexagon_A2_vaddws>;
// ALU64 - Vector average
def : T_PP_pat <A2_vavgub, int_hexagon_A2_vavgub>;
def : T_PP_pat <A2_vavgubr, int_hexagon_A2_vavgubr>;
def : T_PP_pat <A2_vavgh, int_hexagon_A2_vavgh>;
def : T_PP_pat <A2_vavghr, int_hexagon_A2_vavghr>;
def : T_PP_pat <A2_vavghcr, int_hexagon_A2_vavghcr>;
def : T_PP_pat <A2_vavguh, int_hexagon_A2_vavguh>;
def : T_PP_pat <A2_vavguhr, int_hexagon_A2_vavguhr>;
def : T_PP_pat <A2_vavgw, int_hexagon_A2_vavgw>;
def : T_PP_pat <A2_vavgwr, int_hexagon_A2_vavgwr>;
def : T_PP_pat <A2_vavgwcr, int_hexagon_A2_vavgwcr>;
def : T_PP_pat <A2_vavguw, int_hexagon_A2_vavguw>;
def : T_PP_pat <A2_vavguwr, int_hexagon_A2_vavguwr>;
// ALU64 - Vector negative average
def : T_PP_pat <A2_vnavgh, int_hexagon_A2_vnavgh>;
def : T_PP_pat <A2_vnavghr, int_hexagon_A2_vnavghr>;
def : T_PP_pat <A2_vnavghcr, int_hexagon_A2_vnavghcr>;
def : T_PP_pat <A2_vnavgw, int_hexagon_A2_vnavgw>;
def : T_PP_pat <A2_vnavgwr, int_hexagon_A2_vnavgwr>;
def : T_PP_pat <A2_vnavgwcr, int_hexagon_A2_vnavgwcr>;
// ALU64 - Vector max
def : T_PP_pat <A2_vmaxh, int_hexagon_A2_vmaxh>;
def : T_PP_pat <A2_vmaxw, int_hexagon_A2_vmaxw>;
def : T_PP_pat <A2_vmaxub, int_hexagon_A2_vmaxub>;
def : T_PP_pat <A2_vmaxuh, int_hexagon_A2_vmaxuh>;
def : T_PP_pat <A2_vmaxuw, int_hexagon_A2_vmaxuw>;
// ALU64 - Vector min
def : T_PP_pat <A2_vminh, int_hexagon_A2_vminh>;
def : T_PP_pat <A2_vminw, int_hexagon_A2_vminw>;
def : T_PP_pat <A2_vminub, int_hexagon_A2_vminub>;
def : T_PP_pat <A2_vminuh, int_hexagon_A2_vminuh>;
def : T_PP_pat <A2_vminuw, int_hexagon_A2_vminuw>;
// ALU64 - Vector sub
def : T_PP_pat <A2_vsubub, int_hexagon_A2_vsubub>;
def : T_PP_pat <A2_vsububs, int_hexagon_A2_vsububs>;
def : T_PP_pat <A2_vsubh, int_hexagon_A2_vsubh>;
def : T_PP_pat <A2_vsubhs, int_hexagon_A2_vsubhs>;
def : T_PP_pat <A2_vsubuhs, int_hexagon_A2_vsubuhs>;
def : T_PP_pat <A2_vsubw, int_hexagon_A2_vsubw>;
def : T_PP_pat <A2_vsubws, int_hexagon_A2_vsubws>;
// ALU64 - Vector compare bytes
def : T_Q_PP_pat <A2_vcmpbeq, int_hexagon_A2_vcmpbeq>;
def : T_Q_PP_pat <A4_vcmpbgt, int_hexagon_A4_vcmpbgt>;
def : T_Q_PP_pat <A2_vcmpbgtu, int_hexagon_A2_vcmpbgtu>;
// ALU64 - Vector compare halfwords
def : T_Q_PP_pat <A2_vcmpheq, int_hexagon_A2_vcmpheq>;
def : T_Q_PP_pat <A2_vcmphgt, int_hexagon_A2_vcmphgt>;
def : T_Q_PP_pat <A2_vcmphgtu, int_hexagon_A2_vcmphgtu>;
// ALU64 - Vector compare words
def : T_Q_PP_pat <A2_vcmpweq, int_hexagon_A2_vcmpweq>;
def : T_Q_PP_pat <A2_vcmpwgt, int_hexagon_A2_vcmpwgt>;
def : T_Q_PP_pat <A2_vcmpwgtu, int_hexagon_A2_vcmpwgtu>;
// ALU64 / VB / Vector mux.
def : T_QPP_pat <C2_vmux, int_hexagon_C2_vmux>;
// MPY - Multiply and use full result
// Rdd = mpy[u](Rs, Rt)
def : T_RR_pat <M2_dpmpyss_s0, int_hexagon_M2_dpmpyss_s0>;
def : T_RR_pat <M2_dpmpyuu_s0, int_hexagon_M2_dpmpyuu_s0>;
// Complex multiply real or imaginary
def : T_RR_pat <M2_cmpyi_s0, int_hexagon_M2_cmpyi_s0>;
def : T_RR_pat <M2_cmpyr_s0, int_hexagon_M2_cmpyr_s0>;
// Complex multiply
def : T_RR_pat <M2_cmpys_s0, int_hexagon_M2_cmpys_s0>;
def : T_RR_pat <M2_cmpysc_s0, int_hexagon_M2_cmpysc_s0>;
def : T_RR_pat <M2_cmpys_s1, int_hexagon_M2_cmpys_s1>;
def : T_RR_pat <M2_cmpysc_s1, int_hexagon_M2_cmpysc_s1>;
// Vector multiply halfwords
// Rdd=vmpyh(Rs,Rt)[:<<1]:sat
def : T_RR_pat <M2_vmpy2s_s0, int_hexagon_M2_vmpy2s_s0>;
def : T_RR_pat <M2_vmpy2s_s1, int_hexagon_M2_vmpy2s_s1>;
// Rxx[+-]= mpy[u](Rs,Rt)
def : T_PRR_pat <M2_dpmpyss_acc_s0, int_hexagon_M2_dpmpyss_acc_s0>;
def : T_PRR_pat <M2_dpmpyss_nac_s0, int_hexagon_M2_dpmpyss_nac_s0>;
def : T_PRR_pat <M2_dpmpyuu_acc_s0, int_hexagon_M2_dpmpyuu_acc_s0>;
def : T_PRR_pat <M2_dpmpyuu_nac_s0, int_hexagon_M2_dpmpyuu_nac_s0>;
// Rxx[-+]=cmpy(Rs,Rt)[:<<1]:sat
def : T_PRR_pat <M2_cmacs_s0, int_hexagon_M2_cmacs_s0>;
def : T_PRR_pat <M2_cnacs_s0, int_hexagon_M2_cnacs_s0>;
def : T_PRR_pat <M2_cmacs_s1, int_hexagon_M2_cmacs_s1>;
def : T_PRR_pat <M2_cnacs_s1, int_hexagon_M2_cnacs_s1>;
// Rxx[-+]=cmpy(Rs,Rt*)[:<<1]:sat
def : T_PRR_pat <M2_cmacsc_s0, int_hexagon_M2_cmacsc_s0>;
def : T_PRR_pat <M2_cnacsc_s0, int_hexagon_M2_cnacsc_s0>;
def : T_PRR_pat <M2_cmacsc_s1, int_hexagon_M2_cmacsc_s1>;
def : T_PRR_pat <M2_cnacsc_s1, int_hexagon_M2_cnacsc_s1>;
// Rxx+=cmpy[ir](Rs,Rt)
def : T_PRR_pat <M2_cmaci_s0, int_hexagon_M2_cmaci_s0>;
def : T_PRR_pat <M2_cmacr_s0, int_hexagon_M2_cmacr_s0>;
// Rxx+=vmpyh(Rs,Rt)[:<<1][:sat]
def : T_PRR_pat <M2_vmac2, int_hexagon_M2_vmac2>;
def : T_PRR_pat <M2_vmac2s_s0, int_hexagon_M2_vmac2s_s0>;
def : T_PRR_pat <M2_vmac2s_s1, int_hexagon_M2_vmac2s_s1>;
//*******************************************************************
// CR
//*******************************************************************
def: T_Q_Q_pat<C2_not, int_hexagon_C2_not>;
def: T_Q_Q_pat<C2_all8, int_hexagon_C2_all8>;
def: T_Q_Q_pat<C2_any8, int_hexagon_C2_any8>;
def: T_Q_Q_pat<C2_pxfer_map, int_hexagon_C2_pxfer_map>;
def: T_Q_QQ_pat<C2_and, int_hexagon_C2_and>;
def: T_Q_QQ_pat<C2_andn, int_hexagon_C2_andn>;
def: T_Q_QQ_pat<C2_or, int_hexagon_C2_or>;
def: T_Q_QQ_pat<C2_orn, int_hexagon_C2_orn>;
def: T_Q_QQ_pat<C2_xor, int_hexagon_C2_xor>;
// Multiply 32x32 and use lower result
def : T_RRI_pat <M2_macsip, int_hexagon_M2_macsip>;
def : T_RRI_pat <M2_macsin, int_hexagon_M2_macsin>;
def : T_RRR_pat <M2_maci, int_hexagon_M2_maci>;
// Subtract and accumulate
def : T_RRR_pat <M2_subacc, int_hexagon_M2_subacc>;
// Add and accumulate
def : T_RRR_pat <M2_acci, int_hexagon_M2_acci>;
def : T_RRR_pat <M2_nacci, int_hexagon_M2_nacci>;
def : T_RRI_pat <M2_accii, int_hexagon_M2_accii>;
def : T_RRI_pat <M2_naccii, int_hexagon_M2_naccii>;
// XOR and XOR with destination
def : T_RRR_pat <M2_xor_xacc, int_hexagon_M2_xor_xacc>;
// Vector dual multiply with round and pack
def : T_PP_pat <M2_vdmpyrs_s0, int_hexagon_M2_vdmpyrs_s0>;
def : T_PP_pat <M2_vdmpyrs_s1, int_hexagon_M2_vdmpyrs_s1>;
// Vector multiply halfwords with round and pack
def : T_RR_pat <M2_vmpy2s_s0pack, int_hexagon_M2_vmpy2s_s0pack>;
def : T_RR_pat <M2_vmpy2s_s1pack, int_hexagon_M2_vmpy2s_s1pack>;
// Multiply and use lower result
def : T_RR_pat <M2_mpyi, int_hexagon_M2_mpyi>;
def : T_RI_pat <M2_mpysmi, int_hexagon_M2_mpysmi>;
// Assembler mapped from Rd32=mpyui(Rs32,Rt32) to Rd32=mpyi(Rs32,Rt32)
def : T_RR_pat <M2_mpyi, int_hexagon_M2_mpyui>;
// Multiply and use upper result
def : T_RR_pat <M2_mpy_up, int_hexagon_M2_mpy_up>;
def : T_RR_pat <M2_mpyu_up, int_hexagon_M2_mpyu_up>;
def : T_RR_pat <M2_hmmpyh_rs1, int_hexagon_M2_hmmpyh_rs1>;
def : T_RR_pat <M2_hmmpyl_rs1, int_hexagon_M2_hmmpyl_rs1>;
def : T_RR_pat <M2_dpmpyss_rnd_s0, int_hexagon_M2_dpmpyss_rnd_s0>;
// Complex multiply with round and pack
// Rxx32+=cmpy(Rs32,[*]Rt32:<<1]:rnd:sat
def : T_RR_pat <M2_cmpyrs_s0, int_hexagon_M2_cmpyrs_s0>;
def : T_RR_pat <M2_cmpyrs_s1, int_hexagon_M2_cmpyrs_s1>;
def : T_RR_pat <M2_cmpyrsc_s0, int_hexagon_M2_cmpyrsc_s0>;
def : T_RR_pat <M2_cmpyrsc_s1, int_hexagon_M2_cmpyrsc_s1>;
//*******************************************************************
// STYPE/ALU
//*******************************************************************
def : T_P_pat <A2_absp, int_hexagon_A2_absp>;
def : T_P_pat <A2_negp, int_hexagon_A2_negp>;
def : T_P_pat <A2_notp, int_hexagon_A2_notp>;
//*******************************************************************
// STYPE/BIT
//*******************************************************************
// Count leading/trailing
def: T_R_pat<S2_cl0, int_hexagon_S2_cl0>;
def: T_P_pat<S2_cl0p, int_hexagon_S2_cl0p>;
def: T_R_pat<S2_cl1, int_hexagon_S2_cl1>;
def: T_P_pat<S2_cl1p, int_hexagon_S2_cl1p>;
def: T_R_pat<S2_clb, int_hexagon_S2_clb>;
def: T_P_pat<S2_clbp, int_hexagon_S2_clbp>;
def: T_R_pat<S2_clbnorm, int_hexagon_S2_clbnorm>;
def: T_R_pat<S2_ct0, int_hexagon_S2_ct0>;
def: T_R_pat<S2_ct1, int_hexagon_S2_ct1>;
// Compare bit mask
def: T_RR_pat<C2_bitsclr, int_hexagon_C2_bitsclr>;
def: T_RI_pat<C2_bitsclri, int_hexagon_C2_bitsclri>;
def: T_RR_pat<C2_bitsset, int_hexagon_C2_bitsset>;
// Vector shuffle
def : T_PP_pat <S2_shuffeb, int_hexagon_S2_shuffeb>;
def : T_PP_pat <S2_shuffob, int_hexagon_S2_shuffob>;
def : T_PP_pat <S2_shuffeh, int_hexagon_S2_shuffeh>;
def : T_PP_pat <S2_shuffoh, int_hexagon_S2_shuffoh>;
// Vector truncate
def : T_PP_pat <S2_vtrunewh, int_hexagon_S2_vtrunewh>;
def : T_PP_pat <S2_vtrunowh, int_hexagon_S2_vtrunowh>;
// Linear feedback-shift Iteration.
def : T_PP_pat <S2_lfsp, int_hexagon_S2_lfsp>;
// Vector align
// Need custom lowering
def : T_PPQ_pat <S2_valignrb, int_hexagon_S2_valignrb>;
def : T_PPI_pat <S2_valignib, int_hexagon_S2_valignib>;
// Vector splice
def : T_PPQ_pat <S2_vsplicerb, int_hexagon_S2_vsplicerb>;
def : T_PPI_pat <S2_vspliceib, int_hexagon_S2_vspliceib>;
// Shift by immediate and add
def : T_RRI_pat<S2_addasl_rrri, int_hexagon_S2_addasl_rrri>;
// Extract bitfield
def : T_PII_pat<S2_extractup, int_hexagon_S2_extractup>;
def : T_RII_pat<S2_extractu, int_hexagon_S2_extractu>;
def : T_RP_pat <S2_extractu_rp, int_hexagon_S2_extractu_rp>;
def : T_PP_pat <S2_extractup_rp, int_hexagon_S2_extractup_rp>;
// Insert bitfield
def : Pat <(int_hexagon_S2_insert_rp I32:$src1, I32:$src2, I64:$src3),
(S2_insert_rp I32:$src1, I32:$src2, I64:$src3)>;
def : Pat<(i64 (int_hexagon_S2_insertp_rp I64:$src1, I64:$src2, I64:$src3)),
(i64 (S2_insertp_rp I64:$src1, I64:$src2, I64:$src3))>;
def : Pat<(int_hexagon_S2_insert I32:$src1, I32:$src2,
u5ImmPred:$src3, u5ImmPred:$src4),
(S2_insert I32:$src1, I32:$src2,
u5ImmPred:$src3, u5ImmPred:$src4)>;
def : Pat<(i64 (int_hexagon_S2_insertp I64:$src1, I64:$src2,
u6ImmPred:$src3, u6ImmPred:$src4)),
(i64 (S2_insertp I64:$src1, I64:$src2,
u6ImmPred:$src3, u6ImmPred:$src4))>;
// Innterleave/deinterleave
def : T_P_pat <S2_interleave, int_hexagon_S2_interleave>;
def : T_P_pat <S2_deinterleave, int_hexagon_S2_deinterleave>;
// Set/Clear/Toggle Bit
def: T_RI_pat<S2_setbit_i, int_hexagon_S2_setbit_i>;
def: T_RI_pat<S2_clrbit_i, int_hexagon_S2_clrbit_i>;
def: T_RI_pat<S2_togglebit_i, int_hexagon_S2_togglebit_i>;
def: T_RR_pat<S2_setbit_r, int_hexagon_S2_setbit_r>;
def: T_RR_pat<S2_clrbit_r, int_hexagon_S2_clrbit_r>;
def: T_RR_pat<S2_togglebit_r, int_hexagon_S2_togglebit_r>;
// Test Bit
def: T_Q_RI_pat<S2_tstbit_i, int_hexagon_S2_tstbit_i>;
def: T_Q_RR_pat<S2_tstbit_r, int_hexagon_S2_tstbit_r>;
//*******************************************************************
// STYPE/COMPLEX
//*******************************************************************
// Vector Complex conjugate
def : T_P_pat <A2_vconj, int_hexagon_A2_vconj>;
// Vector Complex rotate
def : T_PR_pat <S2_vcrotate, int_hexagon_S2_vcrotate>;
//*******************************************************************
// STYPE/PERM
//*******************************************************************
// Vector saturate without pack
def : T_P_pat <S2_vsathb_nopack, int_hexagon_S2_vsathb_nopack>;
def : T_P_pat <S2_vsathub_nopack, int_hexagon_S2_vsathub_nopack>;
def : T_P_pat <S2_vsatwh_nopack, int_hexagon_S2_vsatwh_nopack>;
def : T_P_pat <S2_vsatwuh_nopack, int_hexagon_S2_vsatwuh_nopack>;
//*******************************************************************
// STYPE/PRED
//*******************************************************************
// Predicate transfer
def: Pat<(i32 (int_hexagon_C2_tfrpr I32:$Rs)),
(i32 (C2_tfrpr (C2_tfrrp I32:$Rs)))>;
def: Pat<(i32 (int_hexagon_C2_tfrrp I32:$Rs)),
(i32 (C2_tfrpr (C2_tfrrp I32:$Rs)))>;
// Mask generate from predicate
def: Pat<(i64 (int_hexagon_C2_mask I32:$Rs)),
(i64 (C2_mask (C2_tfrrp I32:$Rs)))>;
// Viterbi pack even and odd predicate bits
def: T_QQ_pat<C2_vitpack, int_hexagon_C2_vitpack>;
//*******************************************************************
// STYPE/SHIFT
//*******************************************************************
def : T_PI_pat <S2_asr_i_p, int_hexagon_S2_asr_i_p>;
def : T_PI_pat <S2_lsr_i_p, int_hexagon_S2_lsr_i_p>;
def : T_PI_pat <S2_asl_i_p, int_hexagon_S2_asl_i_p>;
def : T_PR_pat <S2_asr_r_p, int_hexagon_S2_asr_r_p>;
def : T_PR_pat <S2_lsr_r_p, int_hexagon_S2_lsr_r_p>;
def : T_PR_pat <S2_asl_r_p, int_hexagon_S2_asl_r_p>;
def : T_PR_pat <S2_lsl_r_p, int_hexagon_S2_lsl_r_p>;
def : T_RR_pat <S2_asr_r_r, int_hexagon_S2_asr_r_r>;
def : T_RR_pat <S2_lsr_r_r, int_hexagon_S2_lsr_r_r>;
def : T_RR_pat <S2_asl_r_r, int_hexagon_S2_asl_r_r>;
def : T_RR_pat <S2_lsl_r_r, int_hexagon_S2_lsl_r_r>;
def : T_RR_pat <S2_asr_r_r_sat, int_hexagon_S2_asr_r_r_sat>;
def : T_RR_pat <S2_asl_r_r_sat, int_hexagon_S2_asl_r_r_sat>;
def : T_R_pat <S2_vsxtbh, int_hexagon_S2_vsxtbh>;
def : T_R_pat <S2_vzxtbh, int_hexagon_S2_vzxtbh>;
def : T_R_pat <S2_vsxthw, int_hexagon_S2_vsxthw>;
def : T_R_pat <S2_vzxthw, int_hexagon_S2_vzxthw>;
def : T_R_pat <S2_vsplatrh, int_hexagon_S2_vsplatrh>;
def : T_R_pat <A2_sxtw, int_hexagon_A2_sxtw>;
// Vector saturate and pack
def : T_R_pat <S2_svsathb, int_hexagon_S2_svsathb>;
def : T_R_pat <S2_svsathub, int_hexagon_S2_svsathub>;
def : T_P_pat <S2_vsathub, int_hexagon_S2_vsathub>;
def : T_P_pat <S2_vsatwh, int_hexagon_S2_vsatwh>;
def : T_P_pat <S2_vsatwuh, int_hexagon_S2_vsatwuh>;
def : T_P_pat <S2_vsathb, int_hexagon_S2_vsathb>;
def : T_P_pat <S2_vtrunohb, int_hexagon_S2_vtrunohb>;
def : T_P_pat <S2_vtrunehb, int_hexagon_S2_vtrunehb>;
def : T_P_pat <S2_vrndpackwh, int_hexagon_S2_vrndpackwh>;
def : T_P_pat <S2_vrndpackwhs, int_hexagon_S2_vrndpackwhs>;
def : T_R_pat <S2_brev, int_hexagon_S2_brev>;
def : T_R_pat <S2_vsplatrb, int_hexagon_S2_vsplatrb>;
def : T_R_pat <A2_abs, int_hexagon_A2_abs>;
def : T_R_pat <A2_abssat, int_hexagon_A2_abssat>;
def : T_R_pat <A2_negsat, int_hexagon_A2_negsat>;
def : T_R_pat <A2_swiz, int_hexagon_A2_swiz>;
def : T_P_pat <A2_sat, int_hexagon_A2_sat>;
def : T_R_pat <A2_sath, int_hexagon_A2_sath>;
def : T_R_pat <A2_satuh, int_hexagon_A2_satuh>;
def : T_R_pat <A2_satub, int_hexagon_A2_satub>;
def : T_R_pat <A2_satb, int_hexagon_A2_satb>;
// Vector arithmetic shift right by immediate with truncate and pack.
def : T_PI_pat<S2_asr_i_svw_trun, int_hexagon_S2_asr_i_svw_trun>;
def : T_RI_pat <S2_asr_i_r, int_hexagon_S2_asr_i_r>;
def : T_RI_pat <S2_lsr_i_r, int_hexagon_S2_lsr_i_r>;
def : T_RI_pat <S2_asl_i_r, int_hexagon_S2_asl_i_r>;
def : T_RI_pat <S2_asr_i_r_rnd, int_hexagon_S2_asr_i_r_rnd>;
def : T_RI_pat <S2_asr_i_r_rnd_goodsyntax,
int_hexagon_S2_asr_i_r_rnd_goodsyntax>;
// Shift left by immediate with saturation.
def : T_RI_pat <S2_asl_i_r_sat, int_hexagon_S2_asl_i_r_sat>;
//===----------------------------------------------------------------------===//
// Template 'def pat' to map tableidx[bhwd] intrinsics to :raw instructions.
//===----------------------------------------------------------------------===//
class S2op_tableidx_pat <Intrinsic IntID, InstHexagon OutputInst,
SDNodeXForm XformImm>
: Pat <(IntID I32:$src1, I32:$src2, u4ImmPred:$src3, u5ImmPred:$src4),
(OutputInst I32:$src1, I32:$src2, u4ImmPred:$src3,
(XformImm u5ImmPred:$src4))>;
// Table Index : Extract and insert bits.
// Map to the real hardware instructions after subtracting appropriate
// values from the 4th input operand. Please note that subtraction is not
// needed for int_hexagon_S2_tableidxb_goodsyntax.
def : Pat <(int_hexagon_S2_tableidxb_goodsyntax I32:$src1, I32:$src2,
u4ImmPred:$src3, u5ImmPred:$src4),
(S2_tableidxb I32:$src1, I32:$src2,
u4ImmPred:$src3, u5ImmPred:$src4)>;
def : S2op_tableidx_pat <int_hexagon_S2_tableidxh_goodsyntax, S2_tableidxh,
DEC_CONST_SIGNED>;
def : S2op_tableidx_pat <int_hexagon_S2_tableidxw_goodsyntax, S2_tableidxw,
DEC2_CONST_SIGNED>;
def : S2op_tableidx_pat <int_hexagon_S2_tableidxd_goodsyntax, S2_tableidxd,
DEC3_CONST_SIGNED>;
//*******************************************************************
// STYPE/VH
//*******************************************************************
// Vector absolute value halfwords with and without saturation
// Rdd64=vabsh(Rss64)[:sat]
def : T_P_pat <A2_vabsh, int_hexagon_A2_vabsh>;
def : T_P_pat <A2_vabshsat, int_hexagon_A2_vabshsat>;
// Vector shift halfwords by immediate
// Rdd64=[vaslh/vasrh/vlsrh](Rss64,u4)
def : T_PI_pat <S2_asr_i_vh, int_hexagon_S2_asr_i_vh>;
def : T_PI_pat <S2_lsr_i_vh, int_hexagon_S2_lsr_i_vh>;
def : T_PI_pat <S2_asl_i_vh, int_hexagon_S2_asl_i_vh>;
// Vector shift halfwords by register
// Rdd64=[vaslw/vasrw/vlslw/vlsrw](Rss64,Rt32)
def : T_PR_pat <S2_asr_r_vh, int_hexagon_S2_asr_r_vh>;
def : T_PR_pat <S2_lsr_r_vh, int_hexagon_S2_lsr_r_vh>;
def : T_PR_pat <S2_asl_r_vh, int_hexagon_S2_asl_r_vh>;
def : T_PR_pat <S2_lsl_r_vh, int_hexagon_S2_lsl_r_vh>;
//*******************************************************************
// STYPE/VW
//*******************************************************************
// Vector absolute value words with and without saturation
def : T_P_pat <A2_vabsw, int_hexagon_A2_vabsw>;
def : T_P_pat <A2_vabswsat, int_hexagon_A2_vabswsat>;
// Vector shift words by immediate.
// Rdd64=[vasrw/vlsrw|vaslw](Rss64,u5)
def : T_PI_pat <S2_asr_i_vw, int_hexagon_S2_asr_i_vw>;
def : T_PI_pat <S2_lsr_i_vw, int_hexagon_S2_lsr_i_vw>;
def : T_PI_pat <S2_asl_i_vw, int_hexagon_S2_asl_i_vw>;
// Vector shift words by register.
// Rdd64=[vasrw/vlsrw|vaslw|vlslw](Rss64,Rt32)
def : T_PR_pat <S2_asr_r_vw, int_hexagon_S2_asr_r_vw>;
def : T_PR_pat <S2_lsr_r_vw, int_hexagon_S2_lsr_r_vw>;
def : T_PR_pat <S2_asl_r_vw, int_hexagon_S2_asl_r_vw>;
def : T_PR_pat <S2_lsl_r_vw, int_hexagon_S2_lsl_r_vw>;
// Vector shift words with truncate and pack
def : T_PR_pat <S2_asr_r_svw_trun, int_hexagon_S2_asr_r_svw_trun>;
// Load/store locked.
def : T_R_pat<L2_loadw_locked, int_hexagon_L2_loadw_locked>;
def : T_R_pat<L4_loadd_locked, int_hexagon_L4_loadd_locked>;
def : Pat<(int_hexagon_S2_storew_locked I32:$Rs, I32:$Rt),
(C2_tfrpr (S2_storew_locked I32:$Rs, I32:$Rt))>;
def : Pat<(int_hexagon_S4_stored_locked I32:$Rs, I64:$Rt),
(C2_tfrpr (S4_stored_locked I32:$Rs, I64:$Rt))>;
//*******************************************************************
// ST
//*******************************************************************
class T_stb_pat <InstHexagon MI, Intrinsic IntID, PatLeaf Val>
: Pat<(IntID I32:$Rs, Val:$Rt, I32:$Ru),
(MI I32:$Rs, I32:$Ru, Val:$Rt)>;
def : T_stb_pat <S2_storerh_pbr, int_hexagon_brev_sth, I32>;
def : T_stb_pat <S2_storerb_pbr, int_hexagon_brev_stb, I32>;
def : T_stb_pat <S2_storeri_pbr, int_hexagon_brev_stw, I32>;
def : T_stb_pat <S2_storerf_pbr, int_hexagon_brev_sthhi, I32>;
def : T_stb_pat <S2_storerd_pbr, int_hexagon_brev_std, I64>;
class T_stc_pat <InstHexagon MI, Intrinsic IntID, PatLeaf Imm, PatLeaf Val>
: Pat<(IntID I32:$Rs, Val:$Rt, I32:$Ru, Imm:$s),
(MI I32:$Rs, Imm:$s, I32:$Ru, Val:$Rt)>;
def: T_stc_pat<S2_storerb_pci, int_hexagon_circ_stb, s4_0ImmPred, I32>;
def: T_stc_pat<S2_storerh_pci, int_hexagon_circ_sth, s4_1ImmPred, I32>;
def: T_stc_pat<S2_storeri_pci, int_hexagon_circ_stw, s4_2ImmPred, I32>;
def: T_stc_pat<S2_storerd_pci, int_hexagon_circ_std, s4_3ImmPred, I64>;
def: T_stc_pat<S2_storerf_pci, int_hexagon_circ_sthhi, s4_1ImmPred, I32>;
include "HexagonIntrinsicsV3.td"
include "HexagonIntrinsicsV4.td"
include "HexagonIntrinsicsV5.td"
include "HexagonIntrinsicsV60.td"