brintos

brintos / llvm-project-archived public Read only

0
0
Text · 153.1 KiB · e84070f Raw
3466 lines · plain
1//===- HexagonPatterns.td - Selection Patterns for Hexagon -*- tablegen -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// Table of contents:10//     (0) Definitions11//     (1) Immediates12//     (2) Type casts13//     (3) Extend/truncate/saturate14//     (4) Logical15//     (5) Compare16//     (6) Select17//     (7) Insert/extract18//     (8) Shift/permute19//     (9) Arithmetic/bitwise20//    (10) Bit21//    (11) PIC22//    (12) Load23//    (13) Store24//    (14) Memop25//    (15) Call26//    (16) Branch27//    (17) Misc28 29// Guidelines (in no particular order):30// 1. Avoid relying on pattern ordering to give preference to one pattern31//    over another, prefer using AddedComplexity instead. The reason for32//    this is to avoid unintended conseqeuences (caused by altering the33//    order) when making changes. The current order of patterns in this34//    file obviously does play some role, but none of the ordering was35//    deliberately chosen (other than to create a logical structure of36//    this file). When making changes, adding AddedComplexity to existing37//    patterns may be needed.38// 2. Maintain the logical structure of the file, try to put new patterns39//    in designated sections.40// 3. Do not use A2_combinew instruction directly, use Combinew fragment41//    instead. It uses REG_SEQUENCE, which is more amenable to optimizations.42// 4. Most selection macros are based on PatFrags. For DAGs that involve43//    SDNodes, use pf1/pf2 to convert them to PatFrags. Use common frags44//    whenever possible (see the Definitions section). When adding new45//    macro, try to make is general to enable reuse across sections.46// 5. Compound instructions (e.g. Rx+Rs*Rt) are generated under the condition47//    that the nested operation has only one use. Having it separated in case48//    of multiple uses avoids duplication of (processor) work.49// 6. The v4 vector instructions (64-bit) are treated as core instructions,50//    for example, A2_vaddh is in the "arithmetic" section with A2_add.51// 7. When adding a pattern for an instruction with a constant-extendable52//    operand, allow all possible kinds of inputs for the immediate value53//    (see AnyImm/anyimm and their variants in the Definitions section).54 55 56// --(0) Definitions -----------------------------------------------------57//58 59// This complex pattern exists only to create a machine instruction operand60// of type "frame index". There doesn't seem to be a way to do that directly61// in the patterns.62def AddrFI: ComplexPattern<i32, 1, "SelectAddrFI", [frameindex], []>;63 64// These complex patterns are not strictly necessary, since global address65// folding will happen during DAG combining. For distinguishing between GA66// and GP, pat frags with HexagonCONST32 and HexagonCONST32_GP can be used.67def AddrGA: ComplexPattern<i32, 1, "SelectAddrGA", [], []>;68def AddrGP: ComplexPattern<i32, 1, "SelectAddrGP", [], []>;69def AnyImm: ComplexPattern<i32, 1, "SelectAnyImm", [], []>;70def AnyInt: ComplexPattern<i32, 1, "SelectAnyInt", [], []>;71 72// Global address or a constant being a multiple of 2^n.73def AnyImm0: ComplexPattern<i32, 1, "SelectAnyImm0", [], []>;74def AnyImm1: ComplexPattern<i32, 1, "SelectAnyImm1", [], []>;75def AnyImm2: ComplexPattern<i32, 1, "SelectAnyImm2", [], []>;76def AnyImm3: ComplexPattern<i32, 1, "SelectAnyImm3", [], []>;77 78 79// Type helper frags.80def V2I1:   PatLeaf<(v2i1    PredRegs:$R)>;81def V4I1:   PatLeaf<(v4i1    PredRegs:$R)>;82def V8I1:   PatLeaf<(v8i1    PredRegs:$R)>;83def V4I8:   PatLeaf<(v4i8    IntRegs:$R)>;84def V2I16:  PatLeaf<(v2i16   IntRegs:$R)>;85 86def V8I8:   PatLeaf<(v8i8    DoubleRegs:$R)>;87def V4I16:  PatLeaf<(v4i16   DoubleRegs:$R)>;88def V2I32:  PatLeaf<(v2i32   DoubleRegs:$R)>;89 90def SDTVecLeaf:91  SDTypeProfile<1, 0, [SDTCisVec<0>]>;92def SDTVecVecIntOp:93  SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<1,2>,94                       SDTCisVT<3,i32>]>;95 96def HexagonPTRUE:      SDNode<"HexagonISD::PTRUE",      SDTVecLeaf>;97def HexagonPFALSE:     SDNode<"HexagonISD::PFALSE",     SDTVecLeaf>;98def HexagonVALIGN:     SDNode<"HexagonISD::VALIGN",     SDTVecVecIntOp>;99def HexagonVALIGNADDR: SDNode<"HexagonISD::VALIGNADDR", SDTIntUnaryOp>;100def HexagonMULHUS:     SDNode<"HexagonISD::MULHUS",     SDTIntBinOp>;101 102def SDTSaturate:103  SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>, SDTCisVT<2, OtherVT>]>;104def HexagonSSAT: SDNode<"HexagonISD::SSAT", SDTSaturate>;105def HexagonUSAT: SDNode<"HexagonISD::USAT", SDTSaturate>;106 107def ptrue:  PatFrag<(ops), (HexagonPTRUE)>;108def pfalse: PatFrag<(ops), (HexagonPFALSE)>;109def pnot:   PatFrag<(ops node:$Pu), (xor node:$Pu, ptrue)>;110 111def: Pat<(v8i1 (HexagonPFALSE)), (C2_tfrrp (A2_tfrsi (i32 0)))>;112def: Pat<(v4i1 (HexagonPFALSE)), (C2_tfrrp (A2_tfrsi (i32 0)))>;113def: Pat<(v2i1 (HexagonPFALSE)), (C2_tfrrp (A2_tfrsi (i32 0)))>;114 115def: Pat<(v8i1 (HexagonPTRUE)), (C2_tfrrp (A2_tfrsi (i32 -1)))>;116def: Pat<(v4i1 (HexagonPTRUE)), (C2_tfrrp (A2_tfrsi (i32 -1)))>;117def: Pat<(v2i1 (HexagonPTRUE)), (C2_tfrrp (A2_tfrsi (i32 -1)))>;118 119def valign: PatFrag<(ops node:$Vt, node:$Vs, node:$Ru),120                    (HexagonVALIGN node:$Vt, node:$Vs, node:$Ru)>;121def valignaddr: PatFrag<(ops node:$Addr), (HexagonVALIGNADDR node:$Addr)>;122 123def ssat: PatFrag<(ops node:$V, node:$Ty), (HexagonSSAT node:$V, node:$Ty)>;124def usat: PatFrag<(ops node:$V, node:$Ty), (HexagonUSAT node:$V, node:$Ty)>;125 126// Pattern fragments to extract the low and high subregisters from a127// 64-bit value.128def LoReg: OutPatFrag<(ops node:$Rs), (EXTRACT_SUBREG $Rs, isub_lo)>;129def HiReg: OutPatFrag<(ops node:$Rs), (EXTRACT_SUBREG $Rs, isub_hi)>;130 131def IsOrAdd: PatFrag<(ops node:$A, node:$B), (or node:$A, node:$B), [{132  return isOrEquivalentToAdd(N);133}]>;134 135def IsPow2_32: PatLeaf<(i32 imm), [{136  uint32_t V = N->getZExtValue();137  return isPowerOf2_32(V);138}]>;139 140def IsPow2_64: PatLeaf<(i64 imm), [{141  uint64_t V = N->getZExtValue();142  return isPowerOf2_64(V);143}]>;144 145def IsNPow2_32: PatLeaf<(i32 imm), [{146  uint32_t NV = ~N->getZExtValue();147  return isPowerOf2_32(NV);148}]>;149 150def IsPow2_64L: PatLeaf<(i64 imm), [{151  uint64_t V = N->getZExtValue();152  return isPowerOf2_64(V) && Log2_64(V) < 32;153}]>;154 155def IsPow2_64H: PatLeaf<(i64 imm), [{156  uint64_t V = N->getZExtValue();157  return isPowerOf2_64(V) && Log2_64(V) >= 32;158}]>;159 160def IsNPow2_64L: PatLeaf<(i64 imm), [{161  uint64_t NV = ~N->getZExtValue();162  return isPowerOf2_64(NV) && Log2_64(NV) < 32;163}]>;164 165def IsNPow2_64H: PatLeaf<(i64 imm), [{166  uint64_t NV = ~N->getZExtValue();167  return isPowerOf2_64(NV) && Log2_64(NV) >= 32;168}]>;169 170class IsULE<int Width, int Arg>: PatLeaf<(i32 imm),171  "uint64_t V = N->getZExtValue();" #172  "return isUInt<" # Width # ">(V) && V <= " # Arg # ";"173>;174 175class IsUGT<int Width, int Arg>: PatLeaf<(i32 imm),176  "uint64_t V = N->getZExtValue();" #177  "return isUInt<" # Width # ">(V) && V > " # Arg # ";"178>;179 180def SDEC1: SDNodeXForm<imm, [{181  int32_t V = N->getSExtValue();182  return CurDAG->getSignedTargetConstant(V-1, SDLoc(N), MVT::i32);183}]>;184 185def UDEC1: SDNodeXForm<imm, [{186  uint32_t V = N->getZExtValue();187  assert(V >= 1);188  return CurDAG->getTargetConstant(V-1, SDLoc(N), MVT::i32);189}]>;190 191def UDEC32: SDNodeXForm<imm, [{192  uint32_t V = N->getZExtValue();193  assert(V >= 32);194  return CurDAG->getTargetConstant(V-32, SDLoc(N), MVT::i32);195}]>;196 197class Subi<int From>: SDNodeXForm<imm,198  "int32_t V = " # From # " - N->getSExtValue();" #199  "return CurDAG->getTargetConstant(V, SDLoc(N), MVT::i32);"200>;201 202def Log2_32: SDNodeXForm<imm, [{203  uint32_t V = N->getZExtValue();204  return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32);205}]>;206 207def Log2_64: SDNodeXForm<imm, [{208  uint64_t V = N->getZExtValue();209  return CurDAG->getTargetConstant(Log2_64(V), SDLoc(N), MVT::i32);210}]>;211 212def LogN2_32: SDNodeXForm<imm, [{213  uint32_t NV = ~N->getZExtValue();214  return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32);215}]>;216 217def LogN2_64: SDNodeXForm<imm, [{218  uint64_t NV = ~N->getZExtValue();219  return CurDAG->getTargetConstant(Log2_64(NV), SDLoc(N), MVT::i32);220}]>;221 222def NegImm8: SDNodeXForm<imm, [{223  int8_t NV = -N->getSExtValue();224  return CurDAG->getTargetConstant(NV, SDLoc(N), MVT::i32);225}]>;226 227def NegImm16: SDNodeXForm<imm, [{228  int16_t NV = -N->getSExtValue();229  return CurDAG->getTargetConstant(NV, SDLoc(N), MVT::i32);230}]>;231 232def NegImm32: SDNodeXForm<imm, [{233  int32_t NV = -N->getSExtValue();234  return CurDAG->getTargetConstant(NV, SDLoc(N), MVT::i32);235}]>;236 237def SplatB: SDNodeXForm<imm, [{238  uint32_t V = N->getZExtValue();239  assert(isUInt<8>(V) || V >> 8 == 0xFFFFFF);240  V &= 0xFF;241  uint32_t S = V << 24 | V << 16 | V << 8 | V;242  return CurDAG->getTargetConstant(S, SDLoc(N), MVT::i32);243}]>;244 245def SplatH: SDNodeXForm<imm, [{246  uint32_t V = N->getZExtValue();247  assert(isUInt<16>(V) || V >> 16 == 0xFFFF);248  V &= 0xFFFF;249  return CurDAG->getTargetConstant(V << 16 | V, SDLoc(N), MVT::i32);250}]>;251 252 253// Helpers for type promotions/contractions.254def I1toI32:  OutPatFrag<(ops node:$Rs), (C2_muxii (i1 $Rs), 1, 0)>;255def I32toI1:  OutPatFrag<(ops node:$Rs), (i1 (C2_cmpgtui (i32 $Rs), (i32 0)))>;256def ToZext64: OutPatFrag<(ops node:$Rs), (i64 (A4_combineir 0, (i32 $Rs)))>;257def ToSext64: OutPatFrag<(ops node:$Rs), (i64 (A2_sxtw (i32 $Rs)))>;258def ToAext64: OutPatFrag<(ops node:$Rs),259  (REG_SEQUENCE DoubleRegs, (i32 (IMPLICIT_DEF)), isub_hi, (i32 $Rs), isub_lo)>;260 261def Combinew: OutPatFrag<(ops node:$Rs, node:$Rt),262  (REG_SEQUENCE DoubleRegs, $Rs, isub_hi, $Rt, isub_lo)>;263 264def addrga: PatLeaf<(i32 AddrGA:$Addr)>;265def addrgp: PatLeaf<(i32 AddrGP:$Addr)>;266def anyimm: PatLeaf<(i32 AnyImm:$Imm)>;267def anyint: PatLeaf<(i32 AnyInt:$Imm)>;268 269// Global address or an aligned constant.270def anyimm0: PatLeaf<(i32 AnyImm0:$Addr)>;271def anyimm1: PatLeaf<(i32 AnyImm1:$Addr)>;272def anyimm2: PatLeaf<(i32 AnyImm2:$Addr)>;273def anyimm3: PatLeaf<(i32 AnyImm3:$Addr)>;274 275def f32ImmPred : PatLeaf<(f32 fpimm:$F)>;276def f64ImmPred : PatLeaf<(f64 fpimm:$F)>;277def f32zero: PatLeaf<(f32 fpimm:$F), [{278  return N->isExactlyValue(APFloat::getZero(APFloat::IEEEsingle(), false));279}]>;280 281// This complex pattern is really only to detect various forms of282// sign-extension i32->i64. The selected value will be of type i64283// whose low word is the value being extended. The high word is284// unspecified.285def Usxtw:  ComplexPattern<i64, 1, "DetectUseSxtw", [], []>;286 287def Aext64: PatFrag<(ops node:$Rs), (i64 (anyext node:$Rs))>;288def Zext64: PatFrag<(ops node:$Rs), (i64 (zext node:$Rs))>;289def Sext64: PatLeaf<(i64 Usxtw:$Rs)>;290 291def azext: PatFrags<(ops node:$Rs), [(zext node:$Rs), (anyext node:$Rs)]>;292def asext: PatFrags<(ops node:$Rs), [(sext node:$Rs), (anyext node:$Rs)]>;293 294def: Pat<(IsOrAdd (i32 AddrFI:$Rs), s32_0ImmPred:$off),295         (PS_fi (i32 AddrFI:$Rs), imm:$off)>;296 297 298// Converters from unary/binary SDNode to PatFrag.299class pf1<SDNode Op> : PatFrag<(ops node:$a), (Op node:$a)>;300class pf2<SDNode Op> : PatFrag<(ops node:$a, node:$b), (Op node:$a, node:$b)>;301 302class Not2<PatFrag P>303  : PatFrag<(ops node:$A, node:$B), (P node:$A, (not node:$B))>;304class VNot2<PatFrag P, PatFrag Not>305  : PatFrag<(ops node:$A, node:$B), (P node:$A, (Not node:$B))>;306 307// If there is a constant operand that feeds the and/or instruction,308// do not generate the compound instructions.309// It is not always profitable, as some times we end up with a transfer.310// Check the below example.311// ra = #65820; rb = lsr(rb, #8); rc ^= and (rb, ra)312// Instead this is preferable.313// ra = and (#65820, lsr(ra, #8)); rb = xor(rb, ra)314class Su_ni1<PatFrag Op>315  : PatFrag<Op.Operands, !head(Op.Fragments), [{316            if (hasOneUse(N)){317              // Check if Op1 is an immediate operand.318              SDValue Op1 = N->getOperand(1);319              return !isa<ConstantSDNode>(Op1);320            }321            return false;}],322            Op.OperandTransform>;323 324class Su<PatFrag Op>325  : PatFrag<Op.Operands, !head(Op.Fragments), [{ return hasOneUse(N); }],326            Op.OperandTransform>;327 328// Main selection macros.329 330class OpR_R_pat<InstHexagon MI, PatFrag Op, ValueType ResVT, PatFrag RegPred>331  : Pat<(ResVT (Op RegPred:$Rs)), (MI RegPred:$Rs)>;332 333class OpR_RI_pat<InstHexagon MI, PatFrag Op, ValueType ResType,334                 PatFrag RegPred, PatFrag ImmPred>335  : Pat<(ResType (Op RegPred:$Rs, ImmPred:$I)),336        (MI RegPred:$Rs, imm:$I)>;337 338class OpR_RR_pat<InstHexagon MI, PatFrag Op, ValueType ResType,339                 PatFrag RsPred, PatFrag RtPred = RsPred>340  : Pat<(ResType (Op RsPred:$Rs, RtPred:$Rt)),341        (MI RsPred:$Rs, RtPred:$Rt)>;342 343class AccRRI_pat<InstHexagon MI, PatFrag AccOp, PatFrag Op,344                 PatFrag RegPred, PatFrag ImmPred>345  : Pat<(AccOp RegPred:$Rx, (Op RegPred:$Rs, ImmPred:$I)),346        (MI RegPred:$Rx, RegPred:$Rs, imm:$I)>;347 348class AccRRR_pat<InstHexagon MI, PatFrag AccOp, PatFrag Op,349                 PatFrag RxPred, PatFrag RsPred, PatFrag RtPred>350  : Pat<(AccOp RxPred:$Rx, (Op RsPred:$Rs, RtPred:$Rt)),351        (MI RxPred:$Rx, RsPred:$Rs, RtPred:$Rt)>;352 353multiclass SelMinMax_pats<PatFrag CmpOp, PatFrag Val,354                          InstHexagon InstA, InstHexagon InstB> {355  def: Pat<(select (i1 (CmpOp Val:$A, Val:$B)), Val:$A, Val:$B),356           (InstA Val:$A, Val:$B)>;357  def: Pat<(select (i1 (CmpOp Val:$A, Val:$B)), Val:$B, Val:$A),358           (InstB Val:$A, Val:$B)>;359}360 361multiclass MinMax_pats<InstHexagon PickT, InstHexagon PickS,362                       SDPatternOperator Sel, SDPatternOperator CmpOp,363                       ValueType CmpType, PatFrag CmpPred> {364  def: Pat<(Sel (CmpType (CmpOp CmpPred:$Vs, CmpPred:$Vt)),365                CmpPred:$Vt, CmpPred:$Vs),366           (PickT CmpPred:$Vs, CmpPred:$Vt)>;367  def: Pat<(Sel (CmpType (CmpOp CmpPred:$Vs, CmpPred:$Vt)),368                CmpPred:$Vs, CmpPred:$Vt),369           (PickS CmpPred:$Vs, CmpPred:$Vt)>;370}371 372// Bitcasts between same-size vector types are no-ops, except for the373// actual type change.374multiclass NopCast_pat<ValueType Ty1, ValueType Ty2, RegisterClass RC> {375  def: Pat<(Ty1 (bitconvert (Ty2 RC:$Val))), (Ty1 RC:$Val)>;376  def: Pat<(Ty2 (bitconvert (Ty1 RC:$Val))), (Ty2 RC:$Val)>;377}378 379// Frags for commonly used SDNodes.380def Add: pf2<add>;    def And: pf2<and>;    def Sra: pf2<sra>;381def Sub: pf2<sub>;    def Or:  pf2<or>;     def Srl: pf2<srl>;382def Mul: pf2<mul>;    def Xor: pf2<xor>;    def Shl: pf2<shl>;383 384def Smin: pf2<smin>;  def Smax: pf2<smax>;385def Umin: pf2<umin>;  def Umax: pf2<umax>;386 387def Rol: pf2<rotl>;388 389def Fptosi: pf1<fp_to_sint>;390def Fptoui: pf1<fp_to_uint>;391def Sitofp: pf1<sint_to_fp>;392def Uitofp: pf1<uint_to_fp>;393 394// --(1) Immediate -------------------------------------------------------395//396 397def Imm64Lo: SDNodeXForm<imm, [{398  return CurDAG->getSignedTargetConstant(int32_t(N->getSExtValue()),399                                         SDLoc(N), MVT::i32);400}]>;401def Imm64Hi: SDNodeXForm<imm, [{402  return CurDAG->getSignedTargetConstant(int32_t(N->getSExtValue()>>32),403                                         SDLoc(N), MVT::i32);404}]>;405 406 407def SDTHexagonCONST32408  : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisPtrTy<0>]>;409 410def HexagonJT:          SDNode<"HexagonISD::JT",          SDTIntUnaryOp>;411def HexagonCP:          SDNode<"HexagonISD::CP",          SDTIntUnaryOp>;412def HexagonCONST32:     SDNode<"HexagonISD::CONST32",     SDTHexagonCONST32>;413def HexagonCONST32_GP:  SDNode<"HexagonISD::CONST32_GP",  SDTHexagonCONST32>;414 415def TruncI64ToI32: SDNodeXForm<imm, [{416  return CurDAG->getSignedTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32);417}]>;418 419def: Pat<(s32_0ImmPred:$s16), (A2_tfrsi imm:$s16)>;420def: Pat<(s8_0Imm64Pred:$s8), (A2_tfrpi (TruncI64ToI32 $s8))>;421 422def: Pat<(HexagonCONST32    tglobaltlsaddr:$A), (A2_tfrsi imm:$A)>;423def: Pat<(HexagonCONST32    bbl:$A),            (A2_tfrsi imm:$A)>;424def: Pat<(HexagonCONST32    tglobaladdr:$A),    (A2_tfrsi imm:$A)>;425def: Pat<(HexagonCONST32_GP tblockaddress:$A),  (A2_tfrsi imm:$A)>;426def: Pat<(HexagonCONST32_GP tglobaladdr:$A),    (A2_tfrsi imm:$A)>;427def: Pat<(HexagonJT         tjumptable:$A),     (A2_tfrsi imm:$A)>;428def: Pat<(HexagonCP         tconstpool:$A),     (A2_tfrsi imm:$A)>;429// The HVX load patterns also match CP directly. Make sure that if430// the selection of this opcode changes, it's updated in all places.431 432def: Pat<(i1 0),        (PS_false)>;433def: Pat<(i1 1),        (PS_true)>;434def: Pat<(i64 imm:$v),  (CONST64 imm:$v)>,435     Requires<[UseSmallData,NotOptTinyCore]>;436def: Pat<(i64 imm:$v),437         (Combinew (A2_tfrsi (Imm64Hi $v)), (A2_tfrsi (Imm64Lo $v)))>;438 439def ftoi : SDNodeXForm<fpimm, [{440  APInt I = N->getValueAPF().bitcastToAPInt();441  return CurDAG->getTargetConstant(I.getZExtValue(), SDLoc(N),442                                   MVT::getIntegerVT(I.getBitWidth()));443}]>;444 445def: Pat<(f32ImmPred:$f), (A2_tfrsi (ftoi $f))>;446def: Pat<(f64ImmPred:$f), (CONST64  (ftoi $f))>;447 448def ToI32: OutPatFrag<(ops node:$V), (A2_tfrsi $V)>;449 450// --(2) Type cast -------------------------------------------------------451//452 453def: OpR_R_pat<F2_conv_sf2df,      pf1<fpextend>,   f64, F32>;454def: OpR_R_pat<F2_conv_df2sf,      pf1<fpround>,    f32, F64>;455 456def: OpR_R_pat<F2_conv_w2sf,       pf1<sint_to_fp>, f32, I32>;457def: OpR_R_pat<F2_conv_d2sf,       pf1<sint_to_fp>, f32, I64>;458def: OpR_R_pat<F2_conv_w2df,       pf1<sint_to_fp>, f64, I32>;459def: OpR_R_pat<F2_conv_d2df,       pf1<sint_to_fp>, f64, I64>;460 461def: OpR_R_pat<F2_conv_uw2sf,      pf1<uint_to_fp>, f32, I32>;462def: OpR_R_pat<F2_conv_ud2sf,      pf1<uint_to_fp>, f32, I64>;463def: OpR_R_pat<F2_conv_uw2df,      pf1<uint_to_fp>, f64, I32>;464def: OpR_R_pat<F2_conv_ud2df,      pf1<uint_to_fp>, f64, I64>;465 466def: OpR_R_pat<F2_conv_sf2w_chop,  pf1<fp_to_sint>, i32, F32>;467def: OpR_R_pat<F2_conv_df2w_chop,  pf1<fp_to_sint>, i32, F64>;468def: OpR_R_pat<F2_conv_sf2d_chop,  pf1<fp_to_sint>, i64, F32>;469def: OpR_R_pat<F2_conv_df2d_chop,  pf1<fp_to_sint>, i64, F64>;470 471def: OpR_R_pat<F2_conv_sf2uw_chop, pf1<fp_to_uint>, i32, F32>;472def: OpR_R_pat<F2_conv_df2uw_chop, pf1<fp_to_uint>, i32, F64>;473def: OpR_R_pat<F2_conv_sf2ud_chop, pf1<fp_to_uint>, i64, F32>;474def: OpR_R_pat<F2_conv_df2ud_chop, pf1<fp_to_uint>, i64, F64>;475 476def: Pat<(i32 (fp_to_bf16 F32:$v)),477         (C2_mux (F2_sfclass F32:$v, 0x10), (A2_tfrsi(i32 0x7fff)),478           (C2_mux479             (C2_cmpeq480               (A2_and F32:$v, (A2_tfrsi (i32 0x1FFFF))),481               (A2_tfrsi (i32 0x08000))),482             (A2_and (A2_asrh F32:$v), (A2_tfrsi (i32 65535))),483             (A2_and484               (A2_asrh485                 (A2_add F32:$v, (A2_and F32:$v, (A2_tfrsi (i32 0x8000))))),486                 (A2_tfrsi (i32 65535))))487         )>;488// Bitcast is different than [fp|sint|uint]_to_[sint|uint|fp].489def: Pat<(i32 (bitconvert F32:$v)), (I32:$v)>;490def: Pat<(f32 (bitconvert I32:$v)), (F32:$v)>;491def: Pat<(i64 (bitconvert F64:$v)), (I64:$v)>;492def: Pat<(f64 (bitconvert I64:$v)), (F64:$v)>;493 494// Bit convert 32- and 64-bit types.495// All of these are bitcastable to one another: i32, v2i16, v4i8.496defm: NopCast_pat<i32,   v2i16, IntRegs>;497defm: NopCast_pat<i32,    v4i8, IntRegs>;498defm: NopCast_pat<v2i16,  v4i8, IntRegs>;499// All of these are bitcastable to one another: i64, v2i32, v4i16, v8i8.500defm: NopCast_pat<i64,   v2i32, DoubleRegs>;501defm: NopCast_pat<i64,   v4i16, DoubleRegs>;502defm: NopCast_pat<i64,    v8i8, DoubleRegs>;503defm: NopCast_pat<v2i32, v4i16, DoubleRegs>;504defm: NopCast_pat<v2i32,  v8i8, DoubleRegs>;505defm: NopCast_pat<v4i16,  v8i8, DoubleRegs>;506 507 508// --(3) Extend/truncate/saturate ----------------------------------------509//510 511def: Pat<(sext_inreg I32:$Rs, i8),  (A2_sxtb I32:$Rs)>;512def: Pat<(sext_inreg I32:$Rs, i16), (A2_sxth I32:$Rs)>;513def: Pat<(sext_inreg I64:$Rs, i32), (A2_sxtw (LoReg $Rs))>;514def: Pat<(sext_inreg I64:$Rs, i16), (A2_sxtw (A2_sxth (LoReg $Rs)))>;515def: Pat<(sext_inreg I64:$Rs, i8),  (A2_sxtw (A2_sxtb (LoReg $Rs)))>;516 517def: Pat<(i64 (sext I32:$Rs)), (A2_sxtw I32:$Rs)>;518def: Pat<(Zext64 I32:$Rs),     (ToZext64 $Rs)>;519def: Pat<(Aext64 I32:$Rs),     (ToZext64 $Rs)>;520 521def: Pat<(i32 (trunc I64:$Rs)), (LoReg $Rs)>;522def: Pat<(i1 (trunc I32:$Rs)),  (S2_tstbit_i I32:$Rs, 0)>;523def: Pat<(i1 (trunc I64:$Rs)),  (S2_tstbit_i (LoReg $Rs), 0)>;524 525let AddedComplexity = 20 in {526  def: Pat<(and I32:$Rs, 255),   (A2_zxtb I32:$Rs)>;527  def: Pat<(and I32:$Rs, 65535), (A2_zxth I32:$Rs)>;528}529 530// Extensions from i1 or vectors of i1.531def: Pat<(i32 (azext I1:$Pu)), (C2_muxii I1:$Pu, 1, 0)>;532def: Pat<(i64 (azext I1:$Pu)), (ToZext64 (C2_muxii I1:$Pu, 1, 0))>;533def: Pat<(i32  (sext I1:$Pu)), (C2_muxii I1:$Pu, -1, 0)>;534def: Pat<(i64  (sext I1:$Pu)), (Combinew (C2_muxii PredRegs:$Pu, -1, 0),535                                         (C2_muxii PredRegs:$Pu, -1, 0))>;536 537def: Pat<(v2i16 (sext V2I1:$Pu)), (S2_vtrunehb (C2_mask V2I1:$Pu))>;538def: Pat<(v2i32 (sext V2I1:$Pu)), (C2_mask V2I1:$Pu)>;539def: Pat<(v4i8  (sext V4I1:$Pu)), (S2_vtrunehb (C2_mask V4I1:$Pu))>;540def: Pat<(v4i16 (sext V4I1:$Pu)), (C2_mask V4I1:$Pu)>;541def: Pat<(v8i8  (sext V8I1:$Pu)), (C2_mask V8I1:$Pu)>;542 543def Vsplatpi: OutPatFrag<(ops node:$V),544                         (Combinew (A2_tfrsi $V), (A2_tfrsi $V))>;545 546def: Pat<(v2i16 (azext V2I1:$Pu)),547         (A2_andir (S2_vtrunehb (C2_mask V2I1:$Pu)), (i32 0x00010001))>;548def: Pat<(v2i32 (azext V2I1:$Pu)),549         (A2_andp (C2_mask V2I1:$Pu), (A2_combineii (i32 1), (i32 1)))>;550def: Pat<(v4i8 (azext V4I1:$Pu)),551         (A2_andir (S2_vtrunehb (C2_mask V4I1:$Pu)), (i32 0x01010101))>;552def: Pat<(v4i16 (azext V4I1:$Pu)),553         (A2_andp (C2_mask V4I1:$Pu), (Vsplatpi (i32 0x00010001)))>;554def: Pat<(v8i8 (azext V8I1:$Pu)),555         (A2_andp (C2_mask V8I1:$Pu), (Vsplatpi (i32 0x01010101)))>;556 557def: Pat<(v4i16 (azext  V4I8:$Rs)),  (S2_vzxtbh V4I8:$Rs)>;558def: Pat<(v2i32 (azext  V2I16:$Rs)), (S2_vzxthw V2I16:$Rs)>;559def: Pat<(v4i16 (sext   V4I8:$Rs)),  (S2_vsxtbh V4I8:$Rs)>;560def: Pat<(v2i32 (sext   V2I16:$Rs)), (S2_vsxthw V2I16:$Rs)>;561 562def: Pat<(v2i32 (sext_inreg V2I32:$Rs, v2i8)),563         (Combinew (A2_sxtb (HiReg $Rs)), (A2_sxtb (LoReg $Rs)))>;564 565def: Pat<(v2i32 (sext_inreg V2I32:$Rs, v2i16)),566         (Combinew (A2_sxth (HiReg $Rs)), (A2_sxth (LoReg $Rs)))>;567 568// Truncate: from vector B copy all 'E'ven 'B'yte elements:569// A[0] = B[0];  A[1] = B[2];  A[2] = B[4];  A[3] = B[6];570def: Pat<(v4i8 (trunc V4I16:$Rs)),571         (S2_vtrunehb V4I16:$Rs)>;572 573// Truncate: from vector B copy all 'O'dd 'B'yte elements:574// A[0] = B[1];  A[1] = B[3];  A[2] = B[5];  A[3] = B[7];575// S2_vtrunohb576 577// Truncate: from vectors B and C copy all 'E'ven 'H'alf-word elements:578// A[0] = B[0];  A[1] = B[2];  A[2] = C[0];  A[3] = C[2];579// S2_vtruneh580 581def: Pat<(v2i16 (trunc V2I32:$Rs)),582         (A2_combine_ll (HiReg $Rs), (LoReg $Rs))>;583 584// Truncate to vNi1585def: Pat<(v2i1 (trunc V2I32:$Rs)),586         (A4_vcmpweqi (A2_andp V2I32:$Rs, (A2_combineii (i32 1), (i32 1))),587                      (i32 1))>;588def: Pat<(v4i1 (trunc V4I16:$Rs)),589         (A4_vcmpheqi (Combinew (A2_andir (HiReg $Rs), (i32 0x00010001)),590                                (A2_andir (LoReg $Rs), (i32 0x00010001))),591                      (i32 1))>;592def: Pat<(v8i1 (trunc V8I8:$Rs)),593         (A4_vcmpbeqi (Combinew (A2_andir (HiReg $Rs), (i32 0x01010101)),594                                (A2_andir (LoReg $Rs), (i32 0x01010101))),595                      (i32 1))>;596def : Pat<(v4i1 (trunc V4I8:$Rs)),597          (A4_vcmpheqi (Combinew (A2_andir (HiReg (S2_vzxtbh $Rs)), 0x00010001),598                                 (A2_andir (LoReg (S2_vzxtbh $Rs)), 0x00010001)),599                       (i32 1))>;600def: Pat<(v2i1 (trunc V2I16:$Rs)),601          (A4_vcmpweqi (A2_andp (S2_vzxthw $Rs), (A2_combineii (i32 1), (i32 1))),602                      (i32 1))>;603 604 605// Saturation:606// Note: saturation assumes the same signed-ness for the input and the607// output.608def: Pat<(i32 (ssat I32:$Rs, i8)),  (A2_satb  I32:$Rs)>;609def: Pat<(i32 (ssat I32:$Rs, i16)), (A2_sath  I32:$Rs)>;610def: Pat<(i32 (ssat I64:$Rs, i32)), (A2_sat   I64:$Rs)>;611def: Pat<(i32 (usat I32:$Rs, i8)),  (A2_satub I32:$Rs)>;612def: Pat<(i32 (usat I32:$Rs, i16)), (A2_satuh I32:$Rs)>;613def: Pat<(i32 (usat I64:$Rs, i32)),614         (C2_mux (C2_cmpeqi (HiReg $Rs), (i32 0)), (LoReg $Rs), (i32 -1))>;615 616def: Pat<(v4i8  (ssat V4I16:$Rs, v4i8)),  (S2_vsathb  V4I16:$Rs)>;617def: Pat<(v2i16 (ssat V2I32:$Rs, v2i16)), (S2_vsatwh  V2I32:$Rs)>;618def: Pat<(v4i8  (usat V4I16:$Rs, v4i8)),  (S2_vsathub V4I16:$Rs)>;619def: Pat<(v2i16 (usat V2I32:$Rs, v2i16)), (S2_vsatwuh V2I32:$Rs)>;620 621 622// --(4) Logical ---------------------------------------------------------623//624 625def: Pat<(not I1:$Ps),      (C2_not I1:$Ps)>;626def: Pat<(pnot V2I1:$Ps),   (C2_not V2I1:$Ps)>;627def: Pat<(pnot V4I1:$Ps),   (C2_not V4I1:$Ps)>;628def: Pat<(pnot V8I1:$Ps),   (C2_not V8I1:$Ps)>;629def: Pat<(add I1:$Ps, -1),  (C2_not I1:$Ps)>;630 631def: OpR_RR_pat<C2_and,         And, i1, I1>;632def: OpR_RR_pat<C2_or,           Or, i1, I1>;633def: OpR_RR_pat<C2_xor,         Xor, i1, I1>;634def: OpR_RR_pat<C2_andn,  Not2<And>, i1, I1>;635def: OpR_RR_pat<C2_orn,    Not2<Or>, i1, I1>;636 637def: AccRRR_pat<C4_and_and,   And,       Su<And>, I1, I1, I1>;638def: AccRRR_pat<C4_and_or,    And,       Su< Or>, I1, I1, I1>;639def: AccRRR_pat<C4_or_and,     Or,       Su<And>, I1, I1, I1>;640def: AccRRR_pat<C4_or_or,      Or,       Su< Or>, I1, I1, I1>;641def: AccRRR_pat<C4_and_andn,  And, Su<Not2<And>>, I1, I1, I1>;642def: AccRRR_pat<C4_and_orn,   And, Su<Not2< Or>>, I1, I1, I1>;643def: AccRRR_pat<C4_or_andn,    Or, Su<Not2<And>>, I1, I1, I1>;644def: AccRRR_pat<C4_or_orn,     Or, Su<Not2< Or>>, I1, I1, I1>;645 646multiclass BoolvOpR_RR_pat<InstHexagon MI, PatFrag VOp> {647  def: OpR_RR_pat<MI, VOp, v2i1, V2I1>;648  def: OpR_RR_pat<MI, VOp, v4i1, V4I1>;649  def: OpR_RR_pat<MI, VOp, v8i1, V8I1>;650}651 652multiclass BoolvAccRRR_pat<InstHexagon MI, PatFrag AccOp, PatFrag VOp> {653  def: AccRRR_pat<MI, AccOp, VOp, V2I1, V2I1, V2I1>;654  def: AccRRR_pat<MI, AccOp, VOp, V4I1, V4I1, V4I1>;655  def: AccRRR_pat<MI, AccOp, VOp, V8I1, V8I1, V8I1>;656}657 658defm: BoolvOpR_RR_pat<C2_and,                    And>;659defm: BoolvOpR_RR_pat<C2_or,                      Or>;660defm: BoolvOpR_RR_pat<C2_xor,                    Xor>;661defm: BoolvOpR_RR_pat<C2_andn,      VNot2<And, pnot>>;662defm: BoolvOpR_RR_pat<C2_orn,       VNot2< Or, pnot>>;663 664// op(Ps, op(Pt, Pu))665defm: BoolvAccRRR_pat<C4_and_and,   And, Su<And>>;666defm: BoolvAccRRR_pat<C4_and_or,    And, Su<Or>>;667defm: BoolvAccRRR_pat<C4_or_and,    Or,  Su<And>>;668defm: BoolvAccRRR_pat<C4_or_or,     Or,  Su<Or>>;669 670// op(Ps, op(Pt, !Pu))671defm: BoolvAccRRR_pat<C4_and_andn,  And, Su<VNot2<And, pnot>>>;672defm: BoolvAccRRR_pat<C4_and_orn,   And, Su<VNot2< Or, pnot>>>;673defm: BoolvAccRRR_pat<C4_or_andn,   Or,  Su<VNot2<And, pnot>>>;674defm: BoolvAccRRR_pat<C4_or_orn,    Or,  Su<VNot2< Or, pnot>>>;675 676 677// --(5) Compare ---------------------------------------------------------678//679 680// Avoid negated comparisons, i.e. those of form "Pd = !cmp(...)".681// These cannot form compounds (e.g. J4_cmpeqi_tp0_jump_nt).682 683def: OpR_RI_pat<C2_cmpeqi,    seteq,          i1, I32,  anyimm>;684def: OpR_RI_pat<C2_cmpgti,    setgt,          i1, I32,  anyimm>;685def: OpR_RI_pat<C2_cmpgtui,   setugt,         i1, I32,  anyimm>;686 687def: Pat<(i1 (setge I32:$Rs, s32_0ImmPred:$s10)),688         (C2_cmpgti I32:$Rs, (SDEC1 imm:$s10))>;689def: Pat<(i1 (setuge I32:$Rs, u32_0ImmPred:$u9)),690         (C2_cmpgtui I32:$Rs, (UDEC1 imm:$u9))>;691 692def: Pat<(i1 (setlt I32:$Rs, s32_0ImmPred:$s10)),693         (C2_not (C2_cmpgti I32:$Rs, (SDEC1 imm:$s10)))>;694def: Pat<(i1 (setult I32:$Rs, u32_0ImmPred:$u9)),695         (C2_not (C2_cmpgtui I32:$Rs, (UDEC1 imm:$u9)))>;696 697// Patfrag to convert the usual comparison patfrags (e.g. setlt) to ones698// that reverse the order of the operands.699class RevCmp<PatFrag F>700  : PatFrag<(ops node:$rhs, node:$lhs), !head(F.Fragments), F.PredicateCode,701            F.OperandTransform>;702 703def: OpR_RR_pat<C2_cmpeq,     seteq,          i1,   I32>;704def: OpR_RR_pat<C2_cmpgt,     setgt,          i1,   I32>;705def: OpR_RR_pat<C2_cmpgtu,    setugt,         i1,   I32>;706def: OpR_RR_pat<C2_cmpgt,     RevCmp<setlt>,  i1,   I32>;707def: OpR_RR_pat<C2_cmpgtu,    RevCmp<setult>, i1,   I32>;708def: OpR_RR_pat<C2_cmpeqp,    seteq,          i1,   I64>;709def: OpR_RR_pat<C2_cmpgtp,    setgt,          i1,   I64>;710def: OpR_RR_pat<C2_cmpgtup,   setugt,         i1,   I64>;711def: OpR_RR_pat<C2_cmpgtp,    RevCmp<setlt>,  i1,   I64>;712def: OpR_RR_pat<C2_cmpgtup,   RevCmp<setult>, i1,   I64>;713def: OpR_RR_pat<A2_vcmpbeq,   seteq,          v8i1, V8I8>;714def: OpR_RR_pat<A4_vcmpbgt,   RevCmp<setlt>,  v8i1, V8I8>;715def: OpR_RR_pat<A4_vcmpbgt,   setgt,          v8i1, V8I8>;716def: OpR_RR_pat<A2_vcmpbgtu,  RevCmp<setult>, v8i1, V8I8>;717def: OpR_RR_pat<A2_vcmpbgtu,  setugt,         v8i1, V8I8>;718def: OpR_RR_pat<A2_vcmpheq,   seteq,          v4i1, V4I16>;719def: OpR_RR_pat<A2_vcmphgt,   RevCmp<setlt>,  v4i1, V4I16>;720def: OpR_RR_pat<A2_vcmphgt,   setgt,          v4i1, V4I16>;721def: OpR_RR_pat<A2_vcmphgtu,  RevCmp<setult>, v4i1, V4I16>;722def: OpR_RR_pat<A2_vcmphgtu,  setugt,         v4i1, V4I16>;723def: OpR_RR_pat<A2_vcmpweq,   seteq,          v2i1, V2I32>;724def: OpR_RR_pat<A2_vcmpwgt,   RevCmp<setlt>,  v2i1, V2I32>;725def: OpR_RR_pat<A2_vcmpwgt,   setgt,          v2i1, V2I32>;726def: OpR_RR_pat<A2_vcmpwgtu,  RevCmp<setult>, v2i1, V2I32>;727def: OpR_RR_pat<A2_vcmpwgtu,  setugt,         v2i1, V2I32>;728 729def: OpR_RR_pat<F2_sfcmpeq,   seteq,          i1, F32>;730def: OpR_RR_pat<F2_sfcmpgt,   setgt,          i1, F32>;731def: OpR_RR_pat<F2_sfcmpge,   setge,          i1, F32>;732def: OpR_RR_pat<F2_sfcmpgt,   RevCmp<setlt>,  i1, F32>;733def: OpR_RR_pat<F2_sfcmpge,   RevCmp<setle>,  i1, F32>;734def: OpR_RR_pat<F2_sfcmpuo,   setuo,          i1, F32>;735 736def: OpR_RR_pat<F2_dfcmpeq,   seteq,          i1, F64>;737def: OpR_RR_pat<F2_dfcmpgt,   setgt,          i1, F64>;738def: OpR_RR_pat<F2_dfcmpge,   setge,          i1, F64>;739def: OpR_RR_pat<F2_dfcmpgt,   RevCmp<setlt>,  i1, F64>;740def: OpR_RR_pat<F2_dfcmpge,   RevCmp<setle>,  i1, F64>;741def: OpR_RR_pat<F2_dfcmpuo,   setuo,          i1, F64>;742 743// Avoid C4_cmpneqi, C4_cmpltei, C4_cmplteui, since they cannot form compounds.744 745def: Pat<(i1 (setne I32:$Rs, anyimm:$u5)),746         (C2_not (C2_cmpeqi I32:$Rs, imm:$u5))>;747def: Pat<(i1 (setle I32:$Rs, anyimm:$u5)),748         (C2_not (C2_cmpgti I32:$Rs, imm:$u5))>;749def: Pat<(i1 (setule I32:$Rs, anyimm:$u5)),750         (C2_not (C2_cmpgtui I32:$Rs, imm:$u5))>;751 752class OpmR_RR_pat<PatFrag Output, PatFrag Op, ValueType ResType,753                  PatFrag RsPred, PatFrag RtPred = RsPred>754  : Pat<(ResType (Op RsPred:$Rs, RtPred:$Rt)),755        (Output RsPred:$Rs, RtPred:$Rt)>;756 757class Outn<InstHexagon MI>758  : OutPatFrag<(ops node:$Rs, node:$Rt),759               (C2_not (MI $Rs, $Rt))>;760 761def: OpmR_RR_pat<Outn<C2_cmpeq>,    setne,          i1,   I32>;762def: OpmR_RR_pat<Outn<C2_cmpgt>,    setle,          i1,   I32>;763def: OpmR_RR_pat<Outn<C2_cmpgtu>,   setule,         i1,   I32>;764def: OpmR_RR_pat<Outn<C2_cmpgt>,    RevCmp<setge>,  i1,   I32>;765def: OpmR_RR_pat<Outn<C2_cmpgtu>,   RevCmp<setuge>, i1,   I32>;766def: OpmR_RR_pat<Outn<C2_cmpeqp>,   setne,          i1,   I64>;767def: OpmR_RR_pat<Outn<C2_cmpgtp>,   setle,          i1,   I64>;768def: OpmR_RR_pat<Outn<C2_cmpgtup>,  setule,         i1,   I64>;769def: OpmR_RR_pat<Outn<C2_cmpgtp>,   RevCmp<setge>,  i1,   I64>;770def: OpmR_RR_pat<Outn<C2_cmpgtup>,  RevCmp<setuge>, i1,   I64>;771def: OpmR_RR_pat<Outn<A2_vcmpbeq>,  setne,          v8i1, V8I8>;772def: OpmR_RR_pat<Outn<A4_vcmpbgt>,  setle,          v8i1, V8I8>;773def: OpmR_RR_pat<Outn<A2_vcmpbgtu>, setule,         v8i1, V8I8>;774def: OpmR_RR_pat<Outn<A4_vcmpbgt>,  RevCmp<setge>,  v8i1, V8I8>;775def: OpmR_RR_pat<Outn<A2_vcmpbgtu>, RevCmp<setuge>, v8i1, V8I8>;776def: OpmR_RR_pat<Outn<A2_vcmpheq>,  setne,          v4i1, V4I16>;777def: OpmR_RR_pat<Outn<A2_vcmphgt>,  setle,          v4i1, V4I16>;778def: OpmR_RR_pat<Outn<A2_vcmphgtu>, setule,         v4i1, V4I16>;779def: OpmR_RR_pat<Outn<A2_vcmphgt>,  RevCmp<setge>,  v4i1, V4I16>;780def: OpmR_RR_pat<Outn<A2_vcmphgtu>, RevCmp<setuge>, v4i1, V4I16>;781def: OpmR_RR_pat<Outn<A2_vcmpweq>,  setne,          v2i1, V2I32>;782def: OpmR_RR_pat<Outn<A2_vcmpwgt>,  setle,          v2i1, V2I32>;783def: OpmR_RR_pat<Outn<A2_vcmpwgtu>, setule,         v2i1, V2I32>;784def: OpmR_RR_pat<Outn<A2_vcmpwgt>,  RevCmp<setge>,  v2i1, V2I32>;785def: OpmR_RR_pat<Outn<A2_vcmpwgtu>, RevCmp<setuge>, v2i1, V2I32>;786 787let AddedComplexity = 100 in {788  def: Pat<(i1 (seteq (and (xor I32:$Rs, I32:$Rt), 255), 0)),789           (A4_cmpbeq IntRegs:$Rs, IntRegs:$Rt)>;790  def: Pat<(i1 (setne (and (xor I32:$Rs, I32:$Rt), 255), 0)),791           (C2_not (A4_cmpbeq IntRegs:$Rs, IntRegs:$Rt))>;792  def: Pat<(i1 (seteq (and (xor I32:$Rs, I32:$Rt), 65535), 0)),793           (A4_cmpheq IntRegs:$Rs, IntRegs:$Rt)>;794  def: Pat<(i1 (setne (and (xor I32:$Rs, I32:$Rt), 65535), 0)),795           (C2_not (A4_cmpheq IntRegs:$Rs, IntRegs:$Rt))>;796}797 798// PatFrag for AsserZext which takes the original type as a parameter.799def SDTAssertZext: SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<0,1>]>;800def AssertZextSD: SDNode<"ISD::AssertZext", SDTAssertZext>;801class AssertZext<ValueType T>: PatFrag<(ops node:$A), (AssertZextSD $A, T)>;802 803multiclass Cmpb_pat<InstHexagon MI, PatFrag Op, PatFrag AssertExt,804                      PatLeaf ImmPred, int Mask> {805  def: Pat<(i1 (Op (and I32:$Rs, Mask), ImmPred:$I)),806           (MI I32:$Rs, imm:$I)>;807  def: Pat<(i1 (Op (AssertExt I32:$Rs), ImmPred:$I)),808           (MI I32:$Rs, imm:$I)>;809}810 811multiclass CmpbN_pat<InstHexagon MI, PatFrag Op, PatFrag AssertExt,812                     PatLeaf ImmPred, int Mask> {813  def: Pat<(i1 (Op (and I32:$Rs, Mask), ImmPred:$I)),814           (C2_not (MI I32:$Rs, imm:$I))>;815  def: Pat<(i1 (Op (AssertExt I32:$Rs), ImmPred:$I)),816           (C2_not (MI I32:$Rs, imm:$I))>;817}818 819multiclass CmpbND_pat<InstHexagon MI, PatFrag Op, PatFrag AssertExt,820                      PatLeaf ImmPred, int Mask> {821  def: Pat<(i1 (Op (and I32:$Rs, Mask), ImmPred:$I)),822           (C2_not (MI I32:$Rs, (UDEC1 imm:$I)))>;823  def: Pat<(i1 (Op (AssertExt I32:$Rs), ImmPred:$I)),824           (C2_not (MI I32:$Rs, (UDEC1 imm:$I)))>;825}826 827let AddedComplexity = 200 in {828  defm: Cmpb_pat  <A4_cmpbeqi,  seteq,  AssertZext<i8>,  IsUGT<8,31>,  255>;829  defm: CmpbN_pat <A4_cmpbeqi,  setne,  AssertZext<i8>,  IsUGT<8,31>,  255>;830  defm: Cmpb_pat  <A4_cmpbgtui, setugt, AssertZext<i8>,  IsUGT<32,31>, 255>;831  defm: CmpbN_pat <A4_cmpbgtui, setule, AssertZext<i8>,  IsUGT<32,31>, 255>;832  defm: Cmpb_pat  <A4_cmphgtui, setugt, AssertZext<i16>, IsUGT<32,31>, 65535>;833  defm: CmpbN_pat <A4_cmphgtui, setule, AssertZext<i16>, IsUGT<32,31>, 65535>;834  defm: CmpbND_pat<A4_cmpbgtui, setult, AssertZext<i8>,  IsUGT<32,32>, 255>;835  defm: CmpbND_pat<A4_cmphgtui, setult, AssertZext<i16>, IsUGT<32,32>, 65535>;836}837 838def: Pat<(i32 (zext (i1 (seteq I32:$Rs, I32:$Rt)))),839         (A4_rcmpeq I32:$Rs, I32:$Rt)>;840def: Pat<(i32 (zext (i1 (setne I32:$Rs, I32:$Rt)))),841         (A4_rcmpneq I32:$Rs, I32:$Rt)>;842def: Pat<(i32 (zext (i1 (seteq I32:$Rs, anyimm:$s8)))),843         (A4_rcmpeqi I32:$Rs, imm:$s8)>;844def: Pat<(i32 (zext (i1 (setne I32:$Rs, anyimm:$s8)))),845         (A4_rcmpneqi I32:$Rs, imm:$s8)>;846 847def: Pat<(i1 (seteq I1:$Ps, (i1 -1))), (I1:$Ps)>;848def: Pat<(i1 (setne I1:$Ps, (i1 -1))), (C2_not I1:$Ps)>;849def: Pat<(i1 (seteq I1:$Ps, I1:$Pt)),  (C2_not (C2_xor I1:$Ps, I1:$Pt))>;850def: Pat<(i1 (setne I1:$Ps, I1:$Pt)),  (C2_xor I1:$Ps, I1:$Pt)>;851 852multiclass BoolE_pat<PatFrag OpPred, ValueType ResTy> {853  def: Pat<(ResTy (seteq OpPred:$Ps, OpPred:$Pt)), (C2_not (C2_xor $Ps, $Pt))>;854  def: Pat<(ResTy (setne OpPred:$Ps, OpPred:$Pt)), (C2_xor $Ps, $Pt)>;855}856 857defm: BoolE_pat<I1,   i1>;858defm: BoolE_pat<V2I1, v2i1>;859defm: BoolE_pat<V4I1, v4i1>;860defm: BoolE_pat<V8I1, v8i1>;861 862multiclass BoolL_pat<PatFrag OpPred, ValueType ResTy> {863  // Signed "true" == -1864  def: Pat<(ResTy (setlt  OpPred:$Ps, OpPred:$Pt)), (C2_andn $Ps, $Pt)>;865  def: Pat<(ResTy (setle  OpPred:$Ps, OpPred:$Pt)), (C2_orn  $Ps, $Pt)>;866  def: Pat<(ResTy (setult OpPred:$Ps, OpPred:$Pt)), (C2_andn $Pt, $Ps)>;867  def: Pat<(ResTy (setule OpPred:$Ps, OpPred:$Pt)), (C2_orn  $Pt, $Ps)>;868}869 870defm: BoolL_pat<I1,   i1>;871defm: BoolL_pat<V2I1, v2i1>;872defm: BoolL_pat<V4I1, v4i1>;873defm: BoolL_pat<V8I1, v8i1>;874 875// Floating-point comparisons with checks for ordered/unordered status.876 877class T3<InstHexagon MI1, InstHexagon MI2, InstHexagon MI3>878  : OutPatFrag<(ops node:$Rs, node:$Rt),879               (MI1 (MI2 $Rs, $Rt), (MI3 $Rs, $Rt))>;880 881class Cmpuf<InstHexagon MI>:  T3<C2_or,  F2_sfcmpuo, MI>;882class Cmpud<InstHexagon MI>:  T3<C2_or,  F2_dfcmpuo, MI>;883 884class Cmpufn<InstHexagon MI>: T3<C2_orn, F2_sfcmpuo, MI>;885class Cmpudn<InstHexagon MI>: T3<C2_orn, F2_dfcmpuo, MI>;886 887def: OpmR_RR_pat<Cmpuf<F2_sfcmpeq>,  setueq,         i1, F32>;888def: OpmR_RR_pat<Cmpuf<F2_sfcmpge>,  setuge,         i1, F32>;889def: OpmR_RR_pat<Cmpuf<F2_sfcmpgt>,  setugt,         i1, F32>;890def: OpmR_RR_pat<Cmpuf<F2_sfcmpge>,  RevCmp<setule>, i1, F32>;891def: OpmR_RR_pat<Cmpuf<F2_sfcmpgt>,  RevCmp<setult>, i1, F32>;892def: OpmR_RR_pat<Cmpufn<F2_sfcmpeq>, setune,         i1, F32>;893 894def: OpmR_RR_pat<Cmpud<F2_dfcmpeq>,  setueq,         i1, F64>;895def: OpmR_RR_pat<Cmpud<F2_dfcmpge>,  setuge,         i1, F64>;896def: OpmR_RR_pat<Cmpud<F2_dfcmpgt>,  setugt,         i1, F64>;897def: OpmR_RR_pat<Cmpud<F2_dfcmpge>,  RevCmp<setule>, i1, F64>;898def: OpmR_RR_pat<Cmpud<F2_dfcmpgt>,  RevCmp<setult>, i1, F64>;899def: OpmR_RR_pat<Cmpudn<F2_dfcmpeq>, setune,         i1, F64>;900 901class T4<InstHexagon MI1, InstHexagon MI2, InstHexagon MI3, InstHexagon MI4>902  : OutPatFrag<(ops node:$Rs, node:$Rt),903               (MI1 (MI2 (MI3 $Rs, $Rt), (MI4 $Rs, $Rt)))>;904 905class Cmpof<InstHexagon MI>: T3<C2_andn, MI,  F2_sfcmpuo>;906class Cmpod<InstHexagon MI>: T3<C2_andn, MI,  F2_dfcmpuo>;907 908class Cmpofn<InstHexagon MI>: T4<C2_not,  C2_or, MI,  F2_sfcmpuo>;909class Cmpodn<InstHexagon MI>: T4<C2_not,  C2_or, MI,  F2_dfcmpuo>;910 911def: OpmR_RR_pat<Cmpof<F2_sfcmpeq>,  setoeq,         i1, F32>;912def: OpmR_RR_pat<Cmpof<F2_sfcmpge>,  setoge,         i1, F32>;913def: OpmR_RR_pat<Cmpof<F2_sfcmpgt>,  setogt,         i1, F32>;914def: OpmR_RR_pat<Cmpof<F2_sfcmpge>,  RevCmp<setole>, i1, F32>;915def: OpmR_RR_pat<Cmpof<F2_sfcmpgt>,  RevCmp<setolt>, i1, F32>;916def: OpmR_RR_pat<Cmpofn<F2_sfcmpeq>, setone,         i1, F32>;917 918def: OpmR_RR_pat<Cmpod<F2_dfcmpeq>,  setoeq,         i1, F64>;919def: OpmR_RR_pat<Cmpod<F2_dfcmpge>,  setoge,         i1, F64>;920def: OpmR_RR_pat<Cmpod<F2_dfcmpgt>,  setogt,         i1, F64>;921def: OpmR_RR_pat<Cmpod<F2_dfcmpge>,  RevCmp<setole>, i1, F64>;922def: OpmR_RR_pat<Cmpod<F2_dfcmpgt>,  RevCmp<setolt>, i1, F64>;923def: OpmR_RR_pat<Cmpodn<F2_dfcmpeq>, setone,         i1, F64>;924 925def: OpmR_RR_pat<Outn<F2_sfcmpuo>, seto,   i1, F32>;926def: OpmR_RR_pat<Outn<F2_dfcmpuo>, seto,   i1, F64>;927 928def: OpmR_RR_pat<Outn<F2_sfcmpeq>, setne,  i1, F32>;929def: OpmR_RR_pat<Outn<F2_dfcmpeq>, setne,  i1, F64>;930 931// --(6) Select ----------------------------------------------------------932//933 934def: Pat<(select I1:$Pu, I32:$Rs, I32:$Rt),935         (C2_mux I1:$Pu, I32:$Rs, I32:$Rt)>;936def: Pat<(select I1:$Pu, v4i8:$Rs, v4i8:$Rt),937         (C2_mux I1:$Pu, v4i8:$Rs, v4i8:$Rt)>;938def: Pat<(select I1:$Pu, v2i16:$Rs, v2i16:$Rt),939         (C2_mux I1:$Pu, v2i16:$Rs, v2i16:$Rt)>;940def: Pat<(select I1:$Pu, anyimm:$s8, I32:$Rs),941         (C2_muxri I1:$Pu, imm:$s8, I32:$Rs)>;942def: Pat<(select I1:$Pu, I32:$Rs, anyimm:$s8),943         (C2_muxir I1:$Pu, I32:$Rs, imm:$s8)>;944def: Pat<(select I1:$Pu, anyimm:$s8, s8_0ImmPred:$S8),945         (C2_muxii I1:$Pu, imm:$s8, imm:$S8)>;946 947def: Pat<(select (not I1:$Pu), I32:$Rs, I32:$Rt),948         (C2_mux I1:$Pu, I32:$Rt, I32:$Rs)>;949def: Pat<(select (not I1:$Pu), s8_0ImmPred:$S8, anyimm:$s8),950         (C2_muxii I1:$Pu, imm:$s8, imm:$S8)>;951def: Pat<(select (not I1:$Pu), anyimm:$s8, I32:$Rs),952         (C2_muxir I1:$Pu, I32:$Rs, imm:$s8)>;953def: Pat<(select (not I1:$Pu), I32:$Rs, anyimm:$s8),954         (C2_muxri I1:$Pu, imm:$s8, I32:$Rs)>;955 956// Map from a 64-bit select to an emulated 64-bit mux.957// Hexagon does not support 64-bit MUXes; so emulate with combines.958def: Pat<(select I1:$Pu, I64:$Rs, I64:$Rt),959         (Combinew (C2_mux I1:$Pu, (HiReg $Rs), (HiReg $Rt)),960                   (C2_mux I1:$Pu, (LoReg $Rs), (LoReg $Rt)))>;961 962def: Pat<(select I1:$Pu, v2i32:$Rs, v2i32:$Rt),963         (Combinew (C2_mux I1:$Pu, (HiReg $Rs), (HiReg $Rt)),964                   (C2_mux I1:$Pu, (LoReg $Rs), (LoReg $Rt)))>;965 966def: Pat<(select I1:$Pu, F32:$Rs, f32ImmPred:$I),967         (C2_muxir I1:$Pu, F32:$Rs, (ftoi $I))>;968def: Pat<(select I1:$Pu, f32ImmPred:$I, F32:$Rt),969         (C2_muxri I1:$Pu, (ftoi $I), F32:$Rt)>;970def: Pat<(select I1:$Pu, F32:$Rs, F32:$Rt),971         (C2_mux I1:$Pu, F32:$Rs, F32:$Rt)>;972def: Pat<(select I1:$Pu, F64:$Rs, F64:$Rt),973         (Combinew (C2_mux I1:$Pu, (HiReg $Rs), (HiReg $Rt)),974                   (C2_mux I1:$Pu, (LoReg $Rs), (LoReg $Rt)))>;975 976def: Pat<(select (i1 (setult F32:$Ra, F32:$Rb)), F32:$Rs, F32:$Rt),977         (C2_mux (F2_sfcmpgt F32:$Rb, F32:$Ra), F32:$Rs, F32:$Rt)>;978def: Pat<(select (i1 (setult F64:$Ra, F64:$Rb)), F64:$Rs, F64:$Rt),979         (C2_vmux (F2_dfcmpgt F64:$Rb, F64:$Ra), F64:$Rs, F64:$Rt)>;980 981def: Pat<(select (not I1:$Pu), f32ImmPred:$I, F32:$Rs),982         (C2_muxir I1:$Pu, F32:$Rs, (ftoi $I))>;983def: Pat<(select (not I1:$Pu), F32:$Rt, f32ImmPred:$I),984         (C2_muxri I1:$Pu, (ftoi $I), F32:$Rt)>;985 986def: Pat<(vselect V8I1:$Pu, V8I8:$Rs, V8I8:$Rt),987         (C2_vmux V8I1:$Pu, V8I8:$Rs, V8I8:$Rt)>;988def: Pat<(vselect V4I1:$Pu, V4I16:$Rs, V4I16:$Rt),989         (C2_vmux V4I1:$Pu, V4I16:$Rs, V4I16:$Rt)>;990def: Pat<(vselect V2I1:$Pu, V2I32:$Rs, V2I32:$Rt),991         (C2_vmux V2I1:$Pu, V2I32:$Rs, V2I32:$Rt)>;992 993def: Pat<(vselect (pnot V8I1:$Pu), V8I8:$Rs, V8I8:$Rt),994         (C2_vmux V8I1:$Pu, V8I8:$Rt, V8I8:$Rs)>;995def: Pat<(vselect (pnot V4I1:$Pu), V4I16:$Rs, V4I16:$Rt),996         (C2_vmux V4I1:$Pu, V4I16:$Rt, V4I16:$Rs)>;997def: Pat<(vselect (pnot V2I1:$Pu), V2I32:$Rs, V2I32:$Rt),998         (C2_vmux V2I1:$Pu, V2I32:$Rt, V2I32:$Rs)>;999 1000 1001// From LegalizeDAG.cpp: (Pu ? Pv : Pw) <=> (Pu & Pv) | (!Pu & Pw).1002def: Pat<(select I1:$Pu, I1:$Ps, I1:$Pt),1003         (C4_or_andn (C2_and $Ps, $Pu), $Pt, $Pu)>;1004 1005def: Pat<(vselect V2I1:$Pu, V2I1:$Ps, V2I1:$Pt),1006         (C4_or_andn (C2_and $Ps, $Pu), $Pt, $Pu)>;1007def: Pat<(vselect V4I1:$Pu, V4I1:$Ps, V4I1:$Pt),1008         (C4_or_andn (C2_and $Ps, $Pu), $Pt, $Pu)>;1009def: Pat<(vselect V8I1:$Pu, V8I1:$Ps, V8I1:$Pt),1010         (C4_or_andn (C2_and $Ps, $Pu), $Pt, $Pu)>;1011 1012def: Pat<(select I1:$Pu, V2I1:$Ps, V2I1:$Pt),1013         (C2_tfrrp (C2_mux $Pu, (C2_tfrpr $Ps), (C2_tfrpr $Pt)))>;1014def: Pat<(select I1:$Pu, V4I1:$Ps, V4I1:$Pt),1015         (C2_tfrrp (C2_mux $Pu, (C2_tfrpr $Ps), (C2_tfrpr $Pt)))>;1016def: Pat<(select I1:$Pu, V8I1:$Ps, V8I1:$Pt),1017         (C2_tfrrp (C2_mux $Pu, (C2_tfrpr $Ps), (C2_tfrpr $Pt)))>;1018 1019def IsPosHalf : PatLeaf<(i32 IntRegs:$a), [{1020  return isPositiveHalfWord(N);1021}]>;1022 1023multiclass SelMinMax16_pats<PatFrag CmpOp, InstHexagon InstA,1024                            InstHexagon InstB> {1025  def: Pat<(sext_inreg (select (i1 (CmpOp IsPosHalf:$Rs, IsPosHalf:$Rt)),1026                               IsPosHalf:$Rs, IsPosHalf:$Rt), i16),1027           (InstA IntRegs:$Rs, IntRegs:$Rt)>;1028  def: Pat<(sext_inreg (select (i1 (CmpOp IsPosHalf:$Rs, IsPosHalf:$Rt)),1029                               IsPosHalf:$Rt, IsPosHalf:$Rs), i16),1030           (InstB IntRegs:$Rs, IntRegs:$Rt)>;1031}1032 1033let AddedComplexity = 200 in {1034  defm: SelMinMax16_pats<setge,  A2_max,  A2_min>;1035  defm: SelMinMax16_pats<setgt,  A2_max,  A2_min>;1036  defm: SelMinMax16_pats<setle,  A2_min,  A2_max>;1037  defm: SelMinMax16_pats<setlt,  A2_min,  A2_max>;1038  defm: SelMinMax16_pats<setuge, A2_maxu, A2_minu>;1039  defm: SelMinMax16_pats<setugt, A2_maxu, A2_minu>;1040  defm: SelMinMax16_pats<setule, A2_minu, A2_maxu>;1041  defm: SelMinMax16_pats<setult, A2_minu, A2_maxu>;1042}1043 1044def: OpR_RR_pat<A2_min,   Smin, i32, I32, I32>;1045def: OpR_RR_pat<A2_max,   Smax, i32, I32, I32>;1046def: OpR_RR_pat<A2_minu,  Umin, i32, I32, I32>;1047def: OpR_RR_pat<A2_maxu,  Umax, i32, I32, I32>;1048def: OpR_RR_pat<A2_minp,  Smin, i64, I64, I64>;1049def: OpR_RR_pat<A2_maxp,  Smax, i64, I64, I64>;1050def: OpR_RR_pat<A2_minup, Umin, i64, I64, I64>;1051def: OpR_RR_pat<A2_maxup, Umax, i64, I64, I64>;1052 1053let AddedComplexity = 100 in {1054  defm: MinMax_pats<F2_sfmin, F2_sfmax, select, setogt, i1, F32>;1055  defm: MinMax_pats<F2_sfmin, F2_sfmax, select, setoge, i1, F32>;1056  defm: MinMax_pats<F2_sfmax, F2_sfmin, select, setolt, i1, F32>;1057  defm: MinMax_pats<F2_sfmax, F2_sfmin, select, setole, i1, F32>;1058}1059 1060let AddedComplexity = 100, Predicates = [HasV67] in {1061  defm: MinMax_pats<F2_dfmin, F2_dfmax, select, setogt, i1, F64>;1062  defm: MinMax_pats<F2_dfmin, F2_dfmax, select, setoge, i1, F64>;1063  defm: MinMax_pats<F2_dfmax, F2_dfmin, select, setolt, i1, F64>;1064  defm: MinMax_pats<F2_dfmax, F2_dfmin, select, setole, i1, F64>;1065}1066 1067def: OpR_RR_pat<A2_vminb,  Smin, v8i8,  V8I8>;1068def: OpR_RR_pat<A2_vmaxb,  Smax, v8i8,  V8I8>;1069def: OpR_RR_pat<A2_vminub, Umin, v8i8,  V8I8>;1070def: OpR_RR_pat<A2_vmaxub, Umax, v8i8,  V8I8>;1071 1072def: OpR_RR_pat<A2_vminh,  Smin, v4i16, V4I16>;1073def: OpR_RR_pat<A2_vmaxh,  Smax, v4i16, V4I16>;1074def: OpR_RR_pat<A2_vminuh, Umin, v4i16, V4I16>;1075def: OpR_RR_pat<A2_vmaxuh, Umax, v4i16, V4I16>;1076 1077def: OpR_RR_pat<A2_vminw,  Smin, v2i32, V2I32>;1078def: OpR_RR_pat<A2_vmaxw,  Smax, v2i32, V2I32>;1079def: OpR_RR_pat<A2_vminuw, Umin, v2i32, V2I32>;1080def: OpR_RR_pat<A2_vmaxuw, Umax, v2i32, V2I32>;1081 1082// --(7) Insert/extract --------------------------------------------------1083//1084 1085def SDTHexagonINSERT:1086  SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,1087                       SDTCisInt<0>, SDTCisVT<3, i32>, SDTCisVT<4, i32>]>;1088def HexagonINSERT:    SDNode<"HexagonISD::INSERT",   SDTHexagonINSERT>;1089 1090let AddedComplexity = 10 in {1091  def: Pat<(HexagonINSERT I32:$Rs, I32:$Rt, u5_0ImmPred:$u1, u5_0ImmPred:$u2),1092           (S2_insert I32:$Rs, I32:$Rt, imm:$u1, imm:$u2)>;1093  def: Pat<(HexagonINSERT I64:$Rs, I64:$Rt, u6_0ImmPred:$u1, u6_0ImmPred:$u2),1094           (S2_insertp I64:$Rs, I64:$Rt, imm:$u1, imm:$u2)>;1095}1096def: Pat<(HexagonINSERT I32:$Rs, I32:$Rt, I32:$Width, I32:$Off),1097         (S2_insert_rp I32:$Rs, I32:$Rt, (Combinew $Width, $Off))>;1098def: Pat<(HexagonINSERT I64:$Rs, I64:$Rt, I32:$Width, I32:$Off),1099         (S2_insertp_rp I64:$Rs, I64:$Rt, (Combinew $Width, $Off))>;1100 1101def SDTHexagonEXTRACTU1102  : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<1>,1103                  SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;1104def HexagonEXTRACTU:   SDNode<"HexagonISD::EXTRACTU",   SDTHexagonEXTRACTU>;1105 1106let AddedComplexity = 10 in {1107  def: Pat<(HexagonEXTRACTU I32:$Rs, u5_0ImmPred:$u5, u5_0ImmPred:$U5),1108           (S2_extractu I32:$Rs, imm:$u5, imm:$U5)>;1109  def: Pat<(HexagonEXTRACTU I64:$Rs, u6_0ImmPred:$u6, u6_0ImmPred:$U6),1110           (S2_extractup I64:$Rs, imm:$u6, imm:$U6)>;1111}1112def: Pat<(HexagonEXTRACTU I32:$Rs, I32:$Width, I32:$Off),1113         (S2_extractu_rp I32:$Rs, (Combinew $Width, $Off))>;1114def: Pat<(HexagonEXTRACTU I64:$Rs, I32:$Width, I32:$Off),1115         (S2_extractup_rp I64:$Rs, (Combinew $Width, $Off))>;1116 1117def: Pat<(v4i8  (splat_vector anyint:$V)), (ToI32 (SplatB $V))>;1118def: Pat<(v2i16 (splat_vector anyint:$V)), (ToI32 (SplatH $V))>;1119def: Pat<(v8i8  (splat_vector anyint:$V)),1120          (Combinew (ToI32 (SplatB $V)), (ToI32 (SplatB $V)))>;1121def: Pat<(v4i16 (splat_vector anyint:$V)),1122          (Combinew (ToI32 (SplatH $V)), (ToI32 (SplatH $V)))>;1123let AddedComplexity = 10 in1124def: Pat<(v2i32 (splat_vector s8_0ImmPred:$s8)),1125         (A2_combineii imm:$s8, imm:$s8)>;1126def: Pat<(v2i32 (splat_vector anyimm:$V)), (Combinew (ToI32 $V), (ToI32 $V))>;1127 1128def: Pat<(v4i8  (splat_vector I32:$Rs)), (S2_vsplatrb I32:$Rs)>;1129def: Pat<(v2i16 (splat_vector I32:$Rs)), (LoReg (S2_vsplatrh I32:$Rs))>;1130def: Pat<(v4i16 (splat_vector I32:$Rs)), (S2_vsplatrh I32:$Rs)>;1131def: Pat<(v2i32 (splat_vector I32:$Rs)), (Combinew I32:$Rs, I32:$Rs)>;1132 1133let AddedComplexity = 10 in1134def: Pat<(v8i8 (splat_vector I32:$Rs)), (S6_vsplatrbp I32:$Rs)>,1135     Requires<[HasV62]>;1136def: Pat<(v8i8 (splat_vector I32:$Rs)),1137         (Combinew (S2_vsplatrb I32:$Rs), (S2_vsplatrb I32:$Rs))>;1138 1139let AddedComplexity = 10 in {1140  def: Pat<(sext_inreg (HexagonEXTRACTU I32:$Rs,  8, u5_0ImmPred:$U5),  i8),1141           (S4_extract  I32:$Rs,  8, imm:$U5)>;1142  def: Pat<(sext_inreg (HexagonEXTRACTU I32:$Rs, 16, u5_0ImmPred:$U5), i16),1143           (S4_extract  I32:$Rs, 16, imm:$U5)>;1144  def: Pat<(sext_inreg (HexagonEXTRACTU I64:$Rs,  8, u6_0ImmPred:$U6),  i8),1145           (S4_extractp I64:$Rs,  8, imm:$U6)>;1146  def: Pat<(sext_inreg (HexagonEXTRACTU I64:$Rs, 16, u6_0ImmPred:$U6), i16),1147           (S4_extractp I64:$Rs, 16, imm:$U6)>;1148  def: Pat<(sext_inreg (HexagonEXTRACTU I64:$Rs, 32, u6_0ImmPred:$U6), i32),1149           (S4_extractp I64:$Rs, 32, imm:$U6)>;1150}1151 1152def: Pat<(sext_inreg (HexagonEXTRACTU I32:$Rs,  8, I32:$Off),  i8),1153         (S4_extract_rp  I32:$Rs, (Combinew (ToI32 8), I32:$Off))>;1154def: Pat<(sext_inreg (HexagonEXTRACTU I32:$Rs, 16, I32:$Off), i16),1155         (S4_extract_rp  I32:$Rs, (Combinew (ToI32 16), I32:$Off))>;1156def: Pat<(sext_inreg (HexagonEXTRACTU I64:$Rs,  8, I32:$Off),  i8),1157         (S4_extractp_rp I64:$Rs, (Combinew (ToI32 8), I32:$Off))>;1158def: Pat<(sext_inreg (HexagonEXTRACTU I64:$Rs, 16, I32:$Off), i16),1159         (S4_extractp_rp I64:$Rs, (Combinew (ToI32 16), I32:$Off))>;1160def: Pat<(sext_inreg (HexagonEXTRACTU I64:$Rs, 32, I32:$Off), i32),1161         (S4_extractp_rp I64:$Rs, (Combinew (ToI32 32), I32:$Off))>;1162 1163 1164// --(8) Shift/permute ---------------------------------------------------1165//1166 1167def SDTHexagonI64I32I32: SDTypeProfile<1, 2,1168  [SDTCisVT<0, i64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;1169 1170def HexagonCOMBINE:  SDNode<"HexagonISD::COMBINE",  SDTHexagonI64I32I32>;1171 1172def: Pat<(HexagonCOMBINE I32:$Rs, I32:$Rt), (Combinew $Rs, $Rt)>;1173 1174// The complexity of the combines involving immediates should be greater1175// than the complexity of the combine with two registers.1176let AddedComplexity = 50 in {1177  def: Pat<(HexagonCOMBINE I32:$Rs, anyimm:$s8),1178           (A4_combineri IntRegs:$Rs, imm:$s8)>;1179  def: Pat<(HexagonCOMBINE anyimm:$s8, I32:$Rs),1180           (A4_combineir imm:$s8, IntRegs:$Rs)>;1181}1182 1183// The complexity of the combine with two immediates should be greater than1184// the complexity of a combine involving a register.1185let AddedComplexity = 75 in {1186  def: Pat<(HexagonCOMBINE s8_0ImmPred:$s8, anyimm:$u6),1187           (A4_combineii imm:$s8, imm:$u6)>;1188  def: Pat<(HexagonCOMBINE anyimm:$s8, s8_0ImmPred:$S8),1189           (A2_combineii imm:$s8, imm:$S8)>;1190}1191 1192def: Pat<(bswap I32:$Rs),  (A2_swiz I32:$Rs)>;1193def: Pat<(bswap I64:$Rss), (Combinew (A2_swiz (LoReg $Rss)),1194                                     (A2_swiz (HiReg $Rss)))>;1195 1196def: Pat<(bswap V2I16:$Rs), (A2_combine_lh (A2_swiz $Rs), (A2_swiz $Rs))>;1197def: Pat<(bswap V2I32:$Rs), (Combinew (A2_swiz (HiReg $Rs)),1198                                      (A2_swiz (LoReg $Rs)))>;1199def: Pat<(bswap V4I16:$Rs), (A2_orp (S2_lsr_i_vh $Rs, 8),1200                                    (S2_asl_i_vh $Rs, 8))>;1201 1202def: Pat<(shl s6_0ImmPred:$s6, I32:$Rt),  (S4_lsli imm:$s6, I32:$Rt)>;1203def: Pat<(shl I32:$Rs, (i32 16)),         (A2_aslh I32:$Rs)>;1204def: Pat<(sra I32:$Rs, (i32 16)),         (A2_asrh I32:$Rs)>;1205 1206def: OpR_RI_pat<S2_asr_i_r,  Sra, i32,   I32,   u5_0ImmPred>;1207def: OpR_RI_pat<S2_lsr_i_r,  Srl, i32,   I32,   u5_0ImmPred>;1208def: OpR_RI_pat<S2_asl_i_r,  Shl, i32,   I32,   u5_0ImmPred>;1209def: OpR_RI_pat<S2_asr_i_p,  Sra, i64,   I64,   u6_0ImmPred>;1210def: OpR_RI_pat<S2_lsr_i_p,  Srl, i64,   I64,   u6_0ImmPred>;1211def: OpR_RI_pat<S2_asl_i_p,  Shl, i64,   I64,   u6_0ImmPred>;1212 1213def: OpR_RR_pat<S2_asr_r_r, Sra, i32, I32, I32>;1214def: OpR_RR_pat<S2_lsr_r_r, Srl, i32, I32, I32>;1215def: OpR_RR_pat<S2_asl_r_r, Shl, i32, I32, I32>;1216def: OpR_RR_pat<S2_asr_r_p, Sra, i64, I64, I32>;1217def: OpR_RR_pat<S2_lsr_r_p, Srl, i64, I64, I32>;1218def: OpR_RR_pat<S2_asl_r_p, Shl, i64, I64, I32>;1219 1220// Funnel shifts.1221def IsMul8_U3: PatLeaf<(i32 imm), [{1222  uint64_t V = N->getZExtValue();1223  return V % 8 == 0 && isUInt<3>(V / 8);1224}]>;1225 1226def Divu8: SDNodeXForm<imm, [{1227  return CurDAG->getTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i32);1228}]>;1229 1230// Funnel shift-left.1231def FShl32i: OutPatFrag<(ops node:$Rs, node:$Rt, node:$S),1232  (HiReg (S2_asl_i_p (Combinew $Rs, $Rt), $S))>;1233def FShl32r: OutPatFrag<(ops node:$Rs, node:$Rt, node:$Ru),1234  (HiReg (S2_asl_r_p (Combinew $Rs, $Rt), $Ru))>;1235 1236def FShl64i: OutPatFrag<(ops node:$Rs, node:$Rt, node:$S),1237  (S2_lsr_i_p_or (S2_asl_i_p $Rs, $S),  $Rt, (Subi<64> $S))>;1238def FShl64r: OutPatFrag<(ops node:$Rs, node:$Rt, node:$Ru),1239  (S2_lsr_r_p_or (S2_asl_r_p $Rs, $Ru), $Rt, (A2_subri 64, $Ru))>;1240 1241// Combined SDNodeXForm: (Divu8 (Subi<64> $S))1242def Divu64_8: SDNodeXForm<imm, [{1243  return CurDAG->getTargetConstant((64 - N->getSExtValue()) / 8,1244                                   SDLoc(N), MVT::i32);1245}]>;1246 1247// Special cases:1248let AddedComplexity = 100 in {1249  def: Pat<(fshl I32:$Rs, I32:$Rt, (i32 16)),1250           (A2_combine_lh I32:$Rs, I32:$Rt)>;1251  def: Pat<(fshl I64:$Rs, I64:$Rt, IsMul8_U3:$S),1252           (S2_valignib I64:$Rs, I64:$Rt, (Divu64_8 $S))>;1253}1254 1255let Predicates = [HasV60], AddedComplexity = 50 in {1256  def: OpR_RI_pat<S6_rol_i_r, Rol, i32, I32, u5_0ImmPred>;1257  def: OpR_RI_pat<S6_rol_i_p, Rol, i64, I64, u6_0ImmPred>;1258}1259let AddedComplexity = 30 in {1260  def: Pat<(rotl I32:$Rs, u5_0ImmPred:$S),          (FShl32i $Rs, $Rs, imm:$S)>;1261  def: Pat<(rotl I64:$Rs, u6_0ImmPred:$S),          (FShl64i $Rs, $Rs, imm:$S)>;1262  def: Pat<(fshl I32:$Rs, I32:$Rt, u5_0ImmPred:$S), (FShl32i $Rs, $Rt, imm:$S)>;1263  def: Pat<(fshl I64:$Rs, I64:$Rt, u6_0ImmPred:$S), (FShl64i $Rs, $Rt, imm:$S)>;1264}1265def: Pat<(rotl I32:$Rs, I32:$Rt),           (FShl32r $Rs, $Rs, $Rt)>;1266def: Pat<(rotl I64:$Rs, I32:$Rt),           (FShl64r $Rs, $Rs, $Rt)>;1267def: Pat<(fshl I32:$Rs, I32:$Rt, I32:$Ru),  (FShl32r $Rs, $Rt, $Ru)>;1268def: Pat<(fshl I64:$Rs, I64:$Rt, I32:$Ru),  (FShl64r $Rs, $Rt, $Ru)>;1269 1270// Funnel shift-right.1271def FShr32i: OutPatFrag<(ops node:$Rs, node:$Rt, node:$S),1272  (LoReg (S2_lsr_i_p (Combinew $Rs, $Rt), $S))>;1273def FShr32r: OutPatFrag<(ops node:$Rs, node:$Rt, node:$Ru),1274  (LoReg (S2_lsr_r_p (Combinew $Rs, $Rt), $Ru))>;1275 1276def FShr64i: OutPatFrag<(ops node:$Rs, node:$Rt, node:$S),1277  (S2_asl_i_p_or (S2_lsr_i_p $Rt, $S),  $Rs, (Subi<64> $S))>;1278def FShr64r: OutPatFrag<(ops node:$Rs, node:$Rt, node:$Ru),1279  (S2_asl_r_p_or (S2_lsr_r_p $Rt, $Ru), $Rs, (A2_subri 64, $Ru))>;1280 1281// Special cases:1282let AddedComplexity = 100 in {1283  def: Pat<(fshr I32:$Rs, I32:$Rt, (i32 16)),1284           (A2_combine_lh I32:$Rs, I32:$Rt)>;1285  def: Pat<(fshr I64:$Rs, I64:$Rt, IsMul8_U3:$S),1286           (S2_valignib I64:$Rs, I64:$Rt, (Divu8 $S))>;1287}1288 1289let Predicates = [HasV60], AddedComplexity = 50 in {1290  def: Pat<(rotr I32:$Rs, u5_0ImmPred:$S), (S6_rol_i_r I32:$Rs, (Subi<32> $S))>;1291  def: Pat<(rotr I64:$Rs, u6_0ImmPred:$S), (S6_rol_i_p I64:$Rs, (Subi<64> $S))>;1292}1293let AddedComplexity = 30 in {1294  def: Pat<(rotr I32:$Rs, u5_0ImmPred:$S),          (FShr32i $Rs, $Rs, imm:$S)>;1295  def: Pat<(rotr I64:$Rs, u6_0ImmPred:$S),          (FShr64i $Rs, $Rs, imm:$S)>;1296  def: Pat<(fshr I32:$Rs, I32:$Rt, u5_0ImmPred:$S), (FShr32i $Rs, $Rt, imm:$S)>;1297  def: Pat<(fshr I64:$Rs, I64:$Rt, u6_0ImmPred:$S), (FShr64i $Rs, $Rt, imm:$S)>;1298}1299def: Pat<(rotr I32:$Rs, I32:$Rt),           (FShr32r $Rs, $Rs, $Rt)>;1300def: Pat<(rotr I64:$Rs, I32:$Rt),           (FShr64r $Rs, $Rs, $Rt)>;1301def: Pat<(fshr I32:$Rs, I32:$Rt, I32:$Ru),  (FShr32r $Rs, $Rt, $Ru)>;1302def: Pat<(fshr I64:$Rs, I64:$Rt, I32:$Ru),  (FShr64r $Rs, $Rt, $Ru)>;1303 1304 1305def: Pat<(sra (add (sra I32:$Rs, u5_0ImmPred:$u5), 1), (i32 1)),1306         (S2_asr_i_r_rnd I32:$Rs, imm:$u5)>;1307def: Pat<(sra (add (sra I64:$Rs, u6_0ImmPred:$u6), 1), (i32 1)),1308         (S2_asr_i_p_rnd I64:$Rs, imm:$u6)>;1309 1310// Prefer S2_addasl_rrri over S2_asl_i_r_acc.1311let AddedComplexity = 120 in1312def: Pat<(add I32:$Rt, (shl I32:$Rs, u3_0ImmPred:$u3)),1313         (S2_addasl_rrri IntRegs:$Rt, IntRegs:$Rs, imm:$u3)>;1314 1315let AddedComplexity = 100 in {1316  def: AccRRI_pat<S2_asr_i_r_acc,   Add, Su<Sra>, I32, u5_0ImmPred>;1317  def: AccRRI_pat<S2_asr_i_r_nac,   Sub, Su<Sra>, I32, u5_0ImmPred>;1318  def: AccRRI_pat<S2_asr_i_r_and,   And, Su<Sra>, I32, u5_0ImmPred>;1319  def: AccRRI_pat<S2_asr_i_r_or,    Or,  Su<Sra>, I32, u5_0ImmPred>;1320 1321  def: AccRRI_pat<S2_asr_i_p_acc,   Add, Su<Sra>, I64, u6_0ImmPred>;1322  def: AccRRI_pat<S2_asr_i_p_nac,   Sub, Su<Sra>, I64, u6_0ImmPred>;1323  def: AccRRI_pat<S2_asr_i_p_and,   And, Su<Sra>, I64, u6_0ImmPred>;1324  def: AccRRI_pat<S2_asr_i_p_or,    Or,  Su<Sra>, I64, u6_0ImmPred>;1325 1326  def: AccRRI_pat<S2_lsr_i_r_acc,   Add, Su<Srl>, I32, u5_0ImmPred>;1327  def: AccRRI_pat<S2_lsr_i_r_nac,   Sub, Su<Srl>, I32, u5_0ImmPred>;1328  def: AccRRI_pat<S2_lsr_i_r_and,   And, Su<Srl>, I32, u5_0ImmPred>;1329  def: AccRRI_pat<S2_lsr_i_r_or,    Or,  Su<Srl>, I32, u5_0ImmPred>;1330  def: AccRRI_pat<S2_lsr_i_r_xacc,  Xor, Su<Srl>, I32, u5_0ImmPred>;1331 1332  def: AccRRI_pat<S2_lsr_i_p_acc,   Add, Su<Srl>, I64, u6_0ImmPred>;1333  def: AccRRI_pat<S2_lsr_i_p_nac,   Sub, Su<Srl>, I64, u6_0ImmPred>;1334  def: AccRRI_pat<S2_lsr_i_p_and,   And, Su<Srl>, I64, u6_0ImmPred>;1335  def: AccRRI_pat<S2_lsr_i_p_or,    Or,  Su<Srl>, I64, u6_0ImmPred>;1336  def: AccRRI_pat<S2_lsr_i_p_xacc,  Xor, Su<Srl>, I64, u6_0ImmPred>;1337 1338  def: AccRRI_pat<S2_asl_i_r_acc,   Add, Su<Shl>, I32, u5_0ImmPred>;1339  def: AccRRI_pat<S2_asl_i_r_nac,   Sub, Su<Shl>, I32, u5_0ImmPred>;1340  def: AccRRI_pat<S2_asl_i_r_and,   And, Su<Shl>, I32, u5_0ImmPred>;1341  def: AccRRI_pat<S2_asl_i_r_or,    Or,  Su<Shl>, I32, u5_0ImmPred>;1342  def: AccRRI_pat<S2_asl_i_r_xacc,  Xor, Su<Shl>, I32, u5_0ImmPred>;1343 1344  def: AccRRI_pat<S2_asl_i_p_acc,   Add, Su<Shl>, I64, u6_0ImmPred>;1345  def: AccRRI_pat<S2_asl_i_p_nac,   Sub, Su<Shl>, I64, u6_0ImmPred>;1346  def: AccRRI_pat<S2_asl_i_p_and,   And, Su<Shl>, I64, u6_0ImmPred>;1347  def: AccRRI_pat<S2_asl_i_p_or,    Or,  Su<Shl>, I64, u6_0ImmPred>;1348  def: AccRRI_pat<S2_asl_i_p_xacc,  Xor, Su<Shl>, I64, u6_0ImmPred>;1349 1350  let Predicates = [HasV60] in {1351    def: AccRRI_pat<S6_rol_i_r_acc,   Add, Su<Rol>, I32, u5_0ImmPred>;1352    def: AccRRI_pat<S6_rol_i_r_nac,   Sub, Su<Rol>, I32, u5_0ImmPred>;1353    def: AccRRI_pat<S6_rol_i_r_and,   And, Su<Rol>, I32, u5_0ImmPred>;1354    def: AccRRI_pat<S6_rol_i_r_or,    Or,  Su<Rol>, I32, u5_0ImmPred>;1355    def: AccRRI_pat<S6_rol_i_r_xacc,  Xor, Su<Rol>, I32, u5_0ImmPred>;1356 1357    def: AccRRI_pat<S6_rol_i_p_acc,   Add, Su<Rol>, I64, u6_0ImmPred>;1358    def: AccRRI_pat<S6_rol_i_p_nac,   Sub, Su<Rol>, I64, u6_0ImmPred>;1359    def: AccRRI_pat<S6_rol_i_p_and,   And, Su<Rol>, I64, u6_0ImmPred>;1360    def: AccRRI_pat<S6_rol_i_p_or,    Or,  Su<Rol>, I64, u6_0ImmPred>;1361    def: AccRRI_pat<S6_rol_i_p_xacc,  Xor, Su<Rol>, I64, u6_0ImmPred>;1362  }1363}1364 1365let AddedComplexity = 100 in {1366  def: AccRRR_pat<S2_asr_r_r_acc,   Add, Su<Sra>, I32, I32, I32>;1367  def: AccRRR_pat<S2_asr_r_r_nac,   Sub, Su<Sra>, I32, I32, I32>;1368  def: AccRRR_pat<S2_asr_r_r_and,   And, Su<Sra>, I32, I32, I32>;1369  def: AccRRR_pat<S2_asr_r_r_or,    Or,  Su<Sra>, I32, I32, I32>;1370 1371  def: AccRRR_pat<S2_asr_r_p_acc,   Add, Su<Sra>, I64, I64, I32>;1372  def: AccRRR_pat<S2_asr_r_p_nac,   Sub, Su<Sra>, I64, I64, I32>;1373  def: AccRRR_pat<S2_asr_r_p_and,   And, Su<Sra>, I64, I64, I32>;1374  def: AccRRR_pat<S2_asr_r_p_or,    Or,  Su<Sra>, I64, I64, I32>;1375  def: AccRRR_pat<S2_asr_r_p_xor,   Xor, Su<Sra>, I64, I64, I32>;1376 1377  def: AccRRR_pat<S2_lsr_r_r_acc,   Add, Su<Srl>, I32, I32, I32>;1378  def: AccRRR_pat<S2_lsr_r_r_nac,   Sub, Su<Srl>, I32, I32, I32>;1379  def: AccRRR_pat<S2_lsr_r_r_and,   And, Su<Srl>, I32, I32, I32>;1380  def: AccRRR_pat<S2_lsr_r_r_or,    Or,  Su<Srl>, I32, I32, I32>;1381 1382  def: AccRRR_pat<S2_lsr_r_p_acc,   Add, Su<Srl>, I64, I64, I32>;1383  def: AccRRR_pat<S2_lsr_r_p_nac,   Sub, Su<Srl>, I64, I64, I32>;1384  def: AccRRR_pat<S2_lsr_r_p_and,   And, Su<Srl>, I64, I64, I32>;1385  def: AccRRR_pat<S2_lsr_r_p_or,    Or,  Su<Srl>, I64, I64, I32>;1386  def: AccRRR_pat<S2_lsr_r_p_xor,   Xor, Su<Srl>, I64, I64, I32>;1387 1388  def: AccRRR_pat<S2_asl_r_r_acc,   Add, Su<Shl>, I32, I32, I32>;1389  def: AccRRR_pat<S2_asl_r_r_nac,   Sub, Su<Shl>, I32, I32, I32>;1390  def: AccRRR_pat<S2_asl_r_r_and,   And, Su<Shl>, I32, I32, I32>;1391  def: AccRRR_pat<S2_asl_r_r_or,    Or,  Su<Shl>, I32, I32, I32>;1392 1393  def: AccRRR_pat<S2_asl_r_p_acc,   Add, Su<Shl>, I64, I64, I32>;1394  def: AccRRR_pat<S2_asl_r_p_nac,   Sub, Su<Shl>, I64, I64, I32>;1395  def: AccRRR_pat<S2_asl_r_p_and,   And, Su<Shl>, I64, I64, I32>;1396  def: AccRRR_pat<S2_asl_r_p_or,    Or,  Su<Shl>, I64, I64, I32>;1397  def: AccRRR_pat<S2_asl_r_p_xor,   Xor, Su<Shl>, I64, I64, I32>;1398}1399 1400 1401class OpshIRI_pat<InstHexagon MI, PatFrag Op, PatFrag ShOp,1402                  PatFrag RegPred, PatFrag ImmPred>1403  : Pat<(Op anyimm:$u8, (ShOp RegPred:$Rs, ImmPred:$U5)),1404        (MI anyimm:$u8, RegPred:$Rs, imm:$U5)>;1405 1406let AddedComplexity = 200, Predicates = [UseCompound] in {1407  def: OpshIRI_pat<S4_addi_asl_ri,  Add, Su<Shl>, I32, u5_0ImmPred>;1408  def: OpshIRI_pat<S4_addi_lsr_ri,  Add, Su<Srl>, I32, u5_0ImmPred>;1409  def: OpshIRI_pat<S4_subi_asl_ri,  Sub, Su<Shl>, I32, u5_0ImmPred>;1410  def: OpshIRI_pat<S4_subi_lsr_ri,  Sub, Su<Srl>, I32, u5_0ImmPred>;1411  def: OpshIRI_pat<S4_andi_asl_ri,  And, Su<Shl>, I32, u5_0ImmPred>;1412  def: OpshIRI_pat<S4_andi_lsr_ri,  And, Su<Srl>, I32, u5_0ImmPred>;1413  def: OpshIRI_pat<S4_ori_asl_ri,   Or,  Su<Shl>, I32, u5_0ImmPred>;1414  def: OpshIRI_pat<S4_ori_lsr_ri,   Or,  Su<Srl>, I32, u5_0ImmPred>;1415}1416 1417// Prefer this pattern to S2_asl_i_p_or for the special case of joining1418// two 32-bit words into a 64-bit word.1419let AddedComplexity = 200 in1420def: Pat<(or (shl (Aext64 I32:$a), (i32 32)), (Zext64 I32:$b)),1421         (Combinew I32:$a, I32:$b)>;1422 1423def: Pat<(or (or (or (shl (Zext64 (and I32:$b, (i32 65535))), (i32 16)),1424                     (Zext64 (and I32:$a, (i32 65535)))),1425                 (shl (Aext64 (and I32:$c, (i32 65535))), (i32 32))),1426             (shl (Aext64 I32:$d), (i32 48))),1427         (Combinew (A2_combine_ll I32:$d, I32:$c),1428                   (A2_combine_ll I32:$b, I32:$a))>;1429 1430let AddedComplexity = 200 in {1431  def: Pat<(or (shl I32:$Rt, (i32 16)), (and I32:$Rs, (i32 65535))),1432           (A2_combine_ll I32:$Rt, I32:$Rs)>;1433  def: Pat<(or (shl I32:$Rt, (i32 16)), (srl I32:$Rs, (i32 16))),1434           (A2_combine_lh I32:$Rt, I32:$Rs)>;1435  def: Pat<(or (and I32:$Rt, (i32 268431360)), (and I32:$Rs, (i32 65535))),1436           (A2_combine_hl I32:$Rt, I32:$Rs)>;1437  def: Pat<(or (and I32:$Rt, (i32 268431360)), (srl I32:$Rs, (i32 16))),1438           (A2_combine_hh I32:$Rt, I32:$Rs)>;1439}1440 1441def SDTHexagonVShift1442  : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisVec<0>, SDTCisVT<2, i32>]>;1443 1444def HexagonVASL: SDNode<"HexagonISD::VASL", SDTHexagonVShift>;1445def HexagonVASR: SDNode<"HexagonISD::VASR", SDTHexagonVShift>;1446def HexagonVLSR: SDNode<"HexagonISD::VLSR", SDTHexagonVShift>;1447 1448// Funnel shifts with the shift amount module element bit width.1449def HexagonMFSHL: SDNode<"HexagonISD::MFSHL", SDTIntShiftDOp>;1450def HexagonMFSHR: SDNode<"HexagonISD::MFSHR", SDTIntShiftDOp>;1451 1452def: OpR_RI_pat<S2_asl_i_vw, pf2<HexagonVASL>, v2i32, V2I32, u5_0ImmPred>;1453def: OpR_RI_pat<S2_asl_i_vh, pf2<HexagonVASL>, v4i16, V4I16, u4_0ImmPred>;1454def: OpR_RI_pat<S2_asr_i_vw, pf2<HexagonVASR>, v2i32, V2I32, u5_0ImmPred>;1455def: OpR_RI_pat<S2_asr_i_vh, pf2<HexagonVASR>, v4i16, V4I16, u4_0ImmPred>;1456def: OpR_RI_pat<S2_lsr_i_vw, pf2<HexagonVLSR>, v2i32, V2I32, u5_0ImmPred>;1457def: OpR_RI_pat<S2_lsr_i_vh, pf2<HexagonVLSR>, v4i16, V4I16, u4_0ImmPred>;1458 1459def: OpR_RR_pat<S2_asl_r_vw, pf2<HexagonVASL>, v2i32, V2I32, I32>;1460def: OpR_RR_pat<S2_asl_r_vh, pf2<HexagonVASL>, v4i16, V4I16, I32>;1461def: OpR_RR_pat<S2_asr_r_vw, pf2<HexagonVASR>, v2i32, V2I32, I32>;1462def: OpR_RR_pat<S2_asr_r_vh, pf2<HexagonVASR>, v4i16, V4I16, I32>;1463def: OpR_RR_pat<S2_lsr_r_vw, pf2<HexagonVLSR>, v2i32, V2I32, I32>;1464def: OpR_RR_pat<S2_lsr_r_vh, pf2<HexagonVLSR>, v4i16, V4I16, I32>;1465 1466def: Pat<(sra V2I32:$b, (v2i32 (splat_vector u5_0ImmPred:$c))),1467         (S2_asr_i_vw V2I32:$b, imm:$c)>;1468def: Pat<(srl V2I32:$b, (v2i32 (splat_vector u5_0ImmPred:$c))),1469         (S2_lsr_i_vw V2I32:$b, imm:$c)>;1470def: Pat<(shl V2I32:$b, (v2i32 (splat_vector u5_0ImmPred:$c))),1471         (S2_asl_i_vw V2I32:$b, imm:$c)>;1472def: Pat<(sra V4I16:$b, (v4i16 (splat_vector u4_0ImmPred:$c))),1473         (S2_asr_i_vh V4I16:$b, imm:$c)>;1474def: Pat<(srl V4I16:$b, (v4i16 (splat_vector u4_0ImmPred:$c))),1475         (S2_lsr_i_vh V4I16:$b, imm:$c)>;1476def: Pat<(shl V4I16:$b, (v4i16 (splat_vector u4_0ImmPred:$c))),1477         (S2_asl_i_vh V4I16:$b, imm:$c)>;1478 1479def: Pat<(HexagonVASR V2I16:$Rs, u4_0ImmPred:$S),1480         (LoReg (S2_asr_i_vh (ToAext64 $Rs), imm:$S))>;1481def: Pat<(HexagonVASL V2I16:$Rs, u4_0ImmPred:$S),1482         (LoReg (S2_asl_i_vh (ToAext64 $Rs), imm:$S))>;1483def: Pat<(HexagonVLSR V2I16:$Rs, u4_0ImmPred:$S),1484         (LoReg (S2_lsr_i_vh (ToAext64 $Rs), imm:$S))>;1485def: Pat<(HexagonVASR V2I16:$Rs, I32:$Rt),1486         (LoReg (S2_asr_i_vh (ToAext64 $Rs), I32:$Rt))>;1487def: Pat<(HexagonVASL V2I16:$Rs, I32:$Rt),1488         (LoReg (S2_asl_i_vh (ToAext64 $Rs), I32:$Rt))>;1489def: Pat<(HexagonVLSR V2I16:$Rs, I32:$Rt),1490         (LoReg (S2_lsr_i_vh (ToAext64 $Rs), I32:$Rt))>;1491 1492 1493// --(9) Arithmetic/bitwise ----------------------------------------------1494//1495 1496def: Pat<(abs  I32:$Rs), (A2_abs   I32:$Rs)>;1497def: Pat<(abs  I64:$Rs), (A2_absp  I64:$Rs)>;1498def: Pat<(not  I32:$Rs), (A2_subri -1, I32:$Rs)>;1499def: Pat<(not  I64:$Rs), (A2_notp  I64:$Rs)>;1500def: Pat<(ineg I64:$Rs), (A2_negp  I64:$Rs)>;1501 1502def: Pat<(fabs F32:$Rs), (S2_clrbit_i    F32:$Rs, 31)>;1503def: Pat<(fneg F32:$Rs), (S2_togglebit_i F32:$Rs, 31)>;1504 1505def: Pat<(fabs F64:$Rs),1506         (Combinew (S2_clrbit_i (HiReg $Rs), 31),1507                   (i32 (LoReg $Rs)))>;1508def: Pat<(fneg F64:$Rs),1509         (Combinew (S2_togglebit_i (HiReg $Rs), 31),1510                   (i32 (LoReg $Rs)))>;1511 1512def: Pat<(add I32:$Rs, anyimm:$s16),   (A2_addi   I32:$Rs,  imm:$s16)>;1513def: Pat<(or  I32:$Rs, anyimm:$s10),   (A2_orir   I32:$Rs,  imm:$s10)>;1514def: Pat<(and I32:$Rs, anyimm:$s10),   (A2_andir  I32:$Rs,  imm:$s10)>;1515def: Pat<(sub anyimm:$s10, I32:$Rs),   (A2_subri  imm:$s10, I32:$Rs)>;1516 1517class OpR_RR_pat_sat<InstHexagon MI, SDNode Op, ValueType ResType,1518                     PatFrag RxPred>1519  : Pat<(ResType (Op RxPred:$Rs, RxPred:$Rt)),1520        (MI RxPred:$Rs, RxPred:$Rt)>;1521 1522def: OpR_RR_pat_sat<A2_addsat,  saddsat, i32, I32>;1523def: OpR_RR_pat_sat<A2_addpsat, saddsat, i64, I64>;1524 1525def: OpR_RR_pat<A2_add,       Add,        i32,   I32>;1526def: OpR_RR_pat<A2_sub,       Sub,        i32,   I32>;1527def: OpR_RR_pat<A2_and,       And,        i32,   I32>;1528def: OpR_RR_pat<A2_or,        Or,         i32,   I32>;1529def: OpR_RR_pat<A2_xor,       Xor,        i32,   I32>;1530def: OpR_RR_pat<A2_addp,      Add,        i64,   I64>;1531def: OpR_RR_pat<A2_subp,      Sub,        i64,   I64>;1532def: OpR_RR_pat<A2_andp,      And,        i64,   I64>;1533def: OpR_RR_pat<A2_orp,       Or,         i64,   I64>;1534def: OpR_RR_pat<A2_xorp,      Xor,        i64,   I64>;1535def: OpR_RR_pat<A4_andnp,     Not2<And>,  i64,   I64>;1536def: OpR_RR_pat<A4_ornp,      Not2<Or>,   i64,   I64>;1537 1538def: OpR_RR_pat<A2_svaddh,    Add,        v2i16, V2I16>;1539def: OpR_RR_pat<A2_svsubh,    Sub,        v2i16, V2I16>;1540 1541def: OpR_RR_pat<A2_vaddub,    Add,        v8i8,  V8I8>;1542def: OpR_RR_pat<A2_vaddh,     Add,        v4i16, V4I16>;1543def: OpR_RR_pat<A2_vaddw,     Add,        v2i32, V2I32>;1544def: OpR_RR_pat<A2_vsubub,    Sub,        v8i8,  V8I8>;1545def: OpR_RR_pat<A2_vsubh,     Sub,        v4i16, V4I16>;1546def: OpR_RR_pat<A2_vsubw,     Sub,        v2i32, V2I32>;1547 1548def: OpR_RR_pat<A2_and,       And,        v4i8,  V4I8>;1549def: OpR_RR_pat<A2_xor,       Xor,        v4i8,  V4I8>;1550def: OpR_RR_pat<A2_or,        Or,         v4i8,  V4I8>;1551def: OpR_RR_pat<A2_and,       And,        v2i16, V2I16>;1552def: OpR_RR_pat<A2_xor,       Xor,        v2i16, V2I16>;1553def: OpR_RR_pat<A2_or,        Or,         v2i16, V2I16>;1554def: OpR_RR_pat<A2_andp,      And,        v8i8,  V8I8>;1555def: OpR_RR_pat<A2_orp,       Or,         v8i8,  V8I8>;1556def: OpR_RR_pat<A2_xorp,      Xor,        v8i8,  V8I8>;1557def: OpR_RR_pat<A2_andp,      And,        v4i16, V4I16>;1558def: OpR_RR_pat<A2_orp,       Or,         v4i16, V4I16>;1559def: OpR_RR_pat<A2_xorp,      Xor,        v4i16, V4I16>;1560def: OpR_RR_pat<A2_andp,      And,        v2i32, V2I32>;1561def: OpR_RR_pat<A2_orp,       Or,         v2i32, V2I32>;1562def: OpR_RR_pat<A2_xorp,      Xor,        v2i32, V2I32>;1563 1564def: OpR_RR_pat<M2_mpyi,      Mul,        i32,   I32>;1565def: OpR_RR_pat<M2_mpy_up,    pf2<mulhs>, i32,   I32>;1566def: OpR_RR_pat<M2_mpyu_up,   pf2<mulhu>, i32,   I32>;1567def: OpR_RI_pat<M2_mpysip,    Mul,        i32,   I32, u32_0ImmPred>;1568def: OpR_RI_pat<M2_mpysmi,    Mul,        i32,   I32, s32_0ImmPred>;1569 1570// Arithmetic on predicates.1571def: OpR_RR_pat<C2_xor,       Add,        i1,    I1>;1572def: OpR_RR_pat<C2_xor,       Add,        v2i1,  V2I1>;1573def: OpR_RR_pat<C2_xor,       Add,        v4i1,  V4I1>;1574def: OpR_RR_pat<C2_xor,       Add,        v8i1,  V8I1>;1575def: OpR_RR_pat<C2_xor,       Sub,        i1,    I1>;1576def: OpR_RR_pat<C2_xor,       Sub,        v2i1,  V2I1>;1577def: OpR_RR_pat<C2_xor,       Sub,        v4i1,  V4I1>;1578def: OpR_RR_pat<C2_xor,       Sub,        v8i1,  V8I1>;1579def: OpR_RR_pat<C2_and,       Mul,        i1,    I1>;1580def: OpR_RR_pat<C2_and,       Mul,        v2i1,  V2I1>;1581def: OpR_RR_pat<C2_and,       Mul,        v4i1,  V4I1>;1582def: OpR_RR_pat<C2_and,       Mul,        v8i1,  V8I1>;1583 1584def: OpR_RR_pat<F2_sfadd,     pf2<fadd>,    f32, F32>;1585def: OpR_RR_pat<F2_sfsub,     pf2<fsub>,    f32, F32>;1586def: OpR_RR_pat<F2_sfmpy,     pf2<fmul>,    f32, F32>;1587def: OpR_RR_pat<F2_sfmin,     pf2<fminimumnum>, f32, F32>;1588def: OpR_RR_pat<F2_sfmax,     pf2<fmaximumnum>, f32, F32>;1589 1590let Predicates = [HasV66] in {1591  def: OpR_RR_pat<F2_dfadd,     pf2<fadd>,    f64, F64>;1592  def: OpR_RR_pat<F2_dfsub,     pf2<fsub>,    f64, F64>;1593}1594 1595def DfMpy: OutPatFrag<(ops node:$Rs, node:$Rt),1596  (F2_dfmpyhh1597    (F2_dfmpylh1598      (F2_dfmpylh1599        (F2_dfmpyll $Rs, $Rt),1600      $Rs, $Rt),1601    $Rt, $Rs),1602  $Rs, $Rt)>;1603 1604def fmul_afn : PatFrag<(ops node:$a, node:$b), (fmul node:$a, node:$b), [{1605  return N->getFlags().hasApproximateFuncs();1606}]>;1607let Predicates = [HasV67], AddedComplexity = 50 in {1608  def : Pat<(fmul_afn F64:$Rs, F64:$Rt), (DfMpy $Rs, $Rt)>;1609}1610let Predicates = [HasV67] in {1611  def: OpR_RR_pat<F2_dfmin,     pf2<fminimumnum>, f64, F64>;1612  def: OpR_RR_pat<F2_dfmax,     pf2<fmaximumnum>, f64, F64>;1613 1614  def: Pat<(fmul F64:$Rs, F64:$Rt), (DfMpy (F2_dfmpyfix $Rs, $Rt),1615                                           (F2_dfmpyfix $Rt, $Rs))>;1616}1617 1618// In expressions like a0*b0 + a1*b1 + ..., prefer to generate multiply-add,1619// over add-add with individual multiplies as inputs.1620let AddedComplexity = 10 in {1621  def: AccRRI_pat<M2_macsip,    Add, Su<Mul>, I32, u32_0ImmPred>;1622  def: AccRRI_pat<M2_macsin,    Sub, Su<Mul>, I32, u32_0ImmPred>;1623  def: AccRRR_pat<M2_maci,      Add, Su<Mul>, I32, I32, I32>;1624  let Predicates = [HasV66] in1625  def: AccRRR_pat<M2_mnaci,     Sub, Su<Mul>, I32, I32, I32>;1626}1627 1628def: AccRRI_pat<M2_naccii,    Sub, Su<Add>, I32, s32_0ImmPred>;1629def: AccRRI_pat<M2_accii,     Add, Su<Add>, I32, s32_0ImmPred>;1630def: AccRRR_pat<M2_acci,      Add, Su<Add>, I32, I32, I32>;1631 1632// Mulh for vectors1633//1634def: Pat<(v2i32 (mulhu V2I32:$Rss, V2I32:$Rtt)),1635         (Combinew (M2_mpyu_up (HiReg $Rss), (HiReg $Rtt)),1636                   (M2_mpyu_up (LoReg $Rss), (LoReg $Rtt)))>;1637 1638def: Pat<(v2i32 (mulhs V2I32:$Rss, V2I32:$Rtt)),1639         (Combinew (M2_mpy_up (HiReg $Rss), (HiReg $Rtt)),1640                   (M2_mpy_up (LoReg $Rss), (LoReg $Rtt)))>;1641 1642def Mulhub4:1643  OutPatFrag<(ops node:$Rs, node:$Rt), (S2_vtrunohb (M5_vmpybuu $Rs, $Rt))>;1644def Mulhub8:1645  OutPatFrag<(ops node:$Rss, node:$Rtt),1646             (Combinew (Mulhub4 (HiReg $Rss), (HiReg $Rtt)),1647                       (Mulhub4 (LoReg $Rss), (LoReg $Rtt)))>;1648 1649// (mux (x >= 0), 0, y)1650def Negbytes8:1651  OutPatFrag<(ops node:$Rss, node:$Rtt),1652             (C2_vmux (A4_vcmpbgti $Rss, -1), (A2_tfrpi 0), $Rtt)>;1653 1654def: Pat<(v4i8 (mulhu  V4I8:$Rs,  V4I8:$Rt)), (Mulhub4  $Rs,  $Rt)>;1655def: Pat<(v8i8 (mulhu V8I8:$Rss, V8I8:$Rtt)), (Mulhub8 $Rss, $Rtt)>;1656 1657// (Mulhs x, y) = (Mulhu x, y) - (x < 0 ? y : 0) - (y < 0 ? x : 0)1658def Mulhsb8:1659  OutPatFrag<(ops node:$Rss, node:$Rtt),1660             (A2_vsubub (Mulhub8 $Rss, $Rtt),1661                        (A2_vaddub (Negbytes8 $Rss, $Rtt),1662                                   (Negbytes8 $Rtt, $Rss)))>;1663 1664def: Pat<(v4i8 (mulhs V4I8:$Rs, V4I8:$Rt)),1665         (LoReg (Mulhsb8 (v8i8 (ToAext64 $Rs)), (v8i8 (ToAext64 $Rt))))>;1666def: Pat<(v8i8 (mulhs V8I8:$Rss, V8I8:$Rtt)), (Mulhsb8 $Rss, $Rtt)>;1667 1668// v2i16 *s v2i16 -> v2i321669def Muli16:1670  OutPatFrag<(ops node:$Rs, node:$Rt), (M2_vmpy2s_s0 $Rs, $Rt)>;1671 1672def Mulhsh2:1673  OutPatFrag<(ops node:$Rs, node:$Rt),1674             (A2_combine_hh (HiReg (Muli16 $Rs, $Rt)),1675                            (LoReg (Muli16 $Rs, $Rt)))>;1676def Mulhsh4:1677  OutPatFrag<(ops node:$Rss, node:$Rtt),1678             (Combinew (Mulhsh2 (HiReg $Rss), (HiReg $Rtt)),1679                       (Mulhsh2 (LoReg $Rss), (LoReg $Rtt)))>;1680 1681def: Pat<(v2i16 (mulhs  V2I16:$Rs,  V2I16:$Rt)), (Mulhsh2  $Rs,  $Rt)>;1682def: Pat<(v4i16 (mulhs V4I16:$Rss, V4I16:$Rtt)), (Mulhsh4 $Rss, $Rtt)>;1683 1684def: Pat<(v2i16 (mulhu V2I16:$Rs, V2I16:$Rt)),1685  (A2_svaddh1686     (Mulhsh2 $Rs, $Rt),1687     (A2_svaddh (LoReg (A2_andp (Combinew $Rt, $Rs),1688                                (S2_asr_i_vh (Combinew $Rs, $Rt), 15))),1689                (HiReg (A2_andp (Combinew $Rt, $Rs),1690                                (S2_asr_i_vh (Combinew $Rs, $Rt), 15)))))>;1691 1692def: Pat<(v4i16 (mulhu V4I16:$Rss, V4I16:$Rtt)),1693         (A2_vaddh1694           (Mulhsh4 $Rss, $Rtt),1695           (A2_vaddh (A2_andp V4I16:$Rss, (S2_asr_i_vh $Rtt, 15)),1696                     (A2_andp V4I16:$Rtt, (S2_asr_i_vh $Rss, 15))))>;1697 1698 1699def: Pat<(ineg (mul I32:$Rs, u8_0ImmPred:$u8)),1700         (M2_mpysin IntRegs:$Rs, imm:$u8)>;1701 1702def n8_0ImmPred: PatLeaf<(i32 imm), [{1703  int64_t V = N->getSExtValue();1704  return -255 <= V && V <= 0;1705}]>;1706 1707// Change the sign of the immediate for Rd=-mpyi(Rs,#u8)1708def: Pat<(mul I32:$Rs, n8_0ImmPred:$n8),1709         (M2_mpysin I32:$Rs, (NegImm8 imm:$n8))>;1710 1711def: Pat<(add Sext64:$Rs, I64:$Rt),1712         (A2_addsp (LoReg Sext64:$Rs), I64:$Rt)>;1713 1714def: AccRRR_pat<M4_and_and,   And, Su_ni1<And>,  I32,  I32,  I32>;1715def: AccRRR_pat<M4_and_or,    And, Su_ni1<Or>,   I32,  I32,  I32>;1716def: AccRRR_pat<M4_and_xor,   And, Su<Xor>,      I32,  I32,  I32>;1717def: AccRRR_pat<M4_or_and,    Or,  Su_ni1<And>,  I32,  I32,  I32>;1718def: AccRRR_pat<M4_or_or,     Or,  Su_ni1<Or>,   I32,  I32,  I32>;1719def: AccRRR_pat<M4_or_xor,    Or,  Su<Xor>,      I32,  I32,  I32>;1720def: AccRRR_pat<M4_xor_and,   Xor, Su_ni1<And>,  I32,  I32,  I32>;1721def: AccRRR_pat<M4_xor_or,    Xor, Su_ni1<Or>,   I32,  I32,  I32>;1722def: AccRRR_pat<M2_xor_xacc,  Xor, Su<Xor>,      I32,  I32,  I32>;1723def: AccRRR_pat<M4_xor_xacc,  Xor, Su<Xor>,      I64,  I64,  I64>;1724 1725// For dags like (or (and (not _), _), (shl _, _)) where the "or" with1726// one argument matches the patterns below, and with the other argument1727// matches S2_asl_r_r_or, etc, prefer the patterns below.1728let AddedComplexity = 110 in {  // greater than S2_asl_r_r_and/or/xor.1729  def: AccRRR_pat<M4_and_andn,  And, Su<Not2<And>>, I32,  I32,  I32>;1730  def: AccRRR_pat<M4_or_andn,   Or,  Su<Not2<And>>, I32,  I32,  I32>;1731  def: AccRRR_pat<M4_xor_andn,  Xor, Su<Not2<And>>, I32,  I32,  I32>;1732}1733 1734// S4_addaddi and S4_subaddi don't have tied operands, so give them1735// a bit of preference.1736let AddedComplexity = 30, Predicates = [UseCompound] in {1737  def: Pat<(add I32:$Rs, (Su<Add> I32:$Ru, anyimm:$s6)),1738           (S4_addaddi IntRegs:$Rs, IntRegs:$Ru, imm:$s6)>;1739  def: Pat<(add anyimm:$s6, (Su<Add> I32:$Rs, I32:$Ru)),1740           (S4_addaddi IntRegs:$Rs, IntRegs:$Ru, imm:$s6)>;1741  def: Pat<(add I32:$Rs, (Su<Sub> anyimm:$s6, I32:$Ru)),1742           (S4_subaddi IntRegs:$Rs, imm:$s6, IntRegs:$Ru)>;1743  def: Pat<(sub (Su<Add> I32:$Rs, anyimm:$s6), I32:$Ru),1744           (S4_subaddi IntRegs:$Rs, imm:$s6, IntRegs:$Ru)>;1745  def: Pat<(add (Su<Sub> I32:$Rs, I32:$Ru), anyimm:$s6),1746           (S4_subaddi IntRegs:$Rs, imm:$s6, IntRegs:$Ru)>;1747}1748 1749let Predicates = [UseCompound] in1750def: Pat<(or I32:$Ru, (Su<And> I32:$Rx, anyimm:$s10)),1751         (S4_or_andix IntRegs:$Ru, IntRegs:$Rx, imm:$s10)>;1752 1753def: Pat<(or I32:$Rx, (Su<And> I32:$Rs, anyimm:$s10)),1754         (S4_or_andi IntRegs:$Rx, IntRegs:$Rs, imm:$s10)>;1755def: Pat<(or I32:$Rx, (Su<Or> I32:$Rs, anyimm:$s10)),1756         (S4_or_ori IntRegs:$Rx, IntRegs:$Rs, imm:$s10)>;1757 1758 1759def: Pat<(i32 (trunc (sra (Su<Mul> Sext64:$Rs, Sext64:$Rt), (i32 32)))),1760         (M2_mpy_up (LoReg Sext64:$Rs), (LoReg Sext64:$Rt))>;1761def: Pat<(i32 (trunc (srl (Su<Mul> Sext64:$Rs, Sext64:$Rt), (i32 32)))),1762         (M2_mpy_up (LoReg Sext64:$Rs), (LoReg Sext64:$Rt))>;1763 1764def: Pat<(mul (Zext64 I32:$Rs), (Zext64 I32:$Rt)),1765         (M2_dpmpyuu_s0 I32:$Rs, I32:$Rt)>;1766def: Pat<(mul (Aext64 I32:$Rs), (Aext64 I32:$Rt)),1767         (M2_dpmpyuu_s0 I32:$Rs, I32:$Rt)>;1768def: Pat<(mul Sext64:$Rs, Sext64:$Rt),1769         (M2_dpmpyss_s0 (LoReg Sext64:$Rs), (LoReg Sext64:$Rt))>;1770 1771def: Pat<(add I64:$Rx, (Su<Mul> Sext64:$Rs, Sext64:$Rt)),1772         (M2_dpmpyss_acc_s0 I64:$Rx, (LoReg Sext64:$Rs), (LoReg Sext64:$Rt))>;1773def: Pat<(sub I64:$Rx, (Su<Mul> Sext64:$Rs, Sext64:$Rt)),1774         (M2_dpmpyss_nac_s0 I64:$Rx, (LoReg Sext64:$Rs), (LoReg Sext64:$Rt))>;1775def: Pat<(add I64:$Rx, (Su<Mul> (Aext64 I32:$Rs), (Aext64 I32:$Rt))),1776         (M2_dpmpyuu_acc_s0 I64:$Rx, I32:$Rs, I32:$Rt)>;1777def: Pat<(add I64:$Rx, (Su<Mul> (Zext64 I32:$Rs), (Zext64 I32:$Rt))),1778         (M2_dpmpyuu_acc_s0 I64:$Rx, I32:$Rs, I32:$Rt)>;1779def: Pat<(sub I64:$Rx, (Su<Mul> (Aext64 I32:$Rs), (Aext64 I32:$Rt))),1780         (M2_dpmpyuu_nac_s0 I64:$Rx, I32:$Rs, I32:$Rt)>;1781def: Pat<(sub I64:$Rx, (Su<Mul> (Zext64 I32:$Rs), (Zext64 I32:$Rt))),1782         (M2_dpmpyuu_nac_s0 I64:$Rx, I32:$Rs, I32:$Rt)>;1783 1784// Add halfword.1785def: Pat<(sext_inreg (add I32:$Rt, I32:$Rs), i16),1786         (A2_addh_l16_ll I32:$Rt, I32:$Rs)>;1787def: Pat<(sra (add (shl I32:$Rt, (i32 16)), I32:$Rs), (i32 16)),1788         (A2_addh_l16_hl I32:$Rt, I32:$Rs)>;1789def: Pat<(shl (add I32:$Rt, I32:$Rs), (i32 16)),1790         (A2_addh_h16_ll I32:$Rt, I32:$Rs)>;1791 1792// Subtract halfword.1793def: Pat<(sext_inreg (sub I32:$Rt, I32:$Rs), i16),1794         (A2_subh_l16_ll I32:$Rt, I32:$Rs)>;1795def: Pat<(sra (add (shl I32:$Rt, (i32 16)), I32:$Rs), (i32 16)),1796         (A2_addh_l16_hl I32:$Rt, I32:$Rs)>;1797def: Pat<(shl (sub I32:$Rt, I32:$Rs), (i32 16)),1798         (A2_subh_h16_ll I32:$Rt, I32:$Rs)>;1799 1800def: Pat<(mul I64:$Rss, I64:$Rtt),1801         (Combinew1802           (M2_maci (M2_maci (HiReg (M2_dpmpyuu_s0 (LoReg $Rss), (LoReg $Rtt))),1803                             (LoReg $Rss),1804                             (HiReg $Rtt)),1805                    (LoReg $Rtt),1806                    (HiReg $Rss)),1807           (i32 (LoReg (M2_dpmpyuu_s0 (LoReg $Rss), (LoReg $Rtt)))))>;1808 1809def MulHU : OutPatFrag<(ops node:$Rss, node:$Rtt),1810  (A2_addp1811    (M2_dpmpyuu_acc_s01812      (S2_lsr_i_p1813        (A2_addp1814          (M2_dpmpyuu_acc_s01815            (S2_lsr_i_p (M2_dpmpyuu_s0 (LoReg $Rss), (LoReg $Rtt)), 32),1816            (HiReg $Rss),1817            (LoReg $Rtt)),1818          (A4_combineir 0, (LoReg (M2_dpmpyuu_s0 (LoReg $Rss), (HiReg $Rtt))))),1819        32),1820      (HiReg $Rss),1821      (HiReg $Rtt)),1822    (S2_lsr_i_p (M2_dpmpyuu_s0 (LoReg $Rss), (HiReg $Rtt)), 32))>;1823 1824// Multiply 64-bit unsigned and use upper result.1825def : Pat <(mulhu I64:$Rss, I64:$Rtt), (MulHU $Rss, $Rtt)>;1826 1827// Multiply 64-bit signed and use upper result.1828//1829// For two signed 64-bit integers A and B, let A' and B' denote A and B1830// with the sign bit cleared. Then A = -2^63*s(A) + A', where s(A) is the1831// sign bit of A (and identically for B). With this notation, the signed1832// product A*B can be written as:1833//   AB = (-2^63 s(A) + A') * (-2^63 s(B) + B')1834//      = 2^126 s(A)s(B) - 2^63 [s(A)B'+s(B)A'] + A'B'1835//      = 2^126 s(A)s(B) + 2^63 [s(A)B'+s(B)A'] + A'B' - 2*2^63 [s(A)B'+s(B)A']1836//      = (unsigned product AB) - 2^64 [s(A)B'+s(B)A']1837 1838// Clear the sign bit in a 64-bit register.1839def ClearSign : OutPatFrag<(ops node:$Rss),1840  (Combinew (S2_clrbit_i (HiReg $Rss), 31), (i32 (LoReg $Rss)))>;1841 1842def : Pat <(mulhs I64:$Rss, I64:$Rtt),1843  (A2_subp1844    (MulHU $Rss, $Rtt),1845    (A2_addp1846      (A2_andp (S2_asr_i_p $Rss, 63), (ClearSign $Rtt)),1847      (A2_andp (S2_asr_i_p $Rtt, 63), (ClearSign $Rss))))>;1848 1849// Prefer these instructions over M2_macsip/M2_macsin: the macsi* instructions1850// will put the immediate addend into a register, while these instructions will1851// use it directly. Such a construct does not appear in the middle of a gep,1852// where M2_macsip would be preferable.1853let AddedComplexity = 20, Predicates = [UseCompound] in {1854  def: Pat<(add (Su<Mul> I32:$Rs, u6_0ImmPred:$U6), anyimm:$u6),1855           (M4_mpyri_addi imm:$u6, IntRegs:$Rs, imm:$U6)>;1856  def: Pat<(add (Su<Mul> I32:$Rs, I32:$Rt), anyimm:$u6),1857           (M4_mpyrr_addi imm:$u6, IntRegs:$Rs, IntRegs:$Rt)>;1858}1859 1860// Keep these instructions less preferable to M2_macsip/M2_macsin.1861let Predicates = [UseCompound] in {1862  def: Pat<(add I32:$Ru, (Su<Mul> I32:$Rs, u6_2ImmPred:$u6_2)),1863           (M4_mpyri_addr_u2 IntRegs:$Ru, imm:$u6_2, IntRegs:$Rs)>;1864  def: Pat<(add I32:$Ru, (Su<Mul> I32:$Rs, anyimm:$u6)),1865           (M4_mpyri_addr IntRegs:$Ru, IntRegs:$Rs, imm:$u6)>;1866  def: Pat<(add I32:$Ru, (Su<Mul> I32:$Ry, I32:$Rs)),1867           (M4_mpyrr_addr IntRegs:$Ru, IntRegs:$Ry, IntRegs:$Rs)>;1868}1869 1870def: Pat<(fma F32:$Rs, F32:$Rt, F32:$Rx),1871         (F2_sffma F32:$Rx, F32:$Rs, F32:$Rt)>;1872def: Pat<(fma (fneg F32:$Rs), F32:$Rt, F32:$Rx),1873         (F2_sffms F32:$Rx, F32:$Rs, F32:$Rt)>;1874 1875def: Pat<(mul V2I32:$Rs, V2I32:$Rt),1876         (PS_vmulw V2I32:$Rs, V2I32:$Rt)>;1877def: Pat<(add V2I32:$Rx, (mul V2I32:$Rs, V2I32:$Rt)),1878         (PS_vmulw_acc V2I32:$Rx, V2I32:$Rs, V2I32:$Rt)>;1879 1880// Add/subtract two v4i8: Hexagon does not have an insn for this one, so1881// we use the double add v8i8, and use only the low part of the result.1882def: Pat<(add V4I8:$Rs, V4I8:$Rt),1883         (LoReg (A2_vaddub (ToAext64 $Rs), (ToAext64 $Rt)))>;1884def: Pat<(sub V4I8:$Rs, V4I8:$Rt),1885         (LoReg (A2_vsubub (ToAext64 $Rs), (ToAext64 $Rt)))>;1886 1887// Use M2_vmpy2s_s0 for half-word vector multiply. It multiplies two1888// half-words, and saturates the result to a 32-bit value, except the1889// saturation never happens (it can only occur with scaling).1890def: Pat<(v2i16 (mul V2I16:$Rs, V2I16:$Rt)),1891         (LoReg (S2_vtrunewh (IMPLICIT_DEF),1892                             (M2_vmpy2s_s0 V2I16:$Rs, V2I16:$Rt)))>;1893def: Pat<(v4i16 (mul V4I16:$Rs, V4I16:$Rt)),1894         (S2_vtrunewh (M2_vmpy2s_s0 (HiReg $Rs), (HiReg $Rt)),1895                      (M2_vmpy2s_s0 (LoReg $Rs), (LoReg $Rt)))>;1896 1897// Multiplies two v4i8 vectors.1898def: Pat<(v4i8 (mul V4I8:$Rs, V4I8:$Rt)),1899         (S2_vtrunehb (M5_vmpybuu V4I8:$Rs, V4I8:$Rt))>;1900 1901// Multiplies two v8i8 vectors.1902def: Pat<(v8i8 (mul V8I8:$Rs, V8I8:$Rt)),1903         (Combinew (S2_vtrunehb (M5_vmpybuu (HiReg $Rs), (HiReg $Rt))),1904                   (S2_vtrunehb (M5_vmpybuu (LoReg $Rs), (LoReg $Rt))))>;1905 1906 1907// --(10) Bit ------------------------------------------------------------1908//1909 1910// Count leading zeros.1911def: Pat<(i32 (ctlz I32:$Rs)),                (S2_cl0 I32:$Rs)>;1912def: Pat<(i32 (trunc (ctlz I64:$Rss))),       (S2_cl0p I64:$Rss)>;1913 1914// Count trailing zeros.1915def: Pat<(i32 (cttz I32:$Rs)),                (S2_ct0 I32:$Rs)>;1916def: Pat<(i32 (trunc (cttz I64:$Rss))),       (S2_ct0p I64:$Rss)>;1917 1918// Count leading ones.1919def: Pat<(i32 (ctlz (not I32:$Rs))),          (S2_cl1 I32:$Rs)>;1920def: Pat<(i32 (trunc (ctlz (not I64:$Rss)))), (S2_cl1p I64:$Rss)>;1921 1922// Count trailing ones.1923def: Pat<(i32 (cttz (not I32:$Rs))),           (S2_ct1 I32:$Rs)>;1924def: Pat<(i32 (trunc (cttz (not I64:$Rss)))), (S2_ct1p I64:$Rss)>;1925 1926// Define leading/trailing patterns that require zero-extensions to 64 bits.1927def: Pat<(i64 (ctlz I64:$Rss)),               (ToZext64 (S2_cl0p I64:$Rss))>;1928def: Pat<(i64 (cttz I64:$Rss)),               (ToZext64 (S2_ct0p I64:$Rss))>;1929def: Pat<(i64 (ctlz (not I64:$Rss))),         (ToZext64 (S2_cl1p I64:$Rss))>;1930def: Pat<(i64 (cttz (not I64:$Rss))),         (ToZext64 (S2_ct1p I64:$Rss))>;1931 1932def: Pat<(i64 (ctpop I64:$Rss)),  (ToZext64 (S5_popcountp I64:$Rss))>;1933def: Pat<(i32 (ctpop I32:$Rs)),   (S5_popcountp (A4_combineir 0, I32:$Rs))>;1934 1935def: Pat<(bitreverse I32:$Rs),    (S2_brev I32:$Rs)>;1936def: Pat<(bitreverse I64:$Rss),   (S2_brevp I64:$Rss)>;1937 1938def: Pat<(bitreverse V4I8:$Rs),   (A2_swiz (S2_brev $Rs))>;1939def: Pat<(bitreverse V8I8:$Rs),   (Combinew (A2_swiz (LoReg (S2_brevp $Rs))),1940                                            (A2_swiz (HiReg (S2_brevp $Rs))))>;1941def: Pat<(bitreverse V2I16:$Rs),  (A2_combine_lh (S2_brev $Rs),1942                                                 (S2_brev $Rs))>;1943def: Pat<(bitreverse V4I16:$Rs),1944         (Combinew (A2_combine_lh (LoReg (S2_brevp $Rs)),1945                                  (LoReg (S2_brevp $Rs))),1946                   (A2_combine_lh (HiReg (S2_brevp $Rs)),1947                                  (HiReg (S2_brevp $Rs))))>;1948def: Pat<(bitreverse V2I32:$Rs),1949         (Combinew (i32 (LoReg (S2_brevp $Rs))),1950                   (i32 (HiReg (S2_brevp $Rs))))>;1951 1952let AddedComplexity = 20 in { // Complexity greater than and/or/xor1953  def: Pat<(and I32:$Rs, IsNPow2_32:$V),1954           (S2_clrbit_i IntRegs:$Rs, (LogN2_32 $V))>;1955  def: Pat<(or I32:$Rs, IsPow2_32:$V),1956           (S2_setbit_i IntRegs:$Rs, (Log2_32 $V))>;1957  def: Pat<(xor I32:$Rs, IsPow2_32:$V),1958           (S2_togglebit_i IntRegs:$Rs, (Log2_32 $V))>;1959 1960  def: Pat<(and I32:$Rs, (not (shl 1, I32:$Rt))),1961           (S2_clrbit_r IntRegs:$Rs, IntRegs:$Rt)>;1962  def: Pat<(or I32:$Rs, (shl 1, I32:$Rt)),1963           (S2_setbit_r IntRegs:$Rs, IntRegs:$Rt)>;1964  def: Pat<(xor I32:$Rs, (shl 1, I32:$Rt)),1965           (S2_togglebit_r IntRegs:$Rs, IntRegs:$Rt)>;1966}1967 1968// Clr/set/toggle bit for 64-bit values with immediate bit index.1969let AddedComplexity = 20 in { // Complexity greater than and/or/xor1970  def: Pat<(and I64:$Rss, IsNPow2_64L:$V),1971           (Combinew (i32 (HiReg $Rss)),1972                     (S2_clrbit_i (LoReg $Rss), (LogN2_64 $V)))>;1973  def: Pat<(and I64:$Rss, IsNPow2_64H:$V),1974           (Combinew (S2_clrbit_i (HiReg $Rss), (UDEC32 (i32 (LogN2_64 $V)))),1975                     (i32 (LoReg $Rss)))>;1976 1977  def: Pat<(or I64:$Rss, IsPow2_64L:$V),1978           (Combinew (i32 (HiReg $Rss)),1979                     (S2_setbit_i (LoReg $Rss), (Log2_64 $V)))>;1980  def: Pat<(or I64:$Rss, IsPow2_64H:$V),1981           (Combinew (S2_setbit_i (HiReg $Rss), (UDEC32 (i32 (Log2_64 $V)))),1982                     (i32 (LoReg $Rss)))>;1983 1984  def: Pat<(xor I64:$Rss, IsPow2_64L:$V),1985           (Combinew (i32 (HiReg $Rss)),1986                     (S2_togglebit_i (LoReg $Rss), (Log2_64 $V)))>;1987  def: Pat<(xor I64:$Rss, IsPow2_64H:$V),1988           (Combinew (S2_togglebit_i (HiReg $Rss), (UDEC32 (i32 (Log2_64 $V)))),1989                     (i32 (LoReg $Rss)))>;1990}1991 1992 1993let AddedComplexity = 20 in { // Complexity greater than cmp reg-imm.1994  def: Pat<(i1 (setne (and (shl 1, u5_0ImmPred:$u5), I32:$Rs), 0)),1995           (S2_tstbit_i IntRegs:$Rs, imm:$u5)>;1996  def: Pat<(i1 (setne (and (shl 1, I32:$Rt), I32:$Rs), 0)),1997           (S2_tstbit_r IntRegs:$Rs, IntRegs:$Rt)>;1998  def: Pat<(i1 (trunc I32:$Rs)),1999           (S2_tstbit_i IntRegs:$Rs, 0)>;2000  def: Pat<(i1 (trunc I64:$Rs)),2001           (S2_tstbit_i (LoReg DoubleRegs:$Rs), 0)>;2002}2003 2004def: Pat<(and (srl I32:$Rs, u5_0ImmPred:$u5), 1),2005         (I1toI32 (S2_tstbit_i I32:$Rs, imm:$u5))>;2006def: Pat<(and (srl I64:$Rss, IsULE<32,31>:$u6), 1),2007         (ToZext64 (I1toI32 (S2_tstbit_i (LoReg $Rss), imm:$u6)))>;2008def: Pat<(and (srl I64:$Rss, IsUGT<32,31>:$u6), 1),2009         (ToZext64 (I1toI32 (S2_tstbit_i (HiReg $Rss), (UDEC32 $u6))))>;2010 2011def: Pat<(and (not (srl I32:$Rs, u5_0ImmPred:$u5)), 1),2012         (I1toI32 (S4_ntstbit_i I32:$Rs, imm:$u5))>;2013def: Pat<(and (not (srl I64:$Rss, IsULE<32,31>:$u6)), 1),2014         (ToZext64 (I1toI32 (S4_ntstbit_i (LoReg $Rss), imm:$u6)))>;2015def: Pat<(and (not (srl I64:$Rss, IsUGT<32,31>:$u6)), 1),2016         (ToZext64 (I1toI32 (S4_ntstbit_i (HiReg $Rss), (UDEC32 $u6))))>;2017 2018let AddedComplexity = 20 in { // Complexity greater than compare reg-imm.2019  def: Pat<(i1 (seteq (and I32:$Rs, u6_0ImmPred:$u6), 0)),2020           (C2_bitsclri IntRegs:$Rs, imm:$u6)>;2021  def: Pat<(i1 (seteq (and I32:$Rs, I32:$Rt), 0)),2022           (C2_bitsclr IntRegs:$Rs, IntRegs:$Rt)>;2023}2024 2025let AddedComplexity = 10 in   // Complexity greater than compare reg-reg.2026def: Pat<(i1 (seteq (and I32:$Rs, I32:$Rt), IntRegs:$Rt)),2027         (C2_bitsset IntRegs:$Rs, IntRegs:$Rt)>;2028 2029def SDTTestBit:2030  SDTypeProfile<1, 2, [SDTCisVT<0, i1>, SDTCisVT<1, i32>, SDTCisVT<2, i32>]>;2031def HexagonTSTBIT: SDNode<"HexagonISD::TSTBIT", SDTTestBit>;2032 2033def: Pat<(HexagonTSTBIT I32:$Rs, u5_0ImmPred:$u5),2034         (S2_tstbit_i I32:$Rs, imm:$u5)>;2035def: Pat<(HexagonTSTBIT I32:$Rs, I32:$Rt),2036         (S2_tstbit_r I32:$Rs, I32:$Rt)>;2037 2038// Add extra complexity to prefer these instructions over bitsset/bitsclr.2039// The reason is that tstbit/ntstbit can be folded into a compound instruction:2040//   if ([!]tstbit(...)) jump ...2041let AddedComplexity = 20 in {   // Complexity greater than cmp reg-imm.2042  def: Pat<(i1 (seteq (and I32:$Rs, IsPow2_32:$u5), 0)),2043           (S4_ntstbit_i I32:$Rs, (Log2_32 imm:$u5))>;2044  def: Pat<(i1 (setne (and I32:$Rs, IsPow2_32:$u5), 0)),2045           (S2_tstbit_i I32:$Rs, (Log2_32 imm:$u5))>;2046  def: Pat<(i1 (seteq (and (shl 1, I32:$Rt), I32:$Rs), 0)),2047           (S4_ntstbit_r I32:$Rs, I32:$Rt)>;2048  def: Pat<(i1 (setne (and (shl 1, I32:$Rt), I32:$Rs), 0)),2049           (S2_tstbit_r I32:$Rs, I32:$Rt)>;2050}2051 2052def: Pat<(i1 (seteq (and I64:$Rs, IsPow2_64L:$u6), 0)),2053         (S4_ntstbit_i (LoReg $Rs), (Log2_64 $u6))>;2054def: Pat<(i1 (seteq (and I64:$Rs, IsPow2_64H:$u6), 0)),2055         (S4_ntstbit_i (HiReg $Rs), (UDEC32 (i32 (Log2_64 $u6))))>;2056def: Pat<(i1 (setne (and I64:$Rs, IsPow2_64L:$u6), 0)),2057         (S2_tstbit_i (LoReg $Rs), (Log2_64 imm:$u6))>;2058def: Pat<(i1 (setne (and I64:$Rs, IsPow2_64H:$u6), 0)),2059         (S2_tstbit_i (HiReg $Rs), (UDEC32 (i32 (Log2_64 imm:$u6))))>;2060 2061// Do not increase complexity of these patterns. In the DAG, "cmp i8" may be2062// represented as a compare against "value & 0xFF", which is an exact match2063// for cmpb (same for cmph). The patterns below do not contain any additional2064// complexity that would make them preferable, and if they were actually used2065// instead of cmpb/cmph, they would result in a compare against register that2066// is loaded with the byte/half mask (i.e. 0xFF or 0xFFFF).2067def: Pat<(i1 (setne (and I32:$Rs, u6_0ImmPred:$u6), 0)),2068         (C4_nbitsclri I32:$Rs, imm:$u6)>;2069def: Pat<(i1 (setne (and I32:$Rs, I32:$Rt), 0)),2070         (C4_nbitsclr I32:$Rs, I32:$Rt)>;2071def: Pat<(i1 (setne (and I32:$Rs, I32:$Rt), I32:$Rt)),2072         (C4_nbitsset I32:$Rs, I32:$Rt)>;2073 2074// Special patterns to address certain cases where the "top-down" matching2075// algorithm would cause suboptimal selection.2076 2077let AddedComplexity = 100 in {2078  // Avoid A4_rcmp[n]eqi in these cases:2079  def: Pat<(i32 (zext (i1 (seteq (and (shl 1, I32:$Rt), I32:$Rs), 0)))),2080           (I1toI32 (S4_ntstbit_r IntRegs:$Rs, IntRegs:$Rt))>;2081  def: Pat<(i32 (zext (i1 (setne (and (shl 1, I32:$Rt), I32:$Rs), 0)))),2082           (I1toI32 (S2_tstbit_r IntRegs:$Rs, IntRegs:$Rt))>;2083  def: Pat<(i32 (zext (i1 (seteq (and I32:$Rs, IsPow2_32:$u5), 0)))),2084           (I1toI32 (S4_ntstbit_i I32:$Rs, (Log2_32 imm:$u5)))>;2085  def: Pat<(i32 (zext (i1 (setne (and I32:$Rs, IsPow2_32:$u5), 0)))),2086           (I1toI32 (S2_tstbit_i I32:$Rs, (Log2_32 imm:$u5)))>;2087  def: Pat<(i32 (zext (i1 (seteq (and (shl 1, I32:$Rt), I32:$Rs), 0)))),2088           (I1toI32 (S4_ntstbit_r I32:$Rs, I32:$Rt))>;2089  def: Pat<(i32 (zext (i1 (setne (and (shl 1, I32:$Rt), I32:$Rs), 0)))),2090           (I1toI32 (S2_tstbit_r I32:$Rs, I32:$Rt))>;2091}2092 2093// --(11) PIC ------------------------------------------------------------2094//2095 2096def SDT_HexagonAtGot2097  : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisVT<2, i32>]>;2098def SDT_HexagonAtPcrel2099  : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;2100 2101// AT_GOT address-of-GOT, address-of-global, offset-in-global2102def HexagonAtGot       : SDNode<"HexagonISD::AT_GOT", SDT_HexagonAtGot>;2103// AT_PCREL address-of-global2104def HexagonAtPcrel     : SDNode<"HexagonISD::AT_PCREL", SDT_HexagonAtPcrel>;2105 2106def: Pat<(HexagonAtGot I32:$got, I32:$addr, (i32 0)),2107         (L2_loadri_io I32:$got, imm:$addr)>;2108def: Pat<(HexagonAtGot I32:$got, I32:$addr, s30_2ImmPred:$off),2109         (A2_addi (L2_loadri_io I32:$got, imm:$addr), imm:$off)>;2110def: Pat<(HexagonAtPcrel I32:$addr),2111         (C4_addipc imm:$addr)>;2112 2113// The HVX load patterns also match AT_PCREL directly. Make sure that2114// if the selection of this opcode changes, it's updated in all places.2115 2116 2117// --(12) Load -----------------------------------------------------------2118//2119 2120def L1toI32:  OutPatFrag<(ops node:$Rs), (A2_subri 0, (i32 $Rs))>;2121def L1toI64:  OutPatFrag<(ops node:$Rs), (ToSext64 (L1toI32 $Rs))>;2122 2123def extloadv2i8: PatFrag<(ops node:$ptr), (extload node:$ptr), [{2124  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v2i8;2125}]>;2126def extloadv4i8: PatFrag<(ops node:$ptr), (extload node:$ptr), [{2127  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v4i8;2128}]>;2129 2130def zextloadv2i8: PatFrag<(ops node:$ptr), (zextload node:$ptr), [{2131  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v2i8;2132}]>;2133def zextloadv4i8: PatFrag<(ops node:$ptr), (zextload node:$ptr), [{2134  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v4i8;2135}]>;2136 2137def sextloadv2i8: PatFrag<(ops node:$ptr), (sextload node:$ptr), [{2138  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v2i8;2139}]>;2140def sextloadv4i8: PatFrag<(ops node:$ptr), (sextload node:$ptr), [{2141  return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v4i8;2142}]>;2143 2144// Patterns to select load-indexed: Rs + Off.2145// - frameindex [+ imm],2146multiclass Loadxfi_pat<PatFrags Load, ValueType VT, PatLeaf ImmPred,2147                       InstHexagon MI> {2148  def: Pat<(VT (Load (add (i32 AddrFI:$fi), ImmPred:$Off))),2149           (VT (MI AddrFI:$fi, imm:$Off))>;2150  def: Pat<(VT (Load (IsOrAdd (i32 AddrFI:$fi), ImmPred:$Off))),2151           (VT (MI AddrFI:$fi, imm:$Off))>;2152  def: Pat<(VT (Load AddrFI:$fi)), (VT (MI AddrFI:$fi, 0))>;2153}2154 2155// Patterns to select load-indexed: Rs + Off.2156// - base reg [+ imm]2157multiclass Loadxgi_pat<PatFrags Load, ValueType VT, PatLeaf ImmPred,2158                       InstHexagon MI> {2159  def: Pat<(VT (Load (add I32:$Rs, ImmPred:$Off))),2160           (VT (MI IntRegs:$Rs, imm:$Off))>;2161  def: Pat<(VT (Load (IsOrAdd I32:$Rs, ImmPred:$Off))),2162           (VT (MI IntRegs:$Rs, imm:$Off))>;2163  def: Pat<(VT (Load I32:$Rs)), (VT (MI IntRegs:$Rs, 0))>;2164}2165 2166// Patterns to select load-indexed: Rs + Off. Combines Loadxfi + Loadxgi.2167multiclass Loadxi_pat<PatFrags Load, ValueType VT, PatLeaf ImmPred,2168                      InstHexagon MI> {2169  defm: Loadxfi_pat<Load, VT, ImmPred, MI>;2170  defm: Loadxgi_pat<Load, VT, ImmPred, MI>;2171}2172 2173// Patterns to select load reg indexed: Rs + Off with a value modifier.2174// - frameindex [+ imm]2175multiclass Loadxfim_pat<PatFrag Load, ValueType VT, PatFrag ValueMod,2176                        PatLeaf ImmPred, InstHexagon MI> {2177  def: Pat<(VT (Load (add (i32 AddrFI:$fi), ImmPred:$Off))),2178           (VT (ValueMod (MI AddrFI:$fi, imm:$Off)))>;2179  def: Pat<(VT (Load (IsOrAdd (i32 AddrFI:$fi), ImmPred:$Off))),2180           (VT (ValueMod (MI AddrFI:$fi, imm:$Off)))>;2181  def: Pat<(VT (Load AddrFI:$fi)), (VT (ValueMod (MI AddrFI:$fi, 0)))>;2182}2183 2184// Patterns to select load reg indexed: Rs + Off with a value modifier.2185// - base reg [+ imm]2186multiclass Loadxgim_pat<PatFrag Load, ValueType VT, PatFrag ValueMod,2187                        PatLeaf ImmPred, InstHexagon MI> {2188  def: Pat<(VT (Load (add I32:$Rs, ImmPred:$Off))),2189           (VT (ValueMod (MI IntRegs:$Rs, imm:$Off)))>;2190  def: Pat<(VT (Load (IsOrAdd I32:$Rs, ImmPred:$Off))),2191           (VT (ValueMod (MI IntRegs:$Rs, imm:$Off)))>;2192  def: Pat<(VT (Load I32:$Rs)), (VT (ValueMod (MI IntRegs:$Rs, 0)))>;2193}2194 2195// Patterns to select load reg indexed: Rs + Off with a value modifier.2196// Combines Loadxfim + Loadxgim.2197multiclass Loadxim_pat<PatFrag Load, ValueType VT, PatFrag ValueMod,2198                       PatLeaf ImmPred, InstHexagon MI> {2199  defm: Loadxfim_pat<Load, VT, ValueMod, ImmPred, MI>;2200  defm: Loadxgim_pat<Load, VT, ValueMod, ImmPred, MI>;2201}2202 2203// Pattern to select load reg reg-indexed: Rs + Rt<<u2.2204class Loadxr_shl_pat<PatFrag Load, ValueType VT, InstHexagon MI>2205  : Pat<(VT (Load (add I32:$Rs, (i32 (shl I32:$Rt, u2_0ImmPred:$u2))))),2206        (VT (MI IntRegs:$Rs, IntRegs:$Rt, imm:$u2))>;2207 2208// Pattern to select load reg reg-indexed: Rs + Rt<<0.2209class Loadxr_add_pat<PatFrag Load, ValueType VT, InstHexagon MI>2210  : Pat<(VT (Load (add I32:$Rs, I32:$Rt))),2211        (VT (MI IntRegs:$Rs, IntRegs:$Rt, 0))>;2212 2213// Pattern to select load reg reg-indexed: Rs + Rt<<u2 with value modifier.2214class Loadxrm_shl_pat<PatFrag Load, ValueType VT, PatFrag ValueMod,2215                      InstHexagon MI>2216  : Pat<(VT (Load (add I32:$Rs, (i32 (shl I32:$Rt, u2_0ImmPred:$u2))))),2217        (VT (ValueMod (MI IntRegs:$Rs, IntRegs:$Rt, imm:$u2)))>;2218 2219// Pattern to select load reg reg-indexed: Rs + Rt<<0 with value modifier.2220class Loadxrm_add_pat<PatFrag Load, ValueType VT, PatFrag ValueMod,2221                      InstHexagon MI>2222  : Pat<(VT (Load (add I32:$Rs, I32:$Rt))),2223        (VT (ValueMod (MI IntRegs:$Rs, IntRegs:$Rt, 0)))>;2224 2225// Pattern to select load long-offset reg-indexed: Addr + Rt<<u2.2226// Don't match for u2==0, instead use reg+imm for those cases.2227class Loadxu_pat<PatFrag Load, ValueType VT, PatFrag ImmPred, InstHexagon MI>2228  : Pat<(VT (Load (add (shl IntRegs:$Rt, u2_0ImmPred:$u2), ImmPred:$Addr))),2229        (VT (MI IntRegs:$Rt, imm:$u2, ImmPred:$Addr))>;2230 2231class Loadxum_pat<PatFrag Load, ValueType VT, PatFrag ImmPred, PatFrag ValueMod,2232                  InstHexagon MI>2233  : Pat<(VT (Load (add (shl IntRegs:$Rt, u2_0ImmPred:$u2), ImmPred:$Addr))),2234        (VT (ValueMod (MI IntRegs:$Rt, imm:$u2, ImmPred:$Addr)))>;2235 2236// Pattern to select load absolute.2237class Loada_pat<PatFrags Load, ValueType VT, PatFrag Addr, InstHexagon MI>2238  : Pat<(VT (Load Addr:$addr)), (MI Addr:$addr)>;2239 2240// Pattern to select load absolute with value modifier.2241class Loadam_pat<PatFrag Load, ValueType VT, PatFrag Addr, PatFrag ValueMod,2242                 InstHexagon MI>2243  : Pat<(VT (Load Addr:$addr)), (ValueMod (MI Addr:$addr))>;2244 2245 2246let AddedComplexity = 20 in {2247  defm: Loadxi_pat<extloadi1,       i32,   anyimm0, L2_loadrub_io>;2248  defm: Loadxi_pat<extloadi8,       i32,   anyimm0, L2_loadrub_io>;2249  defm: Loadxi_pat<extloadi16,      i32,   anyimm1, L2_loadruh_io>;2250  defm: Loadxi_pat<extloadv2i8,     v2i16, anyimm1, L2_loadbzw2_io>;2251  defm: Loadxi_pat<extloadv4i8,     v4i16, anyimm2, L2_loadbzw4_io>;2252  defm: Loadxi_pat<sextloadi8,      i32,   anyimm0, L2_loadrb_io>;2253  defm: Loadxi_pat<sextloadi16,     i32,   anyimm1, L2_loadrh_io>;2254  defm: Loadxi_pat<sextloadv2i8,    v2i16, anyimm1, L2_loadbsw2_io>;2255  defm: Loadxi_pat<sextloadv4i8,    v4i16, anyimm2, L2_loadbsw4_io>;2256  defm: Loadxi_pat<zextloadi1,      i32,   anyimm0, L2_loadrub_io>;2257  defm: Loadxi_pat<zextloadi8,      i32,   anyimm0, L2_loadrub_io>;2258  defm: Loadxi_pat<zextloadi16,     i32,   anyimm1, L2_loadruh_io>;2259  defm: Loadxi_pat<zextloadv2i8,    v2i16, anyimm1, L2_loadbzw2_io>;2260  defm: Loadxi_pat<zextloadv4i8,    v4i16, anyimm2, L2_loadbzw4_io>;2261  defm: Loadxi_pat<load,            i32,   anyimm2, L2_loadri_io>;2262  defm: Loadxi_pat<load,            v2i16, anyimm2, L2_loadri_io>;2263  defm: Loadxi_pat<load,            v4i8,  anyimm2, L2_loadri_io>;2264  defm: Loadxi_pat<load,            i64,   anyimm3, L2_loadrd_io>;2265  defm: Loadxi_pat<load,            v2i32, anyimm3, L2_loadrd_io>;2266  defm: Loadxi_pat<load,            v4i16, anyimm3, L2_loadrd_io>;2267  defm: Loadxi_pat<load,            v8i8,  anyimm3, L2_loadrd_io>;2268  defm: Loadxi_pat<load,            f32,   anyimm2, L2_loadri_io>;2269  defm: Loadxi_pat<load,            f64,   anyimm3, L2_loadrd_io>;2270  // No sextloadi1.2271 2272  defm: Loadxi_pat<atomic_load_azext_8 ,  i32, anyimm0, L2_loadrub_io>;2273  defm: Loadxi_pat<atomic_load_azext_16,  i32, anyimm1, L2_loadruh_io>;2274  defm: Loadxi_pat<atomic_load_nonext_32,  i32, anyimm2, L2_loadri_io>;2275  defm: Loadxi_pat<atomic_load_nonext_64,  i64, anyimm3, L2_loadrd_io>;2276}2277 2278let AddedComplexity = 30 in {2279  // Loads of i1 are loading a byte, and the byte should be either 0 or 1.2280  // It doesn't matter if it's sign- or zero-extended, so use zero-extension2281  // everywhere.2282  defm: Loadxim_pat<sextloadi1,   i32, L1toI32,  anyimm0, L2_loadrub_io>;2283  defm: Loadxim_pat<extloadi1,    i64, ToAext64, anyimm0, L2_loadrub_io>;2284  defm: Loadxim_pat<sextloadi1,   i64, L1toI64,  anyimm0, L2_loadrub_io>;2285  defm: Loadxim_pat<zextloadi1,   i64, ToZext64, anyimm0, L2_loadrub_io>;2286 2287  defm: Loadxim_pat<extloadi8,    i64, ToAext64, anyimm0, L2_loadrub_io>;2288  defm: Loadxim_pat<extloadi16,   i64, ToAext64, anyimm1, L2_loadruh_io>;2289  defm: Loadxim_pat<extloadi32,   i64, ToAext64, anyimm2, L2_loadri_io>;2290  defm: Loadxim_pat<zextloadi8,   i64, ToZext64, anyimm0, L2_loadrub_io>;2291  defm: Loadxim_pat<zextloadi16,  i64, ToZext64, anyimm1, L2_loadruh_io>;2292  defm: Loadxim_pat<zextloadi32,  i64, ToZext64, anyimm2, L2_loadri_io>;2293  defm: Loadxim_pat<sextloadi8,   i64, ToSext64, anyimm0, L2_loadrb_io>;2294  defm: Loadxim_pat<sextloadi16,  i64, ToSext64, anyimm1, L2_loadrh_io>;2295  defm: Loadxim_pat<sextloadi32,  i64, ToSext64, anyimm2, L2_loadri_io>;2296}2297 2298let AddedComplexity  = 60 in {2299  def: Loadxu_pat<extloadi1,    i32,   anyimm0, L4_loadrub_ur>;2300  def: Loadxu_pat<extloadi8,    i32,   anyimm0, L4_loadrub_ur>;2301  def: Loadxu_pat<extloadi16,   i32,   anyimm1, L4_loadruh_ur>;2302  def: Loadxu_pat<extloadv2i8,  v2i16, anyimm1, L4_loadbzw2_ur>;2303  def: Loadxu_pat<extloadv4i8,  v4i16, anyimm2, L4_loadbzw4_ur>;2304  def: Loadxu_pat<sextloadi8,   i32,   anyimm0, L4_loadrb_ur>;2305  def: Loadxu_pat<sextloadi16,  i32,   anyimm1, L4_loadrh_ur>;2306  def: Loadxu_pat<sextloadv2i8, v2i16, anyimm1, L4_loadbsw2_ur>;2307  def: Loadxu_pat<sextloadv4i8, v4i16, anyimm2, L4_loadbsw4_ur>;2308  def: Loadxu_pat<zextloadi1,   i32,   anyimm0, L4_loadrub_ur>;2309  def: Loadxu_pat<zextloadi8,   i32,   anyimm0, L4_loadrub_ur>;2310  def: Loadxu_pat<zextloadi16,  i32,   anyimm1, L4_loadruh_ur>;2311  def: Loadxu_pat<zextloadv2i8, v2i16, anyimm1, L4_loadbzw2_ur>;2312  def: Loadxu_pat<zextloadv4i8, v4i16, anyimm2, L4_loadbzw4_ur>;2313  def: Loadxu_pat<load,         i32,   anyimm2, L4_loadri_ur>;2314  def: Loadxu_pat<load,         v2i16, anyimm2, L4_loadri_ur>;2315  def: Loadxu_pat<load,         v4i8,  anyimm2, L4_loadri_ur>;2316  def: Loadxu_pat<load,         i64,   anyimm3, L4_loadrd_ur>;2317  def: Loadxu_pat<load,         v2i32, anyimm3, L4_loadrd_ur>;2318  def: Loadxu_pat<load,         v4i16, anyimm3, L4_loadrd_ur>;2319  def: Loadxu_pat<load,         v8i8,  anyimm3, L4_loadrd_ur>;2320  def: Loadxu_pat<load,         f32,   anyimm2, L4_loadri_ur>;2321  def: Loadxu_pat<load,         f64,   anyimm3, L4_loadrd_ur>;2322 2323  def: Loadxum_pat<sextloadi1,  i32, anyimm0, L1toI32,  L4_loadrub_ur>;2324  def: Loadxum_pat<extloadi1,   i64, anyimm0, ToAext64, L4_loadrub_ur>;2325  def: Loadxum_pat<sextloadi1,  i64, anyimm0, L1toI64,  L4_loadrub_ur>;2326  def: Loadxum_pat<zextloadi1,  i64, anyimm0, ToZext64, L4_loadrub_ur>;2327 2328  def: Loadxum_pat<sextloadi8,  i64, anyimm0, ToSext64, L4_loadrb_ur>;2329  def: Loadxum_pat<zextloadi8,  i64, anyimm0, ToZext64, L4_loadrub_ur>;2330  def: Loadxum_pat<extloadi8,   i64, anyimm0, ToAext64, L4_loadrub_ur>;2331  def: Loadxum_pat<sextloadi16, i64, anyimm1, ToSext64, L4_loadrh_ur>;2332  def: Loadxum_pat<zextloadi16, i64, anyimm1, ToZext64, L4_loadruh_ur>;2333  def: Loadxum_pat<extloadi16,  i64, anyimm1, ToAext64, L4_loadruh_ur>;2334  def: Loadxum_pat<sextloadi32, i64, anyimm2, ToSext64, L4_loadri_ur>;2335  def: Loadxum_pat<zextloadi32, i64, anyimm2, ToZext64, L4_loadri_ur>;2336  def: Loadxum_pat<extloadi32,  i64, anyimm2, ToAext64, L4_loadri_ur>;2337}2338 2339let AddedComplexity = 40 in {2340  def: Loadxr_shl_pat<extloadi1,     i32,   L4_loadrub_rr>;2341  def: Loadxr_shl_pat<extloadi8,     i32,   L4_loadrub_rr>;2342  def: Loadxr_shl_pat<zextloadi1,    i32,   L4_loadrub_rr>;2343  def: Loadxr_shl_pat<zextloadi8,    i32,   L4_loadrub_rr>;2344  def: Loadxr_shl_pat<sextloadi8,    i32,   L4_loadrb_rr>;2345  def: Loadxr_shl_pat<extloadi16,    i32,   L4_loadruh_rr>;2346  def: Loadxr_shl_pat<zextloadi16,   i32,   L4_loadruh_rr>;2347  def: Loadxr_shl_pat<sextloadi16,   i32,   L4_loadrh_rr>;2348  def: Loadxr_shl_pat<load,          i32,   L4_loadri_rr>;2349  def: Loadxr_shl_pat<load,          v2i16, L4_loadri_rr>;2350  def: Loadxr_shl_pat<load,          v4i8,  L4_loadri_rr>;2351  def: Loadxr_shl_pat<load,          i64,   L4_loadrd_rr>;2352  def: Loadxr_shl_pat<load,          v2i32, L4_loadrd_rr>;2353  def: Loadxr_shl_pat<load,          v4i16, L4_loadrd_rr>;2354  def: Loadxr_shl_pat<load,          v8i8,  L4_loadrd_rr>;2355  def: Loadxr_shl_pat<load,          f32,   L4_loadri_rr>;2356  def: Loadxr_shl_pat<load,          f64,   L4_loadrd_rr>;2357}2358 2359let AddedComplexity = 20 in {2360  def: Loadxr_add_pat<extloadi1,     i32,   L4_loadrub_rr>;2361  def: Loadxr_add_pat<extloadi8,     i32,   L4_loadrub_rr>;2362  def: Loadxr_add_pat<zextloadi8,    i32,   L4_loadrub_rr>;2363  def: Loadxr_add_pat<zextloadi1,    i32,   L4_loadrub_rr>;2364  def: Loadxr_add_pat<sextloadi8,    i32,   L4_loadrb_rr>;2365  def: Loadxr_add_pat<extloadi16,    i32,   L4_loadruh_rr>;2366  def: Loadxr_add_pat<zextloadi16,   i32,   L4_loadruh_rr>;2367  def: Loadxr_add_pat<sextloadi16,   i32,   L4_loadrh_rr>;2368  def: Loadxr_add_pat<load,          i32,   L4_loadri_rr>;2369  def: Loadxr_add_pat<load,          v2i16, L4_loadri_rr>;2370  def: Loadxr_add_pat<load,          v4i8,  L4_loadri_rr>;2371  def: Loadxr_add_pat<load,          i64,   L4_loadrd_rr>;2372  def: Loadxr_add_pat<load,          v2i32, L4_loadrd_rr>;2373  def: Loadxr_add_pat<load,          v4i16, L4_loadrd_rr>;2374  def: Loadxr_add_pat<load,          v8i8,  L4_loadrd_rr>;2375  def: Loadxr_add_pat<load,          f32,   L4_loadri_rr>;2376  def: Loadxr_add_pat<load,          f64,   L4_loadrd_rr>;2377}2378 2379let AddedComplexity = 40 in {2380  def: Loadxrm_shl_pat<sextloadi1,   i32, L1toI32,  L4_loadrub_rr>;2381  def: Loadxrm_shl_pat<extloadi1,    i64, ToAext64, L4_loadrub_rr>;2382  def: Loadxrm_shl_pat<sextloadi1,   i64, L1toI64,  L4_loadrub_rr>;2383  def: Loadxrm_shl_pat<zextloadi1,   i64, ToZext64, L4_loadrub_rr>;2384 2385  def: Loadxrm_shl_pat<extloadi8,    i64, ToAext64, L4_loadrub_rr>;2386  def: Loadxrm_shl_pat<zextloadi8,   i64, ToZext64, L4_loadrub_rr>;2387  def: Loadxrm_shl_pat<sextloadi8,   i64, ToSext64, L4_loadrb_rr>;2388  def: Loadxrm_shl_pat<extloadi16,   i64, ToAext64, L4_loadruh_rr>;2389  def: Loadxrm_shl_pat<zextloadi16,  i64, ToZext64, L4_loadruh_rr>;2390  def: Loadxrm_shl_pat<sextloadi16,  i64, ToSext64, L4_loadrh_rr>;2391  def: Loadxrm_shl_pat<extloadi32,   i64, ToAext64, L4_loadri_rr>;2392  def: Loadxrm_shl_pat<zextloadi32,  i64, ToZext64, L4_loadri_rr>;2393  def: Loadxrm_shl_pat<sextloadi32,  i64, ToSext64, L4_loadri_rr>;2394}2395 2396let AddedComplexity = 30 in {2397  def: Loadxrm_add_pat<sextloadi1,   i32, L1toI32,  L4_loadrub_rr>;2398  def: Loadxrm_add_pat<extloadi1,    i64, ToAext64, L4_loadrub_rr>;2399  def: Loadxrm_add_pat<sextloadi1,   i64, L1toI64,  L4_loadrub_rr>;2400  def: Loadxrm_add_pat<zextloadi1,   i64, ToZext64, L4_loadrub_rr>;2401 2402  def: Loadxrm_add_pat<extloadi8,    i64, ToAext64, L4_loadrub_rr>;2403  def: Loadxrm_add_pat<zextloadi8,   i64, ToZext64, L4_loadrub_rr>;2404  def: Loadxrm_add_pat<sextloadi8,   i64, ToSext64, L4_loadrb_rr>;2405  def: Loadxrm_add_pat<extloadi16,   i64, ToAext64, L4_loadruh_rr>;2406  def: Loadxrm_add_pat<zextloadi16,  i64, ToZext64, L4_loadruh_rr>;2407  def: Loadxrm_add_pat<sextloadi16,  i64, ToSext64, L4_loadrh_rr>;2408  def: Loadxrm_add_pat<extloadi32,   i64, ToAext64, L4_loadri_rr>;2409  def: Loadxrm_add_pat<zextloadi32,  i64, ToZext64, L4_loadri_rr>;2410  def: Loadxrm_add_pat<sextloadi32,  i64, ToSext64, L4_loadri_rr>;2411}2412 2413// Absolute address2414 2415let AddedComplexity  = 60 in {2416  def: Loada_pat<extloadi1,       i32,   anyimm0, PS_loadrubabs>;2417  def: Loada_pat<zextloadi1,      i32,   anyimm0, PS_loadrubabs>;2418  def: Loada_pat<extloadi8,       i32,   anyimm0, PS_loadrubabs>;2419  def: Loada_pat<sextloadi8,      i32,   anyimm0, PS_loadrbabs>;2420  def: Loada_pat<zextloadi8,      i32,   anyimm0, PS_loadrubabs>;2421  def: Loada_pat<extloadi16,      i32,   anyimm1, PS_loadruhabs>;2422  def: Loada_pat<sextloadi16,     i32,   anyimm1, PS_loadrhabs>;2423  def: Loada_pat<zextloadi16,     i32,   anyimm1, PS_loadruhabs>;2424  def: Loada_pat<load,            i32,   anyimm2, PS_loadriabs>;2425  def: Loada_pat<load,            v2i16, anyimm2, PS_loadriabs>;2426  def: Loada_pat<load,            v4i8,  anyimm2, PS_loadriabs>;2427  def: Loada_pat<load,            i64,   anyimm3, PS_loadrdabs>;2428  def: Loada_pat<load,            v2i32, anyimm3, PS_loadrdabs>;2429  def: Loada_pat<load,            v4i16, anyimm3, PS_loadrdabs>;2430  def: Loada_pat<load,            v8i8,  anyimm3, PS_loadrdabs>;2431  def: Loada_pat<load,            f32,   anyimm2, PS_loadriabs>;2432  def: Loada_pat<load,            f64,   anyimm3, PS_loadrdabs>;2433 2434  def: Loada_pat<atomic_load_azext_8,   i32, anyimm0, PS_loadrubabs>;2435  def: Loada_pat<atomic_load_azext_16,  i32, anyimm1, PS_loadruhabs>;2436  def: Loada_pat<atomic_load_nonext_32,  i32, anyimm2, PS_loadriabs>;2437  def: Loada_pat<atomic_load_nonext_64,  i64, anyimm3, PS_loadrdabs>;2438}2439 2440let AddedComplexity  = 30 in {2441  def: Loadam_pat<load,           i1,  anyimm0, I32toI1,  PS_loadrubabs>;2442  def: Loadam_pat<sextloadi1,     i32, anyimm0, L1toI32,  PS_loadrubabs>;2443  def: Loadam_pat<extloadi1,      i64, anyimm0, ToZext64, PS_loadrubabs>;2444  def: Loadam_pat<sextloadi1,     i64, anyimm0, L1toI64,  PS_loadrubabs>;2445  def: Loadam_pat<zextloadi1,     i64, anyimm0, ToZext64, PS_loadrubabs>;2446 2447  def: Loadam_pat<extloadi8,      i64, anyimm0, ToAext64, PS_loadrubabs>;2448  def: Loadam_pat<sextloadi8,     i64, anyimm0, ToSext64, PS_loadrbabs>;2449  def: Loadam_pat<zextloadi8,     i64, anyimm0, ToZext64, PS_loadrubabs>;2450  def: Loadam_pat<extloadi16,     i64, anyimm1, ToAext64, PS_loadruhabs>;2451  def: Loadam_pat<sextloadi16,    i64, anyimm1, ToSext64, PS_loadrhabs>;2452  def: Loadam_pat<zextloadi16,    i64, anyimm1, ToZext64, PS_loadruhabs>;2453  def: Loadam_pat<extloadi32,     i64, anyimm2, ToAext64, PS_loadriabs>;2454  def: Loadam_pat<sextloadi32,    i64, anyimm2, ToSext64, PS_loadriabs>;2455  def: Loadam_pat<zextloadi32,    i64, anyimm2, ToZext64, PS_loadriabs>;2456}2457 2458// GP-relative address2459 2460let AddedComplexity  = 100 in {2461  def: Loada_pat<extloadi1,       i32,   addrgp,  L2_loadrubgp>;2462  def: Loada_pat<zextloadi1,      i32,   addrgp,  L2_loadrubgp>;2463  def: Loada_pat<extloadi8,       i32,   addrgp,  L2_loadrubgp>;2464  def: Loada_pat<sextloadi8,      i32,   addrgp,  L2_loadrbgp>;2465  def: Loada_pat<zextloadi8,      i32,   addrgp,  L2_loadrubgp>;2466  def: Loada_pat<extloadi16,      i32,   addrgp,  L2_loadruhgp>;2467  def: Loada_pat<sextloadi16,     i32,   addrgp,  L2_loadrhgp>;2468  def: Loada_pat<zextloadi16,     i32,   addrgp,  L2_loadruhgp>;2469  def: Loada_pat<load,            i32,   addrgp,  L2_loadrigp>;2470  def: Loada_pat<load,            v2i16, addrgp,  L2_loadrigp>;2471  def: Loada_pat<load,            v4i8,  addrgp,  L2_loadrigp>;2472  def: Loada_pat<load,            i64,   addrgp,  L2_loadrdgp>;2473  def: Loada_pat<load,            v2i32, addrgp,  L2_loadrdgp>;2474  def: Loada_pat<load,            v4i16, addrgp,  L2_loadrdgp>;2475  def: Loada_pat<load,            v8i8,  addrgp,  L2_loadrdgp>;2476  def: Loada_pat<load,            f32,   addrgp,  L2_loadrigp>;2477  def: Loada_pat<load,            f64,   addrgp,  L2_loadrdgp>;2478 2479  def: Loada_pat<atomic_load_azext_8,   i32, addrgp,  L2_loadrubgp>;2480  def: Loada_pat<atomic_load_azext_16,  i32, addrgp,  L2_loadruhgp>;2481  def: Loada_pat<atomic_load_nonext_32,  i32, addrgp,  L2_loadrigp>;2482  def: Loada_pat<atomic_load_nonext_64,  i64, addrgp,  L2_loadrdgp>;2483}2484 2485let AddedComplexity  = 70 in {2486  def: Loadam_pat<sextloadi1,     i32, addrgp,  L1toI32,  L2_loadrubgp>;2487  def: Loadam_pat<extloadi1,      i64, addrgp,  ToAext64, L2_loadrubgp>;2488  def: Loadam_pat<sextloadi1,     i64, addrgp,  L1toI64,  L2_loadrubgp>;2489  def: Loadam_pat<zextloadi1,     i64, addrgp,  ToZext64, L2_loadrubgp>;2490 2491  def: Loadam_pat<extloadi8,      i64, addrgp,  ToAext64, L2_loadrubgp>;2492  def: Loadam_pat<sextloadi8,     i64, addrgp,  ToSext64, L2_loadrbgp>;2493  def: Loadam_pat<zextloadi8,     i64, addrgp,  ToZext64, L2_loadrubgp>;2494  def: Loadam_pat<extloadi16,     i64, addrgp,  ToAext64, L2_loadruhgp>;2495  def: Loadam_pat<sextloadi16,    i64, addrgp,  ToSext64, L2_loadrhgp>;2496  def: Loadam_pat<zextloadi16,    i64, addrgp,  ToZext64, L2_loadruhgp>;2497  def: Loadam_pat<extloadi32,     i64, addrgp,  ToAext64, L2_loadrigp>;2498  def: Loadam_pat<sextloadi32,    i64, addrgp,  ToSext64, L2_loadrigp>;2499  def: Loadam_pat<zextloadi32,    i64, addrgp,  ToZext64, L2_loadrigp>;2500 2501  def: Loadam_pat<load,           i1,  addrgp,  I32toI1,  L2_loadrubgp>;2502}2503 2504// Patterns for loads of i1:2505def: Pat<(i1 (load AddrFI:$fi)),2506         (C2_tfrrp (L2_loadrub_io AddrFI:$fi, 0))>;2507def: Pat<(i1 (load (add I32:$Rs, anyimm0:$Off))),2508         (C2_tfrrp (L2_loadrub_io IntRegs:$Rs, imm:$Off))>;2509def: Pat<(i1 (load I32:$Rs)),2510         (C2_tfrrp (L2_loadrub_io IntRegs:$Rs, 0))>;2511 2512 2513// --(13) Store ----------------------------------------------------------2514//2515 2516class Storepi_pat<PatFrag Store, PatFrag Value, PatFrag Offset, InstHexagon MI>2517  : Pat<(Store Value:$Rt, I32:$Rx, Offset:$s4),2518        (MI I32:$Rx, imm:$s4, Value:$Rt)>;2519 2520def: Storepi_pat<post_truncsti8,  I32, s4_0ImmPred, S2_storerb_pi>;2521def: Storepi_pat<post_truncsti16, I32, s4_1ImmPred, S2_storerh_pi>;2522def: Storepi_pat<post_store,      I32, s4_2ImmPred, S2_storeri_pi>;2523def: Storepi_pat<post_store,      I64, s4_3ImmPred, S2_storerd_pi>;2524 2525// Patterns for generating stores, where the address takes different forms:2526// - frameindex,2527// - frameindex + offset,2528// - base + offset,2529// - simple (base address without offset).2530// These would usually be used together (via Storexi_pat defined below), but2531// in some cases one may want to apply different properties (such as2532// AddedComplexity) to the individual patterns.2533class Storexi_fi_pat<PatFrag Store, PatFrag Value, InstHexagon MI>2534  : Pat<(Store Value:$Rs, AddrFI:$fi), (MI AddrFI:$fi, 0, Value:$Rs)>;2535 2536multiclass Storexi_fi_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred,2537                              InstHexagon MI> {2538  def: Pat<(Store Value:$Rs, (add (i32 AddrFI:$fi), ImmPred:$Off)),2539           (MI AddrFI:$fi, imm:$Off, Value:$Rs)>;2540  def: Pat<(Store Value:$Rs, (IsOrAdd (i32 AddrFI:$fi), ImmPred:$Off)),2541           (MI AddrFI:$fi, imm:$Off, Value:$Rs)>;2542}2543 2544multiclass Storexi_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred,2545                           InstHexagon MI> {2546  def: Pat<(Store Value:$Rt, (add I32:$Rs, ImmPred:$Off)),2547           (MI IntRegs:$Rs, imm:$Off, Value:$Rt)>;2548  def: Pat<(Store Value:$Rt, (IsOrAdd I32:$Rs, ImmPred:$Off)),2549           (MI IntRegs:$Rs, imm:$Off, Value:$Rt)>;2550}2551 2552class Storexi_base_pat<PatFrag Store, PatFrag Value, InstHexagon MI>2553  : Pat<(Store Value:$Rt, I32:$Rs),2554        (MI IntRegs:$Rs, 0, Value:$Rt)>;2555 2556// Patterns for generating stores, where the address takes different forms,2557// and where the value being stored is transformed through the value modifier2558// ValueMod.  The address forms are same as above.2559class Storexim_fi_pat<PatFrag Store, PatFrag Value, PatFrag ValueMod,2560                      InstHexagon MI>2561  : Pat<(Store Value:$Rs, AddrFI:$fi),2562        (MI AddrFI:$fi, 0, (ValueMod Value:$Rs))>;2563 2564multiclass Storexim_fi_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred,2565                               PatFrag ValueMod, InstHexagon MI> {2566  def: Pat<(Store Value:$Rs, (add (i32 AddrFI:$fi), ImmPred:$Off)),2567           (MI AddrFI:$fi, imm:$Off, (ValueMod Value:$Rs))>;2568  def: Pat<(Store Value:$Rs, (IsOrAdd (i32 AddrFI:$fi), ImmPred:$Off)),2569           (MI AddrFI:$fi, imm:$Off, (ValueMod Value:$Rs))>;2570}2571 2572multiclass Storexim_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred,2573                            PatFrag ValueMod, InstHexagon MI> {2574  def: Pat<(Store Value:$Rt, (add I32:$Rs, ImmPred:$Off)),2575           (MI IntRegs:$Rs, imm:$Off, (ValueMod Value:$Rt))>;2576  def: Pat<(Store Value:$Rt, (IsOrAdd I32:$Rs, ImmPred:$Off)),2577           (MI IntRegs:$Rs, imm:$Off, (ValueMod Value:$Rt))>;2578}2579 2580class Storexim_base_pat<PatFrag Store, PatFrag Value, PatFrag ValueMod,2581                        InstHexagon MI>2582  : Pat<(Store Value:$Rt, I32:$Rs),2583        (MI IntRegs:$Rs, 0, (ValueMod Value:$Rt))>;2584 2585multiclass Storexi_pat<PatFrag Store, PatFrag Value, PatLeaf ImmPred,2586                       InstHexagon MI> {2587  defm: Storexi_fi_add_pat <Store, Value, ImmPred, MI>;2588  def:  Storexi_fi_pat     <Store, Value,          MI>;2589  defm: Storexi_add_pat    <Store, Value, ImmPred, MI>;2590}2591 2592multiclass Storexim_pat<PatFrag Store, PatFrag Value, PatLeaf ImmPred,2593                        PatFrag ValueMod, InstHexagon MI> {2594  defm: Storexim_fi_add_pat <Store, Value, ImmPred, ValueMod, MI>;2595  def:  Storexim_fi_pat     <Store, Value,          ValueMod, MI>;2596  defm: Storexim_add_pat    <Store, Value, ImmPred, ValueMod, MI>;2597}2598 2599// Reg<<S + Imm2600class Storexu_shl_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred, InstHexagon MI>2601  : Pat<(Store Value:$Rt, (add (shl I32:$Ru, u2_0ImmPred:$u2), ImmPred:$A)),2602        (MI IntRegs:$Ru, imm:$u2, ImmPred:$A, Value:$Rt)>;2603 2604// Reg<<S + Reg2605class Storexr_shl_pat<PatFrag Store, PatFrag Value, InstHexagon MI>2606  : Pat<(Store Value:$Ru, (add I32:$Rs, (shl I32:$Rt, u2_0ImmPred:$u2))),2607        (MI IntRegs:$Rs, IntRegs:$Rt, imm:$u2, Value:$Ru)>;2608 2609// Reg + Reg2610class Storexr_add_pat<PatFrag Store, PatFrag Value, InstHexagon MI>2611  : Pat<(Store Value:$Ru, (add I32:$Rs, I32:$Rt)),2612        (MI IntRegs:$Rs, IntRegs:$Rt, 0, Value:$Ru)>;2613 2614class Storea_pat<PatFrag Store, PatFrag Value, PatFrag Addr, InstHexagon MI>2615  : Pat<(Store Value:$val, Addr:$addr), (MI Addr:$addr, Value:$val)>;2616 2617class Stoream_pat<PatFrag Store, PatFrag Value, PatFrag Addr, PatFrag ValueMod,2618                  InstHexagon MI>2619  : Pat<(Store Value:$val, Addr:$addr),2620        (MI Addr:$addr, (ValueMod Value:$val))>;2621 2622def IMM_BYTE : SDNodeXForm<imm, [{2623  // -1 can be represented as 255, etc.2624  // assigning to a byte restores our desired signed value.2625  int8_t imm = N->getSExtValue();2626  return CurDAG->getSignedTargetConstant(imm, SDLoc(N), MVT::i32);2627}]>;2628 2629def IMM_HALF : SDNodeXForm<imm, [{2630  // -1 can be represented as 65535, etc.2631  // assigning to a short restores our desired signed value.2632  int16_t imm = N->getSExtValue();2633  return CurDAG->getSignedTargetConstant(imm, SDLoc(N), MVT::i32);2634}]>;2635 2636def IMM_WORD : SDNodeXForm<imm, [{2637  // -1 can be represented as 4294967295, etc.2638  // Currently, it's not doing this. But some optimization2639  // might convert -1 to a large +ve number.2640  // assigning to a word restores our desired signed value.2641  int32_t imm = N->getSExtValue();2642  return CurDAG->getSignedTargetConstant(imm, SDLoc(N), MVT::i32);2643}]>;2644 2645def ToImmByte : OutPatFrag<(ops node:$R), (IMM_BYTE $R)>;2646def ToImmHalf : OutPatFrag<(ops node:$R), (IMM_HALF $R)>;2647def ToImmWord : OutPatFrag<(ops node:$R), (IMM_WORD $R)>;2648 2649// Even though the offset is not extendable in the store-immediate, we2650// can still generate the fi# in the base address. If the final offset2651// is not valid for the instruction, we will replace it with a scratch2652// register.2653class SmallStackStore<PatFrag Store>2654  : PatFrag<(ops node:$Val, node:$Addr), (Store node:$Val, node:$Addr), [{2655  return isSmallStackStore(cast<StoreSDNode>(N));2656}]>;2657 2658// This is the complement of SmallStackStore.2659class LargeStackStore<PatFrag Store>2660  : PatFrag<(ops node:$Val, node:$Addr), (Store node:$Val, node:$Addr), [{2661  return !isSmallStackStore(cast<StoreSDNode>(N));2662}]>;2663 2664// Preferred addressing modes for various combinations of stored value2665// and address computation.2666// For stores where the address and value are both immediates, prefer2667// store-immediate. The reason is that the constant-extender optimization2668// can replace store-immediate with a store-register, but there is nothing2669// to generate a store-immediate out of a store-register.2670//2671//         C     R     F    F+C   R+C   R+R   R<<S+C   R<<S+R2672// --+-------+-----+-----+------+-----+-----+--------+--------2673// C |   imm | imm | imm |  imm | imm |  rr |     ur |     rr2674// R |  abs* |  io |  io |   io |  io |  rr |     ur |     rr2675//2676// (*) Absolute or GP-relative.2677//2678// Note that any expression can be matched by Reg. In particular, an immediate2679// can always be placed in a register, so patterns checking for Imm should2680// have a higher priority than the ones involving Reg that could also match.2681// For example, *(p+4) could become r1=#4; memw(r0+r1<<#0) instead of the2682// preferred memw(r0+#4). Similarly Reg+Imm or Reg+Reg should be tried before2683// Reg alone.2684//2685// The order in which the different combinations are tried:2686//2687//         C     F     R    F+C   R+C   R+R   R<<S+C   R<<S+R2688// --+-------+-----+-----+------+-----+-----+--------+--------2689// C |     1 |   6 |   - |    5 |   9 |   - |      - |      -2690// R |     2 |   8 |  12 |    7 |  10 |  11 |      3 |      42691 2692 2693// First, match the unusual case of doubleword store into Reg+Imm4, i.e.2694// a store where the offset Imm4 is a multiple of 4, but not of 8. This2695// implies that Reg is also a proper multiple of 4. To still generate a2696// doubleword store, add 4 to Reg, and subtract 4 from the offset.2697 2698def s30_2ProperPred  : PatLeaf<(i32 imm), [{2699  int64_t v = (int64_t)N->getSExtValue();2700  return isShiftedInt<30,2>(v) && !isShiftedInt<29,3>(v);2701}]>;2702def RoundTo8 : SDNodeXForm<imm, [{2703  int32_t Imm = N->getSExtValue();2704  return CurDAG->getSignedTargetConstant(Imm & -8, SDLoc(N), MVT::i32);2705}]>;2706 2707let AddedComplexity = 150 in2708def: Pat<(store I64:$Ru, (add I32:$Rs, s30_2ProperPred:$Off)),2709         (S2_storerd_io (A2_addi I32:$Rs, 4), (RoundTo8 $Off), I64:$Ru)>;2710 2711class Storexi_abs_pat<PatFrag Store, PatFrag Value, InstHexagon MI>2712  : Pat<(Store Value:$val, anyimm:$addr),2713        (MI (ToI32 $addr), 0, Value:$val)>;2714class Storexim_abs_pat<PatFrag Store, PatFrag Value, PatFrag ValueMod,2715                       InstHexagon MI>2716  : Pat<(Store Value:$val, anyimm:$addr),2717        (MI (ToI32 $addr), 0, (ValueMod Value:$val))>;2718 2719let AddedComplexity = 140 in {2720  def: Storexim_abs_pat<truncstorei8,  anyint, ToImmByte, S4_storeirb_io>;2721  def: Storexim_abs_pat<truncstorei16, anyint, ToImmHalf, S4_storeirh_io>;2722  def: Storexim_abs_pat<store,         anyint, ToImmWord, S4_storeiri_io>;2723 2724  def: Storexi_abs_pat<truncstorei8,  anyimm, S4_storeirb_io>;2725  def: Storexi_abs_pat<truncstorei16, anyimm, S4_storeirh_io>;2726  def: Storexi_abs_pat<store,         anyimm, S4_storeiri_io>;2727}2728 2729// GP-relative address2730let AddedComplexity = 120 in {2731  def: Storea_pat<truncstorei8,               I32, addrgp, S2_storerbgp>;2732  def: Storea_pat<truncstorei16,              I32, addrgp, S2_storerhgp>;2733  def: Storea_pat<store,                      I32, addrgp, S2_storerigp>;2734  def: Storea_pat<store,                     V4I8, addrgp, S2_storerigp>;2735  def: Storea_pat<store,                    V2I16, addrgp, S2_storerigp>;2736  def: Storea_pat<store,                      I64, addrgp, S2_storerdgp>;2737  def: Storea_pat<store,                     V8I8, addrgp, S2_storerdgp>;2738  def: Storea_pat<store,                    V4I16, addrgp, S2_storerdgp>;2739  def: Storea_pat<store,                    V2I32, addrgp, S2_storerdgp>;2740  def: Storea_pat<store,                      F32, addrgp, S2_storerigp>;2741  def: Storea_pat<store,                      F64, addrgp, S2_storerdgp>;2742  def: Storea_pat<atomic_store_8,             I32, addrgp, S2_storerbgp>;2743  def: Storea_pat<atomic_store_16,            I32, addrgp, S2_storerhgp>;2744  def: Storea_pat<atomic_store_32,            I32, addrgp, S2_storerigp>;2745  def: Storea_pat<atomic_store_32,           V4I8, addrgp, S2_storerigp>;2746  def: Storea_pat<atomic_store_32,          V2I16, addrgp, S2_storerigp>;2747  def: Storea_pat<atomic_store_64,            I64, addrgp, S2_storerdgp>;2748  def: Storea_pat<atomic_store_64,           V8I8, addrgp, S2_storerdgp>;2749  def: Storea_pat<atomic_store_64,          V4I16, addrgp, S2_storerdgp>;2750  def: Storea_pat<atomic_store_64,          V2I32, addrgp, S2_storerdgp>;2751 2752  def: Stoream_pat<truncstorei8,  I64, addrgp, LoReg,    S2_storerbgp>;2753  def: Stoream_pat<truncstorei16, I64, addrgp, LoReg,    S2_storerhgp>;2754  def: Stoream_pat<truncstorei32, I64, addrgp, LoReg,    S2_storerigp>;2755  def: Stoream_pat<store,         I1,  addrgp, I1toI32,  S2_storerbgp>;2756}2757 2758// Absolute address2759let AddedComplexity = 110 in {2760  def: Storea_pat<truncstorei8,               I32, anyimm0, PS_storerbabs>;2761  def: Storea_pat<truncstorei16,              I32, anyimm1, PS_storerhabs>;2762  def: Storea_pat<store,                      I32, anyimm2, PS_storeriabs>;2763  def: Storea_pat<store,                     V4I8, anyimm2, PS_storeriabs>;2764  def: Storea_pat<store,                    V2I16, anyimm2, PS_storeriabs>;2765  def: Storea_pat<store,                      I64, anyimm3, PS_storerdabs>;2766  def: Storea_pat<store,                     V8I8, anyimm3, PS_storerdabs>;2767  def: Storea_pat<store,                    V4I16, anyimm3, PS_storerdabs>;2768  def: Storea_pat<store,                    V2I32, anyimm3, PS_storerdabs>;2769  def: Storea_pat<store,                      F32, anyimm2, PS_storeriabs>;2770  def: Storea_pat<store,                      F64, anyimm3, PS_storerdabs>;2771  def: Storea_pat<atomic_store_8,             I32, anyimm0, PS_storerbabs>;2772  def: Storea_pat<atomic_store_16,            I32, anyimm1, PS_storerhabs>;2773  def: Storea_pat<atomic_store_32,            I32, anyimm2, PS_storeriabs>;2774  def: Storea_pat<atomic_store_32,           V4I8, anyimm2, PS_storeriabs>;2775  def: Storea_pat<atomic_store_32,          V2I16, anyimm2, PS_storeriabs>;2776  def: Storea_pat<atomic_store_64,            I64, anyimm3, PS_storerdabs>;2777  def: Storea_pat<atomic_store_64,           V8I8, anyimm3, PS_storerdabs>;2778  def: Storea_pat<atomic_store_64,          V4I16, anyimm3, PS_storerdabs>;2779  def: Storea_pat<atomic_store_64,          V2I32, anyimm3, PS_storerdabs>;2780 2781  def: Stoream_pat<truncstorei8,  I64, anyimm0, LoReg,    PS_storerbabs>;2782  def: Stoream_pat<truncstorei16, I64, anyimm1, LoReg,    PS_storerhabs>;2783  def: Stoream_pat<truncstorei32, I64, anyimm2, LoReg,    PS_storeriabs>;2784  def: Stoream_pat<store,         I1,  anyimm0, I1toI32,  PS_storerbabs>;2785}2786 2787// Reg<<S + Imm2788let AddedComplexity = 100 in {2789  def: Storexu_shl_pat<truncstorei8,    I32, anyimm0, S4_storerb_ur>;2790  def: Storexu_shl_pat<truncstorei16,   I32, anyimm1, S4_storerh_ur>;2791  def: Storexu_shl_pat<store,           I32, anyimm2, S4_storeri_ur>;2792  def: Storexu_shl_pat<store,          V4I8, anyimm2, S4_storeri_ur>;2793  def: Storexu_shl_pat<store,         V2I16, anyimm2, S4_storeri_ur>;2794  def: Storexu_shl_pat<store,           I64, anyimm3, S4_storerd_ur>;2795  def: Storexu_shl_pat<store,          V8I8, anyimm3, S4_storerd_ur>;2796  def: Storexu_shl_pat<store,         V4I16, anyimm3, S4_storerd_ur>;2797  def: Storexu_shl_pat<store,         V2I32, anyimm3, S4_storerd_ur>;2798  def: Storexu_shl_pat<store,           F32, anyimm2, S4_storeri_ur>;2799  def: Storexu_shl_pat<store,           F64, anyimm3, S4_storerd_ur>;2800 2801  def: Pat<(store I1:$Pu, (add (shl I32:$Rs, u2_0ImmPred:$u2), anyimm:$A)),2802           (S4_storerb_ur IntRegs:$Rs, imm:$u2, imm:$A, (I1toI32 I1:$Pu))>;2803}2804 2805// Reg<<S + Reg2806let AddedComplexity = 90 in {2807  def: Storexr_shl_pat<truncstorei8,    I32, S4_storerb_rr>;2808  def: Storexr_shl_pat<truncstorei16,   I32, S4_storerh_rr>;2809  def: Storexr_shl_pat<store,           I32, S4_storeri_rr>;2810  def: Storexr_shl_pat<store,          V4I8, S4_storeri_rr>;2811  def: Storexr_shl_pat<store,         V2I16, S4_storeri_rr>;2812  def: Storexr_shl_pat<store,           I64, S4_storerd_rr>;2813  def: Storexr_shl_pat<store,          V8I8, S4_storerd_rr>;2814  def: Storexr_shl_pat<store,         V4I16, S4_storerd_rr>;2815  def: Storexr_shl_pat<store,         V2I32, S4_storerd_rr>;2816  def: Storexr_shl_pat<store,           F32, S4_storeri_rr>;2817  def: Storexr_shl_pat<store,           F64, S4_storerd_rr>;2818 2819  def: Pat<(store I1:$Pu, (add (shl I32:$Rs, u2_0ImmPred:$u2), I32:$Rt)),2820           (S4_storerb_rr IntRegs:$Rt, IntRegs:$Rs, imm:$u2, (I1toI32 I1:$Pu))>;2821}2822 2823class SS_<PatFrag F> : SmallStackStore<F>;2824class LS_<PatFrag F> : LargeStackStore<F>;2825 2826multiclass IMFA_<PatFrag S, PatFrag V, PatFrag O, PatFrag M, InstHexagon I> {2827  defm: Storexim_fi_add_pat<S, V, O, M, I>;2828}2829multiclass IFA_<PatFrag S, PatFrag V, PatFrag O, InstHexagon I> {2830  defm: Storexi_fi_add_pat<S, V, O, I>;2831}2832 2833// Fi+Imm, store-immediate2834let AddedComplexity = 80 in {2835  defm: IMFA_<SS_<truncstorei8>,  anyint, u6_0ImmPred, ToImmByte, S4_storeirb_io>;2836  defm: IMFA_<SS_<truncstorei16>, anyint, u6_1ImmPred, ToImmHalf, S4_storeirh_io>;2837  defm: IMFA_<SS_<store>,         anyint, u6_2ImmPred, ToImmWord, S4_storeiri_io>;2838 2839  defm: IFA_<SS_<truncstorei8>,   anyimm, u6_0ImmPred, S4_storeirb_io>;2840  defm: IFA_<SS_<truncstorei16>,  anyimm, u6_1ImmPred, S4_storeirh_io>;2841  defm: IFA_<SS_<store>,          anyimm, u6_2ImmPred, S4_storeiri_io>;2842 2843  // For large-stack stores, generate store-register (prefer explicit Fi2844  // in the address).2845  defm: IMFA_<LS_<truncstorei8>,   anyimm, u6_0ImmPred, ToI32, S2_storerb_io>;2846  defm: IMFA_<LS_<truncstorei16>,  anyimm, u6_1ImmPred, ToI32, S2_storerh_io>;2847  defm: IMFA_<LS_<store>,          anyimm, u6_2ImmPred, ToI32, S2_storeri_io>;2848}2849 2850// Fi, store-immediate2851let AddedComplexity = 70 in {2852  def: Storexim_fi_pat<SS_<truncstorei8>,  anyint, ToImmByte, S4_storeirb_io>;2853  def: Storexim_fi_pat<SS_<truncstorei16>, anyint, ToImmHalf, S4_storeirh_io>;2854  def: Storexim_fi_pat<SS_<store>,         anyint, ToImmWord, S4_storeiri_io>;2855 2856  def: Storexi_fi_pat<SS_<truncstorei8>,   anyimm, S4_storeirb_io>;2857  def: Storexi_fi_pat<SS_<truncstorei16>,  anyimm, S4_storeirh_io>;2858  def: Storexi_fi_pat<SS_<store>,          anyimm, S4_storeiri_io>;2859 2860  // For large-stack stores, generate store-register (prefer explicit Fi2861  // in the address).2862  def: Storexim_fi_pat<LS_<truncstorei8>,  anyimm, ToI32, S2_storerb_io>;2863  def: Storexim_fi_pat<LS_<truncstorei16>, anyimm, ToI32, S2_storerh_io>;2864  def: Storexim_fi_pat<LS_<store>,         anyimm, ToI32, S2_storeri_io>;2865}2866 2867// Fi+Imm, Fi, store-register2868let AddedComplexity = 60 in {2869  defm: Storexi_fi_add_pat<truncstorei8,    I32, anyimm, S2_storerb_io>;2870  defm: Storexi_fi_add_pat<truncstorei16,   I32, anyimm, S2_storerh_io>;2871  defm: Storexi_fi_add_pat<store,           I32, anyimm, S2_storeri_io>;2872  defm: Storexi_fi_add_pat<store,          V4I8, anyimm, S2_storeri_io>;2873  defm: Storexi_fi_add_pat<store,         V2I16, anyimm, S2_storeri_io>;2874  defm: Storexi_fi_add_pat<store,           I64, anyimm, S2_storerd_io>;2875  defm: Storexi_fi_add_pat<store,          V8I8, anyimm, S2_storerd_io>;2876  defm: Storexi_fi_add_pat<store,         V4I16, anyimm, S2_storerd_io>;2877  defm: Storexi_fi_add_pat<store,         V2I32, anyimm, S2_storerd_io>;2878  defm: Storexi_fi_add_pat<store,           F32, anyimm, S2_storeri_io>;2879  defm: Storexi_fi_add_pat<store,           F64, anyimm, S2_storerd_io>;2880  defm: Storexim_fi_add_pat<store, I1, anyimm, I1toI32, S2_storerb_io>;2881 2882  def: Storexi_fi_pat<truncstorei8,     I32, S2_storerb_io>;2883  def: Storexi_fi_pat<truncstorei16,    I32, S2_storerh_io>;2884  def: Storexi_fi_pat<store,            I32, S2_storeri_io>;2885  def: Storexi_fi_pat<store,           V4I8, S2_storeri_io>;2886  def: Storexi_fi_pat<store,          V2I16, S2_storeri_io>;2887  def: Storexi_fi_pat<store,            I64, S2_storerd_io>;2888  def: Storexi_fi_pat<store,           V8I8, S2_storerd_io>;2889  def: Storexi_fi_pat<store,          V4I16, S2_storerd_io>;2890  def: Storexi_fi_pat<store,          V2I32, S2_storerd_io>;2891  def: Storexi_fi_pat<store,            F32, S2_storeri_io>;2892  def: Storexi_fi_pat<store,            F64, S2_storerd_io>;2893  def: Storexim_fi_pat<store, I1, I1toI32, S2_storerb_io>;2894}2895 2896 2897multiclass IMRA_<PatFrag S, PatFrag V, PatFrag O, PatFrag M, InstHexagon I> {2898  defm: Storexim_add_pat<S, V, O, M, I>;2899}2900multiclass IRA_<PatFrag S, PatFrag V, PatFrag O, InstHexagon I> {2901  defm: Storexi_add_pat<S, V, O, I>;2902}2903 2904// Reg+Imm, store-immediate2905let AddedComplexity = 50 in {2906  defm: IMRA_<truncstorei8,   anyint, u6_0ImmPred, ToImmByte, S4_storeirb_io>;2907  defm: IMRA_<truncstorei16,  anyint, u6_1ImmPred, ToImmHalf, S4_storeirh_io>;2908  defm: IMRA_<store,          anyint, u6_2ImmPred, ToImmWord, S4_storeiri_io>;2909 2910  defm: IRA_<truncstorei8,    anyimm, u6_0ImmPred, S4_storeirb_io>;2911  defm: IRA_<truncstorei16,   anyimm, u6_1ImmPred, S4_storeirh_io>;2912  defm: IRA_<store,           anyimm, u6_2ImmPred, S4_storeiri_io>;2913}2914 2915// Reg+Imm, store-register2916let AddedComplexity = 40 in {2917  defm: Storexi_pat<truncstorei8,     I32, anyimm0, S2_storerb_io>;2918  defm: Storexi_pat<truncstorei16,    I32, anyimm1, S2_storerh_io>;2919  defm: Storexi_pat<store,            I32, anyimm2, S2_storeri_io>;2920  defm: Storexi_pat<store,           V4I8, anyimm2, S2_storeri_io>;2921  defm: Storexi_pat<store,          V2I16, anyimm2, S2_storeri_io>;2922  defm: Storexi_pat<store,            I64, anyimm3, S2_storerd_io>;2923  defm: Storexi_pat<store,           V8I8, anyimm3, S2_storerd_io>;2924  defm: Storexi_pat<store,          V4I16, anyimm3, S2_storerd_io>;2925  defm: Storexi_pat<store,          V2I32, anyimm3, S2_storerd_io>;2926  defm: Storexi_pat<store,            F32, anyimm2, S2_storeri_io>;2927  defm: Storexi_pat<store,            F64, anyimm3, S2_storerd_io>;2928 2929  defm: Storexim_pat<truncstorei8,  I64, anyimm0, LoReg,   S2_storerb_io>;2930  defm: Storexim_pat<truncstorei16, I64, anyimm1, LoReg,   S2_storerh_io>;2931  defm: Storexim_pat<truncstorei32, I64, anyimm2, LoReg,   S2_storeri_io>;2932  defm: Storexim_pat<store,         I1,  anyimm0, I1toI32, S2_storerb_io>;2933 2934  defm: Storexi_pat<atomic_store_8,     I32, anyimm0, S2_storerb_io>;2935  defm: Storexi_pat<atomic_store_16,    I32, anyimm1, S2_storerh_io>;2936  defm: Storexi_pat<atomic_store_32,    I32, anyimm2, S2_storeri_io>;2937  defm: Storexi_pat<atomic_store_32,   V4I8, anyimm2, S2_storeri_io>;2938  defm: Storexi_pat<atomic_store_32,  V2I16, anyimm2, S2_storeri_io>;2939  defm: Storexi_pat<atomic_store_64,    I64, anyimm3, S2_storerd_io>;2940  defm: Storexi_pat<atomic_store_64,   V8I8, anyimm3, S2_storerd_io>;2941  defm: Storexi_pat<atomic_store_64,  V4I16, anyimm3, S2_storerd_io>;2942  defm: Storexi_pat<atomic_store_64,  V2I32, anyimm3, S2_storerd_io>;2943}2944 2945// Reg+Reg2946let AddedComplexity = 30 in {2947  def: Storexr_add_pat<truncstorei8,    I32, S4_storerb_rr>;2948  def: Storexr_add_pat<truncstorei16,   I32, S4_storerh_rr>;2949  def: Storexr_add_pat<store,           I32, S4_storeri_rr>;2950  def: Storexr_add_pat<store,          V4I8, S4_storeri_rr>;2951  def: Storexr_add_pat<store,         V2I16, S4_storeri_rr>;2952  def: Storexr_add_pat<store,           I64, S4_storerd_rr>;2953  def: Storexr_add_pat<store,          V8I8, S4_storerd_rr>;2954  def: Storexr_add_pat<store,         V4I16, S4_storerd_rr>;2955  def: Storexr_add_pat<store,         V2I32, S4_storerd_rr>;2956  def: Storexr_add_pat<store,           F32, S4_storeri_rr>;2957  def: Storexr_add_pat<store,           F64, S4_storerd_rr>;2958 2959  def: Pat<(store I1:$Pu, (add I32:$Rs, I32:$Rt)),2960           (S4_storerb_rr IntRegs:$Rs, IntRegs:$Rt, 0, (I1toI32 I1:$Pu))>;2961}2962 2963// Reg, store-immediate2964let AddedComplexity = 20 in {2965  def: Storexim_base_pat<truncstorei8,  anyint, ToImmByte, S4_storeirb_io>;2966  def: Storexim_base_pat<truncstorei16, anyint, ToImmHalf, S4_storeirh_io>;2967  def: Storexim_base_pat<store,         anyint, ToImmWord, S4_storeiri_io>;2968 2969  def: Storexi_base_pat<truncstorei8,   anyimm, S4_storeirb_io>;2970  def: Storexi_base_pat<truncstorei16,  anyimm, S4_storeirh_io>;2971  def: Storexi_base_pat<store,          anyimm, S4_storeiri_io>;2972}2973 2974// Reg, store-register2975let AddedComplexity = 10 in {2976  def: Storexi_base_pat<truncstorei8,     I32, S2_storerb_io>;2977  def: Storexi_base_pat<truncstorei16,    I32, S2_storerh_io>;2978  def: Storexi_base_pat<store,            I32, S2_storeri_io>;2979  def: Storexi_base_pat<store,           V4I8, S2_storeri_io>;2980  def: Storexi_base_pat<store,          V2I16, S2_storeri_io>;2981  def: Storexi_base_pat<store,            I64, S2_storerd_io>;2982  def: Storexi_base_pat<store,           V8I8, S2_storerd_io>;2983  def: Storexi_base_pat<store,          V4I16, S2_storerd_io>;2984  def: Storexi_base_pat<store,          V2I32, S2_storerd_io>;2985  def: Storexi_base_pat<store,            F32, S2_storeri_io>;2986  def: Storexi_base_pat<store,            F64, S2_storerd_io>;2987 2988  def: Storexim_base_pat<truncstorei8,  I64, LoReg,   S2_storerb_io>;2989  def: Storexim_base_pat<truncstorei16, I64, LoReg,   S2_storerh_io>;2990  def: Storexim_base_pat<truncstorei32, I64, LoReg,   S2_storeri_io>;2991  def: Storexim_base_pat<store,         I1,  I1toI32, S2_storerb_io>;2992 2993  def: Storexi_base_pat<atomic_store_8,     I32, S2_storerb_io>;2994  def: Storexi_base_pat<atomic_store_16,    I32, S2_storerh_io>;2995  def: Storexi_base_pat<atomic_store_32,    I32, S2_storeri_io>;2996  def: Storexi_base_pat<atomic_store_32,   V4I8, S2_storeri_io>;2997  def: Storexi_base_pat<atomic_store_32,  V2I16, S2_storeri_io>;2998  def: Storexi_base_pat<atomic_store_64,    I64, S2_storerd_io>;2999  def: Storexi_base_pat<atomic_store_64,   V8I8, S2_storerd_io>;3000  def: Storexi_base_pat<atomic_store_64,  V4I16, S2_storerd_io>;3001  def: Storexi_base_pat<atomic_store_64,  V2I32, S2_storerd_io>;3002}3003 3004 3005// --(14) Memop ----------------------------------------------------------3006//3007 3008def m5_0Imm8Pred : PatLeaf<(i32 imm), [{3009  int8_t V = N->getSExtValue();3010  return -32 < V && V <= -1;3011}]>;3012 3013def m5_0Imm16Pred : PatLeaf<(i32 imm), [{3014  int16_t V = N->getSExtValue();3015  return -32 < V && V <= -1;3016}]>;3017 3018def m5_0ImmPred  : PatLeaf<(i32 imm), [{3019  int64_t V = N->getSExtValue();3020  return -31 <= V && V <= -1;3021}]>;3022 3023def IsNPow2_8 : PatLeaf<(i32 imm), [{3024  uint8_t NV = ~N->getZExtValue();3025  return isPowerOf2_32(NV);3026}]>;3027 3028def IsNPow2_16 : PatLeaf<(i32 imm), [{3029  uint16_t NV = ~N->getZExtValue();3030  return isPowerOf2_32(NV);3031}]>;3032 3033def Log2_8 : SDNodeXForm<imm, [{3034  uint8_t V = N->getZExtValue();3035  return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32);3036}]>;3037 3038def Log2_16 : SDNodeXForm<imm, [{3039  uint16_t V = N->getZExtValue();3040  return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32);3041}]>;3042 3043def LogN2_8 : SDNodeXForm<imm, [{3044  uint8_t NV = ~N->getZExtValue();3045  return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32);3046}]>;3047 3048def LogN2_16 : SDNodeXForm<imm, [{3049  uint16_t NV = ~N->getZExtValue();3050  return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32);3051}]>;3052 3053def IdImm : SDNodeXForm<imm, [{ return SDValue(N, 0); }]>;3054 3055multiclass Memopxr_base_pat<PatFrag Load, PatFrag Store, SDNode Oper,3056                            InstHexagon MI> {3057  // Addr: i323058  def: Pat<(Store (Oper (Load I32:$Rs), I32:$A), I32:$Rs),3059           (MI I32:$Rs, 0, I32:$A)>;3060  // Addr: fi3061  def: Pat<(Store (Oper (Load AddrFI:$Rs), I32:$A), AddrFI:$Rs),3062           (MI AddrFI:$Rs, 0, I32:$A)>;3063}3064 3065multiclass Memopxr_add_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred,3066                           SDNode Oper, InstHexagon MI> {3067  // Addr: i323068  def: Pat<(Store (Oper (Load (add I32:$Rs, ImmPred:$Off)), I32:$A),3069                  (add I32:$Rs, ImmPred:$Off)),3070           (MI I32:$Rs, imm:$Off, I32:$A)>;3071  def: Pat<(Store (Oper (Load (IsOrAdd I32:$Rs, ImmPred:$Off)), I32:$A),3072                  (IsOrAdd I32:$Rs, ImmPred:$Off)),3073           (MI I32:$Rs, imm:$Off, I32:$A)>;3074  // Addr: fi3075  def: Pat<(Store (Oper (Load (add AddrFI:$Rs, ImmPred:$Off)), I32:$A),3076                  (add AddrFI:$Rs, ImmPred:$Off)),3077           (MI AddrFI:$Rs, imm:$Off, I32:$A)>;3078  def: Pat<(Store (Oper (Load (IsOrAdd AddrFI:$Rs, ImmPred:$Off)), I32:$A),3079                  (IsOrAdd AddrFI:$Rs, ImmPred:$Off)),3080           (MI AddrFI:$Rs, imm:$Off, I32:$A)>;3081}3082 3083multiclass Memopxr_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred,3084                       SDNode Oper, InstHexagon MI> {3085  let Predicates = [UseMEMOPS] in {3086    defm: Memopxr_base_pat <Load, Store,          Oper, MI>;3087    defm: Memopxr_add_pat  <Load, Store, ImmPred, Oper, MI>;3088  }3089}3090 3091let AddedComplexity = 200 in {3092  // add reg3093  defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, add,3094        /*anyext*/  L4_add_memopb_io>;3095  defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, add,3096        /*sext*/    L4_add_memopb_io>;3097  defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, add,3098        /*zext*/    L4_add_memopb_io>;3099  defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, add,3100        /*anyext*/  L4_add_memoph_io>;3101  defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, add,3102        /*sext*/    L4_add_memoph_io>;3103  defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, add,3104        /*zext*/    L4_add_memoph_io>;3105  defm: Memopxr_pat<load, store, u6_2ImmPred, add, L4_add_memopw_io>;3106 3107  // sub reg3108  defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, sub,3109        /*anyext*/  L4_sub_memopb_io>;3110  defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, sub,3111        /*sext*/    L4_sub_memopb_io>;3112  defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, sub,3113        /*zext*/    L4_sub_memopb_io>;3114  defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, sub,3115        /*anyext*/  L4_sub_memoph_io>;3116  defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, sub,3117        /*sext*/    L4_sub_memoph_io>;3118  defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, sub,3119        /*zext*/    L4_sub_memoph_io>;3120  defm: Memopxr_pat<load, store, u6_2ImmPred, sub, L4_sub_memopw_io>;3121 3122  // and reg3123  defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, and,3124        /*anyext*/  L4_and_memopb_io>;3125  defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, and,3126        /*sext*/    L4_and_memopb_io>;3127  defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, and,3128        /*zext*/    L4_and_memopb_io>;3129  defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, and,3130        /*anyext*/  L4_and_memoph_io>;3131  defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, and,3132        /*sext*/    L4_and_memoph_io>;3133  defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, and,3134        /*zext*/    L4_and_memoph_io>;3135  defm: Memopxr_pat<load, store, u6_2ImmPred, and, L4_and_memopw_io>;3136 3137  // or reg3138  defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, or,3139        /*anyext*/  L4_or_memopb_io>;3140  defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, or,3141        /*sext*/    L4_or_memopb_io>;3142  defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, or,3143        /*zext*/    L4_or_memopb_io>;3144  defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, or,3145        /*anyext*/  L4_or_memoph_io>;3146  defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, or,3147        /*sext*/    L4_or_memoph_io>;3148  defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, or,3149        /*zext*/    L4_or_memoph_io>;3150  defm: Memopxr_pat<load, store, u6_2ImmPred, or, L4_or_memopw_io>;3151}3152 3153 3154multiclass Memopxi_base_pat<PatFrag Load, PatFrag Store, SDNode Oper,3155                            PatFrag Arg, SDNodeXForm ArgMod, InstHexagon MI> {3156  // Addr: i323157  def: Pat<(Store (Oper (Load I32:$Rs), Arg:$A), I32:$Rs),3158           (MI I32:$Rs, 0, (ArgMod Arg:$A))>;3159  // Addr: fi3160  def: Pat<(Store (Oper (Load AddrFI:$Rs), Arg:$A), AddrFI:$Rs),3161           (MI AddrFI:$Rs, 0, (ArgMod Arg:$A))>;3162}3163 3164multiclass Memopxi_add_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred,3165                           SDNode Oper, PatFrag Arg, SDNodeXForm ArgMod,3166                           InstHexagon MI> {3167  // Addr: i323168  def: Pat<(Store (Oper (Load (add I32:$Rs, ImmPred:$Off)), Arg:$A),3169                  (add I32:$Rs, ImmPred:$Off)),3170           (MI I32:$Rs, imm:$Off, (ArgMod Arg:$A))>;3171  def: Pat<(Store (Oper (Load (IsOrAdd I32:$Rs, ImmPred:$Off)), Arg:$A),3172                  (IsOrAdd I32:$Rs, ImmPred:$Off)),3173           (MI I32:$Rs, imm:$Off, (ArgMod Arg:$A))>;3174  // Addr: fi3175  def: Pat<(Store (Oper (Load (add AddrFI:$Rs, ImmPred:$Off)), Arg:$A),3176                  (add AddrFI:$Rs, ImmPred:$Off)),3177           (MI AddrFI:$Rs, imm:$Off, (ArgMod Arg:$A))>;3178  def: Pat<(Store (Oper (Load (IsOrAdd AddrFI:$Rs, ImmPred:$Off)), Arg:$A),3179                  (IsOrAdd AddrFI:$Rs, ImmPred:$Off)),3180           (MI AddrFI:$Rs, imm:$Off, (ArgMod Arg:$A))>;3181}3182 3183multiclass Memopxi_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred,3184                       SDNode Oper, PatFrag Arg, SDNodeXForm ArgMod,3185                       InstHexagon MI> {3186  let Predicates = [UseMEMOPS] in {3187    defm: Memopxi_base_pat <Load, Store,          Oper, Arg, ArgMod, MI>;3188    defm: Memopxi_add_pat  <Load, Store, ImmPred, Oper, Arg, ArgMod, MI>;3189  }3190}3191 3192let AddedComplexity = 220 in {3193  // add imm3194  defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, add, u5_0ImmPred,3195        /*anyext*/  IdImm, L4_iadd_memopb_io>;3196  defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, add, u5_0ImmPred,3197        /*sext*/    IdImm, L4_iadd_memopb_io>;3198  defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, add, u5_0ImmPred,3199        /*zext*/    IdImm, L4_iadd_memopb_io>;3200  defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, u5_0ImmPred,3201        /*anyext*/  IdImm, L4_iadd_memoph_io>;3202  defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, u5_0ImmPred,3203        /*sext*/    IdImm, L4_iadd_memoph_io>;3204  defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, u5_0ImmPred,3205        /*zext*/    IdImm, L4_iadd_memoph_io>;3206  defm: Memopxi_pat<load, store, u6_2ImmPred, add, u5_0ImmPred, IdImm,3207                    L4_iadd_memopw_io>;3208  defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, sub, m5_0Imm8Pred,3209        /*anyext*/  NegImm8, L4_iadd_memopb_io>;3210  defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, sub, m5_0Imm8Pred,3211        /*sext*/    NegImm8, L4_iadd_memopb_io>;3212  defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, sub, m5_0Imm8Pred,3213        /*zext*/    NegImm8, L4_iadd_memopb_io>;3214  defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, sub, m5_0Imm16Pred,3215        /*anyext*/  NegImm16, L4_iadd_memoph_io>;3216  defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, sub, m5_0Imm16Pred,3217        /*sext*/    NegImm16, L4_iadd_memoph_io>;3218  defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, sub, m5_0Imm16Pred,3219        /*zext*/    NegImm16, L4_iadd_memoph_io>;3220  defm: Memopxi_pat<load, store, u6_2ImmPred, sub, m5_0ImmPred, NegImm32,3221                    L4_iadd_memopw_io>;3222 3223  // sub imm3224  defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, sub, u5_0ImmPred,3225        /*anyext*/  IdImm, L4_isub_memopb_io>;3226  defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, sub, u5_0ImmPred,3227        /*sext*/    IdImm, L4_isub_memopb_io>;3228  defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, sub, u5_0ImmPred,3229        /*zext*/    IdImm, L4_isub_memopb_io>;3230  defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, sub, u5_0ImmPred,3231        /*anyext*/  IdImm, L4_isub_memoph_io>;3232  defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, sub, u5_0ImmPred,3233        /*sext*/    IdImm, L4_isub_memoph_io>;3234  defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, sub, u5_0ImmPred,3235        /*zext*/    IdImm, L4_isub_memoph_io>;3236  defm: Memopxi_pat<load, store, u6_2ImmPred, sub, u5_0ImmPred, IdImm,3237                    L4_isub_memopw_io>;3238  defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, add, m5_0Imm8Pred,3239        /*anyext*/  NegImm8, L4_isub_memopb_io>;3240  defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, add, m5_0Imm8Pred,3241        /*sext*/    NegImm8, L4_isub_memopb_io>;3242  defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, add, m5_0Imm8Pred,3243        /*zext*/    NegImm8, L4_isub_memopb_io>;3244  defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, m5_0Imm16Pred,3245        /*anyext*/  NegImm16, L4_isub_memoph_io>;3246  defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, add, m5_0Imm16Pred,3247        /*sext*/    NegImm16, L4_isub_memoph_io>;3248  defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, add, m5_0Imm16Pred,3249        /*zext*/    NegImm16, L4_isub_memoph_io>;3250  defm: Memopxi_pat<load, store, u6_2ImmPred, add, m5_0ImmPred, NegImm32,3251                    L4_isub_memopw_io>;3252 3253  // clrbit imm3254  defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, and, IsNPow2_8,3255        /*anyext*/  LogN2_8, L4_iand_memopb_io>;3256  defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, and, IsNPow2_8,3257        /*sext*/    LogN2_8, L4_iand_memopb_io>;3258  defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, and, IsNPow2_8,3259        /*zext*/    LogN2_8, L4_iand_memopb_io>;3260  defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, and, IsNPow2_16,3261        /*anyext*/  LogN2_16, L4_iand_memoph_io>;3262  defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, and, IsNPow2_16,3263        /*sext*/    LogN2_16, L4_iand_memoph_io>;3264  defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, and, IsNPow2_16,3265        /*zext*/    LogN2_16, L4_iand_memoph_io>;3266  defm: Memopxi_pat<load, store, u6_2ImmPred, and, IsNPow2_32,3267		    LogN2_32, L4_iand_memopw_io>;3268 3269  // setbit imm3270  defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, or, IsPow2_32,3271        /*anyext*/  Log2_8, L4_ior_memopb_io>;3272  defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, or, IsPow2_32,3273        /*sext*/    Log2_8, L4_ior_memopb_io>;3274  defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, or, IsPow2_32,3275        /*zext*/    Log2_8, L4_ior_memopb_io>;3276  defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, or, IsPow2_32,3277        /*anyext*/  Log2_16, L4_ior_memoph_io>;3278  defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, or, IsPow2_32,3279        /*sext*/    Log2_16, L4_ior_memoph_io>;3280  defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, or, IsPow2_32,3281        /*zext*/    Log2_16, L4_ior_memoph_io>;3282  defm: Memopxi_pat<load, store, u6_2ImmPred, or, IsPow2_32,3283		    Log2_32, L4_ior_memopw_io>;3284}3285 3286 3287// --(15) Call -----------------------------------------------------------3288//3289 3290// Pseudo instructions.3291def SDT_SPCallSeqStart3292  : SDCallSeqStart<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;3293def SDT_SPCallSeqEnd3294  : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;3295 3296def callseq_start: SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart,3297                          [SDNPHasChain, SDNPOutGlue]>;3298def callseq_end:   SDNode<"ISD::CALLSEQ_END",   SDT_SPCallSeqEnd,3299                          [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;3300 3301def SDT_SPCall: SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;3302 3303def HexagonTCRet: SDNode<"HexagonISD::TC_RETURN", SDT_SPCall,3304                         [SDNPHasChain,  SDNPOptInGlue, SDNPVariadic]>;3305def callv3: SDNode<"HexagonISD::CALL", SDT_SPCall,3306                   [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>;3307def callv3nr: SDNode<"HexagonISD::CALLnr", SDT_SPCall,3308                     [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>;3309 3310def: Pat<(callseq_start timm:$amt, timm:$amt2),3311         (ADJCALLSTACKDOWN imm:$amt, imm:$amt2)>;3312def: Pat<(callseq_end timm:$amt1, timm:$amt2),3313         (ADJCALLSTACKUP imm:$amt1, imm:$amt2)>;3314 3315def: Pat<(HexagonTCRet tglobaladdr:$dst),   (PS_tailcall_i tglobaladdr:$dst)>;3316def: Pat<(HexagonTCRet texternalsym:$dst),  (PS_tailcall_i texternalsym:$dst)>;3317def: Pat<(HexagonTCRet I32:$dst),           (PS_tailcall_r I32:$dst)>;3318 3319def: Pat<(callv3 I32:$dst),                 (J2_callr I32:$dst)>;3320def: Pat<(callv3 tglobaladdr:$dst),         (J2_call tglobaladdr:$dst)>;3321def: Pat<(callv3 texternalsym:$dst),        (J2_call texternalsym:$dst)>;3322def: Pat<(callv3 tglobaltlsaddr:$dst),      (J2_call tglobaltlsaddr:$dst)>;3323 3324def: Pat<(callv3nr I32:$dst),               (PS_callr_nr I32:$dst)>;3325def: Pat<(callv3nr tglobaladdr:$dst),       (PS_call_nr tglobaladdr:$dst)>;3326def: Pat<(callv3nr texternalsym:$dst),      (PS_call_nr texternalsym:$dst)>;3327 3328def retglue : SDNode<"HexagonISD::RET_GLUE", SDTNone,3329                     [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;3330def eh_return: SDNode<"HexagonISD::EH_RETURN", SDTNone, [SDNPHasChain]>;3331 3332def: Pat<(retglue),   (PS_jmpret (i32 R31))>;3333def: Pat<(eh_return), (EH_RETURN_JMPR (i32 R31))>;3334 3335 3336// --(16) Branch ---------------------------------------------------------3337//3338 3339def: Pat<(br      bb:$dst),         (J2_jump  b30_2Imm:$dst)>;3340def: Pat<(brind   I32:$dst),        (J2_jumpr I32:$dst)>;3341 3342def: Pat<(brcond I1:$Pu, bb:$dst),3343         (J2_jumpt I1:$Pu, bb:$dst)>;3344def: Pat<(brcond (not I1:$Pu), bb:$dst),3345         (J2_jumpf I1:$Pu, bb:$dst)>;3346def: Pat<(brcond (i1 (setne I1:$Pu, -1)), bb:$dst),3347         (J2_jumpf I1:$Pu, bb:$dst)>;3348def: Pat<(brcond (i1 (seteq I1:$Pu, 0)), bb:$dst),3349         (J2_jumpf I1:$Pu, bb:$dst)>;3350def: Pat<(brcond (i1 (setne I1:$Pu, 0)), bb:$dst),3351         (J2_jumpt I1:$Pu, bb:$dst)>;3352 3353 3354// --(17) Misc -----------------------------------------------------------3355 3356 3357// Generate code of the form 'C2_muxii(cmpbgtui(Rdd, C-1),0,1)'3358// for C code of the form r = (c>='0' && c<='9') ? 1 : 0.3359// The isdigit transformation relies on two 'clever' aspects:3360// 1) The data type is unsigned which allows us to eliminate a zero test after3361//    biasing the expression by 48. We are depending on the representation of3362//    the unsigned types, and semantics.3363// 2) The front end has converted <= 9 into < 10 on entry to LLVM.3364//3365// For the C code:3366//   retval = (c >= '0' && c <= '9') ? 1 : 0;3367// The code is transformed upstream of llvm into3368//   retval = (c-48) < 10 ? 1 : 0;3369 3370def u7_0PosImmPred : ImmLeaf<i32, [{3371  // True if the immediate fits in an 7-bit unsigned field and is positive.3372  return Imm > 0 && isUInt<7>(Imm);3373}]>;3374 3375let AddedComplexity = 139 in3376def: Pat<(i32 (zext (i1 (setult (and I32:$Rs, 255), u7_0PosImmPred:$u7)))),3377         (C2_muxii (A4_cmpbgtui IntRegs:$Rs, (UDEC1 imm:$u7)), 0, 1)>;3378 3379let AddedComplexity = 100 in3380def: Pat<(or (or (shl (HexagonINSERT (i32 (zextloadi8 (add I32:$b, 2))),3381                                     (i32 (extloadi8  (add I32:$b, 3))),3382                                     24, 8),3383                      (i32 16)),3384                 (shl (i32 (zextloadi8 (add I32:$b, 1))), (i32 8))),3385             (zextloadi8 I32:$b)),3386         (A2_swiz (L2_loadri_io I32:$b, 0))>;3387 3388 3389// We need custom lowering of ISD::PREFETCH into HexagonISD::DCFETCH3390// because the SDNode ISD::PREFETCH has properties MayLoad and MayStore.3391// We don't really want either one here.3392def SDTHexagonDCFETCH: SDTypeProfile<0, 2, [SDTCisPtrTy<0>,SDTCisInt<1>]>;3393def HexagonDCFETCH: SDNode<"HexagonISD::DCFETCH", SDTHexagonDCFETCH,3394                           [SDNPHasChain]>;3395 3396def: Pat<(HexagonDCFETCH IntRegs:$Rs, u11_3ImmPred:$u11_3),3397         (Y2_dcfetchbo IntRegs:$Rs, imm:$u11_3)>;3398def: Pat<(HexagonDCFETCH (i32 (add IntRegs:$Rs, u11_3ImmPred:$u11_3)), (i32 0)),3399         (Y2_dcfetchbo IntRegs:$Rs, imm:$u11_3)>;3400 3401def SDTHexagonALLOCA3402  : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;3403def HexagonALLOCA3404  : SDNode<"HexagonISD::ALLOCA", SDTHexagonALLOCA, [SDNPHasChain]>;3405 3406def: Pat<(HexagonALLOCA I32:$Rs, (i32 imm:$A)),3407         (PS_alloca IntRegs:$Rs, imm:$A)>;3408 3409def HexagonBARRIER: SDNode<"HexagonISD::BARRIER", SDTNone, [SDNPHasChain]>;3410def: Pat<(HexagonBARRIER), (Y2_barrier)>;3411 3412def: Pat<(trap), (PS_crash)>;3413def: Pat<(debugtrap), (Y2_break)>;3414 3415// Read cycle counter.3416def SDTInt64Leaf: SDTypeProfile<1, 0, [SDTCisVT<0, i64>]>;3417def HexagonREADCYCLE: SDNode<"HexagonISD::READCYCLE", SDTInt64Leaf,3418  [SDNPHasChain]>;3419 3420def: Pat<(HexagonREADCYCLE), (A4_tfrcpp UPCYCLE)>;3421 3422// Read time counter.3423def HexagonREADTIMER: SDNode<"HexagonISD::READTIMER", SDTInt64Leaf,3424  [SDNPHasChain]>;3425 3426def: Pat<(HexagonREADTIMER), (A4_tfrcpp UTIMER)>;3427 3428def SDTInt32Leaf : SDTypeProfile<1, 0, [SDTCisVT<0, i32>]>;3429def HexagonTHREADPOINTER : SDNode<"HexagonISD::THREAD_POINTER", SDTPtrLeaf>;3430 3431def : Pat<(HexagonTHREADPOINTER), (i32(COPY UGP))>;3432 3433// The declared return value of the store-locked intrinsics is i32, but3434// the instructions actually define i1. To avoid register copies from3435// IntRegs to PredRegs and back, fold the entire pattern checking the3436// result against true/false.3437let AddedComplexity = 100 in {3438  def: Pat<(i1 (setne (int_hexagon_S2_storew_locked I32:$Rs, I32:$Rt), 0)),3439           (S2_storew_locked I32:$Rs, I32:$Rt)>;3440  def: Pat<(i1 (seteq (int_hexagon_S2_storew_locked I32:$Rs, I32:$Rt), 0)),3441           (C2_not (S2_storew_locked I32:$Rs, I32:$Rt))>;3442  def: Pat<(i1 (setne (int_hexagon_S4_stored_locked I32:$Rs, I64:$Rt), 0)),3443           (S4_stored_locked I32:$Rs, I64:$Rt)>;3444  def: Pat<(i1 (seteq (int_hexagon_S4_stored_locked I32:$Rs, I64:$Rt), 0)),3445           (C2_not (S4_stored_locked I32:$Rs, I64:$Rt))>;3446}3447 3448multiclass FloatClass<SDPatternOperator IntOp, InstHexagon MI,3449                      PatFrag RegPred> {3450  let AddedComplexity = 100 in {3451    def: Pat<(i1 (seteq (IntOp RegPred:$Rs, u5_0ImmPred_timm:$u5), 0)),3452             (C2_not (MI RegPred:$Rs, u5_0ImmPred_timm:$u5))>;3453    def: Pat<(i1 (setne (IntOp RegPred:$Rs, u5_0ImmPred_timm:$u5), 0)),3454             (MI RegPred:$Rs, u5_0ImmPred_timm:$u5)>;3455  }3456}3457 3458defm : FloatClass<int_hexagon_F2_sfclass, F2_sfclass, F32>;3459defm : FloatClass<int_hexagon_F2_dfclass, F2_dfclass, F64>;3460 3461def: Pat<(int_hexagon_instrprof_custom (HexagonAtPcrel tglobaladdr:$addr), u32_0ImmPred:$I),3462         (PS_call_instrprof_custom tglobaladdr:$addr, imm:$I)>;3463 3464def: Pat<(int_hexagon_instrprof_custom (HexagonCONST32 tglobaladdr:$addr), u32_0ImmPred:$I),3465         (PS_call_instrprof_custom tglobaladdr:$addr, imm:$I)>;3466