1//===----------X86InstrFragments - X86 Pattern fragments. --*- 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-exception 6// 7//===----------------------------------------------------------------------===// 8 9// X86-specific DAG node. 10def SDTX86CmpTest : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisInt<1>, 11 SDTCisSameAs<1, 2>]>; 12def SDTX86FCmp : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisFP<1>, 13 SDTCisSameAs<1, 2>]>; 14 15def SDTX86Ccmp : SDTypeProfile<1, 5, 16 [SDTCisVT<3, i8>, SDTCisVT<4, i8>, SDTCisVT<5, i32>]>; 17 18// RES = op PTR, PASSTHRU, COND, EFLAGS 19def SDTX86Cload : SDTypeProfile<1, 4, 20 [SDTCisInt<0>, SDTCisPtrTy<1>, SDTCisSameAs<0, 2>, 21 SDTCisVT<3, i8>, SDTCisVT<4, i32>]>; 22// op VAL, PTR, COND, EFLAGS 23def SDTX86Cstore : SDTypeProfile<0, 4, 24 [SDTCisInt<0>, SDTCisPtrTy<1>, 25 SDTCisVT<2, i8>, SDTCisVT<3, i32>]>; 26 27def SDTX86Cmov : SDTypeProfile<1, 4, 28 [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, 29 SDTCisVT<3, i8>, SDTCisVT<4, i32>]>; 30 31// Unary and binary operator instructions that set EFLAGS as a side-effect. 32def SDTUnaryArithWithFlags : SDTypeProfile<2, 1, 33 [SDTCisSameAs<0, 2>, 34 SDTCisInt<0>, SDTCisVT<1, i32>]>; 35 36def SDTBinaryArithWithFlags : SDTypeProfile<2, 2, 37 [SDTCisSameAs<0, 2>, 38 SDTCisSameAs<0, 3>, 39 SDTCisInt<0>, SDTCisVT<1, i32>]>; 40 41// SDTBinaryArithWithFlagsInOut - RES1, EFLAGS = op LHS, RHS, EFLAGS 42def SDTBinaryArithWithFlagsInOut : SDTypeProfile<2, 3, 43 [SDTCisSameAs<0, 2>, 44 SDTCisSameAs<0, 3>, 45 SDTCisInt<0>, 46 SDTCisVT<1, i32>, 47 SDTCisVT<4, i32>]>; 48 49def SDTX86BrCond : SDTypeProfile<0, 3, 50 [SDTCisVT<0, OtherVT>, 51 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>; 52 53def SDTX86SetCC : SDTypeProfile<1, 2, 54 [SDTCisVT<0, i8>, 55 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>; 56def SDTX86SetCC_C : SDTypeProfile<1, 2, 57 [SDTCisInt<0>, 58 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>; 59 60def SDTX86sahf : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i8>]>; 61 62def SDTX86rdrand : SDTypeProfile<2, 0, [SDTCisInt<0>, SDTCisVT<1, i32>]>; 63 64def SDTX86rdpkru : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; 65def SDTX86wrpkru : SDTypeProfile<0, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, 66 SDTCisVT<2, i32>]>; 67 68def SDTX86cas : SDTypeProfile<0, 3, [SDTCisPtrTy<0>, SDTCisInt<1>, 69 SDTCisVT<2, i8>]>; 70def SDTX86cas8pair : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; 71def SDTX86cas16pair : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i64>]>; 72 73def SDTLockBinaryArithWithFlags : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, 74 SDTCisPtrTy<1>, 75 SDTCisInt<2>]>; 76 77def SDTLockUnaryArithWithFlags : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, 78 SDTCisPtrTy<1>]>; 79 80def SDTX86Ret : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>; 81 82def SDT_X86CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>, 83 SDTCisVT<1, i32>]>; 84def SDT_X86CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, 85 SDTCisVT<1, i32>]>; 86 87def SDT_X86Call : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>; 88 89def SDT_X86NtBrind : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>; 90 91def SDT_X86VASTART_SAVE_XMM_REGS : SDTypeProfile<0, -1, [SDTCisVT<0, i8>, 92 SDTCisPtrTy<1>]>; 93 94def SDT_X86VAARG : SDTypeProfile<1, -1, [SDTCisPtrTy<0>, 95 SDTCisPtrTy<1>, 96 SDTCisVT<2, i32>, 97 SDTCisVT<3, i8>, 98 SDTCisVT<4, i32>]>; 99 100def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>; 101 102def SDTX86Void : SDTypeProfile<0, 0, []>; 103 104def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>; 105 106def SDT_X86TLSADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>; 107 108def SDT_X86TLSBASEADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>; 109 110def SDT_X86TLSCALL : SDTypeProfile<0, 1, [SDTCisInt<0>]>; 111 112def SDT_X86DYN_ALLOCA : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>; 113 114def SDT_X86SEG_ALLOCA : SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>; 115 116def SDT_X86PROBED_ALLOCA : SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>; 117 118def SDT_X86EHRET : SDTypeProfile<0, 1, [SDTCisInt<0>]>; 119 120def SDT_X86TCRET : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>; 121 122def SDT_X86ENQCMD : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, 123 SDTCisPtrTy<1>, SDTCisSameAs<1, 2>]>; 124 125def SDT_X86AESENCDECKL : SDTypeProfile<2, 2, [SDTCisVT<0, v2i64>, 126 SDTCisVT<1, i32>, 127 SDTCisVT<2, v2i64>, 128 SDTCisPtrTy<3>]>; 129 130def SDTX86Cmpccxadd : SDTypeProfile<1, 4, [SDTCisSameAs<0, 2>, 131 SDTCisPtrTy<1>, SDTCisSameAs<2, 3>, 132 SDTCisVT<4, i8>]>; 133 134def X86MFence : SDNode<"X86ISD::MFENCE", SDTNone, [SDNPHasChain]>; 135 136 137def X86bsf : SDNode<"X86ISD::BSF", SDTBinaryArithWithFlags>; 138def X86bsr : SDNode<"X86ISD::BSR", SDTBinaryArithWithFlags>; 139def X86fshl : SDNode<"X86ISD::FSHL", SDTIntShiftDOp>; 140def X86fshr : SDNode<"X86ISD::FSHR", SDTIntShiftDOp>; 141 142def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest>; 143def X86fcmp : SDNode<"X86ISD::FCMP", SDTX86FCmp>; 144def X86strict_fcmp : SDNode<"X86ISD::STRICT_FCMP", SDTX86FCmp, [SDNPHasChain]>; 145def X86strict_fcmps : SDNode<"X86ISD::STRICT_FCMPS", SDTX86FCmp, [SDNPHasChain]>; 146def X86bt : SDNode<"X86ISD::BT", SDTX86CmpTest>; 147 148def X86ccmp : SDNode<"X86ISD::CCMP", SDTX86Ccmp>; 149def X86ctest : SDNode<"X86ISD::CTEST", SDTX86Ccmp>; 150 151def X86cload : SDNode<"X86ISD::CLOAD", SDTX86Cload, [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 152def X86cstore : SDNode<"X86ISD::CSTORE", SDTX86Cstore, [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 153 154def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov>; 155def X86brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond, 156 [SDNPHasChain]>; 157def X86setcc : SDNode<"X86ISD::SETCC", SDTX86SetCC>; 158def X86setcc_c : SDNode<"X86ISD::SETCC_CARRY", SDTX86SetCC_C>; 159 160def X86rdrand : SDNode<"X86ISD::RDRAND", SDTX86rdrand, 161 [SDNPHasChain, SDNPSideEffect]>; 162 163def X86rdseed : SDNode<"X86ISD::RDSEED", SDTX86rdrand, 164 [SDNPHasChain, SDNPSideEffect]>; 165 166def X86rdpkru : SDNode<"X86ISD::RDPKRU", SDTX86rdpkru, 167 [SDNPHasChain, SDNPSideEffect]>; 168def X86wrpkru : SDNode<"X86ISD::WRPKRU", SDTX86wrpkru, 169 [SDNPHasChain, SDNPSideEffect]>; 170 171def X86cas : SDNode<"X86ISD::LCMPXCHG_DAG", SDTX86cas, 172 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore, 173 SDNPMayLoad, SDNPMemOperand]>; 174def X86cas8 : SDNode<"X86ISD::LCMPXCHG8_DAG", SDTX86cas8pair, 175 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore, 176 SDNPMayLoad, SDNPMemOperand]>; 177def X86cas16 : SDNode<"X86ISD::LCMPXCHG16_DAG", SDTX86cas16pair, 178 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore, 179 SDNPMayLoad, SDNPMemOperand]>; 180 181def X86retglue : SDNode<"X86ISD::RET_GLUE", SDTX86Ret, 182 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 183def X86iret : SDNode<"X86ISD::IRET", SDTX86Ret, 184 [SDNPHasChain, SDNPOptInGlue]>; 185 186def X86vastart_save_xmm_regs : 187 SDNode<"X86ISD::VASTART_SAVE_XMM_REGS", 188 SDT_X86VASTART_SAVE_XMM_REGS, 189 [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPVariadic]>; 190def X86vaarg64 : 191 SDNode<"X86ISD::VAARG_64", SDT_X86VAARG, 192 [SDNPHasChain, SDNPMayLoad, SDNPMayStore, 193 SDNPMemOperand]>; 194def X86vaargx32 : 195 SDNode<"X86ISD::VAARG_X32", SDT_X86VAARG, 196 [SDNPHasChain, SDNPMayLoad, SDNPMayStore, 197 SDNPMemOperand]>; 198def X86callseq_start : 199 SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart, 200 [SDNPHasChain, SDNPOutGlue]>; 201def X86callseq_end : 202 SDNode<"ISD::CALLSEQ_END", SDT_X86CallSeqEnd, 203 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 204 205def X86call : SDNode<"X86ISD::CALL", SDT_X86Call, 206 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, 207 SDNPVariadic]>; 208 209def X86call_rvmarker : SDNode<"X86ISD::CALL_RVMARKER", SDT_X86Call, 210 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, 211 SDNPVariadic]>; 212 213def X86imp_call : SDNode<"X86ISD::IMP_CALL", SDT_X86Call, 214 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, 215 SDNPVariadic]>; 216 217def X86NoTrackCall : SDNode<"X86ISD::NT_CALL", SDT_X86Call, 218 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, 219 SDNPVariadic]>; 220def X86NoTrackBrind : SDNode<"X86ISD::NT_BRIND", SDT_X86NtBrind, 221 [SDNPHasChain]>; 222 223def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr, 224 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore]>; 225def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr, 226 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore, 227 SDNPMayLoad]>; 228 229def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>; 230def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>; 231 232def X86RecoverFrameAlloc : SDNode<"ISD::LOCAL_RECOVER", 233 SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, 234 SDTCisInt<1>]>>; 235 236def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR, 237 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 238 239def X86tlsbaseaddr : SDNode<"X86ISD::TLSBASEADDR", SDT_X86TLSBASEADDR, 240 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 241 242def X86tlsdesc : SDNode<"X86ISD::TLSDESC", SDT_X86TLSADDR, 243 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 244 245def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET, 246 [SDNPHasChain]>; 247 248def X86eh_sjlj_setjmp : SDNode<"X86ISD::EH_SJLJ_SETJMP", 249 SDTypeProfile<1, 1, [SDTCisInt<0>, 250 SDTCisPtrTy<1>]>, 251 [SDNPHasChain, SDNPSideEffect]>; 252def X86eh_sjlj_longjmp : SDNode<"X86ISD::EH_SJLJ_LONGJMP", 253 SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>, 254 [SDNPHasChain, SDNPSideEffect]>; 255def X86eh_sjlj_setup_dispatch : SDNode<"X86ISD::EH_SJLJ_SETUP_DISPATCH", 256 SDTypeProfile<0, 0, []>, 257 [SDNPHasChain, SDNPSideEffect]>; 258 259def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET, 260 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 261 262def X86add_flag : SDNode<"X86ISD::ADD", SDTBinaryArithWithFlags, 263 [SDNPCommutative]>; 264def X86sub_flag : SDNode<"X86ISD::SUB", SDTBinaryArithWithFlags>; 265def X86smul_flag : SDNode<"X86ISD::SMUL", SDTBinaryArithWithFlags, 266 [SDNPCommutative]>; 267def X86umul_flag : SDNode<"X86ISD::UMUL", SDTBinaryArithWithFlags, 268 [SDNPCommutative]>; 269def X86adc_flag : SDNode<"X86ISD::ADC", SDTBinaryArithWithFlagsInOut>; 270def X86sbb_flag : SDNode<"X86ISD::SBB", SDTBinaryArithWithFlagsInOut>; 271 272def X86or_flag : SDNode<"X86ISD::OR", SDTBinaryArithWithFlags, 273 [SDNPCommutative]>; 274def X86xor_flag : SDNode<"X86ISD::XOR", SDTBinaryArithWithFlags, 275 [SDNPCommutative]>; 276def X86and_flag : SDNode<"X86ISD::AND", SDTBinaryArithWithFlags, 277 [SDNPCommutative]>; 278 279def X86lock_add : SDNode<"X86ISD::LADD", SDTLockBinaryArithWithFlags, 280 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, 281 SDNPMemOperand]>; 282def X86lock_sub : SDNode<"X86ISD::LSUB", SDTLockBinaryArithWithFlags, 283 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, 284 SDNPMemOperand]>; 285def X86lock_or : SDNode<"X86ISD::LOR", SDTLockBinaryArithWithFlags, 286 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, 287 SDNPMemOperand]>; 288def X86lock_xor : SDNode<"X86ISD::LXOR", SDTLockBinaryArithWithFlags, 289 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, 290 SDNPMemOperand]>; 291def X86lock_and : SDNode<"X86ISD::LAND", SDTLockBinaryArithWithFlags, 292 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, 293 SDNPMemOperand]>; 294 295def X86bextr : SDNode<"X86ISD::BEXTR", SDTIntBinOp>; 296def X86bextri : SDNode<"X86ISD::BEXTRI", SDTIntBinOp>; 297 298def X86bzhi : SDNode<"X86ISD::BZHI", SDTIntBinOp>; 299 300def X86pdep : SDNode<"X86ISD::PDEP", SDTIntBinOp>; 301def X86pext : SDNode<"X86ISD::PEXT", SDTIntBinOp>; 302 303def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>; 304 305def X86DynAlloca : SDNode<"X86ISD::DYN_ALLOCA", SDT_X86DYN_ALLOCA, 306 [SDNPHasChain, SDNPOutGlue]>; 307 308def X86SegAlloca : SDNode<"X86ISD::SEG_ALLOCA", SDT_X86SEG_ALLOCA, 309 [SDNPHasChain]>; 310 311def X86ProbedAlloca : SDNode<"X86ISD::PROBED_ALLOCA", SDT_X86PROBED_ALLOCA, 312 [SDNPHasChain]>; 313 314def X86TLSCall : SDNode<"X86ISD::TLSCALL", SDT_X86TLSCALL, 315 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 316 317def X86lwpins : SDNode<"X86ISD::LWPINS", 318 SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisInt<1>, 319 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>, 320 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPSideEffect]>; 321 322def X86umwait : SDNode<"X86ISD::UMWAIT", 323 SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisInt<1>, 324 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>, 325 [SDNPHasChain, SDNPSideEffect]>; 326 327def X86tpause : SDNode<"X86ISD::TPAUSE", 328 SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisInt<1>, 329 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>, 330 [SDNPHasChain, SDNPSideEffect]>; 331 332def X86enqcmd : SDNode<"X86ISD::ENQCMD", SDT_X86ENQCMD, 333 [SDNPHasChain, SDNPSideEffect]>; 334def X86enqcmds : SDNode<"X86ISD::ENQCMDS", SDT_X86ENQCMD, 335 [SDNPHasChain, SDNPSideEffect]>; 336def X86testui : SDNode<"X86ISD::TESTUI", 337 SDTypeProfile<1, 0, [SDTCisVT<0, i32>]>, 338 [SDNPHasChain, SDNPSideEffect]>; 339 340def X86aesenc128kl : SDNode<"X86ISD::AESENC128KL", SDT_X86AESENCDECKL, 341 [SDNPHasChain, SDNPMayLoad, SDNPSideEffect, 342 SDNPMemOperand]>; 343def X86aesdec128kl : SDNode<"X86ISD::AESDEC128KL", SDT_X86AESENCDECKL, 344 [SDNPHasChain, SDNPMayLoad, SDNPSideEffect, 345 SDNPMemOperand]>; 346def X86aesenc256kl : SDNode<"X86ISD::AESENC256KL", SDT_X86AESENCDECKL, 347 [SDNPHasChain, SDNPMayLoad, SDNPSideEffect, 348 SDNPMemOperand]>; 349def X86aesdec256kl : SDNode<"X86ISD::AESDEC256KL", SDT_X86AESENCDECKL, 350 [SDNPHasChain, SDNPMayLoad, SDNPSideEffect, 351 SDNPMemOperand]>; 352 353def X86cmpccxadd : SDNode<"X86ISD::CMPCCXADD", SDTX86Cmpccxadd, 354 [SDNPHasChain, SDNPMayLoad, SDNPMayStore, 355 SDNPMemOperand]>; 356 357// Define X86-specific addressing mode. 358let WantsParent = true in 359def addr : ComplexPattern<iPTR, 5, "selectAddr">; 360def gi_addr : GIComplexOperandMatcher<s32, "selectAddr">, 361 GIComplexPatternEquiv<addr>; 362def lea32addr : ComplexPattern<i32, 5, "selectLEAAddr", 363 [add, sub, mul, X86mul_imm, shl, or, xor, frameindex], 364 []>; 365// In 64-bit mode 8/16/32-bit LEAs can use RIP-relative addressing. 366def lea64_iaddr : ComplexPattern<iAny, 5, "selectLEA64_Addr", 367 [add, sub, mul, X86mul_imm, shl, or, xor, 368 frameindex, X86WrapperRIP], 369 []>; 370 371def tls32addr : ComplexPattern<i32, 5, "selectTLSADDRAddr", 372 [tglobaltlsaddr], []>; 373 374def tls32baseaddr : ComplexPattern<i32, 5, "selectTLSADDRAddr", 375 [tglobaltlsaddr], []>; 376 377def lea64addr : ComplexPattern<i64, 5, "selectLEAAddr", 378 [add, sub, mul, X86mul_imm, shl, or, xor, frameindex, 379 X86WrapperRIP], []>; 380 381def tls64addr : ComplexPattern<i64, 5, "selectTLSADDRAddr", 382 [tglobaltlsaddr], []>; 383 384def tls64baseaddr : ComplexPattern<i64, 5, "selectTLSADDRAddr", 385 [tglobaltlsaddr], []>; 386 387let WantsParent = true in 388def vectoraddr : ComplexPattern<iPTR, 5, "selectVectorAddr">; 389 390// A relocatable immediate is an operand that can be relocated by the linker to 391// an immediate, such as a regular symbol in non-PIC code. 392def relocImm : ComplexPattern<iAny, 1, "selectRelocImm", 393 [X86Wrapper], [], 0>; 394 395// X86 specific condition code. These correspond to CondCode in 396// X86InstrInfo.h. They must be kept in synch. 397def X86_COND_O : PatLeaf<(i8 0)>; 398def X86_COND_NO : PatLeaf<(i8 1)>; 399def X86_COND_B : PatLeaf<(i8 2)>; // alt. COND_C 400def X86_COND_AE : PatLeaf<(i8 3)>; // alt. COND_NC 401def X86_COND_E : PatLeaf<(i8 4)>; // alt. COND_Z 402def X86_COND_NE : PatLeaf<(i8 5)>; // alt. COND_NZ 403def X86_COND_BE : PatLeaf<(i8 6)>; // alt. COND_NA 404def X86_COND_A : PatLeaf<(i8 7)>; // alt. COND_NBE 405def X86_COND_S : PatLeaf<(i8 8)>; 406def X86_COND_NS : PatLeaf<(i8 9)>; 407def X86_COND_P : PatLeaf<(i8 10)>; // alt. COND_PE 408def X86_COND_NP : PatLeaf<(i8 11)>; // alt. COND_PO 409def X86_COND_L : PatLeaf<(i8 12)>; // alt. COND_NGE 410def X86_COND_GE : PatLeaf<(i8 13)>; // alt. COND_NL 411def X86_COND_LE : PatLeaf<(i8 14)>; // alt. COND_NG 412def X86_COND_G : PatLeaf<(i8 15)>; // alt. COND_NLE 413 414def i16immSExt8 : ImmLeaf<i16, [{ return isInt<8>(Imm); }]>; 415def i32immSExt8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>; 416def i64immSExt8 : ImmLeaf<i64, [{ return isInt<8>(Imm); }]>; 417def i64immSExt32 : ImmLeaf<i64, [{ return isInt<32>(Imm); }]>; 418def i64timmSExt32 : TImmLeaf<i64, [{ return isInt<32>(Imm); }]>; 419 420def i16relocImmSExt8 : PatLeaf<(i16 relocImm), [{ 421 return isSExtAbsoluteSymbolRef(8, N); 422}]>; 423def i32relocImmSExt8 : PatLeaf<(i32 relocImm), [{ 424 return isSExtAbsoluteSymbolRef(8, N); 425}]>; 426def i64relocImmSExt8 : PatLeaf<(i64 relocImm), [{ 427 return isSExtAbsoluteSymbolRef(8, N); 428}]>; 429def i64relocImmSExt32 : PatLeaf<(i64 relocImm), [{ 430 return isSExtAbsoluteSymbolRef(32, N); 431}]>; 432 433// If we have multiple users of an immediate, it's much smaller to reuse 434// the register, rather than encode the immediate in every instruction. 435// This has the risk of increasing register pressure from stretched live 436// ranges, however, the immediates should be trivial to rematerialize by 437// the RA in the event of high register pressure. 438// TODO : This is currently enabled for stores and binary ops. There are more 439// cases for which this can be enabled, though this catches the bulk of the 440// issues. 441// TODO2 : This should really also be enabled under O2, but there's currently 442// an issue with RA where we don't pull the constants into their users 443// when we rematerialize them. I'll follow-up on enabling O2 after we fix that 444// issue. 445// TODO3 : This is currently limited to single basic blocks (DAG creation 446// pulls block immediates to the top and merges them if necessary). 447// Eventually, it would be nice to allow ConstantHoisting to merge constants 448// globally for potentially added savings. 449// 450def imm_su : PatLeaf<(imm), [{ 451 return !shouldAvoidImmediateInstFormsForSize(N); 452}]> { 453 // TODO : introduce the same check as in SDAG 454 let GISelPredicateCode = [{ return true; }]; 455} 456 457def i64immSExt32_su : PatLeaf<(i64immSExt32), [{ 458 return !shouldAvoidImmediateInstFormsForSize(N); 459}]>; 460 461def relocImm8_su : PatLeaf<(i8 relocImm), [{ 462 return !shouldAvoidImmediateInstFormsForSize(N); 463}]>; 464def relocImm16_su : PatLeaf<(i16 relocImm), [{ 465 return !shouldAvoidImmediateInstFormsForSize(N); 466}]>; 467def relocImm32_su : PatLeaf<(i32 relocImm), [{ 468 return !shouldAvoidImmediateInstFormsForSize(N); 469}]>; 470 471def i16relocImmSExt8_su : PatLeaf<(i16relocImmSExt8), [{ 472 return !shouldAvoidImmediateInstFormsForSize(N); 473}]>; 474def i32relocImmSExt8_su : PatLeaf<(i32relocImmSExt8), [{ 475 return !shouldAvoidImmediateInstFormsForSize(N); 476}]>; 477def i64relocImmSExt8_su : PatLeaf<(i64relocImmSExt8), [{ 478 return !shouldAvoidImmediateInstFormsForSize(N); 479}]>; 480def i64relocImmSExt32_su : PatLeaf<(i64relocImmSExt32), [{ 481 return !shouldAvoidImmediateInstFormsForSize(N); 482}]>; 483 484def i16immSExt8_su : PatLeaf<(i16immSExt8), [{ 485 return !shouldAvoidImmediateInstFormsForSize(N); 486}]>; 487def i32immSExt8_su : PatLeaf<(i32immSExt8), [{ 488 return !shouldAvoidImmediateInstFormsForSize(N); 489}]>; 490def i64immSExt8_su : PatLeaf<(i64immSExt8), [{ 491 return !shouldAvoidImmediateInstFormsForSize(N); 492}]>; 493 494// i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit 495// unsigned field. 496def i64immZExt32 : ImmLeaf<i64, [{ return isUInt<32>(Imm); }]>; 497 498def i64immZExt32SExt8 : ImmLeaf<i64, [{ 499 return isUInt<32>(Imm) && isInt<8>(static_cast<int32_t>(Imm)); 500}]>; 501 502// Helper fragments for loads. 503 504// It's safe to fold a zextload/extload from i1 as a regular i8 load. The 505// upper bits are guaranteed to be zero and we were going to emit a MOV8rm 506// which might get folded during peephole anyway. 507def loadi8 : PatFrag<(ops node:$ptr), (i8 (unindexedload node:$ptr)), [{ 508 LoadSDNode *LD = cast<LoadSDNode>(N); 509 ISD::LoadExtType ExtType = LD->getExtensionType(); 510 return ExtType == ISD::NON_EXTLOAD || ExtType == ISD::EXTLOAD || 511 ExtType == ISD::ZEXTLOAD; 512}]> { 513 let GISelPredicateCode = [{ return isa<GLoad>(MI); }]; 514} 515 516// It's always safe to treat a anyext i16 load as a i32 load if the i16 is 517// known to be 32-bit aligned or better. Ditto for i8 to i16. 518def loadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{ 519 LoadSDNode *LD = cast<LoadSDNode>(N); 520 ISD::LoadExtType ExtType = LD->getExtensionType(); 521 if (ExtType == ISD::NON_EXTLOAD) 522 return true; 523 if (ExtType == ISD::EXTLOAD && EnablePromoteAnyextLoad) 524 return LD->getAlign() >= 2 && LD->isSimple(); 525 return false; 526}]> { 527 let GISelPredicateCode = [{ 528 auto &Load = cast<GLoad>(MI); 529 LLT Ty = MRI.getType(Load.getDstReg()); 530 // Non extending load has MMO and destination types of the same size 531 if (Load.getMemSizeInBits() == Ty.getSizeInBits()) 532 return true; 533 return Load.getAlign() >= 2 && Load.isSimple(); 534 }]; 535} 536 537def loadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{ 538 LoadSDNode *LD = cast<LoadSDNode>(N); 539 ISD::LoadExtType ExtType = LD->getExtensionType(); 540 if (ExtType == ISD::NON_EXTLOAD) 541 return true; 542 if (ExtType == ISD::EXTLOAD && EnablePromoteAnyextLoad) 543 return LD->getAlign() >= 4 && LD->isSimple(); 544 return false; 545}]> { 546 let GISelPredicateCode = [{ 547 auto &Load = cast<GLoad>(MI); 548 LLT Ty = MRI.getType(Load.getDstReg()); 549 // Non extending load has MMO and destination types of the same size 550 if (Load.getMemSizeInBits() == Ty.getSizeInBits()) 551 return true; 552 return Load.getAlign() >= 4 && Load.isSimple(); 553 }]; 554} 555 556def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>; 557def loadf16 : PatFrag<(ops node:$ptr), (f16 (load node:$ptr))>; 558def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>; 559def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>; 560def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr))>; 561def loadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr))>; 562def alignedloadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr)), [{ 563 LoadSDNode *Ld = cast<LoadSDNode>(N); 564 return Ld->getAlign() >= Ld->getMemoryVT().getStoreSize(); 565}]>; 566def memopf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr)), [{ 567 LoadSDNode *Ld = cast<LoadSDNode>(N); 568 return Subtarget->hasSSEUnalignedMem() || 569 Ld->getAlign() >= Ld->getMemoryVT().getStoreSize(); 570}]>; 571 572def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>; 573def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>; 574def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>; 575def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>; 576def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>; 577def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>; 578 579def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>; 580def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>; 581def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>; 582def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>; 583def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>; 584def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>; 585def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>; 586def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>; 587def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>; 588def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>; 589 590def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>; 591def extloadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>; 592def extloadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>; 593def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>; 594def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>; 595def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>; 596def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>; 597def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>; 598def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>; 599 600// We can treat an i8/i16 extending load to i64 as a 32 bit load if its known 601// to be 4 byte aligned or better. 602def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (unindexedload node:$ptr)), [{ 603 LoadSDNode *LD = cast<LoadSDNode>(N); 604 ISD::LoadExtType ExtType = LD->getExtensionType(); 605 if (ExtType != ISD::EXTLOAD) 606 return false; 607 if (LD->getMemoryVT() == MVT::i32) 608 return true; 609 610 return LD->getAlign() >= 4 && LD->isSimple(); 611}]>; 612 613// binary op with only one user 614class binop_oneuse<SDPatternOperator operator> 615 : PatFrag<(ops node:$A, node:$B), 616 (operator node:$A, node:$B), [{ 617 return N->hasOneUse(); 618}]>; 619 620def add_su : binop_oneuse<add>; 621def and_su : binop_oneuse<and>; 622def srl_su : binop_oneuse<srl>; 623 624class binop_twouses<SDPatternOperator operator> 625 : PatFrag<(ops node:$A, node:$B), 626 (operator node:$A, node:$B), [{ 627 return N->hasNUsesOfValue(2, 0); 628}]>; 629 630def and_du : binop_twouses<and>; 631 632// unary op with only one user 633class unop_oneuse<SDPatternOperator operator> 634 : PatFrag<(ops node:$A), 635 (operator node:$A), [{ 636 return N->hasOneUse(); 637}]>; 638 639 640def ineg_su : unop_oneuse<ineg>; 641def trunc_su : unop_oneuse<trunc>; 642 643def X86add_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs), 644 (X86add_flag node:$lhs, node:$rhs), [{ 645 return hasNoCarryFlagUses(SDValue(N, 1)); 646}]>; 647 648def X86sub_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs), 649 (X86sub_flag node:$lhs, node:$rhs), [{ 650 // Only use DEC if the result is used. 651 return !SDValue(N, 0).use_empty() && hasNoCarryFlagUses(SDValue(N, 1)); 652}]>; 653 654def X86testpat : PatFrag<(ops node:$lhs, node:$rhs), 655 (X86cmp (and_su node:$lhs, node:$rhs), 0)>; 656def X86ctestpat : PatFrag<(ops node:$lhs, node:$rhs, node:$dcf, node:$cond), 657 (X86ctest (and_du node:$lhs, node:$rhs), 658 (and_du node:$lhs, node:$rhs), node:$dcf, 659 node:$cond, EFLAGS)>; 660 661def X86any_fcmp : PatFrags<(ops node:$lhs, node:$rhs), 662 [(X86strict_fcmp node:$lhs, node:$rhs), 663 (X86fcmp node:$lhs, node:$rhs)]>; 664 665def PrefetchWLevel : PatFrag<(ops), (i32 timm), [{ 666 return N->getSExtValue() <= 3; 667}]>; 668 669def X86lock_add_nocf : PatFrag<(ops node:$lhs, node:$rhs), 670 (X86lock_add node:$lhs, node:$rhs), [{ 671 return hasNoCarryFlagUses(SDValue(N, 0)); 672}]>; 673 674def X86lock_sub_nocf : PatFrag<(ops node:$lhs, node:$rhs), 675 (X86lock_sub node:$lhs, node:$rhs), [{ 676 return hasNoCarryFlagUses(SDValue(N, 0)); 677}]>; 678 679def X86tcret_6regs : PatFrag<(ops node:$ptr, node:$off), 680 (X86tcret node:$ptr, node:$off), [{ 681 // X86tcret args: (*chain, ptr, imm, regs..., glue) 682 unsigned NumRegs = 0; 683 for (unsigned i = 3, e = N->getNumOperands(); i != e; ++i) 684 if (isa<RegisterSDNode>(N->getOperand(i)) && ++NumRegs > 6) 685 return false; 686 return true; 687}]>; 688 689def X86tcret_1reg : PatFrag<(ops node:$ptr, node:$off), 690 (X86tcret node:$ptr, node:$off), [{ 691 // X86tcret args: (*chain, ptr, imm, regs..., glue) 692 unsigned NumRegs = 1; 693 const SDValue& BasePtr = cast<LoadSDNode>(N->getOperand(1))->getBasePtr(); 694 if (isa<FrameIndexSDNode>(BasePtr)) 695 NumRegs = 3; 696 else if (BasePtr->getNumOperands() && isa<GlobalAddressSDNode>(BasePtr->getOperand(0))) 697 NumRegs = 3; 698 for (unsigned i = 3, e = N->getNumOperands(); i != e; ++i) 699 if (isa<RegisterSDNode>(N->getOperand(i)) && ( NumRegs-- == 0)) 700 return false; 701 return true; 702}]>; 703 704// If this is an anyext of the remainder of an 8-bit sdivrem, use a MOVSX 705// instead of a MOVZX. The sdivrem lowering will emit emit a MOVSX to move 706// %ah to the lower byte of a register. By using a MOVSX here we allow a 707// post-isel peephole to merge the two MOVSX instructions into one. 708def anyext_sdiv : PatFrag<(ops node:$lhs), (anyext node:$lhs),[{ 709 return (N->getOperand(0).getOpcode() == ISD::SDIVREM && 710 N->getOperand(0).getResNo() == 1); 711}]>; 712 713// Any instruction that defines a 32-bit result leaves the high half of the 714// register. Truncate can be lowered to EXTRACT_SUBREG. CopyFromReg may 715// be copying from a truncate. AssertSext/AssertZext/AssertAlign aren't saying 716// anything about the upper 32 bits, they're probably just qualifying a 717// CopyFromReg. FREEZE may be coming from a a truncate. BitScan fall through 718// values may not zero the upper bits correctly. 719// Any other 32-bit operation will zero-extend up to 64 bits. 720def def32 : PatLeaf<(i32 GR32:$src), [{ 721 return N->getOpcode() != ISD::TRUNCATE && 722 N->getOpcode() != TargetOpcode::EXTRACT_SUBREG && 723 N->getOpcode() != ISD::CopyFromReg && 724 N->getOpcode() != ISD::AssertSext && 725 N->getOpcode() != ISD::AssertZext && 726 N->getOpcode() != ISD::AssertAlign && 727 N->getOpcode() != ISD::FREEZE && 728 !((N->getOpcode() == X86ISD::BSF || N->getOpcode() == X86ISD::BSR) && 729 (!N->getOperand(0).isUndef() && !isa<ConstantSDNode>(N->getOperand(0)))); 730}]>; 731 732// Treat an 'or' node is as an 'add' if the or'ed bits are known to be zero. 733def or_is_add : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs),[{ 734 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1))) 735 return CurDAG->MaskedValueIsZero(N->getOperand(0), CN->getAPIntValue()); 736 737 KnownBits Known0 = CurDAG->computeKnownBits(N->getOperand(0), 0); 738 KnownBits Known1 = CurDAG->computeKnownBits(N->getOperand(1), 0); 739 return (~Known0.Zero & ~Known1.Zero) == 0; 740}]>; 741 742def shiftMask8 : PatFrag<(ops node:$lhs), (and node:$lhs, imm), [{ 743 return isUnneededShiftMask(N, 3); 744}]>; 745 746def shiftMask16 : PatFrag<(ops node:$lhs), (and node:$lhs, imm), [{ 747 return isUnneededShiftMask(N, 4); 748}]>; 749 750def shiftMask32 : PatFrag<(ops node:$lhs), (and node:$lhs, imm), [{ 751 return isUnneededShiftMask(N, 5); 752}]>; 753 754def shiftMask64 : PatFrag<(ops node:$lhs), (and node:$lhs, imm), [{ 755 return isUnneededShiftMask(N, 6); 756}]>; 757 758//===----------------------------------------------------------------------===// 759// Pattern fragments to auto generate BMI instructions. 760//===----------------------------------------------------------------------===// 761 762def or_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs), 763 (X86or_flag node:$lhs, node:$rhs), [{ 764 return hasNoCarryFlagUses(SDValue(N, 1)); 765}]>; 766 767def xor_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs), 768 (X86xor_flag node:$lhs, node:$rhs), [{ 769 return hasNoCarryFlagUses(SDValue(N, 1)); 770}]>; 771 772def and_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs), 773 (X86and_flag node:$lhs, node:$rhs), [{ 774 return hasNoCarryFlagUses(SDValue(N, 1)); 775}]>; 776 777//===----------------------------------------------------------------------===// 778// FPStack specific DAG Nodes. 779//===----------------------------------------------------------------------===// 780 781def SDTX86Fld : SDTypeProfile<1, 1, [SDTCisFP<0>, 782 SDTCisPtrTy<1>]>; 783def SDTX86Fst : SDTypeProfile<0, 2, [SDTCisFP<0>, 784 SDTCisPtrTy<1>]>; 785def SDTX86Fild : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisPtrTy<1>]>; 786def SDTX86Fist : SDTypeProfile<0, 2, [SDTCisFP<0>, SDTCisPtrTy<1>]>; 787 788def SDTX86CwdStore : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; 789def SDTX86CwdLoad : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; 790def SDTX86FPEnv : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; 791 792def X86fp80_add : SDNode<"X86ISD::FP80_ADD", SDTFPBinOp, [SDNPCommutative]>; 793def X86strict_fp80_add : SDNode<"X86ISD::STRICT_FP80_ADD", SDTFPBinOp, 794 [SDNPHasChain,SDNPCommutative]>; 795def any_X86fp80_add : PatFrags<(ops node:$lhs, node:$rhs), 796 [(X86strict_fp80_add node:$lhs, node:$rhs), 797 (X86fp80_add node:$lhs, node:$rhs)]>; 798 799def X86fld : SDNode<"X86ISD::FLD", SDTX86Fld, 800 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 801def X86fst : SDNode<"X86ISD::FST", SDTX86Fst, 802 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 803def X86fild : SDNode<"X86ISD::FILD", SDTX86Fild, 804 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 805def X86fist : SDNode<"X86ISD::FIST", SDTX86Fist, 806 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 807def X86fp_to_mem : SDNode<"X86ISD::FP_TO_INT_IN_MEM", SDTX86Fst, 808 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 809def X86fp_cwd_get16 : SDNode<"X86ISD::FNSTCW16m", SDTX86CwdStore, 810 [SDNPHasChain, SDNPMayStore, SDNPSideEffect, 811 SDNPMemOperand]>; 812def X86fp_cwd_set16 : SDNode<"X86ISD::FLDCW16m", SDTX86CwdLoad, 813 [SDNPHasChain, SDNPMayLoad, SDNPSideEffect, 814 SDNPMemOperand]>; 815def X86fpenv_get : SDNode<"X86ISD::FNSTENVm", SDTX86FPEnv, 816 [SDNPHasChain, SDNPMayStore, SDNPSideEffect, 817 SDNPMemOperand]>; 818def X86fpenv_set : SDNode<"X86ISD::FLDENVm", SDTX86FPEnv, 819 [SDNPHasChain, SDNPMayLoad, SDNPSideEffect, 820 SDNPMemOperand]>; 821 822def X86fstf32 : PatFrag<(ops node:$val, node:$ptr), 823 (X86fst node:$val, node:$ptr), [{ 824 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::f32; 825}]>; 826def X86fstf64 : PatFrag<(ops node:$val, node:$ptr), 827 (X86fst node:$val, node:$ptr), [{ 828 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::f64; 829}]>; 830def X86fstf80 : PatFrag<(ops node:$val, node:$ptr), 831 (X86fst node:$val, node:$ptr), [{ 832 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::f80; 833}]>; 834 835def X86fldf32 : PatFrag<(ops node:$ptr), (X86fld node:$ptr), [{ 836 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::f32; 837}]>; 838def X86fldf64 : PatFrag<(ops node:$ptr), (X86fld node:$ptr), [{ 839 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::f64; 840}]>; 841def X86fldf80 : PatFrag<(ops node:$ptr), (X86fld node:$ptr), [{ 842 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::f80; 843}]>; 844 845def X86fild16 : PatFrag<(ops node:$ptr), (X86fild node:$ptr)> { 846 let IsLoad = true; 847 let MemoryVT = i16; 848} 849 850def X86fild32 : PatFrag<(ops node:$ptr), (X86fild node:$ptr)> { 851 let IsLoad = true; 852 let MemoryVT = i32; 853} 854 855def X86fild64 : PatFrag<(ops node:$ptr), (X86fild node:$ptr)> { 856 let IsLoad = true; 857 let MemoryVT = i64; 858} 859 860def X86fist32 : PatFrag<(ops node:$val, node:$ptr), 861 (X86fist node:$val, node:$ptr), [{ 862 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32; 863}]>; 864 865def X86fist64 : PatFrag<(ops node:$val, node:$ptr), 866 (X86fist node:$val, node:$ptr), [{ 867 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i64; 868}]>; 869 870def X86fp_to_i16mem 871 : PatFrag<(ops node:$val, node:$ptr), (X86fp_to_mem node:$val, node:$ptr)> { 872 let IsStore = true; 873 let MemoryVT = i16; 874} 875 876def X86fp_to_i32mem 877 : PatFrag<(ops node:$val, node:$ptr), (X86fp_to_mem node:$val, node:$ptr)> { 878 let IsStore = true; 879 let MemoryVT = i32; 880} 881 882def X86fp_to_i64mem 883 : PatFrag<(ops node:$val, node:$ptr), (X86fp_to_mem node:$val, node:$ptr)> { 884 let IsStore = true; 885 let MemoryVT = i64; 886} 887 888//===----------------------------------------------------------------------===// 889// FPStack pattern fragments 890//===----------------------------------------------------------------------===// 891 892def fpimm0 : FPImmLeaf<fAny, [{ 893 return Imm.isExactlyValue(+0.0); 894}]>; 895 896def fpimmneg0 : FPImmLeaf<fAny, [{ 897 return Imm.isExactlyValue(-0.0); 898}]>; 899 900def fpimm1 : FPImmLeaf<fAny, [{ 901 return Imm.isExactlyValue(+1.0); 902}]>; 903 904def fpimmneg1 : FPImmLeaf<fAny, [{ 905 return Imm.isExactlyValue(-1.0); 906}]>; 907