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