1*9880d681SAndroid Build Coastguard Worker//===- X86InstrCompiler.td - Compiler Pseudos and Patterns -*- tablegen -*-===// 2*9880d681SAndroid Build Coastguard Worker// 3*9880d681SAndroid Build Coastguard Worker// The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker// 5*9880d681SAndroid Build Coastguard Worker// This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker// License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker// 8*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker// 10*9880d681SAndroid Build Coastguard Worker// This file describes the various pseudo instructions used by the compiler, 11*9880d681SAndroid Build Coastguard Worker// as well as Pat patterns used during instruction selection. 12*9880d681SAndroid Build Coastguard Worker// 13*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 16*9880d681SAndroid Build Coastguard Worker// Pattern Matching Support 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Workerdef GetLo32XForm : SDNodeXForm<imm, [{ 19*9880d681SAndroid Build Coastguard Worker // Transformation function: get the low 32 bits. 20*9880d681SAndroid Build Coastguard Worker return getI32Imm((unsigned)N->getZExtValue(), SDLoc(N)); 21*9880d681SAndroid Build Coastguard Worker}]>; 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Workerdef GetLo8XForm : SDNodeXForm<imm, [{ 24*9880d681SAndroid Build Coastguard Worker // Transformation function: get the low 8 bits. 25*9880d681SAndroid Build Coastguard Worker return getI8Imm((uint8_t)N->getZExtValue(), SDLoc(N)); 26*9880d681SAndroid Build Coastguard Worker}]>; 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker 29*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 30*9880d681SAndroid Build Coastguard Worker// Random Pseudo Instructions. 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker// PIC base construction. This expands to code that looks like this: 33*9880d681SAndroid Build Coastguard Worker// call $next_inst 34*9880d681SAndroid Build Coastguard Worker// popl %destreg" 35*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 0, isNotDuplicable = 1, Uses = [ESP] in 36*9880d681SAndroid Build Coastguard Worker def MOVPC32r : Ii32<0xE8, Pseudo, (outs GR32:$reg), (ins i32imm:$label), 37*9880d681SAndroid Build Coastguard Worker "", []>; 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Worker// ADJCALLSTACKDOWN/UP implicitly use/def ESP because they may be expanded into 41*9880d681SAndroid Build Coastguard Worker// a stack adjustment and the codegen must know that they may modify the stack 42*9880d681SAndroid Build Coastguard Worker// pointer before prolog-epilog rewriting occurs. 43*9880d681SAndroid Build Coastguard Worker// Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become 44*9880d681SAndroid Build Coastguard Worker// sub / add which can clobber EFLAGS. 45*9880d681SAndroid Build Coastguard Workerlet Defs = [ESP, EFLAGS], Uses = [ESP] in { 46*9880d681SAndroid Build Coastguard Workerdef ADJCALLSTACKDOWN32 : I<0, Pseudo, (outs), (ins i32imm:$amt1, i32imm:$amt2), 47*9880d681SAndroid Build Coastguard Worker "#ADJCALLSTACKDOWN", 48*9880d681SAndroid Build Coastguard Worker []>, 49*9880d681SAndroid Build Coastguard Worker Requires<[NotLP64]>; 50*9880d681SAndroid Build Coastguard Workerdef ADJCALLSTACKUP32 : I<0, Pseudo, (outs), (ins i32imm:$amt1, i32imm:$amt2), 51*9880d681SAndroid Build Coastguard Worker "#ADJCALLSTACKUP", 52*9880d681SAndroid Build Coastguard Worker [(X86callseq_end timm:$amt1, timm:$amt2)]>, 53*9880d681SAndroid Build Coastguard Worker Requires<[NotLP64]>; 54*9880d681SAndroid Build Coastguard Worker} 55*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86callseq_start timm:$amt1), 56*9880d681SAndroid Build Coastguard Worker (ADJCALLSTACKDOWN32 i32imm:$amt1, 0)>, Requires<[NotLP64]>; 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Worker 59*9880d681SAndroid Build Coastguard Worker// ADJCALLSTACKDOWN/UP implicitly use/def RSP because they may be expanded into 60*9880d681SAndroid Build Coastguard Worker// a stack adjustment and the codegen must know that they may modify the stack 61*9880d681SAndroid Build Coastguard Worker// pointer before prolog-epilog rewriting occurs. 62*9880d681SAndroid Build Coastguard Worker// Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become 63*9880d681SAndroid Build Coastguard Worker// sub / add which can clobber EFLAGS. 64*9880d681SAndroid Build Coastguard Workerlet Defs = [RSP, EFLAGS], Uses = [RSP] in { 65*9880d681SAndroid Build Coastguard Workerdef ADJCALLSTACKDOWN64 : I<0, Pseudo, (outs), (ins i32imm:$amt1, i32imm:$amt2), 66*9880d681SAndroid Build Coastguard Worker "#ADJCALLSTACKDOWN", 67*9880d681SAndroid Build Coastguard Worker []>, 68*9880d681SAndroid Build Coastguard Worker Requires<[IsLP64]>; 69*9880d681SAndroid Build Coastguard Workerdef ADJCALLSTACKUP64 : I<0, Pseudo, (outs), (ins i32imm:$amt1, i32imm:$amt2), 70*9880d681SAndroid Build Coastguard Worker "#ADJCALLSTACKUP", 71*9880d681SAndroid Build Coastguard Worker [(X86callseq_end timm:$amt1, timm:$amt2)]>, 72*9880d681SAndroid Build Coastguard Worker Requires<[IsLP64]>; 73*9880d681SAndroid Build Coastguard Worker} 74*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86callseq_start timm:$amt1), 75*9880d681SAndroid Build Coastguard Worker (ADJCALLSTACKDOWN64 i32imm:$amt1, 0)>, Requires<[IsLP64]>; 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Worker// x86-64 va_start lowering magic. 79*9880d681SAndroid Build Coastguard Workerlet usesCustomInserter = 1, Defs = [EFLAGS] in { 80*9880d681SAndroid Build Coastguard Workerdef VASTART_SAVE_XMM_REGS : I<0, Pseudo, 81*9880d681SAndroid Build Coastguard Worker (outs), 82*9880d681SAndroid Build Coastguard Worker (ins GR8:$al, 83*9880d681SAndroid Build Coastguard Worker i64imm:$regsavefi, i64imm:$offset, 84*9880d681SAndroid Build Coastguard Worker variable_ops), 85*9880d681SAndroid Build Coastguard Worker "#VASTART_SAVE_XMM_REGS $al, $regsavefi, $offset", 86*9880d681SAndroid Build Coastguard Worker [(X86vastart_save_xmm_regs GR8:$al, 87*9880d681SAndroid Build Coastguard Worker imm:$regsavefi, 88*9880d681SAndroid Build Coastguard Worker imm:$offset), 89*9880d681SAndroid Build Coastguard Worker (implicit EFLAGS)]>; 90*9880d681SAndroid Build Coastguard Worker 91*9880d681SAndroid Build Coastguard Worker// The VAARG_64 pseudo-instruction takes the address of the va_list, 92*9880d681SAndroid Build Coastguard Worker// and places the address of the next argument into a register. 93*9880d681SAndroid Build Coastguard Workerlet Defs = [EFLAGS] in 94*9880d681SAndroid Build Coastguard Workerdef VAARG_64 : I<0, Pseudo, 95*9880d681SAndroid Build Coastguard Worker (outs GR64:$dst), 96*9880d681SAndroid Build Coastguard Worker (ins i8mem:$ap, i32imm:$size, i8imm:$mode, i32imm:$align), 97*9880d681SAndroid Build Coastguard Worker "#VAARG_64 $dst, $ap, $size, $mode, $align", 98*9880d681SAndroid Build Coastguard Worker [(set GR64:$dst, 99*9880d681SAndroid Build Coastguard Worker (X86vaarg64 addr:$ap, imm:$size, imm:$mode, imm:$align)), 100*9880d681SAndroid Build Coastguard Worker (implicit EFLAGS)]>; 101*9880d681SAndroid Build Coastguard Worker 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Worker// When using segmented stacks these are lowered into instructions which first 104*9880d681SAndroid Build Coastguard Worker// check if the current stacklet has enough free memory. If it does, memory is 105*9880d681SAndroid Build Coastguard Worker// allocated by bumping the stack pointer. Otherwise memory is allocated from 106*9880d681SAndroid Build Coastguard Worker// the heap. 107*9880d681SAndroid Build Coastguard Worker 108*9880d681SAndroid Build Coastguard Workerlet Defs = [EAX, ESP, EFLAGS], Uses = [ESP] in 109*9880d681SAndroid Build Coastguard Workerdef SEG_ALLOCA_32 : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$size), 110*9880d681SAndroid Build Coastguard Worker "# variable sized alloca for segmented stacks", 111*9880d681SAndroid Build Coastguard Worker [(set GR32:$dst, 112*9880d681SAndroid Build Coastguard Worker (X86SegAlloca GR32:$size))]>, 113*9880d681SAndroid Build Coastguard Worker Requires<[NotLP64]>; 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Workerlet Defs = [RAX, RSP, EFLAGS], Uses = [RSP] in 116*9880d681SAndroid Build Coastguard Workerdef SEG_ALLOCA_64 : I<0, Pseudo, (outs GR64:$dst), (ins GR64:$size), 117*9880d681SAndroid Build Coastguard Worker "# variable sized alloca for segmented stacks", 118*9880d681SAndroid Build Coastguard Worker [(set GR64:$dst, 119*9880d681SAndroid Build Coastguard Worker (X86SegAlloca GR64:$size))]>, 120*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 121*9880d681SAndroid Build Coastguard Worker} 122*9880d681SAndroid Build Coastguard Worker 123*9880d681SAndroid Build Coastguard Worker// Dynamic stack allocation yields a _chkstk or _alloca call for all Windows 124*9880d681SAndroid Build Coastguard Worker// targets. These calls are needed to probe the stack when allocating more than 125*9880d681SAndroid Build Coastguard Worker// 4k bytes in one go. Touching the stack at 4K increments is necessary to 126*9880d681SAndroid Build Coastguard Worker// ensure that the guard pages used by the OS virtual memory manager are 127*9880d681SAndroid Build Coastguard Worker// allocated in correct sequence. 128*9880d681SAndroid Build Coastguard Worker// The main point of having separate instruction are extra unmodelled effects 129*9880d681SAndroid Build Coastguard Worker// (compared to ordinary calls) like stack pointer change. 130*9880d681SAndroid Build Coastguard Worker 131*9880d681SAndroid Build Coastguard Workerlet Defs = [EAX, ESP, EFLAGS], Uses = [ESP] in 132*9880d681SAndroid Build Coastguard Workerdef WIN_ALLOCA_32 : I<0, Pseudo, (outs), (ins GR32:$size), 133*9880d681SAndroid Build Coastguard Worker "# dynamic stack allocation", 134*9880d681SAndroid Build Coastguard Worker [(X86WinAlloca GR32:$size)]>, 135*9880d681SAndroid Build Coastguard Worker Requires<[NotLP64]>; 136*9880d681SAndroid Build Coastguard Worker 137*9880d681SAndroid Build Coastguard Workerlet Defs = [RAX, RSP, EFLAGS], Uses = [RSP] in 138*9880d681SAndroid Build Coastguard Workerdef WIN_ALLOCA_64 : I<0, Pseudo, (outs), (ins GR64:$size), 139*9880d681SAndroid Build Coastguard Worker "# dynamic stack allocation", 140*9880d681SAndroid Build Coastguard Worker [(X86WinAlloca GR64:$size)]>, 141*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 142*9880d681SAndroid Build Coastguard Worker 143*9880d681SAndroid Build Coastguard Worker 144*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 145*9880d681SAndroid Build Coastguard Worker// EH Pseudo Instructions 146*9880d681SAndroid Build Coastguard Worker// 147*9880d681SAndroid Build Coastguard Workerlet SchedRW = [WriteSystem] in { 148*9880d681SAndroid Build Coastguard Workerlet isTerminator = 1, isReturn = 1, isBarrier = 1, 149*9880d681SAndroid Build Coastguard Worker hasCtrlDep = 1, isCodeGenOnly = 1 in { 150*9880d681SAndroid Build Coastguard Workerdef EH_RETURN : I<0xC3, RawFrm, (outs), (ins GR32:$addr), 151*9880d681SAndroid Build Coastguard Worker "ret\t#eh_return, addr: $addr", 152*9880d681SAndroid Build Coastguard Worker [(X86ehret GR32:$addr)], IIC_RET>, Sched<[WriteJumpLd]>; 153*9880d681SAndroid Build Coastguard Worker 154*9880d681SAndroid Build Coastguard Worker} 155*9880d681SAndroid Build Coastguard Worker 156*9880d681SAndroid Build Coastguard Workerlet isTerminator = 1, isReturn = 1, isBarrier = 1, 157*9880d681SAndroid Build Coastguard Worker hasCtrlDep = 1, isCodeGenOnly = 1 in { 158*9880d681SAndroid Build Coastguard Workerdef EH_RETURN64 : I<0xC3, RawFrm, (outs), (ins GR64:$addr), 159*9880d681SAndroid Build Coastguard Worker "ret\t#eh_return, addr: $addr", 160*9880d681SAndroid Build Coastguard Worker [(X86ehret GR64:$addr)], IIC_RET>, Sched<[WriteJumpLd]>; 161*9880d681SAndroid Build Coastguard Worker 162*9880d681SAndroid Build Coastguard Worker} 163*9880d681SAndroid Build Coastguard Worker 164*9880d681SAndroid Build Coastguard Workerlet isTerminator = 1, hasSideEffects = 1, isBarrier = 1, hasCtrlDep = 1, 165*9880d681SAndroid Build Coastguard Worker isCodeGenOnly = 1, isReturn = 1 in { 166*9880d681SAndroid Build Coastguard Worker def CLEANUPRET : I<0, Pseudo, (outs), (ins), "# CLEANUPRET", [(cleanupret)]>; 167*9880d681SAndroid Build Coastguard Worker 168*9880d681SAndroid Build Coastguard Worker // CATCHRET needs a custom inserter for SEH. 169*9880d681SAndroid Build Coastguard Worker let usesCustomInserter = 1 in 170*9880d681SAndroid Build Coastguard Worker def CATCHRET : I<0, Pseudo, (outs), (ins brtarget32:$dst, brtarget32:$from), 171*9880d681SAndroid Build Coastguard Worker "# CATCHRET", 172*9880d681SAndroid Build Coastguard Worker [(catchret bb:$dst, bb:$from)]>; 173*9880d681SAndroid Build Coastguard Worker} 174*9880d681SAndroid Build Coastguard Worker 175*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 1, hasCtrlDep = 1, isCodeGenOnly = 1, 176*9880d681SAndroid Build Coastguard Worker usesCustomInserter = 1 in 177*9880d681SAndroid Build Coastguard Workerdef CATCHPAD : I<0, Pseudo, (outs), (ins), "# CATCHPAD", [(catchpad)]>; 178*9880d681SAndroid Build Coastguard Worker 179*9880d681SAndroid Build Coastguard Worker// This instruction is responsible for re-establishing stack pointers after an 180*9880d681SAndroid Build Coastguard Worker// exception has been caught and we are rejoining normal control flow in the 181*9880d681SAndroid Build Coastguard Worker// parent function or funclet. It generally sets ESP and EBP, and optionally 182*9880d681SAndroid Build Coastguard Worker// ESI. It is only needed for 32-bit WinEH, as the runtime restores CSRs for us 183*9880d681SAndroid Build Coastguard Worker// elsewhere. 184*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 1, hasCtrlDep = 1, isCodeGenOnly = 1 in 185*9880d681SAndroid Build Coastguard Workerdef EH_RESTORE : I<0, Pseudo, (outs), (ins), "# EH_RESTORE", []>; 186*9880d681SAndroid Build Coastguard Worker 187*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1, 188*9880d681SAndroid Build Coastguard Worker usesCustomInserter = 1 in { 189*9880d681SAndroid Build Coastguard Worker def EH_SjLj_SetJmp32 : I<0, Pseudo, (outs GR32:$dst), (ins i32mem:$buf), 190*9880d681SAndroid Build Coastguard Worker "#EH_SJLJ_SETJMP32", 191*9880d681SAndroid Build Coastguard Worker [(set GR32:$dst, (X86eh_sjlj_setjmp addr:$buf))]>, 192*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 193*9880d681SAndroid Build Coastguard Worker def EH_SjLj_SetJmp64 : I<0, Pseudo, (outs GR32:$dst), (ins i64mem:$buf), 194*9880d681SAndroid Build Coastguard Worker "#EH_SJLJ_SETJMP64", 195*9880d681SAndroid Build Coastguard Worker [(set GR32:$dst, (X86eh_sjlj_setjmp addr:$buf))]>, 196*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 197*9880d681SAndroid Build Coastguard Worker let isTerminator = 1 in { 198*9880d681SAndroid Build Coastguard Worker def EH_SjLj_LongJmp32 : I<0, Pseudo, (outs), (ins i32mem:$buf), 199*9880d681SAndroid Build Coastguard Worker "#EH_SJLJ_LONGJMP32", 200*9880d681SAndroid Build Coastguard Worker [(X86eh_sjlj_longjmp addr:$buf)]>, 201*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 202*9880d681SAndroid Build Coastguard Worker def EH_SjLj_LongJmp64 : I<0, Pseudo, (outs), (ins i64mem:$buf), 203*9880d681SAndroid Build Coastguard Worker "#EH_SJLJ_LONGJMP64", 204*9880d681SAndroid Build Coastguard Worker [(X86eh_sjlj_longjmp addr:$buf)]>, 205*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 206*9880d681SAndroid Build Coastguard Worker } 207*9880d681SAndroid Build Coastguard Worker} 208*9880d681SAndroid Build Coastguard Worker} // SchedRW 209*9880d681SAndroid Build Coastguard Worker 210*9880d681SAndroid Build Coastguard Workerlet isBranch = 1, isTerminator = 1, isCodeGenOnly = 1 in { 211*9880d681SAndroid Build Coastguard Worker def EH_SjLj_Setup : I<0, Pseudo, (outs), (ins brtarget:$dst), 212*9880d681SAndroid Build Coastguard Worker "#EH_SjLj_Setup\t$dst", []>; 213*9880d681SAndroid Build Coastguard Worker} 214*9880d681SAndroid Build Coastguard Worker 215*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 216*9880d681SAndroid Build Coastguard Worker// Pseudo instructions used by unwind info. 217*9880d681SAndroid Build Coastguard Worker// 218*9880d681SAndroid Build Coastguard Workerlet isPseudo = 1 in { 219*9880d681SAndroid Build Coastguard Worker def SEH_PushReg : I<0, Pseudo, (outs), (ins i32imm:$reg), 220*9880d681SAndroid Build Coastguard Worker "#SEH_PushReg $reg", []>; 221*9880d681SAndroid Build Coastguard Worker def SEH_SaveReg : I<0, Pseudo, (outs), (ins i32imm:$reg, i32imm:$dst), 222*9880d681SAndroid Build Coastguard Worker "#SEH_SaveReg $reg, $dst", []>; 223*9880d681SAndroid Build Coastguard Worker def SEH_SaveXMM : I<0, Pseudo, (outs), (ins i32imm:$reg, i32imm:$dst), 224*9880d681SAndroid Build Coastguard Worker "#SEH_SaveXMM $reg, $dst", []>; 225*9880d681SAndroid Build Coastguard Worker def SEH_StackAlloc : I<0, Pseudo, (outs), (ins i32imm:$size), 226*9880d681SAndroid Build Coastguard Worker "#SEH_StackAlloc $size", []>; 227*9880d681SAndroid Build Coastguard Worker def SEH_SetFrame : I<0, Pseudo, (outs), (ins i32imm:$reg, i32imm:$offset), 228*9880d681SAndroid Build Coastguard Worker "#SEH_SetFrame $reg, $offset", []>; 229*9880d681SAndroid Build Coastguard Worker def SEH_PushFrame : I<0, Pseudo, (outs), (ins i1imm:$mode), 230*9880d681SAndroid Build Coastguard Worker "#SEH_PushFrame $mode", []>; 231*9880d681SAndroid Build Coastguard Worker def SEH_EndPrologue : I<0, Pseudo, (outs), (ins), 232*9880d681SAndroid Build Coastguard Worker "#SEH_EndPrologue", []>; 233*9880d681SAndroid Build Coastguard Worker def SEH_Epilogue : I<0, Pseudo, (outs), (ins), 234*9880d681SAndroid Build Coastguard Worker "#SEH_Epilogue", []>; 235*9880d681SAndroid Build Coastguard Worker} 236*9880d681SAndroid Build Coastguard Worker 237*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 238*9880d681SAndroid Build Coastguard Worker// Pseudo instructions used by segmented stacks. 239*9880d681SAndroid Build Coastguard Worker// 240*9880d681SAndroid Build Coastguard Worker 241*9880d681SAndroid Build Coastguard Worker// This is lowered into a RET instruction by MCInstLower. We need 242*9880d681SAndroid Build Coastguard Worker// this so that we don't have to have a MachineBasicBlock which ends 243*9880d681SAndroid Build Coastguard Worker// with a RET and also has successors. 244*9880d681SAndroid Build Coastguard Workerlet isPseudo = 1 in { 245*9880d681SAndroid Build Coastguard Workerdef MORESTACK_RET: I<0, Pseudo, (outs), (ins), 246*9880d681SAndroid Build Coastguard Worker "", []>; 247*9880d681SAndroid Build Coastguard Worker 248*9880d681SAndroid Build Coastguard Worker// This instruction is lowered to a RET followed by a MOV. The two 249*9880d681SAndroid Build Coastguard Worker// instructions are not generated on a higher level since then the 250*9880d681SAndroid Build Coastguard Worker// verifier sees a MachineBasicBlock ending with a non-terminator. 251*9880d681SAndroid Build Coastguard Workerdef MORESTACK_RET_RESTORE_R10 : I<0, Pseudo, (outs), (ins), 252*9880d681SAndroid Build Coastguard Worker "", []>; 253*9880d681SAndroid Build Coastguard Worker} 254*9880d681SAndroid Build Coastguard Worker 255*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 256*9880d681SAndroid Build Coastguard Worker// Alias Instructions 257*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 258*9880d681SAndroid Build Coastguard Worker 259*9880d681SAndroid Build Coastguard Worker// Alias instruction mapping movr0 to xor. 260*9880d681SAndroid Build Coastguard Worker// FIXME: remove when we can teach regalloc that xor reg, reg is ok. 261*9880d681SAndroid Build Coastguard Workerlet Defs = [EFLAGS], isReMaterializable = 1, isAsCheapAsAMove = 1, 262*9880d681SAndroid Build Coastguard Worker isPseudo = 1, AddedComplexity = 20 in 263*9880d681SAndroid Build Coastguard Workerdef MOV32r0 : I<0, Pseudo, (outs GR32:$dst), (ins), "", 264*9880d681SAndroid Build Coastguard Worker [(set GR32:$dst, 0)], IIC_ALU_NONMEM>, Sched<[WriteZero]>; 265*9880d681SAndroid Build Coastguard Worker 266*9880d681SAndroid Build Coastguard Worker// Other widths can also make use of the 32-bit xor, which may have a smaller 267*9880d681SAndroid Build Coastguard Worker// encoding and avoid partial register updates. 268*9880d681SAndroid Build Coastguard Workerdef : Pat<(i8 0), (EXTRACT_SUBREG (MOV32r0), sub_8bit)>; 269*9880d681SAndroid Build Coastguard Workerdef : Pat<(i16 0), (EXTRACT_SUBREG (MOV32r0), sub_16bit)>; 270*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 0), (SUBREG_TO_REG (i64 0), (MOV32r0), sub_32bit)> { 271*9880d681SAndroid Build Coastguard Worker let AddedComplexity = 20; 272*9880d681SAndroid Build Coastguard Worker} 273*9880d681SAndroid Build Coastguard Worker 274*9880d681SAndroid Build Coastguard Workerlet Predicates = [OptForSize, NotSlowIncDec, Not64BitMode], 275*9880d681SAndroid Build Coastguard Worker AddedComplexity = 15 in { 276*9880d681SAndroid Build Coastguard Worker // Pseudo instructions for materializing 1 and -1 using XOR+INC/DEC, 277*9880d681SAndroid Build Coastguard Worker // which only require 3 bytes compared to MOV32ri which requires 5. 278*9880d681SAndroid Build Coastguard Worker let Defs = [EFLAGS], isReMaterializable = 1, isPseudo = 1 in { 279*9880d681SAndroid Build Coastguard Worker def MOV32r1 : I<0, Pseudo, (outs GR32:$dst), (ins), "", 280*9880d681SAndroid Build Coastguard Worker [(set GR32:$dst, 1)]>; 281*9880d681SAndroid Build Coastguard Worker def MOV32r_1 : I<0, Pseudo, (outs GR32:$dst), (ins), "", 282*9880d681SAndroid Build Coastguard Worker [(set GR32:$dst, -1)]>; 283*9880d681SAndroid Build Coastguard Worker } 284*9880d681SAndroid Build Coastguard Worker 285*9880d681SAndroid Build Coastguard Worker // MOV16ri is 4 bytes, so the instructions above are smaller. 286*9880d681SAndroid Build Coastguard Worker def : Pat<(i16 1), (EXTRACT_SUBREG (MOV32r1), sub_16bit)>; 287*9880d681SAndroid Build Coastguard Worker def : Pat<(i16 -1), (EXTRACT_SUBREG (MOV32r_1), sub_16bit)>; 288*9880d681SAndroid Build Coastguard Worker} 289*9880d681SAndroid Build Coastguard Worker 290*9880d681SAndroid Build Coastguard Workerlet isReMaterializable = 1, isPseudo = 1, AddedComplexity = 10 in { 291*9880d681SAndroid Build Coastguard Worker// AddedComplexity higher than MOV64ri but lower than MOV32r0 and MOV32r1. 292*9880d681SAndroid Build Coastguard Worker// FIXME: Add itinerary class and Schedule. 293*9880d681SAndroid Build Coastguard Workerdef MOV32ImmSExti8 : I<0, Pseudo, (outs GR32:$dst), (ins i32i8imm:$src), "", 294*9880d681SAndroid Build Coastguard Worker [(set GR32:$dst, i32immSExt8:$src)]>, 295*9880d681SAndroid Build Coastguard Worker Requires<[OptForMinSize, NotWin64WithoutFP]>; 296*9880d681SAndroid Build Coastguard Workerdef MOV64ImmSExti8 : I<0, Pseudo, (outs GR64:$dst), (ins i64i8imm:$src), "", 297*9880d681SAndroid Build Coastguard Worker [(set GR64:$dst, i64immSExt8:$src)]>, 298*9880d681SAndroid Build Coastguard Worker Requires<[OptForMinSize, NotWin64WithoutFP]>; 299*9880d681SAndroid Build Coastguard Worker} 300*9880d681SAndroid Build Coastguard Worker 301*9880d681SAndroid Build Coastguard Worker// Materialize i64 constant where top 32-bits are zero. This could theoretically 302*9880d681SAndroid Build Coastguard Worker// use MOV32ri with a SUBREG_TO_REG to represent the zero-extension, however 303*9880d681SAndroid Build Coastguard Worker// that would make it more difficult to rematerialize. 304*9880d681SAndroid Build Coastguard Workerlet isReMaterializable = 1, isAsCheapAsAMove = 1, 305*9880d681SAndroid Build Coastguard Worker isPseudo = 1, hasSideEffects = 0 in 306*9880d681SAndroid Build Coastguard Workerdef MOV32ri64 : I<0, Pseudo, (outs GR32:$dst), (ins i64i32imm:$src), "", []>; 307*9880d681SAndroid Build Coastguard Worker 308*9880d681SAndroid Build Coastguard Worker// This 64-bit pseudo-move can be used for both a 64-bit constant that is 309*9880d681SAndroid Build Coastguard Worker// actually the zero-extension of a 32-bit constant and for labels in the 310*9880d681SAndroid Build Coastguard Worker// x86-64 small code model. 311*9880d681SAndroid Build Coastguard Workerdef mov64imm32 : ComplexPattern<i64, 1, "selectMOV64Imm32", [imm, X86Wrapper]>; 312*9880d681SAndroid Build Coastguard Worker 313*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 1 in 314*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 mov64imm32:$src), 315*9880d681SAndroid Build Coastguard Worker (SUBREG_TO_REG (i64 0), (MOV32ri64 mov64imm32:$src), sub_32bit)>; 316*9880d681SAndroid Build Coastguard Worker 317*9880d681SAndroid Build Coastguard Worker// Use sbb to materialize carry bit. 318*9880d681SAndroid Build Coastguard Workerlet Uses = [EFLAGS], Defs = [EFLAGS], isPseudo = 1, SchedRW = [WriteALU] in { 319*9880d681SAndroid Build Coastguard Worker// FIXME: These are pseudo ops that should be replaced with Pat<> patterns. 320*9880d681SAndroid Build Coastguard Worker// However, Pat<> can't replicate the destination reg into the inputs of the 321*9880d681SAndroid Build Coastguard Worker// result. 322*9880d681SAndroid Build Coastguard Workerdef SETB_C8r : I<0, Pseudo, (outs GR8:$dst), (ins), "", 323*9880d681SAndroid Build Coastguard Worker [(set GR8:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>; 324*9880d681SAndroid Build Coastguard Workerdef SETB_C16r : I<0, Pseudo, (outs GR16:$dst), (ins), "", 325*9880d681SAndroid Build Coastguard Worker [(set GR16:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>; 326*9880d681SAndroid Build Coastguard Workerdef SETB_C32r : I<0, Pseudo, (outs GR32:$dst), (ins), "", 327*9880d681SAndroid Build Coastguard Worker [(set GR32:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>; 328*9880d681SAndroid Build Coastguard Workerdef SETB_C64r : I<0, Pseudo, (outs GR64:$dst), (ins), "", 329*9880d681SAndroid Build Coastguard Worker [(set GR64:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>; 330*9880d681SAndroid Build Coastguard Worker} // isCodeGenOnly 331*9880d681SAndroid Build Coastguard Worker 332*9880d681SAndroid Build Coastguard Worker 333*9880d681SAndroid Build Coastguard Workerdef : Pat<(i16 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), 334*9880d681SAndroid Build Coastguard Worker (SETB_C16r)>; 335*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), 336*9880d681SAndroid Build Coastguard Worker (SETB_C32r)>; 337*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), 338*9880d681SAndroid Build Coastguard Worker (SETB_C64r)>; 339*9880d681SAndroid Build Coastguard Worker 340*9880d681SAndroid Build Coastguard Workerdef : Pat<(i16 (sext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), 341*9880d681SAndroid Build Coastguard Worker (SETB_C16r)>; 342*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 (sext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), 343*9880d681SAndroid Build Coastguard Worker (SETB_C32r)>; 344*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (sext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), 345*9880d681SAndroid Build Coastguard Worker (SETB_C64r)>; 346*9880d681SAndroid Build Coastguard Worker 347*9880d681SAndroid Build Coastguard Worker// We canonicalize 'setb' to "(and (sbb reg,reg), 1)" on the hope that the and 348*9880d681SAndroid Build Coastguard Worker// will be eliminated and that the sbb can be extended up to a wider type. When 349*9880d681SAndroid Build Coastguard Worker// this happens, it is great. However, if we are left with an 8-bit sbb and an 350*9880d681SAndroid Build Coastguard Worker// and, we might as well just match it as a setb. 351*9880d681SAndroid Build Coastguard Workerdef : Pat<(and (i8 (X86setcc_c X86_COND_B, EFLAGS)), 1), 352*9880d681SAndroid Build Coastguard Worker (SETBr)>; 353*9880d681SAndroid Build Coastguard Worker 354*9880d681SAndroid Build Coastguard Worker// (add OP, SETB) -> (adc OP, 0) 355*9880d681SAndroid Build Coastguard Workerdef : Pat<(add (and (i8 (X86setcc_c X86_COND_B, EFLAGS)), 1), GR8:$op), 356*9880d681SAndroid Build Coastguard Worker (ADC8ri GR8:$op, 0)>; 357*9880d681SAndroid Build Coastguard Workerdef : Pat<(add (and (i32 (X86setcc_c X86_COND_B, EFLAGS)), 1), GR32:$op), 358*9880d681SAndroid Build Coastguard Worker (ADC32ri8 GR32:$op, 0)>; 359*9880d681SAndroid Build Coastguard Workerdef : Pat<(add (and (i64 (X86setcc_c X86_COND_B, EFLAGS)), 1), GR64:$op), 360*9880d681SAndroid Build Coastguard Worker (ADC64ri8 GR64:$op, 0)>; 361*9880d681SAndroid Build Coastguard Worker 362*9880d681SAndroid Build Coastguard Worker// (sub OP, SETB) -> (sbb OP, 0) 363*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR8:$op, (and (i8 (X86setcc_c X86_COND_B, EFLAGS)), 1)), 364*9880d681SAndroid Build Coastguard Worker (SBB8ri GR8:$op, 0)>; 365*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR32:$op, (and (i32 (X86setcc_c X86_COND_B, EFLAGS)), 1)), 366*9880d681SAndroid Build Coastguard Worker (SBB32ri8 GR32:$op, 0)>; 367*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR64:$op, (and (i64 (X86setcc_c X86_COND_B, EFLAGS)), 1)), 368*9880d681SAndroid Build Coastguard Worker (SBB64ri8 GR64:$op, 0)>; 369*9880d681SAndroid Build Coastguard Worker 370*9880d681SAndroid Build Coastguard Worker// (sub OP, SETCC_CARRY) -> (adc OP, 0) 371*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR8:$op, (i8 (X86setcc_c X86_COND_B, EFLAGS))), 372*9880d681SAndroid Build Coastguard Worker (ADC8ri GR8:$op, 0)>; 373*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR32:$op, (i32 (X86setcc_c X86_COND_B, EFLAGS))), 374*9880d681SAndroid Build Coastguard Worker (ADC32ri8 GR32:$op, 0)>; 375*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR64:$op, (i64 (X86setcc_c X86_COND_B, EFLAGS))), 376*9880d681SAndroid Build Coastguard Worker (ADC64ri8 GR64:$op, 0)>; 377*9880d681SAndroid Build Coastguard Worker 378*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 379*9880d681SAndroid Build Coastguard Worker// String Pseudo Instructions 380*9880d681SAndroid Build Coastguard Worker// 381*9880d681SAndroid Build Coastguard Workerlet SchedRW = [WriteMicrocoded] in { 382*9880d681SAndroid Build Coastguard Workerlet Defs = [ECX,EDI,ESI], Uses = [ECX,EDI,ESI], isCodeGenOnly = 1 in { 383*9880d681SAndroid Build Coastguard Workerdef REP_MOVSB_32 : I<0xA4, RawFrm, (outs), (ins), "{rep;movsb|rep movsb}", 384*9880d681SAndroid Build Coastguard Worker [(X86rep_movs i8)], IIC_REP_MOVS>, REP, 385*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 386*9880d681SAndroid Build Coastguard Workerdef REP_MOVSW_32 : I<0xA5, RawFrm, (outs), (ins), "{rep;movsw|rep movsw}", 387*9880d681SAndroid Build Coastguard Worker [(X86rep_movs i16)], IIC_REP_MOVS>, REP, OpSize16, 388*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 389*9880d681SAndroid Build Coastguard Workerdef REP_MOVSD_32 : I<0xA5, RawFrm, (outs), (ins), "{rep;movsl|rep movsd}", 390*9880d681SAndroid Build Coastguard Worker [(X86rep_movs i32)], IIC_REP_MOVS>, REP, OpSize32, 391*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 392*9880d681SAndroid Build Coastguard Worker} 393*9880d681SAndroid Build Coastguard Worker 394*9880d681SAndroid Build Coastguard Workerlet Defs = [RCX,RDI,RSI], Uses = [RCX,RDI,RSI], isCodeGenOnly = 1 in { 395*9880d681SAndroid Build Coastguard Workerdef REP_MOVSB_64 : I<0xA4, RawFrm, (outs), (ins), "{rep;movsb|rep movsb}", 396*9880d681SAndroid Build Coastguard Worker [(X86rep_movs i8)], IIC_REP_MOVS>, REP, 397*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 398*9880d681SAndroid Build Coastguard Workerdef REP_MOVSW_64 : I<0xA5, RawFrm, (outs), (ins), "{rep;movsw|rep movsw}", 399*9880d681SAndroid Build Coastguard Worker [(X86rep_movs i16)], IIC_REP_MOVS>, REP, OpSize16, 400*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 401*9880d681SAndroid Build Coastguard Workerdef REP_MOVSD_64 : I<0xA5, RawFrm, (outs), (ins), "{rep;movsl|rep movsd}", 402*9880d681SAndroid Build Coastguard Worker [(X86rep_movs i32)], IIC_REP_MOVS>, REP, OpSize32, 403*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 404*9880d681SAndroid Build Coastguard Workerdef REP_MOVSQ_64 : RI<0xA5, RawFrm, (outs), (ins), "{rep;movsq|rep movsq}", 405*9880d681SAndroid Build Coastguard Worker [(X86rep_movs i64)], IIC_REP_MOVS>, REP, 406*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 407*9880d681SAndroid Build Coastguard Worker} 408*9880d681SAndroid Build Coastguard Worker 409*9880d681SAndroid Build Coastguard Worker// FIXME: Should use "(X86rep_stos AL)" as the pattern. 410*9880d681SAndroid Build Coastguard Workerlet Defs = [ECX,EDI], isCodeGenOnly = 1 in { 411*9880d681SAndroid Build Coastguard Worker let Uses = [AL,ECX,EDI] in 412*9880d681SAndroid Build Coastguard Worker def REP_STOSB_32 : I<0xAA, RawFrm, (outs), (ins), "{rep;stosb|rep stosb}", 413*9880d681SAndroid Build Coastguard Worker [(X86rep_stos i8)], IIC_REP_STOS>, REP, 414*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 415*9880d681SAndroid Build Coastguard Worker let Uses = [AX,ECX,EDI] in 416*9880d681SAndroid Build Coastguard Worker def REP_STOSW_32 : I<0xAB, RawFrm, (outs), (ins), "{rep;stosw|rep stosw}", 417*9880d681SAndroid Build Coastguard Worker [(X86rep_stos i16)], IIC_REP_STOS>, REP, OpSize16, 418*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 419*9880d681SAndroid Build Coastguard Worker let Uses = [EAX,ECX,EDI] in 420*9880d681SAndroid Build Coastguard Worker def REP_STOSD_32 : I<0xAB, RawFrm, (outs), (ins), "{rep;stosl|rep stosd}", 421*9880d681SAndroid Build Coastguard Worker [(X86rep_stos i32)], IIC_REP_STOS>, REP, OpSize32, 422*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 423*9880d681SAndroid Build Coastguard Worker} 424*9880d681SAndroid Build Coastguard Worker 425*9880d681SAndroid Build Coastguard Workerlet Defs = [RCX,RDI], isCodeGenOnly = 1 in { 426*9880d681SAndroid Build Coastguard Worker let Uses = [AL,RCX,RDI] in 427*9880d681SAndroid Build Coastguard Worker def REP_STOSB_64 : I<0xAA, RawFrm, (outs), (ins), "{rep;stosb|rep stosb}", 428*9880d681SAndroid Build Coastguard Worker [(X86rep_stos i8)], IIC_REP_STOS>, REP, 429*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 430*9880d681SAndroid Build Coastguard Worker let Uses = [AX,RCX,RDI] in 431*9880d681SAndroid Build Coastguard Worker def REP_STOSW_64 : I<0xAB, RawFrm, (outs), (ins), "{rep;stosw|rep stosw}", 432*9880d681SAndroid Build Coastguard Worker [(X86rep_stos i16)], IIC_REP_STOS>, REP, OpSize16, 433*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 434*9880d681SAndroid Build Coastguard Worker let Uses = [RAX,RCX,RDI] in 435*9880d681SAndroid Build Coastguard Worker def REP_STOSD_64 : I<0xAB, RawFrm, (outs), (ins), "{rep;stosl|rep stosd}", 436*9880d681SAndroid Build Coastguard Worker [(X86rep_stos i32)], IIC_REP_STOS>, REP, OpSize32, 437*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 438*9880d681SAndroid Build Coastguard Worker 439*9880d681SAndroid Build Coastguard Worker let Uses = [RAX,RCX,RDI] in 440*9880d681SAndroid Build Coastguard Worker def REP_STOSQ_64 : RI<0xAB, RawFrm, (outs), (ins), "{rep;stosq|rep stosq}", 441*9880d681SAndroid Build Coastguard Worker [(X86rep_stos i64)], IIC_REP_STOS>, REP, 442*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 443*9880d681SAndroid Build Coastguard Worker} 444*9880d681SAndroid Build Coastguard Worker} // SchedRW 445*9880d681SAndroid Build Coastguard Worker 446*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 447*9880d681SAndroid Build Coastguard Worker// Thread Local Storage Instructions 448*9880d681SAndroid Build Coastguard Worker// 449*9880d681SAndroid Build Coastguard Worker 450*9880d681SAndroid Build Coastguard Worker// ELF TLS Support 451*9880d681SAndroid Build Coastguard Worker// All calls clobber the non-callee saved registers. ESP is marked as 452*9880d681SAndroid Build Coastguard Worker// a use to prevent stack-pointer assignments that appear immediately 453*9880d681SAndroid Build Coastguard Worker// before calls from potentially appearing dead. 454*9880d681SAndroid Build Coastguard Workerlet Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, FP7, 455*9880d681SAndroid Build Coastguard Worker ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7, 456*9880d681SAndroid Build Coastguard Worker MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7, 457*9880d681SAndroid Build Coastguard Worker XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, 458*9880d681SAndroid Build Coastguard Worker XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS], 459*9880d681SAndroid Build Coastguard Worker usesCustomInserter = 1, Uses = [ESP] in { 460*9880d681SAndroid Build Coastguard Workerdef TLS_addr32 : I<0, Pseudo, (outs), (ins i32mem:$sym), 461*9880d681SAndroid Build Coastguard Worker "# TLS_addr32", 462*9880d681SAndroid Build Coastguard Worker [(X86tlsaddr tls32addr:$sym)]>, 463*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 464*9880d681SAndroid Build Coastguard Workerdef TLS_base_addr32 : I<0, Pseudo, (outs), (ins i32mem:$sym), 465*9880d681SAndroid Build Coastguard Worker "# TLS_base_addr32", 466*9880d681SAndroid Build Coastguard Worker [(X86tlsbaseaddr tls32baseaddr:$sym)]>, 467*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 468*9880d681SAndroid Build Coastguard Worker} 469*9880d681SAndroid Build Coastguard Worker 470*9880d681SAndroid Build Coastguard Worker// All calls clobber the non-callee saved registers. RSP is marked as 471*9880d681SAndroid Build Coastguard Worker// a use to prevent stack-pointer assignments that appear immediately 472*9880d681SAndroid Build Coastguard Worker// before calls from potentially appearing dead. 473*9880d681SAndroid Build Coastguard Workerlet Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11, 474*9880d681SAndroid Build Coastguard Worker FP0, FP1, FP2, FP3, FP4, FP5, FP6, FP7, 475*9880d681SAndroid Build Coastguard Worker ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7, 476*9880d681SAndroid Build Coastguard Worker MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7, 477*9880d681SAndroid Build Coastguard Worker XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, 478*9880d681SAndroid Build Coastguard Worker XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS], 479*9880d681SAndroid Build Coastguard Worker usesCustomInserter = 1, Uses = [RSP] in { 480*9880d681SAndroid Build Coastguard Workerdef TLS_addr64 : I<0, Pseudo, (outs), (ins i64mem:$sym), 481*9880d681SAndroid Build Coastguard Worker "# TLS_addr64", 482*9880d681SAndroid Build Coastguard Worker [(X86tlsaddr tls64addr:$sym)]>, 483*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 484*9880d681SAndroid Build Coastguard Workerdef TLS_base_addr64 : I<0, Pseudo, (outs), (ins i64mem:$sym), 485*9880d681SAndroid Build Coastguard Worker "# TLS_base_addr64", 486*9880d681SAndroid Build Coastguard Worker [(X86tlsbaseaddr tls64baseaddr:$sym)]>, 487*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 488*9880d681SAndroid Build Coastguard Worker} 489*9880d681SAndroid Build Coastguard Worker 490*9880d681SAndroid Build Coastguard Worker// Darwin TLS Support 491*9880d681SAndroid Build Coastguard Worker// For i386, the address of the thunk is passed on the stack, on return the 492*9880d681SAndroid Build Coastguard Worker// address of the variable is in %eax. %ecx is trashed during the function 493*9880d681SAndroid Build Coastguard Worker// call. All other registers are preserved. 494*9880d681SAndroid Build Coastguard Workerlet Defs = [EAX, ECX, EFLAGS], 495*9880d681SAndroid Build Coastguard Worker Uses = [ESP], 496*9880d681SAndroid Build Coastguard Worker usesCustomInserter = 1 in 497*9880d681SAndroid Build Coastguard Workerdef TLSCall_32 : I<0, Pseudo, (outs), (ins i32mem:$sym), 498*9880d681SAndroid Build Coastguard Worker "# TLSCall_32", 499*9880d681SAndroid Build Coastguard Worker [(X86TLSCall addr:$sym)]>, 500*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 501*9880d681SAndroid Build Coastguard Worker 502*9880d681SAndroid Build Coastguard Worker// For x86_64, the address of the thunk is passed in %rdi, but the 503*9880d681SAndroid Build Coastguard Worker// pseudo directly use the symbol, so do not add an implicit use of 504*9880d681SAndroid Build Coastguard Worker// %rdi. The lowering will do the right thing with RDI. 505*9880d681SAndroid Build Coastguard Worker// On return the address of the variable is in %rax. All other 506*9880d681SAndroid Build Coastguard Worker// registers are preserved. 507*9880d681SAndroid Build Coastguard Workerlet Defs = [RAX, EFLAGS], 508*9880d681SAndroid Build Coastguard Worker Uses = [RSP], 509*9880d681SAndroid Build Coastguard Worker usesCustomInserter = 1 in 510*9880d681SAndroid Build Coastguard Workerdef TLSCall_64 : I<0, Pseudo, (outs), (ins i64mem:$sym), 511*9880d681SAndroid Build Coastguard Worker "# TLSCall_64", 512*9880d681SAndroid Build Coastguard Worker [(X86TLSCall addr:$sym)]>, 513*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 514*9880d681SAndroid Build Coastguard Worker 515*9880d681SAndroid Build Coastguard Worker 516*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 517*9880d681SAndroid Build Coastguard Worker// Conditional Move Pseudo Instructions 518*9880d681SAndroid Build Coastguard Worker 519*9880d681SAndroid Build Coastguard Worker// CMOV* - Used to implement the SELECT DAG operation. Expanded after 520*9880d681SAndroid Build Coastguard Worker// instruction selection into a branch sequence. 521*9880d681SAndroid Build Coastguard Workermulticlass CMOVrr_PSEUDO<RegisterClass RC, ValueType VT> { 522*9880d681SAndroid Build Coastguard Worker def CMOV#NAME : I<0, Pseudo, 523*9880d681SAndroid Build Coastguard Worker (outs RC:$dst), (ins RC:$t, RC:$f, i8imm:$cond), 524*9880d681SAndroid Build Coastguard Worker "#CMOV_"#NAME#" PSEUDO!", 525*9880d681SAndroid Build Coastguard Worker [(set RC:$dst, (VT (X86cmov RC:$t, RC:$f, imm:$cond, 526*9880d681SAndroid Build Coastguard Worker EFLAGS)))]>; 527*9880d681SAndroid Build Coastguard Worker} 528*9880d681SAndroid Build Coastguard Worker 529*9880d681SAndroid Build Coastguard Workerlet usesCustomInserter = 1, Uses = [EFLAGS] in { 530*9880d681SAndroid Build Coastguard Worker // X86 doesn't have 8-bit conditional moves. Use a customInserter to 531*9880d681SAndroid Build Coastguard Worker // emit control flow. An alternative to this is to mark i8 SELECT as Promote, 532*9880d681SAndroid Build Coastguard Worker // however that requires promoting the operands, and can induce additional 533*9880d681SAndroid Build Coastguard Worker // i8 register pressure. 534*9880d681SAndroid Build Coastguard Worker defm _GR8 : CMOVrr_PSEUDO<GR8, i8>; 535*9880d681SAndroid Build Coastguard Worker 536*9880d681SAndroid Build Coastguard Worker let Predicates = [NoCMov] in { 537*9880d681SAndroid Build Coastguard Worker defm _GR32 : CMOVrr_PSEUDO<GR32, i32>; 538*9880d681SAndroid Build Coastguard Worker defm _GR16 : CMOVrr_PSEUDO<GR16, i16>; 539*9880d681SAndroid Build Coastguard Worker } // Predicates = [NoCMov] 540*9880d681SAndroid Build Coastguard Worker 541*9880d681SAndroid Build Coastguard Worker // fcmov doesn't handle all possible EFLAGS, provide a fallback if there is no 542*9880d681SAndroid Build Coastguard Worker // SSE1/SSE2. 543*9880d681SAndroid Build Coastguard Worker let Predicates = [FPStackf32] in 544*9880d681SAndroid Build Coastguard Worker defm _RFP32 : CMOVrr_PSEUDO<RFP32, f32>; 545*9880d681SAndroid Build Coastguard Worker 546*9880d681SAndroid Build Coastguard Worker let Predicates = [FPStackf64] in 547*9880d681SAndroid Build Coastguard Worker defm _RFP64 : CMOVrr_PSEUDO<RFP64, f64>; 548*9880d681SAndroid Build Coastguard Worker 549*9880d681SAndroid Build Coastguard Worker defm _RFP80 : CMOVrr_PSEUDO<RFP80, f80>; 550*9880d681SAndroid Build Coastguard Worker 551*9880d681SAndroid Build Coastguard Worker defm _FR32 : CMOVrr_PSEUDO<FR32, f32>; 552*9880d681SAndroid Build Coastguard Worker defm _FR64 : CMOVrr_PSEUDO<FR64, f64>; 553*9880d681SAndroid Build Coastguard Worker defm _FR128 : CMOVrr_PSEUDO<FR128, f128>; 554*9880d681SAndroid Build Coastguard Worker defm _V4F32 : CMOVrr_PSEUDO<VR128, v4f32>; 555*9880d681SAndroid Build Coastguard Worker defm _V2F64 : CMOVrr_PSEUDO<VR128, v2f64>; 556*9880d681SAndroid Build Coastguard Worker defm _V2I64 : CMOVrr_PSEUDO<VR128, v2i64>; 557*9880d681SAndroid Build Coastguard Worker defm _V8F32 : CMOVrr_PSEUDO<VR256, v8f32>; 558*9880d681SAndroid Build Coastguard Worker defm _V4F64 : CMOVrr_PSEUDO<VR256, v4f64>; 559*9880d681SAndroid Build Coastguard Worker defm _V4I64 : CMOVrr_PSEUDO<VR256, v4i64>; 560*9880d681SAndroid Build Coastguard Worker defm _V8I64 : CMOVrr_PSEUDO<VR512, v8i64>; 561*9880d681SAndroid Build Coastguard Worker defm _V8F64 : CMOVrr_PSEUDO<VR512, v8f64>; 562*9880d681SAndroid Build Coastguard Worker defm _V16F32 : CMOVrr_PSEUDO<VR512, v16f32>; 563*9880d681SAndroid Build Coastguard Worker defm _V8I1 : CMOVrr_PSEUDO<VK8, v8i1>; 564*9880d681SAndroid Build Coastguard Worker defm _V16I1 : CMOVrr_PSEUDO<VK16, v16i1>; 565*9880d681SAndroid Build Coastguard Worker defm _V32I1 : CMOVrr_PSEUDO<VK32, v32i1>; 566*9880d681SAndroid Build Coastguard Worker defm _V64I1 : CMOVrr_PSEUDO<VK64, v64i1>; 567*9880d681SAndroid Build Coastguard Worker} // usesCustomInserter = 1, Uses = [EFLAGS] 568*9880d681SAndroid Build Coastguard Worker 569*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 570*9880d681SAndroid Build Coastguard Worker// Normal-Instructions-With-Lock-Prefix Pseudo Instructions 571*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 572*9880d681SAndroid Build Coastguard Worker 573*9880d681SAndroid Build Coastguard Worker// FIXME: Use normal instructions and add lock prefix dynamically. 574*9880d681SAndroid Build Coastguard Worker 575*9880d681SAndroid Build Coastguard Worker// Memory barriers 576*9880d681SAndroid Build Coastguard Worker 577*9880d681SAndroid Build Coastguard Worker// TODO: Get this to fold the constant into the instruction. 578*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1, Defs = [EFLAGS] in 579*9880d681SAndroid Build Coastguard Workerdef OR32mrLocked : I<0x09, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$zero), 580*9880d681SAndroid Build Coastguard Worker "or{l}\t{$zero, $dst|$dst, $zero}", [], 581*9880d681SAndroid Build Coastguard Worker IIC_ALU_MEM>, Requires<[Not64BitMode]>, OpSize32, LOCK, 582*9880d681SAndroid Build Coastguard Worker Sched<[WriteALULd, WriteRMW]>; 583*9880d681SAndroid Build Coastguard Worker 584*9880d681SAndroid Build Coastguard Workerlet hasSideEffects = 1 in 585*9880d681SAndroid Build Coastguard Workerdef Int_MemBarrier : I<0, Pseudo, (outs), (ins), 586*9880d681SAndroid Build Coastguard Worker "#MEMBARRIER", 587*9880d681SAndroid Build Coastguard Worker [(X86MemBarrier)]>, Sched<[WriteLoad]>; 588*9880d681SAndroid Build Coastguard Worker 589*9880d681SAndroid Build Coastguard Worker// RegOpc corresponds to the mr version of the instruction 590*9880d681SAndroid Build Coastguard Worker// ImmOpc corresponds to the mi version of the instruction 591*9880d681SAndroid Build Coastguard Worker// ImmOpc8 corresponds to the mi8 version of the instruction 592*9880d681SAndroid Build Coastguard Worker// ImmMod corresponds to the instruction format of the mi and mi8 versions 593*9880d681SAndroid Build Coastguard Workermulticlass LOCK_ArithBinOp<bits<8> RegOpc, bits<8> ImmOpc, bits<8> ImmOpc8, 594*9880d681SAndroid Build Coastguard Worker Format ImmMod, SDPatternOperator Op, string mnemonic> { 595*9880d681SAndroid Build Coastguard Workerlet Defs = [EFLAGS], mayLoad = 1, mayStore = 1, isCodeGenOnly = 1, 596*9880d681SAndroid Build Coastguard Worker SchedRW = [WriteALULd, WriteRMW] in { 597*9880d681SAndroid Build Coastguard Worker 598*9880d681SAndroid Build Coastguard Workerdef NAME#8mr : I<{RegOpc{7}, RegOpc{6}, RegOpc{5}, RegOpc{4}, 599*9880d681SAndroid Build Coastguard Worker RegOpc{3}, RegOpc{2}, RegOpc{1}, 0 }, 600*9880d681SAndroid Build Coastguard Worker MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src2), 601*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{b}\t", 602*9880d681SAndroid Build Coastguard Worker "{$src2, $dst|$dst, $src2}"), 603*9880d681SAndroid Build Coastguard Worker [(set EFLAGS, (Op addr:$dst, GR8:$src2))], 604*9880d681SAndroid Build Coastguard Worker IIC_ALU_NONMEM>, LOCK; 605*9880d681SAndroid Build Coastguard Worker 606*9880d681SAndroid Build Coastguard Workerdef NAME#16mr : I<{RegOpc{7}, RegOpc{6}, RegOpc{5}, RegOpc{4}, 607*9880d681SAndroid Build Coastguard Worker RegOpc{3}, RegOpc{2}, RegOpc{1}, 1 }, 608*9880d681SAndroid Build Coastguard Worker MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2), 609*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{w}\t", 610*9880d681SAndroid Build Coastguard Worker "{$src2, $dst|$dst, $src2}"), 611*9880d681SAndroid Build Coastguard Worker [(set EFLAGS, (Op addr:$dst, GR16:$src2))], 612*9880d681SAndroid Build Coastguard Worker IIC_ALU_NONMEM>, OpSize16, LOCK; 613*9880d681SAndroid Build Coastguard Worker 614*9880d681SAndroid Build Coastguard Workerdef NAME#32mr : I<{RegOpc{7}, RegOpc{6}, RegOpc{5}, RegOpc{4}, 615*9880d681SAndroid Build Coastguard Worker RegOpc{3}, RegOpc{2}, RegOpc{1}, 1 }, 616*9880d681SAndroid Build Coastguard Worker MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2), 617*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{l}\t", 618*9880d681SAndroid Build Coastguard Worker "{$src2, $dst|$dst, $src2}"), 619*9880d681SAndroid Build Coastguard Worker [(set EFLAGS, (Op addr:$dst, GR32:$src2))], 620*9880d681SAndroid Build Coastguard Worker IIC_ALU_NONMEM>, OpSize32, LOCK; 621*9880d681SAndroid Build Coastguard Worker 622*9880d681SAndroid Build Coastguard Workerdef NAME#64mr : RI<{RegOpc{7}, RegOpc{6}, RegOpc{5}, RegOpc{4}, 623*9880d681SAndroid Build Coastguard Worker RegOpc{3}, RegOpc{2}, RegOpc{1}, 1 }, 624*9880d681SAndroid Build Coastguard Worker MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2), 625*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{q}\t", 626*9880d681SAndroid Build Coastguard Worker "{$src2, $dst|$dst, $src2}"), 627*9880d681SAndroid Build Coastguard Worker [(set EFLAGS, (Op addr:$dst, GR64:$src2))], 628*9880d681SAndroid Build Coastguard Worker IIC_ALU_NONMEM>, LOCK; 629*9880d681SAndroid Build Coastguard Worker 630*9880d681SAndroid Build Coastguard Workerdef NAME#8mi : Ii8<{ImmOpc{7}, ImmOpc{6}, ImmOpc{5}, ImmOpc{4}, 631*9880d681SAndroid Build Coastguard Worker ImmOpc{3}, ImmOpc{2}, ImmOpc{1}, 0 }, 632*9880d681SAndroid Build Coastguard Worker ImmMod, (outs), (ins i8mem :$dst, i8imm :$src2), 633*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{b}\t", 634*9880d681SAndroid Build Coastguard Worker "{$src2, $dst|$dst, $src2}"), 635*9880d681SAndroid Build Coastguard Worker [(set EFLAGS, (Op addr:$dst, (i8 imm:$src2)))], 636*9880d681SAndroid Build Coastguard Worker IIC_ALU_MEM>, LOCK; 637*9880d681SAndroid Build Coastguard Worker 638*9880d681SAndroid Build Coastguard Workerdef NAME#16mi : Ii16<{ImmOpc{7}, ImmOpc{6}, ImmOpc{5}, ImmOpc{4}, 639*9880d681SAndroid Build Coastguard Worker ImmOpc{3}, ImmOpc{2}, ImmOpc{1}, 1 }, 640*9880d681SAndroid Build Coastguard Worker ImmMod, (outs), (ins i16mem :$dst, i16imm :$src2), 641*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{w}\t", 642*9880d681SAndroid Build Coastguard Worker "{$src2, $dst|$dst, $src2}"), 643*9880d681SAndroid Build Coastguard Worker [(set EFLAGS, (Op addr:$dst, (i16 imm:$src2)))], 644*9880d681SAndroid Build Coastguard Worker IIC_ALU_MEM>, OpSize16, LOCK; 645*9880d681SAndroid Build Coastguard Worker 646*9880d681SAndroid Build Coastguard Workerdef NAME#32mi : Ii32<{ImmOpc{7}, ImmOpc{6}, ImmOpc{5}, ImmOpc{4}, 647*9880d681SAndroid Build Coastguard Worker ImmOpc{3}, ImmOpc{2}, ImmOpc{1}, 1 }, 648*9880d681SAndroid Build Coastguard Worker ImmMod, (outs), (ins i32mem :$dst, i32imm :$src2), 649*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{l}\t", 650*9880d681SAndroid Build Coastguard Worker "{$src2, $dst|$dst, $src2}"), 651*9880d681SAndroid Build Coastguard Worker [(set EFLAGS, (Op addr:$dst, (i32 imm:$src2)))], 652*9880d681SAndroid Build Coastguard Worker IIC_ALU_MEM>, OpSize32, LOCK; 653*9880d681SAndroid Build Coastguard Worker 654*9880d681SAndroid Build Coastguard Workerdef NAME#64mi32 : RIi32S<{ImmOpc{7}, ImmOpc{6}, ImmOpc{5}, ImmOpc{4}, 655*9880d681SAndroid Build Coastguard Worker ImmOpc{3}, ImmOpc{2}, ImmOpc{1}, 1 }, 656*9880d681SAndroid Build Coastguard Worker ImmMod, (outs), (ins i64mem :$dst, i64i32imm :$src2), 657*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{q}\t", 658*9880d681SAndroid Build Coastguard Worker "{$src2, $dst|$dst, $src2}"), 659*9880d681SAndroid Build Coastguard Worker [(set EFLAGS, (Op addr:$dst, i64immSExt32:$src2))], 660*9880d681SAndroid Build Coastguard Worker IIC_ALU_MEM>, LOCK; 661*9880d681SAndroid Build Coastguard Worker 662*9880d681SAndroid Build Coastguard Workerdef NAME#16mi8 : Ii8<{ImmOpc8{7}, ImmOpc8{6}, ImmOpc8{5}, ImmOpc8{4}, 663*9880d681SAndroid Build Coastguard Worker ImmOpc8{3}, ImmOpc8{2}, ImmOpc8{1}, 1 }, 664*9880d681SAndroid Build Coastguard Worker ImmMod, (outs), (ins i16mem :$dst, i16i8imm :$src2), 665*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{w}\t", 666*9880d681SAndroid Build Coastguard Worker "{$src2, $dst|$dst, $src2}"), 667*9880d681SAndroid Build Coastguard Worker [(set EFLAGS, (Op addr:$dst, i16immSExt8:$src2))], 668*9880d681SAndroid Build Coastguard Worker IIC_ALU_MEM>, OpSize16, LOCK; 669*9880d681SAndroid Build Coastguard Worker 670*9880d681SAndroid Build Coastguard Workerdef NAME#32mi8 : Ii8<{ImmOpc8{7}, ImmOpc8{6}, ImmOpc8{5}, ImmOpc8{4}, 671*9880d681SAndroid Build Coastguard Worker ImmOpc8{3}, ImmOpc8{2}, ImmOpc8{1}, 1 }, 672*9880d681SAndroid Build Coastguard Worker ImmMod, (outs), (ins i32mem :$dst, i32i8imm :$src2), 673*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{l}\t", 674*9880d681SAndroid Build Coastguard Worker "{$src2, $dst|$dst, $src2}"), 675*9880d681SAndroid Build Coastguard Worker [(set EFLAGS, (Op addr:$dst, i32immSExt8:$src2))], 676*9880d681SAndroid Build Coastguard Worker IIC_ALU_MEM>, OpSize32, LOCK; 677*9880d681SAndroid Build Coastguard Worker 678*9880d681SAndroid Build Coastguard Workerdef NAME#64mi8 : RIi8<{ImmOpc8{7}, ImmOpc8{6}, ImmOpc8{5}, ImmOpc8{4}, 679*9880d681SAndroid Build Coastguard Worker ImmOpc8{3}, ImmOpc8{2}, ImmOpc8{1}, 1 }, 680*9880d681SAndroid Build Coastguard Worker ImmMod, (outs), (ins i64mem :$dst, i64i8imm :$src2), 681*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{q}\t", 682*9880d681SAndroid Build Coastguard Worker "{$src2, $dst|$dst, $src2}"), 683*9880d681SAndroid Build Coastguard Worker [(set EFLAGS, (Op addr:$dst, i64immSExt8:$src2))], 684*9880d681SAndroid Build Coastguard Worker IIC_ALU_MEM>, LOCK; 685*9880d681SAndroid Build Coastguard Worker 686*9880d681SAndroid Build Coastguard Worker} 687*9880d681SAndroid Build Coastguard Worker 688*9880d681SAndroid Build Coastguard Worker} 689*9880d681SAndroid Build Coastguard Worker 690*9880d681SAndroid Build Coastguard Workerdefm LOCK_ADD : LOCK_ArithBinOp<0x00, 0x80, 0x83, MRM0m, X86lock_add, "add">; 691*9880d681SAndroid Build Coastguard Workerdefm LOCK_SUB : LOCK_ArithBinOp<0x28, 0x80, 0x83, MRM5m, X86lock_sub, "sub">; 692*9880d681SAndroid Build Coastguard Workerdefm LOCK_OR : LOCK_ArithBinOp<0x08, 0x80, 0x83, MRM1m, X86lock_or , "or">; 693*9880d681SAndroid Build Coastguard Workerdefm LOCK_AND : LOCK_ArithBinOp<0x20, 0x80, 0x83, MRM4m, X86lock_and, "and">; 694*9880d681SAndroid Build Coastguard Workerdefm LOCK_XOR : LOCK_ArithBinOp<0x30, 0x80, 0x83, MRM6m, X86lock_xor, "xor">; 695*9880d681SAndroid Build Coastguard Worker 696*9880d681SAndroid Build Coastguard Workermulticlass LOCK_ArithUnOp<bits<8> Opc8, bits<8> Opc, Format Form, 697*9880d681SAndroid Build Coastguard Worker int Increment, string mnemonic> { 698*9880d681SAndroid Build Coastguard Workerlet Defs = [EFLAGS], mayLoad = 1, mayStore = 1, isCodeGenOnly = 1, 699*9880d681SAndroid Build Coastguard Worker SchedRW = [WriteALULd, WriteRMW], Predicates = [NotSlowIncDec] in { 700*9880d681SAndroid Build Coastguard Workerdef NAME#8m : I<Opc8, Form, (outs), (ins i8mem :$dst), 701*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{b}\t$dst"), 702*9880d681SAndroid Build Coastguard Worker [(set EFLAGS, (X86lock_add addr:$dst, (i8 Increment)))], 703*9880d681SAndroid Build Coastguard Worker IIC_UNARY_MEM>, LOCK; 704*9880d681SAndroid Build Coastguard Workerdef NAME#16m : I<Opc, Form, (outs), (ins i16mem:$dst), 705*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{w}\t$dst"), 706*9880d681SAndroid Build Coastguard Worker [(set EFLAGS, (X86lock_add addr:$dst, (i16 Increment)))], 707*9880d681SAndroid Build Coastguard Worker IIC_UNARY_MEM>, OpSize16, LOCK; 708*9880d681SAndroid Build Coastguard Workerdef NAME#32m : I<Opc, Form, (outs), (ins i32mem:$dst), 709*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{l}\t$dst"), 710*9880d681SAndroid Build Coastguard Worker [(set EFLAGS, (X86lock_add addr:$dst, (i32 Increment)))], 711*9880d681SAndroid Build Coastguard Worker IIC_UNARY_MEM>, OpSize32, LOCK; 712*9880d681SAndroid Build Coastguard Workerdef NAME#64m : RI<Opc, Form, (outs), (ins i64mem:$dst), 713*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{q}\t$dst"), 714*9880d681SAndroid Build Coastguard Worker [(set EFLAGS, (X86lock_add addr:$dst, (i64 Increment)))], 715*9880d681SAndroid Build Coastguard Worker IIC_UNARY_MEM>, LOCK; 716*9880d681SAndroid Build Coastguard Worker} 717*9880d681SAndroid Build Coastguard Worker} 718*9880d681SAndroid Build Coastguard Worker 719*9880d681SAndroid Build Coastguard Workerdefm LOCK_INC : LOCK_ArithUnOp<0xFE, 0xFF, MRM0m, 1, "inc">; 720*9880d681SAndroid Build Coastguard Workerdefm LOCK_DEC : LOCK_ArithUnOp<0xFE, 0xFF, MRM1m, -1, "dec">; 721*9880d681SAndroid Build Coastguard Worker 722*9880d681SAndroid Build Coastguard Worker// Atomic compare and swap. 723*9880d681SAndroid Build Coastguard Workermulticlass LCMPXCHG_UnOp<bits<8> Opc, Format Form, string mnemonic, 724*9880d681SAndroid Build Coastguard Worker SDPatternOperator frag, X86MemOperand x86memop, 725*9880d681SAndroid Build Coastguard Worker InstrItinClass itin> { 726*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1 in { 727*9880d681SAndroid Build Coastguard Worker def NAME : I<Opc, Form, (outs), (ins x86memop:$ptr), 728*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "\t$ptr"), 729*9880d681SAndroid Build Coastguard Worker [(frag addr:$ptr)], itin>, TB, LOCK; 730*9880d681SAndroid Build Coastguard Worker} 731*9880d681SAndroid Build Coastguard Worker} 732*9880d681SAndroid Build Coastguard Worker 733*9880d681SAndroid Build Coastguard Workermulticlass LCMPXCHG_BinOp<bits<8> Opc8, bits<8> Opc, Format Form, 734*9880d681SAndroid Build Coastguard Worker string mnemonic, SDPatternOperator frag, 735*9880d681SAndroid Build Coastguard Worker InstrItinClass itin8, InstrItinClass itin> { 736*9880d681SAndroid Build Coastguard Workerlet isCodeGenOnly = 1, SchedRW = [WriteALULd, WriteRMW] in { 737*9880d681SAndroid Build Coastguard Worker let Defs = [AL, EFLAGS], Uses = [AL] in 738*9880d681SAndroid Build Coastguard Worker def NAME#8 : I<Opc8, Form, (outs), (ins i8mem:$ptr, GR8:$swap), 739*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{b}\t{$swap, $ptr|$ptr, $swap}"), 740*9880d681SAndroid Build Coastguard Worker [(frag addr:$ptr, GR8:$swap, 1)], itin8>, TB, LOCK; 741*9880d681SAndroid Build Coastguard Worker let Defs = [AX, EFLAGS], Uses = [AX] in 742*9880d681SAndroid Build Coastguard Worker def NAME#16 : I<Opc, Form, (outs), (ins i16mem:$ptr, GR16:$swap), 743*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{w}\t{$swap, $ptr|$ptr, $swap}"), 744*9880d681SAndroid Build Coastguard Worker [(frag addr:$ptr, GR16:$swap, 2)], itin>, TB, OpSize16, LOCK; 745*9880d681SAndroid Build Coastguard Worker let Defs = [EAX, EFLAGS], Uses = [EAX] in 746*9880d681SAndroid Build Coastguard Worker def NAME#32 : I<Opc, Form, (outs), (ins i32mem:$ptr, GR32:$swap), 747*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{l}\t{$swap, $ptr|$ptr, $swap}"), 748*9880d681SAndroid Build Coastguard Worker [(frag addr:$ptr, GR32:$swap, 4)], itin>, TB, OpSize32, LOCK; 749*9880d681SAndroid Build Coastguard Worker let Defs = [RAX, EFLAGS], Uses = [RAX] in 750*9880d681SAndroid Build Coastguard Worker def NAME#64 : RI<Opc, Form, (outs), (ins i64mem:$ptr, GR64:$swap), 751*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{q}\t{$swap, $ptr|$ptr, $swap}"), 752*9880d681SAndroid Build Coastguard Worker [(frag addr:$ptr, GR64:$swap, 8)], itin>, TB, LOCK; 753*9880d681SAndroid Build Coastguard Worker} 754*9880d681SAndroid Build Coastguard Worker} 755*9880d681SAndroid Build Coastguard Worker 756*9880d681SAndroid Build Coastguard Workerlet Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX], 757*9880d681SAndroid Build Coastguard Worker SchedRW = [WriteALULd, WriteRMW] in { 758*9880d681SAndroid Build Coastguard Workerdefm LCMPXCHG8B : LCMPXCHG_UnOp<0xC7, MRM1m, "cmpxchg8b", 759*9880d681SAndroid Build Coastguard Worker X86cas8, i64mem, 760*9880d681SAndroid Build Coastguard Worker IIC_CMPX_LOCK_8B>; 761*9880d681SAndroid Build Coastguard Worker} 762*9880d681SAndroid Build Coastguard Worker 763*9880d681SAndroid Build Coastguard Worker// This pseudo must be used when the frame uses RBX as 764*9880d681SAndroid Build Coastguard Worker// the base pointer. Indeed, in such situation RBX is a reserved 765*9880d681SAndroid Build Coastguard Worker// register and the register allocator will ignore any use/def of 766*9880d681SAndroid Build Coastguard Worker// it. In other words, the register will not fix the clobbering of 767*9880d681SAndroid Build Coastguard Worker// RBX that will happen when setting the arguments for the instrucion. 768*9880d681SAndroid Build Coastguard Worker// 769*9880d681SAndroid Build Coastguard Worker// Unlike the actual related instuction, we mark that this one 770*9880d681SAndroid Build Coastguard Worker// defines EBX (instead of using EBX). 771*9880d681SAndroid Build Coastguard Worker// The rationale is that we will define RBX during the expansion of 772*9880d681SAndroid Build Coastguard Worker// the pseudo. The argument feeding EBX is ebx_input. 773*9880d681SAndroid Build Coastguard Worker// 774*9880d681SAndroid Build Coastguard Worker// The additional argument, $ebx_save, is a temporary register used to 775*9880d681SAndroid Build Coastguard Worker// save the value of RBX accross the actual instruction. 776*9880d681SAndroid Build Coastguard Worker// 777*9880d681SAndroid Build Coastguard Worker// To make sure the register assigned to $ebx_save does not interfere with 778*9880d681SAndroid Build Coastguard Worker// the definition of the actual instruction, we use a definition $dst which 779*9880d681SAndroid Build Coastguard Worker// is tied to $rbx_save. That way, the live-range of $rbx_save spans accross 780*9880d681SAndroid Build Coastguard Worker// the instruction and we are sure we will have a valid register to restore 781*9880d681SAndroid Build Coastguard Worker// the value of RBX. 782*9880d681SAndroid Build Coastguard Workerlet Defs = [EAX, EDX, EBX, EFLAGS], Uses = [EAX, ECX, EDX], 783*9880d681SAndroid Build Coastguard Worker SchedRW = [WriteALULd, WriteRMW], isCodeGenOnly = 1, isPseudo = 1, 784*9880d681SAndroid Build Coastguard Worker Constraints = "$ebx_save = $dst", usesCustomInserter = 1 in { 785*9880d681SAndroid Build Coastguard Workerdef LCMPXCHG8B_SAVE_EBX : 786*9880d681SAndroid Build Coastguard Worker I<0, Pseudo, (outs GR32:$dst), 787*9880d681SAndroid Build Coastguard Worker (ins i64mem:$ptr, GR32:$ebx_input, GR32:$ebx_save), 788*9880d681SAndroid Build Coastguard Worker !strconcat("cmpxchg8b", "\t$ptr"), 789*9880d681SAndroid Build Coastguard Worker [(set GR32:$dst, (X86cas8save_ebx addr:$ptr, GR32:$ebx_input, 790*9880d681SAndroid Build Coastguard Worker GR32:$ebx_save))], 791*9880d681SAndroid Build Coastguard Worker IIC_CMPX_LOCK_8B>; 792*9880d681SAndroid Build Coastguard Worker} 793*9880d681SAndroid Build Coastguard Worker 794*9880d681SAndroid Build Coastguard Worker 795*9880d681SAndroid Build Coastguard Workerlet Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX], 796*9880d681SAndroid Build Coastguard Worker Predicates = [HasCmpxchg16b], SchedRW = [WriteALULd, WriteRMW] in { 797*9880d681SAndroid Build Coastguard Workerdefm LCMPXCHG16B : LCMPXCHG_UnOp<0xC7, MRM1m, "cmpxchg16b", 798*9880d681SAndroid Build Coastguard Worker X86cas16, i128mem, 799*9880d681SAndroid Build Coastguard Worker IIC_CMPX_LOCK_16B>, REX_W; 800*9880d681SAndroid Build Coastguard Worker} 801*9880d681SAndroid Build Coastguard Worker 802*9880d681SAndroid Build Coastguard Worker// Same as LCMPXCHG8B_SAVE_RBX but for the 16 Bytes variant. 803*9880d681SAndroid Build Coastguard Workerlet Defs = [RAX, RDX, RBX, EFLAGS], Uses = [RAX, RCX, RDX], 804*9880d681SAndroid Build Coastguard Worker Predicates = [HasCmpxchg16b], SchedRW = [WriteALULd, WriteRMW], 805*9880d681SAndroid Build Coastguard Worker isCodeGenOnly = 1, isPseudo = 1, Constraints = "$rbx_save = $dst", 806*9880d681SAndroid Build Coastguard Worker usesCustomInserter = 1 in { 807*9880d681SAndroid Build Coastguard Workerdef LCMPXCHG16B_SAVE_RBX : 808*9880d681SAndroid Build Coastguard Worker I<0, Pseudo, (outs GR64:$dst), 809*9880d681SAndroid Build Coastguard Worker (ins i128mem:$ptr, GR64:$rbx_input, GR64:$rbx_save), 810*9880d681SAndroid Build Coastguard Worker !strconcat("cmpxchg16b", "\t$ptr"), 811*9880d681SAndroid Build Coastguard Worker [(set GR64:$dst, (X86cas16save_rbx addr:$ptr, GR64:$rbx_input, 812*9880d681SAndroid Build Coastguard Worker GR64:$rbx_save))], 813*9880d681SAndroid Build Coastguard Worker IIC_CMPX_LOCK_16B>; 814*9880d681SAndroid Build Coastguard Worker} 815*9880d681SAndroid Build Coastguard Worker 816*9880d681SAndroid Build Coastguard Workerdefm LCMPXCHG : LCMPXCHG_BinOp<0xB0, 0xB1, MRMDestMem, "cmpxchg", 817*9880d681SAndroid Build Coastguard Worker X86cas, IIC_CMPX_LOCK_8, IIC_CMPX_LOCK>; 818*9880d681SAndroid Build Coastguard Worker 819*9880d681SAndroid Build Coastguard Worker// Atomic exchange and add 820*9880d681SAndroid Build Coastguard Workermulticlass ATOMIC_LOAD_BINOP<bits<8> opc8, bits<8> opc, string mnemonic, 821*9880d681SAndroid Build Coastguard Worker string frag, 822*9880d681SAndroid Build Coastguard Worker InstrItinClass itin8, InstrItinClass itin> { 823*9880d681SAndroid Build Coastguard Worker let Constraints = "$val = $dst", Defs = [EFLAGS], isCodeGenOnly = 1, 824*9880d681SAndroid Build Coastguard Worker SchedRW = [WriteALULd, WriteRMW] in { 825*9880d681SAndroid Build Coastguard Worker def NAME#8 : I<opc8, MRMSrcMem, (outs GR8:$dst), 826*9880d681SAndroid Build Coastguard Worker (ins GR8:$val, i8mem:$ptr), 827*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"), 828*9880d681SAndroid Build Coastguard Worker [(set GR8:$dst, 829*9880d681SAndroid Build Coastguard Worker (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))], 830*9880d681SAndroid Build Coastguard Worker itin8>; 831*9880d681SAndroid Build Coastguard Worker def NAME#16 : I<opc, MRMSrcMem, (outs GR16:$dst), 832*9880d681SAndroid Build Coastguard Worker (ins GR16:$val, i16mem:$ptr), 833*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"), 834*9880d681SAndroid Build Coastguard Worker [(set 835*9880d681SAndroid Build Coastguard Worker GR16:$dst, 836*9880d681SAndroid Build Coastguard Worker (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))], 837*9880d681SAndroid Build Coastguard Worker itin>, OpSize16; 838*9880d681SAndroid Build Coastguard Worker def NAME#32 : I<opc, MRMSrcMem, (outs GR32:$dst), 839*9880d681SAndroid Build Coastguard Worker (ins GR32:$val, i32mem:$ptr), 840*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"), 841*9880d681SAndroid Build Coastguard Worker [(set 842*9880d681SAndroid Build Coastguard Worker GR32:$dst, 843*9880d681SAndroid Build Coastguard Worker (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))], 844*9880d681SAndroid Build Coastguard Worker itin>, OpSize32; 845*9880d681SAndroid Build Coastguard Worker def NAME#64 : RI<opc, MRMSrcMem, (outs GR64:$dst), 846*9880d681SAndroid Build Coastguard Worker (ins GR64:$val, i64mem:$ptr), 847*9880d681SAndroid Build Coastguard Worker !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"), 848*9880d681SAndroid Build Coastguard Worker [(set 849*9880d681SAndroid Build Coastguard Worker GR64:$dst, 850*9880d681SAndroid Build Coastguard Worker (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))], 851*9880d681SAndroid Build Coastguard Worker itin>; 852*9880d681SAndroid Build Coastguard Worker } 853*9880d681SAndroid Build Coastguard Worker} 854*9880d681SAndroid Build Coastguard Worker 855*9880d681SAndroid Build Coastguard Workerdefm LXADD : ATOMIC_LOAD_BINOP<0xc0, 0xc1, "xadd", "atomic_load_add", 856*9880d681SAndroid Build Coastguard Worker IIC_XADD_LOCK_MEM8, IIC_XADD_LOCK_MEM>, 857*9880d681SAndroid Build Coastguard Worker TB, LOCK; 858*9880d681SAndroid Build Coastguard Worker 859*9880d681SAndroid Build Coastguard Worker/* The following multiclass tries to make sure that in code like 860*9880d681SAndroid Build Coastguard Worker * x.store (immediate op x.load(acquire), release) 861*9880d681SAndroid Build Coastguard Worker * and 862*9880d681SAndroid Build Coastguard Worker * x.store (register op x.load(acquire), release) 863*9880d681SAndroid Build Coastguard Worker * an operation directly on memory is generated instead of wasting a register. 864*9880d681SAndroid Build Coastguard Worker * It is not automatic as atomic_store/load are only lowered to MOV instructions 865*9880d681SAndroid Build Coastguard Worker * extremely late to prevent them from being accidentally reordered in the backend 866*9880d681SAndroid Build Coastguard Worker * (see below the RELEASE_MOV* / ACQUIRE_MOV* pseudo-instructions) 867*9880d681SAndroid Build Coastguard Worker */ 868*9880d681SAndroid Build Coastguard Workermulticlass RELEASE_BINOP_MI<SDNode op> { 869*9880d681SAndroid Build Coastguard Worker def NAME#8mi : I<0, Pseudo, (outs), (ins i8mem:$dst, i8imm:$src), 870*9880d681SAndroid Build Coastguard Worker "#BINOP "#NAME#"8mi PSEUDO!", 871*9880d681SAndroid Build Coastguard Worker [(atomic_store_8 addr:$dst, (op 872*9880d681SAndroid Build Coastguard Worker (atomic_load_8 addr:$dst), (i8 imm:$src)))]>; 873*9880d681SAndroid Build Coastguard Worker def NAME#8mr : I<0, Pseudo, (outs), (ins i8mem:$dst, GR8:$src), 874*9880d681SAndroid Build Coastguard Worker "#BINOP "#NAME#"8mr PSEUDO!", 875*9880d681SAndroid Build Coastguard Worker [(atomic_store_8 addr:$dst, (op 876*9880d681SAndroid Build Coastguard Worker (atomic_load_8 addr:$dst), GR8:$src))]>; 877*9880d681SAndroid Build Coastguard Worker // NAME#16 is not generated as 16-bit arithmetic instructions are considered 878*9880d681SAndroid Build Coastguard Worker // costly and avoided as far as possible by this backend anyway 879*9880d681SAndroid Build Coastguard Worker def NAME#32mi : I<0, Pseudo, (outs), (ins i32mem:$dst, i32imm:$src), 880*9880d681SAndroid Build Coastguard Worker "#BINOP "#NAME#"32mi PSEUDO!", 881*9880d681SAndroid Build Coastguard Worker [(atomic_store_32 addr:$dst, (op 882*9880d681SAndroid Build Coastguard Worker (atomic_load_32 addr:$dst), (i32 imm:$src)))]>; 883*9880d681SAndroid Build Coastguard Worker def NAME#32mr : I<0, Pseudo, (outs), (ins i32mem:$dst, GR32:$src), 884*9880d681SAndroid Build Coastguard Worker "#BINOP "#NAME#"32mr PSEUDO!", 885*9880d681SAndroid Build Coastguard Worker [(atomic_store_32 addr:$dst, (op 886*9880d681SAndroid Build Coastguard Worker (atomic_load_32 addr:$dst), GR32:$src))]>; 887*9880d681SAndroid Build Coastguard Worker def NAME#64mi32 : I<0, Pseudo, (outs), (ins i64mem:$dst, i64i32imm:$src), 888*9880d681SAndroid Build Coastguard Worker "#BINOP "#NAME#"64mi32 PSEUDO!", 889*9880d681SAndroid Build Coastguard Worker [(atomic_store_64 addr:$dst, (op 890*9880d681SAndroid Build Coastguard Worker (atomic_load_64 addr:$dst), (i64immSExt32:$src)))]>; 891*9880d681SAndroid Build Coastguard Worker def NAME#64mr : I<0, Pseudo, (outs), (ins i64mem:$dst, GR64:$src), 892*9880d681SAndroid Build Coastguard Worker "#BINOP "#NAME#"64mr PSEUDO!", 893*9880d681SAndroid Build Coastguard Worker [(atomic_store_64 addr:$dst, (op 894*9880d681SAndroid Build Coastguard Worker (atomic_load_64 addr:$dst), GR64:$src))]>; 895*9880d681SAndroid Build Coastguard Worker} 896*9880d681SAndroid Build Coastguard Workerlet Defs = [EFLAGS] in { 897*9880d681SAndroid Build Coastguard Worker defm RELEASE_ADD : RELEASE_BINOP_MI<add>; 898*9880d681SAndroid Build Coastguard Worker defm RELEASE_AND : RELEASE_BINOP_MI<and>; 899*9880d681SAndroid Build Coastguard Worker defm RELEASE_OR : RELEASE_BINOP_MI<or>; 900*9880d681SAndroid Build Coastguard Worker defm RELEASE_XOR : RELEASE_BINOP_MI<xor>; 901*9880d681SAndroid Build Coastguard Worker // Note: we don't deal with sub, because substractions of constants are 902*9880d681SAndroid Build Coastguard Worker // optimized into additions before this code can run. 903*9880d681SAndroid Build Coastguard Worker} 904*9880d681SAndroid Build Coastguard Worker 905*9880d681SAndroid Build Coastguard Worker// Same as above, but for floating-point. 906*9880d681SAndroid Build Coastguard Worker// FIXME: imm version. 907*9880d681SAndroid Build Coastguard Worker// FIXME: Version that doesn't clobber $src, using AVX's VADDSS. 908*9880d681SAndroid Build Coastguard Worker// FIXME: This could also handle SIMD operations with *ps and *pd instructions. 909*9880d681SAndroid Build Coastguard Workerlet usesCustomInserter = 1 in { 910*9880d681SAndroid Build Coastguard Workermulticlass RELEASE_FP_BINOP_MI<SDNode op> { 911*9880d681SAndroid Build Coastguard Worker def NAME#32mr : I<0, Pseudo, (outs), (ins i32mem:$dst, FR32:$src), 912*9880d681SAndroid Build Coastguard Worker "#BINOP "#NAME#"32mr PSEUDO!", 913*9880d681SAndroid Build Coastguard Worker [(atomic_store_32 addr:$dst, 914*9880d681SAndroid Build Coastguard Worker (i32 (bitconvert (op 915*9880d681SAndroid Build Coastguard Worker (f32 (bitconvert (i32 (atomic_load_32 addr:$dst)))), 916*9880d681SAndroid Build Coastguard Worker FR32:$src))))]>, Requires<[HasSSE1]>; 917*9880d681SAndroid Build Coastguard Worker def NAME#64mr : I<0, Pseudo, (outs), (ins i64mem:$dst, FR64:$src), 918*9880d681SAndroid Build Coastguard Worker "#BINOP "#NAME#"64mr PSEUDO!", 919*9880d681SAndroid Build Coastguard Worker [(atomic_store_64 addr:$dst, 920*9880d681SAndroid Build Coastguard Worker (i64 (bitconvert (op 921*9880d681SAndroid Build Coastguard Worker (f64 (bitconvert (i64 (atomic_load_64 addr:$dst)))), 922*9880d681SAndroid Build Coastguard Worker FR64:$src))))]>, Requires<[HasSSE2]>; 923*9880d681SAndroid Build Coastguard Worker} 924*9880d681SAndroid Build Coastguard Workerdefm RELEASE_FADD : RELEASE_FP_BINOP_MI<fadd>; 925*9880d681SAndroid Build Coastguard Worker// FIXME: Add fsub, fmul, fdiv, ... 926*9880d681SAndroid Build Coastguard Worker} 927*9880d681SAndroid Build Coastguard Worker 928*9880d681SAndroid Build Coastguard Workermulticlass RELEASE_UNOP<dag dag8, dag dag16, dag dag32, dag dag64> { 929*9880d681SAndroid Build Coastguard Worker def NAME#8m : I<0, Pseudo, (outs), (ins i8mem:$dst), 930*9880d681SAndroid Build Coastguard Worker "#UNOP "#NAME#"8m PSEUDO!", 931*9880d681SAndroid Build Coastguard Worker [(atomic_store_8 addr:$dst, dag8)]>; 932*9880d681SAndroid Build Coastguard Worker def NAME#16m : I<0, Pseudo, (outs), (ins i16mem:$dst), 933*9880d681SAndroid Build Coastguard Worker "#UNOP "#NAME#"16m PSEUDO!", 934*9880d681SAndroid Build Coastguard Worker [(atomic_store_16 addr:$dst, dag16)]>; 935*9880d681SAndroid Build Coastguard Worker def NAME#32m : I<0, Pseudo, (outs), (ins i32mem:$dst), 936*9880d681SAndroid Build Coastguard Worker "#UNOP "#NAME#"32m PSEUDO!", 937*9880d681SAndroid Build Coastguard Worker [(atomic_store_32 addr:$dst, dag32)]>; 938*9880d681SAndroid Build Coastguard Worker def NAME#64m : I<0, Pseudo, (outs), (ins i64mem:$dst), 939*9880d681SAndroid Build Coastguard Worker "#UNOP "#NAME#"64m PSEUDO!", 940*9880d681SAndroid Build Coastguard Worker [(atomic_store_64 addr:$dst, dag64)]>; 941*9880d681SAndroid Build Coastguard Worker} 942*9880d681SAndroid Build Coastguard Worker 943*9880d681SAndroid Build Coastguard Workerlet Defs = [EFLAGS] in { 944*9880d681SAndroid Build Coastguard Worker defm RELEASE_INC : RELEASE_UNOP< 945*9880d681SAndroid Build Coastguard Worker (add (atomic_load_8 addr:$dst), (i8 1)), 946*9880d681SAndroid Build Coastguard Worker (add (atomic_load_16 addr:$dst), (i16 1)), 947*9880d681SAndroid Build Coastguard Worker (add (atomic_load_32 addr:$dst), (i32 1)), 948*9880d681SAndroid Build Coastguard Worker (add (atomic_load_64 addr:$dst), (i64 1))>, Requires<[NotSlowIncDec]>; 949*9880d681SAndroid Build Coastguard Worker defm RELEASE_DEC : RELEASE_UNOP< 950*9880d681SAndroid Build Coastguard Worker (add (atomic_load_8 addr:$dst), (i8 -1)), 951*9880d681SAndroid Build Coastguard Worker (add (atomic_load_16 addr:$dst), (i16 -1)), 952*9880d681SAndroid Build Coastguard Worker (add (atomic_load_32 addr:$dst), (i32 -1)), 953*9880d681SAndroid Build Coastguard Worker (add (atomic_load_64 addr:$dst), (i64 -1))>, Requires<[NotSlowIncDec]>; 954*9880d681SAndroid Build Coastguard Worker} 955*9880d681SAndroid Build Coastguard Worker/* 956*9880d681SAndroid Build Coastguard WorkerTODO: These don't work because the type inference of TableGen fails. 957*9880d681SAndroid Build Coastguard WorkerTODO: find a way to fix it. 958*9880d681SAndroid Build Coastguard Workerlet Defs = [EFLAGS] in { 959*9880d681SAndroid Build Coastguard Worker defm RELEASE_NEG : RELEASE_UNOP< 960*9880d681SAndroid Build Coastguard Worker (ineg (atomic_load_8 addr:$dst)), 961*9880d681SAndroid Build Coastguard Worker (ineg (atomic_load_16 addr:$dst)), 962*9880d681SAndroid Build Coastguard Worker (ineg (atomic_load_32 addr:$dst)), 963*9880d681SAndroid Build Coastguard Worker (ineg (atomic_load_64 addr:$dst))>; 964*9880d681SAndroid Build Coastguard Worker} 965*9880d681SAndroid Build Coastguard Worker// NOT doesn't set flags. 966*9880d681SAndroid Build Coastguard Workerdefm RELEASE_NOT : RELEASE_UNOP< 967*9880d681SAndroid Build Coastguard Worker (not (atomic_load_8 addr:$dst)), 968*9880d681SAndroid Build Coastguard Worker (not (atomic_load_16 addr:$dst)), 969*9880d681SAndroid Build Coastguard Worker (not (atomic_load_32 addr:$dst)), 970*9880d681SAndroid Build Coastguard Worker (not (atomic_load_64 addr:$dst))>; 971*9880d681SAndroid Build Coastguard Worker*/ 972*9880d681SAndroid Build Coastguard Worker 973*9880d681SAndroid Build Coastguard Workerdef RELEASE_MOV8mi : I<0, Pseudo, (outs), (ins i8mem:$dst, i8imm:$src), 974*9880d681SAndroid Build Coastguard Worker "#RELEASE_MOV8mi PSEUDO!", 975*9880d681SAndroid Build Coastguard Worker [(atomic_store_8 addr:$dst, (i8 imm:$src))]>; 976*9880d681SAndroid Build Coastguard Workerdef RELEASE_MOV16mi : I<0, Pseudo, (outs), (ins i16mem:$dst, i16imm:$src), 977*9880d681SAndroid Build Coastguard Worker "#RELEASE_MOV16mi PSEUDO!", 978*9880d681SAndroid Build Coastguard Worker [(atomic_store_16 addr:$dst, (i16 imm:$src))]>; 979*9880d681SAndroid Build Coastguard Workerdef RELEASE_MOV32mi : I<0, Pseudo, (outs), (ins i32mem:$dst, i32imm:$src), 980*9880d681SAndroid Build Coastguard Worker "#RELEASE_MOV32mi PSEUDO!", 981*9880d681SAndroid Build Coastguard Worker [(atomic_store_32 addr:$dst, (i32 imm:$src))]>; 982*9880d681SAndroid Build Coastguard Workerdef RELEASE_MOV64mi32 : I<0, Pseudo, (outs), (ins i64mem:$dst, i64i32imm:$src), 983*9880d681SAndroid Build Coastguard Worker "#RELEASE_MOV64mi32 PSEUDO!", 984*9880d681SAndroid Build Coastguard Worker [(atomic_store_64 addr:$dst, i64immSExt32:$src)]>; 985*9880d681SAndroid Build Coastguard Worker 986*9880d681SAndroid Build Coastguard Workerdef RELEASE_MOV8mr : I<0, Pseudo, (outs), (ins i8mem :$dst, GR8 :$src), 987*9880d681SAndroid Build Coastguard Worker "#RELEASE_MOV8mr PSEUDO!", 988*9880d681SAndroid Build Coastguard Worker [(atomic_store_8 addr:$dst, GR8 :$src)]>; 989*9880d681SAndroid Build Coastguard Workerdef RELEASE_MOV16mr : I<0, Pseudo, (outs), (ins i16mem:$dst, GR16:$src), 990*9880d681SAndroid Build Coastguard Worker "#RELEASE_MOV16mr PSEUDO!", 991*9880d681SAndroid Build Coastguard Worker [(atomic_store_16 addr:$dst, GR16:$src)]>; 992*9880d681SAndroid Build Coastguard Workerdef RELEASE_MOV32mr : I<0, Pseudo, (outs), (ins i32mem:$dst, GR32:$src), 993*9880d681SAndroid Build Coastguard Worker "#RELEASE_MOV32mr PSEUDO!", 994*9880d681SAndroid Build Coastguard Worker [(atomic_store_32 addr:$dst, GR32:$src)]>; 995*9880d681SAndroid Build Coastguard Workerdef RELEASE_MOV64mr : I<0, Pseudo, (outs), (ins i64mem:$dst, GR64:$src), 996*9880d681SAndroid Build Coastguard Worker "#RELEASE_MOV64mr PSEUDO!", 997*9880d681SAndroid Build Coastguard Worker [(atomic_store_64 addr:$dst, GR64:$src)]>; 998*9880d681SAndroid Build Coastguard Worker 999*9880d681SAndroid Build Coastguard Workerdef ACQUIRE_MOV8rm : I<0, Pseudo, (outs GR8 :$dst), (ins i8mem :$src), 1000*9880d681SAndroid Build Coastguard Worker "#ACQUIRE_MOV8rm PSEUDO!", 1001*9880d681SAndroid Build Coastguard Worker [(set GR8:$dst, (atomic_load_8 addr:$src))]>; 1002*9880d681SAndroid Build Coastguard Workerdef ACQUIRE_MOV16rm : I<0, Pseudo, (outs GR16:$dst), (ins i16mem:$src), 1003*9880d681SAndroid Build Coastguard Worker "#ACQUIRE_MOV16rm PSEUDO!", 1004*9880d681SAndroid Build Coastguard Worker [(set GR16:$dst, (atomic_load_16 addr:$src))]>; 1005*9880d681SAndroid Build Coastguard Workerdef ACQUIRE_MOV32rm : I<0, Pseudo, (outs GR32:$dst), (ins i32mem:$src), 1006*9880d681SAndroid Build Coastguard Worker "#ACQUIRE_MOV32rm PSEUDO!", 1007*9880d681SAndroid Build Coastguard Worker [(set GR32:$dst, (atomic_load_32 addr:$src))]>; 1008*9880d681SAndroid Build Coastguard Workerdef ACQUIRE_MOV64rm : I<0, Pseudo, (outs GR64:$dst), (ins i64mem:$src), 1009*9880d681SAndroid Build Coastguard Worker "#ACQUIRE_MOV64rm PSEUDO!", 1010*9880d681SAndroid Build Coastguard Worker [(set GR64:$dst, (atomic_load_64 addr:$src))]>; 1011*9880d681SAndroid Build Coastguard Worker 1012*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 1013*9880d681SAndroid Build Coastguard Worker// DAG Pattern Matching Rules 1014*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 1015*9880d681SAndroid Build Coastguard Worker 1016*9880d681SAndroid Build Coastguard Worker// Use AND/OR to store 0/-1 in memory when optimizing for minsize. This saves 1017*9880d681SAndroid Build Coastguard Worker// binary size compared to a regular MOV, but it introduces an unnecessary 1018*9880d681SAndroid Build Coastguard Worker// load, so is not suitable for regular or optsize functions. 1019*9880d681SAndroid Build Coastguard Workerlet Predicates = [OptForMinSize] in { 1020*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (i16 0), addr:$dst), (AND16mi8 addr:$dst, 0)>; 1021*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (i32 0), addr:$dst), (AND32mi8 addr:$dst, 0)>; 1022*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (i64 0), addr:$dst), (AND64mi8 addr:$dst, 0)>; 1023*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (i16 -1), addr:$dst), (OR16mi8 addr:$dst, -1)>; 1024*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (i32 -1), addr:$dst), (OR32mi8 addr:$dst, -1)>; 1025*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (i64 -1), addr:$dst), (OR64mi8 addr:$dst, -1)>; 1026*9880d681SAndroid Build Coastguard Worker} 1027*9880d681SAndroid Build Coastguard Worker 1028*9880d681SAndroid Build Coastguard Worker// ConstantPool GlobalAddress, ExternalSymbol, and JumpTable 1029*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 (X86Wrapper tconstpool :$dst)), (MOV32ri tconstpool :$dst)>; 1030*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 (X86Wrapper tjumptable :$dst)), (MOV32ri tjumptable :$dst)>; 1031*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 (X86Wrapper tglobaltlsaddr:$dst)),(MOV32ri tglobaltlsaddr:$dst)>; 1032*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 (X86Wrapper tglobaladdr :$dst)), (MOV32ri tglobaladdr :$dst)>; 1033*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 (X86Wrapper texternalsym:$dst)), (MOV32ri texternalsym:$dst)>; 1034*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 (X86Wrapper mcsym:$dst)), (MOV32ri mcsym:$dst)>; 1035*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 (X86Wrapper tblockaddress:$dst)), (MOV32ri tblockaddress:$dst)>; 1036*9880d681SAndroid Build Coastguard Worker 1037*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR32:$src1, (X86Wrapper tconstpool:$src2)), 1038*9880d681SAndroid Build Coastguard Worker (ADD32ri GR32:$src1, tconstpool:$src2)>; 1039*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR32:$src1, (X86Wrapper tjumptable:$src2)), 1040*9880d681SAndroid Build Coastguard Worker (ADD32ri GR32:$src1, tjumptable:$src2)>; 1041*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR32:$src1, (X86Wrapper tglobaladdr :$src2)), 1042*9880d681SAndroid Build Coastguard Worker (ADD32ri GR32:$src1, tglobaladdr:$src2)>; 1043*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR32:$src1, (X86Wrapper texternalsym:$src2)), 1044*9880d681SAndroid Build Coastguard Worker (ADD32ri GR32:$src1, texternalsym:$src2)>; 1045*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR32:$src1, (X86Wrapper mcsym:$src2)), 1046*9880d681SAndroid Build Coastguard Worker (ADD32ri GR32:$src1, mcsym:$src2)>; 1047*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR32:$src1, (X86Wrapper tblockaddress:$src2)), 1048*9880d681SAndroid Build Coastguard Worker (ADD32ri GR32:$src1, tblockaddress:$src2)>; 1049*9880d681SAndroid Build Coastguard Worker 1050*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (i32 (X86Wrapper tglobaladdr:$src)), addr:$dst), 1051*9880d681SAndroid Build Coastguard Worker (MOV32mi addr:$dst, tglobaladdr:$src)>; 1052*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (i32 (X86Wrapper texternalsym:$src)), addr:$dst), 1053*9880d681SAndroid Build Coastguard Worker (MOV32mi addr:$dst, texternalsym:$src)>; 1054*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (i32 (X86Wrapper mcsym:$src)), addr:$dst), 1055*9880d681SAndroid Build Coastguard Worker (MOV32mi addr:$dst, mcsym:$src)>; 1056*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (i32 (X86Wrapper tblockaddress:$src)), addr:$dst), 1057*9880d681SAndroid Build Coastguard Worker (MOV32mi addr:$dst, tblockaddress:$src)>; 1058*9880d681SAndroid Build Coastguard Worker 1059*9880d681SAndroid Build Coastguard Worker// ConstantPool GlobalAddress, ExternalSymbol, and JumpTable when not in small 1060*9880d681SAndroid Build Coastguard Worker// code model mode, should use 'movabs'. FIXME: This is really a hack, the 1061*9880d681SAndroid Build Coastguard Worker// 'movabs' predicate should handle this sort of thing. 1062*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (X86Wrapper tconstpool :$dst)), 1063*9880d681SAndroid Build Coastguard Worker (MOV64ri tconstpool :$dst)>, Requires<[FarData]>; 1064*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (X86Wrapper tjumptable :$dst)), 1065*9880d681SAndroid Build Coastguard Worker (MOV64ri tjumptable :$dst)>, Requires<[FarData]>; 1066*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (X86Wrapper tglobaladdr :$dst)), 1067*9880d681SAndroid Build Coastguard Worker (MOV64ri tglobaladdr :$dst)>, Requires<[FarData]>; 1068*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (X86Wrapper texternalsym:$dst)), 1069*9880d681SAndroid Build Coastguard Worker (MOV64ri texternalsym:$dst)>, Requires<[FarData]>; 1070*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (X86Wrapper mcsym:$dst)), 1071*9880d681SAndroid Build Coastguard Worker (MOV64ri mcsym:$dst)>, Requires<[FarData]>; 1072*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (X86Wrapper tblockaddress:$dst)), 1073*9880d681SAndroid Build Coastguard Worker (MOV64ri tblockaddress:$dst)>, Requires<[FarData]>; 1074*9880d681SAndroid Build Coastguard Worker 1075*9880d681SAndroid Build Coastguard Worker// In kernel code model, we can get the address of a label 1076*9880d681SAndroid Build Coastguard Worker// into a register with 'movq'. FIXME: This is a hack, the 'imm' predicate of 1077*9880d681SAndroid Build Coastguard Worker// the MOV64ri32 should accept these. 1078*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (X86Wrapper tconstpool :$dst)), 1079*9880d681SAndroid Build Coastguard Worker (MOV64ri32 tconstpool :$dst)>, Requires<[KernelCode]>; 1080*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (X86Wrapper tjumptable :$dst)), 1081*9880d681SAndroid Build Coastguard Worker (MOV64ri32 tjumptable :$dst)>, Requires<[KernelCode]>; 1082*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (X86Wrapper tglobaladdr :$dst)), 1083*9880d681SAndroid Build Coastguard Worker (MOV64ri32 tglobaladdr :$dst)>, Requires<[KernelCode]>; 1084*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (X86Wrapper texternalsym:$dst)), 1085*9880d681SAndroid Build Coastguard Worker (MOV64ri32 texternalsym:$dst)>, Requires<[KernelCode]>; 1086*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (X86Wrapper mcsym:$dst)), 1087*9880d681SAndroid Build Coastguard Worker (MOV64ri32 mcsym:$dst)>, Requires<[KernelCode]>; 1088*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (X86Wrapper tblockaddress:$dst)), 1089*9880d681SAndroid Build Coastguard Worker (MOV64ri32 tblockaddress:$dst)>, Requires<[KernelCode]>; 1090*9880d681SAndroid Build Coastguard Worker 1091*9880d681SAndroid Build Coastguard Worker// If we have small model and -static mode, it is safe to store global addresses 1092*9880d681SAndroid Build Coastguard Worker// directly as immediates. FIXME: This is really a hack, the 'imm' predicate 1093*9880d681SAndroid Build Coastguard Worker// for MOV64mi32 should handle this sort of thing. 1094*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (i64 (X86Wrapper tconstpool:$src)), addr:$dst), 1095*9880d681SAndroid Build Coastguard Worker (MOV64mi32 addr:$dst, tconstpool:$src)>, 1096*9880d681SAndroid Build Coastguard Worker Requires<[NearData, IsNotPIC]>; 1097*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (i64 (X86Wrapper tjumptable:$src)), addr:$dst), 1098*9880d681SAndroid Build Coastguard Worker (MOV64mi32 addr:$dst, tjumptable:$src)>, 1099*9880d681SAndroid Build Coastguard Worker Requires<[NearData, IsNotPIC]>; 1100*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (i64 (X86Wrapper tglobaladdr:$src)), addr:$dst), 1101*9880d681SAndroid Build Coastguard Worker (MOV64mi32 addr:$dst, tglobaladdr:$src)>, 1102*9880d681SAndroid Build Coastguard Worker Requires<[NearData, IsNotPIC]>; 1103*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (i64 (X86Wrapper texternalsym:$src)), addr:$dst), 1104*9880d681SAndroid Build Coastguard Worker (MOV64mi32 addr:$dst, texternalsym:$src)>, 1105*9880d681SAndroid Build Coastguard Worker Requires<[NearData, IsNotPIC]>; 1106*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (i64 (X86Wrapper mcsym:$src)), addr:$dst), 1107*9880d681SAndroid Build Coastguard Worker (MOV64mi32 addr:$dst, mcsym:$src)>, 1108*9880d681SAndroid Build Coastguard Worker Requires<[NearData, IsNotPIC]>; 1109*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (i64 (X86Wrapper tblockaddress:$src)), addr:$dst), 1110*9880d681SAndroid Build Coastguard Worker (MOV64mi32 addr:$dst, tblockaddress:$src)>, 1111*9880d681SAndroid Build Coastguard Worker Requires<[NearData, IsNotPIC]>; 1112*9880d681SAndroid Build Coastguard Worker 1113*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 (X86RecoverFrameAlloc mcsym:$dst)), (MOV32ri mcsym:$dst)>; 1114*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (X86RecoverFrameAlloc mcsym:$dst)), (MOV64ri mcsym:$dst)>; 1115*9880d681SAndroid Build Coastguard Worker 1116*9880d681SAndroid Build Coastguard Worker// Calls 1117*9880d681SAndroid Build Coastguard Worker 1118*9880d681SAndroid Build Coastguard Worker// tls has some funny stuff here... 1119*9880d681SAndroid Build Coastguard Worker// This corresponds to movabs $foo@tpoff, %rax 1120*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (X86Wrapper tglobaltlsaddr :$dst)), 1121*9880d681SAndroid Build Coastguard Worker (MOV64ri32 tglobaltlsaddr :$dst)>; 1122*9880d681SAndroid Build Coastguard Worker// This corresponds to add $foo@tpoff, %rax 1123*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR64:$src1, (X86Wrapper tglobaltlsaddr :$dst)), 1124*9880d681SAndroid Build Coastguard Worker (ADD64ri32 GR64:$src1, tglobaltlsaddr :$dst)>; 1125*9880d681SAndroid Build Coastguard Worker 1126*9880d681SAndroid Build Coastguard Worker 1127*9880d681SAndroid Build Coastguard Worker// Direct PC relative function call for small code model. 32-bit displacement 1128*9880d681SAndroid Build Coastguard Worker// sign extended to 64-bit. 1129*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86call (i64 tglobaladdr:$dst)), 1130*9880d681SAndroid Build Coastguard Worker (CALL64pcrel32 tglobaladdr:$dst)>; 1131*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86call (i64 texternalsym:$dst)), 1132*9880d681SAndroid Build Coastguard Worker (CALL64pcrel32 texternalsym:$dst)>; 1133*9880d681SAndroid Build Coastguard Worker 1134*9880d681SAndroid Build Coastguard Worker// Tailcall stuff. The TCRETURN instructions execute after the epilog, so they 1135*9880d681SAndroid Build Coastguard Worker// can never use callee-saved registers. That is the purpose of the GR64_TC 1136*9880d681SAndroid Build Coastguard Worker// register classes. 1137*9880d681SAndroid Build Coastguard Worker// 1138*9880d681SAndroid Build Coastguard Worker// The only volatile register that is never used by the calling convention is 1139*9880d681SAndroid Build Coastguard Worker// %r11. This happens when calling a vararg function with 6 arguments. 1140*9880d681SAndroid Build Coastguard Worker// 1141*9880d681SAndroid Build Coastguard Worker// Match an X86tcret that uses less than 7 volatile registers. 1142*9880d681SAndroid Build Coastguard Workerdef X86tcret_6regs : PatFrag<(ops node:$ptr, node:$off), 1143*9880d681SAndroid Build Coastguard Worker (X86tcret node:$ptr, node:$off), [{ 1144*9880d681SAndroid Build Coastguard Worker // X86tcret args: (*chain, ptr, imm, regs..., glue) 1145*9880d681SAndroid Build Coastguard Worker unsigned NumRegs = 0; 1146*9880d681SAndroid Build Coastguard Worker for (unsigned i = 3, e = N->getNumOperands(); i != e; ++i) 1147*9880d681SAndroid Build Coastguard Worker if (isa<RegisterSDNode>(N->getOperand(i)) && ++NumRegs > 6) 1148*9880d681SAndroid Build Coastguard Worker return false; 1149*9880d681SAndroid Build Coastguard Worker return true; 1150*9880d681SAndroid Build Coastguard Worker}]>; 1151*9880d681SAndroid Build Coastguard Worker 1152*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86tcret ptr_rc_tailcall:$dst, imm:$off), 1153*9880d681SAndroid Build Coastguard Worker (TCRETURNri ptr_rc_tailcall:$dst, imm:$off)>, 1154*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 1155*9880d681SAndroid Build Coastguard Worker 1156*9880d681SAndroid Build Coastguard Worker// FIXME: This is disabled for 32-bit PIC mode because the global base 1157*9880d681SAndroid Build Coastguard Worker// register which is part of the address mode may be assigned a 1158*9880d681SAndroid Build Coastguard Worker// callee-saved register. 1159*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86tcret (load addr:$dst), imm:$off), 1160*9880d681SAndroid Build Coastguard Worker (TCRETURNmi addr:$dst, imm:$off)>, 1161*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode, IsNotPIC]>; 1162*9880d681SAndroid Build Coastguard Worker 1163*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86tcret (i32 tglobaladdr:$dst), imm:$off), 1164*9880d681SAndroid Build Coastguard Worker (TCRETURNdi tglobaladdr:$dst, imm:$off)>, 1165*9880d681SAndroid Build Coastguard Worker Requires<[NotLP64]>; 1166*9880d681SAndroid Build Coastguard Worker 1167*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86tcret (i32 texternalsym:$dst), imm:$off), 1168*9880d681SAndroid Build Coastguard Worker (TCRETURNdi texternalsym:$dst, imm:$off)>, 1169*9880d681SAndroid Build Coastguard Worker Requires<[NotLP64]>; 1170*9880d681SAndroid Build Coastguard Worker 1171*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86tcret ptr_rc_tailcall:$dst, imm:$off), 1172*9880d681SAndroid Build Coastguard Worker (TCRETURNri64 ptr_rc_tailcall:$dst, imm:$off)>, 1173*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 1174*9880d681SAndroid Build Coastguard Worker 1175*9880d681SAndroid Build Coastguard Worker// Don't fold loads into X86tcret requiring more than 6 regs. 1176*9880d681SAndroid Build Coastguard Worker// There wouldn't be enough scratch registers for base+index. 1177*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86tcret_6regs (load addr:$dst), imm:$off), 1178*9880d681SAndroid Build Coastguard Worker (TCRETURNmi64 addr:$dst, imm:$off)>, 1179*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 1180*9880d681SAndroid Build Coastguard Worker 1181*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86tcret (i64 tglobaladdr:$dst), imm:$off), 1182*9880d681SAndroid Build Coastguard Worker (TCRETURNdi64 tglobaladdr:$dst, imm:$off)>, 1183*9880d681SAndroid Build Coastguard Worker Requires<[IsLP64]>; 1184*9880d681SAndroid Build Coastguard Worker 1185*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86tcret (i64 texternalsym:$dst), imm:$off), 1186*9880d681SAndroid Build Coastguard Worker (TCRETURNdi64 texternalsym:$dst, imm:$off)>, 1187*9880d681SAndroid Build Coastguard Worker Requires<[IsLP64]>; 1188*9880d681SAndroid Build Coastguard Worker 1189*9880d681SAndroid Build Coastguard Worker// Normal calls, with various flavors of addresses. 1190*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86call (i32 tglobaladdr:$dst)), 1191*9880d681SAndroid Build Coastguard Worker (CALLpcrel32 tglobaladdr:$dst)>; 1192*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86call (i32 texternalsym:$dst)), 1193*9880d681SAndroid Build Coastguard Worker (CALLpcrel32 texternalsym:$dst)>; 1194*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86call (i32 imm:$dst)), 1195*9880d681SAndroid Build Coastguard Worker (CALLpcrel32 imm:$dst)>, Requires<[CallImmAddr]>; 1196*9880d681SAndroid Build Coastguard Worker 1197*9880d681SAndroid Build Coastguard Worker// Comparisons. 1198*9880d681SAndroid Build Coastguard Worker 1199*9880d681SAndroid Build Coastguard Worker// TEST R,R is smaller than CMP R,0 1200*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86cmp GR8:$src1, 0), 1201*9880d681SAndroid Build Coastguard Worker (TEST8rr GR8:$src1, GR8:$src1)>; 1202*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86cmp GR16:$src1, 0), 1203*9880d681SAndroid Build Coastguard Worker (TEST16rr GR16:$src1, GR16:$src1)>; 1204*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86cmp GR32:$src1, 0), 1205*9880d681SAndroid Build Coastguard Worker (TEST32rr GR32:$src1, GR32:$src1)>; 1206*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86cmp GR64:$src1, 0), 1207*9880d681SAndroid Build Coastguard Worker (TEST64rr GR64:$src1, GR64:$src1)>; 1208*9880d681SAndroid Build Coastguard Worker 1209*9880d681SAndroid Build Coastguard Worker// Conditional moves with folded loads with operands swapped and conditions 1210*9880d681SAndroid Build Coastguard Worker// inverted. 1211*9880d681SAndroid Build Coastguard Workermulticlass CMOVmr<PatLeaf InvertedCond, Instruction Inst16, Instruction Inst32, 1212*9880d681SAndroid Build Coastguard Worker Instruction Inst64> { 1213*9880d681SAndroid Build Coastguard Worker let Predicates = [HasCMov] in { 1214*9880d681SAndroid Build Coastguard Worker def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, InvertedCond, EFLAGS), 1215*9880d681SAndroid Build Coastguard Worker (Inst16 GR16:$src2, addr:$src1)>; 1216*9880d681SAndroid Build Coastguard Worker def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, InvertedCond, EFLAGS), 1217*9880d681SAndroid Build Coastguard Worker (Inst32 GR32:$src2, addr:$src1)>; 1218*9880d681SAndroid Build Coastguard Worker def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, InvertedCond, EFLAGS), 1219*9880d681SAndroid Build Coastguard Worker (Inst64 GR64:$src2, addr:$src1)>; 1220*9880d681SAndroid Build Coastguard Worker } 1221*9880d681SAndroid Build Coastguard Worker} 1222*9880d681SAndroid Build Coastguard Worker 1223*9880d681SAndroid Build Coastguard Workerdefm : CMOVmr<X86_COND_B , CMOVAE16rm, CMOVAE32rm, CMOVAE64rm>; 1224*9880d681SAndroid Build Coastguard Workerdefm : CMOVmr<X86_COND_AE, CMOVB16rm , CMOVB32rm , CMOVB64rm>; 1225*9880d681SAndroid Build Coastguard Workerdefm : CMOVmr<X86_COND_E , CMOVNE16rm, CMOVNE32rm, CMOVNE64rm>; 1226*9880d681SAndroid Build Coastguard Workerdefm : CMOVmr<X86_COND_NE, CMOVE16rm , CMOVE32rm , CMOVE64rm>; 1227*9880d681SAndroid Build Coastguard Workerdefm : CMOVmr<X86_COND_BE, CMOVA16rm , CMOVA32rm , CMOVA64rm>; 1228*9880d681SAndroid Build Coastguard Workerdefm : CMOVmr<X86_COND_A , CMOVBE16rm, CMOVBE32rm, CMOVBE64rm>; 1229*9880d681SAndroid Build Coastguard Workerdefm : CMOVmr<X86_COND_L , CMOVGE16rm, CMOVGE32rm, CMOVGE64rm>; 1230*9880d681SAndroid Build Coastguard Workerdefm : CMOVmr<X86_COND_GE, CMOVL16rm , CMOVL32rm , CMOVL64rm>; 1231*9880d681SAndroid Build Coastguard Workerdefm : CMOVmr<X86_COND_LE, CMOVG16rm , CMOVG32rm , CMOVG64rm>; 1232*9880d681SAndroid Build Coastguard Workerdefm : CMOVmr<X86_COND_G , CMOVLE16rm, CMOVLE32rm, CMOVLE64rm>; 1233*9880d681SAndroid Build Coastguard Workerdefm : CMOVmr<X86_COND_P , CMOVNP16rm, CMOVNP32rm, CMOVNP64rm>; 1234*9880d681SAndroid Build Coastguard Workerdefm : CMOVmr<X86_COND_NP, CMOVP16rm , CMOVP32rm , CMOVP64rm>; 1235*9880d681SAndroid Build Coastguard Workerdefm : CMOVmr<X86_COND_S , CMOVNS16rm, CMOVNS32rm, CMOVNS64rm>; 1236*9880d681SAndroid Build Coastguard Workerdefm : CMOVmr<X86_COND_NS, CMOVS16rm , CMOVS32rm , CMOVS64rm>; 1237*9880d681SAndroid Build Coastguard Workerdefm : CMOVmr<X86_COND_O , CMOVNO16rm, CMOVNO32rm, CMOVNO64rm>; 1238*9880d681SAndroid Build Coastguard Workerdefm : CMOVmr<X86_COND_NO, CMOVO16rm , CMOVO32rm , CMOVO64rm>; 1239*9880d681SAndroid Build Coastguard Worker 1240*9880d681SAndroid Build Coastguard Worker// zextload bool -> zextload byte 1241*9880d681SAndroid Build Coastguard Worker// i1 stored in one byte in zero-extended form. 1242*9880d681SAndroid Build Coastguard Worker// Upper bits cleanup should be executed before Store. 1243*9880d681SAndroid Build Coastguard Workerdef : Pat<(zextloadi8i1 addr:$src), (MOV8rm addr:$src)>; 1244*9880d681SAndroid Build Coastguard Workerdef : Pat<(zextloadi16i1 addr:$src), (MOVZX16rm8 addr:$src)>; 1245*9880d681SAndroid Build Coastguard Workerdef : Pat<(zextloadi32i1 addr:$src), (MOVZX32rm8 addr:$src)>; 1246*9880d681SAndroid Build Coastguard Workerdef : Pat<(zextloadi64i1 addr:$src), 1247*9880d681SAndroid Build Coastguard Worker (SUBREG_TO_REG (i64 0), (MOVZX32rm8 addr:$src), sub_32bit)>; 1248*9880d681SAndroid Build Coastguard Worker 1249*9880d681SAndroid Build Coastguard Worker// extload bool -> extload byte 1250*9880d681SAndroid Build Coastguard Worker// When extloading from 16-bit and smaller memory locations into 64-bit 1251*9880d681SAndroid Build Coastguard Worker// registers, use zero-extending loads so that the entire 64-bit register is 1252*9880d681SAndroid Build Coastguard Worker// defined, avoiding partial-register updates. 1253*9880d681SAndroid Build Coastguard Worker 1254*9880d681SAndroid Build Coastguard Workerdef : Pat<(extloadi8i1 addr:$src), (MOV8rm addr:$src)>; 1255*9880d681SAndroid Build Coastguard Workerdef : Pat<(extloadi16i1 addr:$src), (MOVZX16rm8 addr:$src)>; 1256*9880d681SAndroid Build Coastguard Workerdef : Pat<(extloadi32i1 addr:$src), (MOVZX32rm8 addr:$src)>; 1257*9880d681SAndroid Build Coastguard Workerdef : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>; 1258*9880d681SAndroid Build Coastguard Workerdef : Pat<(extloadi32i8 addr:$src), (MOVZX32rm8 addr:$src)>; 1259*9880d681SAndroid Build Coastguard Workerdef : Pat<(extloadi32i16 addr:$src), (MOVZX32rm16 addr:$src)>; 1260*9880d681SAndroid Build Coastguard Worker 1261*9880d681SAndroid Build Coastguard Worker// For other extloads, use subregs, since the high contents of the register are 1262*9880d681SAndroid Build Coastguard Worker// defined after an extload. 1263*9880d681SAndroid Build Coastguard Workerdef : Pat<(extloadi64i1 addr:$src), 1264*9880d681SAndroid Build Coastguard Worker (SUBREG_TO_REG (i64 0), (MOVZX32rm8 addr:$src), sub_32bit)>; 1265*9880d681SAndroid Build Coastguard Workerdef : Pat<(extloadi64i8 addr:$src), 1266*9880d681SAndroid Build Coastguard Worker (SUBREG_TO_REG (i64 0), (MOVZX32rm8 addr:$src), sub_32bit)>; 1267*9880d681SAndroid Build Coastguard Workerdef : Pat<(extloadi64i16 addr:$src), 1268*9880d681SAndroid Build Coastguard Worker (SUBREG_TO_REG (i64 0), (MOVZX32rm16 addr:$src), sub_32bit)>; 1269*9880d681SAndroid Build Coastguard Workerdef : Pat<(extloadi64i32 addr:$src), 1270*9880d681SAndroid Build Coastguard Worker (SUBREG_TO_REG (i64 0), (MOV32rm addr:$src), sub_32bit)>; 1271*9880d681SAndroid Build Coastguard Worker 1272*9880d681SAndroid Build Coastguard Worker// anyext. Define these to do an explicit zero-extend to 1273*9880d681SAndroid Build Coastguard Worker// avoid partial-register updates. 1274*9880d681SAndroid Build Coastguard Workerdef : Pat<(i16 (anyext GR8 :$src)), (EXTRACT_SUBREG 1275*9880d681SAndroid Build Coastguard Worker (MOVZX32rr8 GR8 :$src), sub_16bit)>; 1276*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 (anyext GR8 :$src)), (MOVZX32rr8 GR8 :$src)>; 1277*9880d681SAndroid Build Coastguard Worker 1278*9880d681SAndroid Build Coastguard Worker// Except for i16 -> i32 since isel expect i16 ops to be promoted to i32. 1279*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 (anyext GR16:$src)), 1280*9880d681SAndroid Build Coastguard Worker (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR16:$src, sub_16bit)>; 1281*9880d681SAndroid Build Coastguard Worker 1282*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (anyext GR8 :$src)), 1283*9880d681SAndroid Build Coastguard Worker (SUBREG_TO_REG (i64 0), (MOVZX32rr8 GR8 :$src), sub_32bit)>; 1284*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (anyext GR16:$src)), 1285*9880d681SAndroid Build Coastguard Worker (SUBREG_TO_REG (i64 0), (MOVZX32rr16 GR16 :$src), sub_32bit)>; 1286*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (anyext GR32:$src)), 1287*9880d681SAndroid Build Coastguard Worker (SUBREG_TO_REG (i64 0), GR32:$src, sub_32bit)>; 1288*9880d681SAndroid Build Coastguard Worker 1289*9880d681SAndroid Build Coastguard Worker 1290*9880d681SAndroid Build Coastguard Worker// Any instruction that defines a 32-bit result leaves the high half of the 1291*9880d681SAndroid Build Coastguard Worker// register. Truncate can be lowered to EXTRACT_SUBREG. CopyFromReg may 1292*9880d681SAndroid Build Coastguard Worker// be copying from a truncate. And x86's cmov doesn't do anything if the 1293*9880d681SAndroid Build Coastguard Worker// condition is false. But any other 32-bit operation will zero-extend 1294*9880d681SAndroid Build Coastguard Worker// up to 64 bits. 1295*9880d681SAndroid Build Coastguard Workerdef def32 : PatLeaf<(i32 GR32:$src), [{ 1296*9880d681SAndroid Build Coastguard Worker return N->getOpcode() != ISD::TRUNCATE && 1297*9880d681SAndroid Build Coastguard Worker N->getOpcode() != TargetOpcode::EXTRACT_SUBREG && 1298*9880d681SAndroid Build Coastguard Worker N->getOpcode() != ISD::CopyFromReg && 1299*9880d681SAndroid Build Coastguard Worker N->getOpcode() != ISD::AssertSext && 1300*9880d681SAndroid Build Coastguard Worker N->getOpcode() != X86ISD::CMOV; 1301*9880d681SAndroid Build Coastguard Worker}]>; 1302*9880d681SAndroid Build Coastguard Worker 1303*9880d681SAndroid Build Coastguard Worker// In the case of a 32-bit def that is known to implicitly zero-extend, 1304*9880d681SAndroid Build Coastguard Worker// we can use a SUBREG_TO_REG. 1305*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (zext def32:$src)), 1306*9880d681SAndroid Build Coastguard Worker (SUBREG_TO_REG (i64 0), GR32:$src, sub_32bit)>; 1307*9880d681SAndroid Build Coastguard Worker 1308*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 1309*9880d681SAndroid Build Coastguard Worker// Pattern match OR as ADD 1310*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 1311*9880d681SAndroid Build Coastguard Worker 1312*9880d681SAndroid Build Coastguard Worker// If safe, we prefer to pattern match OR as ADD at isel time. ADD can be 1313*9880d681SAndroid Build Coastguard Worker// 3-addressified into an LEA instruction to avoid copies. However, we also 1314*9880d681SAndroid Build Coastguard Worker// want to finally emit these instructions as an or at the end of the code 1315*9880d681SAndroid Build Coastguard Worker// generator to make the generated code easier to read. To do this, we select 1316*9880d681SAndroid Build Coastguard Worker// into "disjoint bits" pseudo ops. 1317*9880d681SAndroid Build Coastguard Worker 1318*9880d681SAndroid Build Coastguard Worker// Treat an 'or' node is as an 'add' if the or'ed bits are known to be zero. 1319*9880d681SAndroid Build Coastguard Workerdef or_is_add : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs),[{ 1320*9880d681SAndroid Build Coastguard Worker if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1))) 1321*9880d681SAndroid Build Coastguard Worker return CurDAG->MaskedValueIsZero(N->getOperand(0), CN->getAPIntValue()); 1322*9880d681SAndroid Build Coastguard Worker 1323*9880d681SAndroid Build Coastguard Worker APInt KnownZero0, KnownOne0; 1324*9880d681SAndroid Build Coastguard Worker CurDAG->computeKnownBits(N->getOperand(0), KnownZero0, KnownOne0, 0); 1325*9880d681SAndroid Build Coastguard Worker APInt KnownZero1, KnownOne1; 1326*9880d681SAndroid Build Coastguard Worker CurDAG->computeKnownBits(N->getOperand(1), KnownZero1, KnownOne1, 0); 1327*9880d681SAndroid Build Coastguard Worker return (~KnownZero0 & ~KnownZero1) == 0; 1328*9880d681SAndroid Build Coastguard Worker}]>; 1329*9880d681SAndroid Build Coastguard Worker 1330*9880d681SAndroid Build Coastguard Worker 1331*9880d681SAndroid Build Coastguard Worker// (or x1, x2) -> (add x1, x2) if two operands are known not to share bits. 1332*9880d681SAndroid Build Coastguard Worker// Try this before the selecting to OR. 1333*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 5, SchedRW = [WriteALU] in { 1334*9880d681SAndroid Build Coastguard Worker 1335*9880d681SAndroid Build Coastguard Workerlet isConvertibleToThreeAddress = 1, 1336*9880d681SAndroid Build Coastguard Worker Constraints = "$src1 = $dst", Defs = [EFLAGS] in { 1337*9880d681SAndroid Build Coastguard Workerlet isCommutable = 1 in { 1338*9880d681SAndroid Build Coastguard Workerdef ADD16rr_DB : I<0, Pseudo, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), 1339*9880d681SAndroid Build Coastguard Worker "", // orw/addw REG, REG 1340*9880d681SAndroid Build Coastguard Worker [(set GR16:$dst, (or_is_add GR16:$src1, GR16:$src2))]>; 1341*9880d681SAndroid Build Coastguard Workerdef ADD32rr_DB : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), 1342*9880d681SAndroid Build Coastguard Worker "", // orl/addl REG, REG 1343*9880d681SAndroid Build Coastguard Worker [(set GR32:$dst, (or_is_add GR32:$src1, GR32:$src2))]>; 1344*9880d681SAndroid Build Coastguard Workerdef ADD64rr_DB : I<0, Pseudo, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), 1345*9880d681SAndroid Build Coastguard Worker "", // orq/addq REG, REG 1346*9880d681SAndroid Build Coastguard Worker [(set GR64:$dst, (or_is_add GR64:$src1, GR64:$src2))]>; 1347*9880d681SAndroid Build Coastguard Worker} // isCommutable 1348*9880d681SAndroid Build Coastguard Worker 1349*9880d681SAndroid Build Coastguard Worker// NOTE: These are order specific, we want the ri8 forms to be listed 1350*9880d681SAndroid Build Coastguard Worker// first so that they are slightly preferred to the ri forms. 1351*9880d681SAndroid Build Coastguard Worker 1352*9880d681SAndroid Build Coastguard Workerdef ADD16ri8_DB : I<0, Pseudo, 1353*9880d681SAndroid Build Coastguard Worker (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2), 1354*9880d681SAndroid Build Coastguard Worker "", // orw/addw REG, imm8 1355*9880d681SAndroid Build Coastguard Worker [(set GR16:$dst,(or_is_add GR16:$src1,i16immSExt8:$src2))]>; 1356*9880d681SAndroid Build Coastguard Workerdef ADD16ri_DB : I<0, Pseudo, (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2), 1357*9880d681SAndroid Build Coastguard Worker "", // orw/addw REG, imm 1358*9880d681SAndroid Build Coastguard Worker [(set GR16:$dst, (or_is_add GR16:$src1, imm:$src2))]>; 1359*9880d681SAndroid Build Coastguard Worker 1360*9880d681SAndroid Build Coastguard Workerdef ADD32ri8_DB : I<0, Pseudo, 1361*9880d681SAndroid Build Coastguard Worker (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2), 1362*9880d681SAndroid Build Coastguard Worker "", // orl/addl REG, imm8 1363*9880d681SAndroid Build Coastguard Worker [(set GR32:$dst,(or_is_add GR32:$src1,i32immSExt8:$src2))]>; 1364*9880d681SAndroid Build Coastguard Workerdef ADD32ri_DB : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2), 1365*9880d681SAndroid Build Coastguard Worker "", // orl/addl REG, imm 1366*9880d681SAndroid Build Coastguard Worker [(set GR32:$dst, (or_is_add GR32:$src1, imm:$src2))]>; 1367*9880d681SAndroid Build Coastguard Worker 1368*9880d681SAndroid Build Coastguard Worker 1369*9880d681SAndroid Build Coastguard Workerdef ADD64ri8_DB : I<0, Pseudo, 1370*9880d681SAndroid Build Coastguard Worker (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), 1371*9880d681SAndroid Build Coastguard Worker "", // orq/addq REG, imm8 1372*9880d681SAndroid Build Coastguard Worker [(set GR64:$dst, (or_is_add GR64:$src1, 1373*9880d681SAndroid Build Coastguard Worker i64immSExt8:$src2))]>; 1374*9880d681SAndroid Build Coastguard Workerdef ADD64ri32_DB : I<0, Pseudo, 1375*9880d681SAndroid Build Coastguard Worker (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2), 1376*9880d681SAndroid Build Coastguard Worker "", // orq/addq REG, imm 1377*9880d681SAndroid Build Coastguard Worker [(set GR64:$dst, (or_is_add GR64:$src1, 1378*9880d681SAndroid Build Coastguard Worker i64immSExt32:$src2))]>; 1379*9880d681SAndroid Build Coastguard Worker} 1380*9880d681SAndroid Build Coastguard Worker} // AddedComplexity, SchedRW 1381*9880d681SAndroid Build Coastguard Worker 1382*9880d681SAndroid Build Coastguard Worker 1383*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 1384*9880d681SAndroid Build Coastguard Worker// Some peepholes 1385*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 1386*9880d681SAndroid Build Coastguard Worker 1387*9880d681SAndroid Build Coastguard Worker// Odd encoding trick: -128 fits into an 8-bit immediate field while 1388*9880d681SAndroid Build Coastguard Worker// +128 doesn't, so in this special case use a sub instead of an add. 1389*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR16:$src1, 128), 1390*9880d681SAndroid Build Coastguard Worker (SUB16ri8 GR16:$src1, -128)>; 1391*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (add (loadi16 addr:$dst), 128), addr:$dst), 1392*9880d681SAndroid Build Coastguard Worker (SUB16mi8 addr:$dst, -128)>; 1393*9880d681SAndroid Build Coastguard Worker 1394*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR32:$src1, 128), 1395*9880d681SAndroid Build Coastguard Worker (SUB32ri8 GR32:$src1, -128)>; 1396*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (add (loadi32 addr:$dst), 128), addr:$dst), 1397*9880d681SAndroid Build Coastguard Worker (SUB32mi8 addr:$dst, -128)>; 1398*9880d681SAndroid Build Coastguard Worker 1399*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR64:$src1, 128), 1400*9880d681SAndroid Build Coastguard Worker (SUB64ri8 GR64:$src1, -128)>; 1401*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (add (loadi64 addr:$dst), 128), addr:$dst), 1402*9880d681SAndroid Build Coastguard Worker (SUB64mi8 addr:$dst, -128)>; 1403*9880d681SAndroid Build Coastguard Worker 1404*9880d681SAndroid Build Coastguard Worker// The same trick applies for 32-bit immediate fields in 64-bit 1405*9880d681SAndroid Build Coastguard Worker// instructions. 1406*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR64:$src1, 0x0000000080000000), 1407*9880d681SAndroid Build Coastguard Worker (SUB64ri32 GR64:$src1, 0xffffffff80000000)>; 1408*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (add (loadi64 addr:$dst), 0x0000000080000000), addr:$dst), 1409*9880d681SAndroid Build Coastguard Worker (SUB64mi32 addr:$dst, 0xffffffff80000000)>; 1410*9880d681SAndroid Build Coastguard Worker 1411*9880d681SAndroid Build Coastguard Worker// To avoid needing to materialize an immediate in a register, use a 32-bit and 1412*9880d681SAndroid Build Coastguard Worker// with implicit zero-extension instead of a 64-bit and if the immediate has at 1413*9880d681SAndroid Build Coastguard Worker// least 32 bits of leading zeros. If in addition the last 32 bits can be 1414*9880d681SAndroid Build Coastguard Worker// represented with a sign extension of a 8 bit constant, use that. 1415*9880d681SAndroid Build Coastguard Worker// This can also reduce instruction size by eliminating the need for the REX 1416*9880d681SAndroid Build Coastguard Worker// prefix. 1417*9880d681SAndroid Build Coastguard Worker 1418*9880d681SAndroid Build Coastguard Worker// AddedComplexity is needed to give priority over i64immSExt8 and i64immSExt32. 1419*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 1 in { 1420*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR64:$src, i64immZExt32SExt8:$imm), 1421*9880d681SAndroid Build Coastguard Worker (SUBREG_TO_REG 1422*9880d681SAndroid Build Coastguard Worker (i64 0), 1423*9880d681SAndroid Build Coastguard Worker (AND32ri8 1424*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG GR64:$src, sub_32bit), 1425*9880d681SAndroid Build Coastguard Worker (i32 (GetLo8XForm imm:$imm))), 1426*9880d681SAndroid Build Coastguard Worker sub_32bit)>; 1427*9880d681SAndroid Build Coastguard Worker 1428*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR64:$src, i64immZExt32:$imm), 1429*9880d681SAndroid Build Coastguard Worker (SUBREG_TO_REG 1430*9880d681SAndroid Build Coastguard Worker (i64 0), 1431*9880d681SAndroid Build Coastguard Worker (AND32ri 1432*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG GR64:$src, sub_32bit), 1433*9880d681SAndroid Build Coastguard Worker (i32 (GetLo32XForm imm:$imm))), 1434*9880d681SAndroid Build Coastguard Worker sub_32bit)>; 1435*9880d681SAndroid Build Coastguard Worker} // AddedComplexity = 1 1436*9880d681SAndroid Build Coastguard Worker 1437*9880d681SAndroid Build Coastguard Worker 1438*9880d681SAndroid Build Coastguard Worker// AddedComplexity is needed due to the increased complexity on the 1439*9880d681SAndroid Build Coastguard Worker// i64immZExt32SExt8 and i64immZExt32 patterns above. Applying this to all 1440*9880d681SAndroid Build Coastguard Worker// the MOVZX patterns keeps thems together in DAGIsel tables. 1441*9880d681SAndroid Build Coastguard Workerlet AddedComplexity = 1 in { 1442*9880d681SAndroid Build Coastguard Worker// r & (2^16-1) ==> movz 1443*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR32:$src1, 0xffff), 1444*9880d681SAndroid Build Coastguard Worker (MOVZX32rr16 (EXTRACT_SUBREG GR32:$src1, sub_16bit))>; 1445*9880d681SAndroid Build Coastguard Worker// r & (2^8-1) ==> movz 1446*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR32:$src1, 0xff), 1447*9880d681SAndroid Build Coastguard Worker (MOVZX32rr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src1, 1448*9880d681SAndroid Build Coastguard Worker GR32_ABCD)), 1449*9880d681SAndroid Build Coastguard Worker sub_8bit))>, 1450*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 1451*9880d681SAndroid Build Coastguard Worker// r & (2^8-1) ==> movz 1452*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR16:$src1, 0xff), 1453*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (MOVZX32rr8 (EXTRACT_SUBREG 1454*9880d681SAndroid Build Coastguard Worker (i16 (COPY_TO_REGCLASS GR16:$src1, GR16_ABCD)), sub_8bit)), 1455*9880d681SAndroid Build Coastguard Worker sub_16bit)>, 1456*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 1457*9880d681SAndroid Build Coastguard Worker 1458*9880d681SAndroid Build Coastguard Worker// r & (2^32-1) ==> movz 1459*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR64:$src, 0x00000000FFFFFFFF), 1460*9880d681SAndroid Build Coastguard Worker (SUBREG_TO_REG (i64 0), 1461*9880d681SAndroid Build Coastguard Worker (MOV32rr (EXTRACT_SUBREG GR64:$src, sub_32bit)), 1462*9880d681SAndroid Build Coastguard Worker sub_32bit)>; 1463*9880d681SAndroid Build Coastguard Worker// r & (2^16-1) ==> movz 1464*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR64:$src, 0xffff), 1465*9880d681SAndroid Build Coastguard Worker (SUBREG_TO_REG (i64 0), 1466*9880d681SAndroid Build Coastguard Worker (MOVZX32rr16 (i16 (EXTRACT_SUBREG GR64:$src, sub_16bit))), 1467*9880d681SAndroid Build Coastguard Worker sub_32bit)>; 1468*9880d681SAndroid Build Coastguard Worker// r & (2^8-1) ==> movz 1469*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR64:$src, 0xff), 1470*9880d681SAndroid Build Coastguard Worker (SUBREG_TO_REG (i64 0), 1471*9880d681SAndroid Build Coastguard Worker (MOVZX32rr8 (i8 (EXTRACT_SUBREG GR64:$src, sub_8bit))), 1472*9880d681SAndroid Build Coastguard Worker sub_32bit)>; 1473*9880d681SAndroid Build Coastguard Worker// r & (2^8-1) ==> movz 1474*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR32:$src1, 0xff), 1475*9880d681SAndroid Build Coastguard Worker (MOVZX32rr8 (EXTRACT_SUBREG GR32:$src1, sub_8bit))>, 1476*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 1477*9880d681SAndroid Build Coastguard Worker// r & (2^8-1) ==> movz 1478*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR16:$src1, 0xff), 1479*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (MOVZX32rr8 (i8 1480*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG GR16:$src1, sub_8bit))), sub_16bit)>, 1481*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 1482*9880d681SAndroid Build Coastguard Worker} // AddedComplexity = 1 1483*9880d681SAndroid Build Coastguard Worker 1484*9880d681SAndroid Build Coastguard Worker 1485*9880d681SAndroid Build Coastguard Worker// sext_inreg patterns 1486*9880d681SAndroid Build Coastguard Workerdef : Pat<(sext_inreg GR32:$src, i16), 1487*9880d681SAndroid Build Coastguard Worker (MOVSX32rr16 (EXTRACT_SUBREG GR32:$src, sub_16bit))>; 1488*9880d681SAndroid Build Coastguard Workerdef : Pat<(sext_inreg GR32:$src, i8), 1489*9880d681SAndroid Build Coastguard Worker (MOVSX32rr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, 1490*9880d681SAndroid Build Coastguard Worker GR32_ABCD)), 1491*9880d681SAndroid Build Coastguard Worker sub_8bit))>, 1492*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 1493*9880d681SAndroid Build Coastguard Worker 1494*9880d681SAndroid Build Coastguard Workerdef : Pat<(sext_inreg GR16:$src, i8), 1495*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (i32 (MOVSX32rr8 (EXTRACT_SUBREG 1496*9880d681SAndroid Build Coastguard Worker (i32 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), sub_8bit))), 1497*9880d681SAndroid Build Coastguard Worker sub_16bit)>, 1498*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 1499*9880d681SAndroid Build Coastguard Worker 1500*9880d681SAndroid Build Coastguard Workerdef : Pat<(sext_inreg GR64:$src, i32), 1501*9880d681SAndroid Build Coastguard Worker (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, sub_32bit))>; 1502*9880d681SAndroid Build Coastguard Workerdef : Pat<(sext_inreg GR64:$src, i16), 1503*9880d681SAndroid Build Coastguard Worker (MOVSX64rr16 (EXTRACT_SUBREG GR64:$src, sub_16bit))>; 1504*9880d681SAndroid Build Coastguard Workerdef : Pat<(sext_inreg GR64:$src, i8), 1505*9880d681SAndroid Build Coastguard Worker (MOVSX64rr8 (EXTRACT_SUBREG GR64:$src, sub_8bit))>; 1506*9880d681SAndroid Build Coastguard Workerdef : Pat<(sext_inreg GR32:$src, i8), 1507*9880d681SAndroid Build Coastguard Worker (MOVSX32rr8 (EXTRACT_SUBREG GR32:$src, sub_8bit))>, 1508*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 1509*9880d681SAndroid Build Coastguard Workerdef : Pat<(sext_inreg GR16:$src, i8), 1510*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (MOVSX32rr8 1511*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG GR16:$src, sub_8bit)), sub_16bit)>, 1512*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 1513*9880d681SAndroid Build Coastguard Worker 1514*9880d681SAndroid Build Coastguard Worker// sext, sext_load, zext, zext_load 1515*9880d681SAndroid Build Coastguard Workerdef: Pat<(i16 (sext GR8:$src)), 1516*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (MOVSX32rr8 GR8:$src), sub_16bit)>; 1517*9880d681SAndroid Build Coastguard Workerdef: Pat<(sextloadi16i8 addr:$src), 1518*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (MOVSX32rm8 addr:$src), sub_16bit)>; 1519*9880d681SAndroid Build Coastguard Workerdef: Pat<(i16 (zext GR8:$src)), 1520*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (MOVZX32rr8 GR8:$src), sub_16bit)>; 1521*9880d681SAndroid Build Coastguard Workerdef: Pat<(zextloadi16i8 addr:$src), 1522*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (MOVZX32rm8 addr:$src), sub_16bit)>; 1523*9880d681SAndroid Build Coastguard Worker 1524*9880d681SAndroid Build Coastguard Worker// trunc patterns 1525*9880d681SAndroid Build Coastguard Workerdef : Pat<(i16 (trunc GR32:$src)), 1526*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG GR32:$src, sub_16bit)>; 1527*9880d681SAndroid Build Coastguard Workerdef : Pat<(i8 (trunc GR32:$src)), 1528*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), 1529*9880d681SAndroid Build Coastguard Worker sub_8bit)>, 1530*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 1531*9880d681SAndroid Build Coastguard Workerdef : Pat<(i8 (trunc GR16:$src)), 1532*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), 1533*9880d681SAndroid Build Coastguard Worker sub_8bit)>, 1534*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 1535*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 (trunc GR64:$src)), 1536*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG GR64:$src, sub_32bit)>; 1537*9880d681SAndroid Build Coastguard Workerdef : Pat<(i16 (trunc GR64:$src)), 1538*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG GR64:$src, sub_16bit)>; 1539*9880d681SAndroid Build Coastguard Workerdef : Pat<(i8 (trunc GR64:$src)), 1540*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG GR64:$src, sub_8bit)>; 1541*9880d681SAndroid Build Coastguard Workerdef : Pat<(i8 (trunc GR32:$src)), 1542*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG GR32:$src, sub_8bit)>, 1543*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 1544*9880d681SAndroid Build Coastguard Workerdef : Pat<(i8 (trunc GR16:$src)), 1545*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG GR16:$src, sub_8bit)>, 1546*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 1547*9880d681SAndroid Build Coastguard Worker 1548*9880d681SAndroid Build Coastguard Worker// h-register tricks 1549*9880d681SAndroid Build Coastguard Workerdef : Pat<(i8 (trunc (srl_su GR16:$src, (i8 8)))), 1550*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), 1551*9880d681SAndroid Build Coastguard Worker sub_8bit_hi)>, 1552*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 1553*9880d681SAndroid Build Coastguard Workerdef : Pat<(i8 (trunc (srl_su (i32 (anyext GR16:$src)), (i8 8)))), 1554*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), 1555*9880d681SAndroid Build Coastguard Worker sub_8bit_hi)>, 1556*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 1557*9880d681SAndroid Build Coastguard Workerdef : Pat<(i8 (trunc (srl_su GR32:$src, (i8 8)))), 1558*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), 1559*9880d681SAndroid Build Coastguard Worker sub_8bit_hi)>, 1560*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 1561*9880d681SAndroid Build Coastguard Workerdef : Pat<(srl GR16:$src, (i8 8)), 1562*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG 1563*9880d681SAndroid Build Coastguard Worker (MOVZX32rr8 1564*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), 1565*9880d681SAndroid Build Coastguard Worker sub_8bit_hi)), 1566*9880d681SAndroid Build Coastguard Worker sub_16bit)>, 1567*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 1568*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 (zext (srl_su GR16:$src, (i8 8)))), 1569*9880d681SAndroid Build Coastguard Worker (MOVZX32rr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, 1570*9880d681SAndroid Build Coastguard Worker GR16_ABCD)), 1571*9880d681SAndroid Build Coastguard Worker sub_8bit_hi))>, 1572*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 1573*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 (anyext (srl_su GR16:$src, (i8 8)))), 1574*9880d681SAndroid Build Coastguard Worker (MOVZX32rr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, 1575*9880d681SAndroid Build Coastguard Worker GR16_ABCD)), 1576*9880d681SAndroid Build Coastguard Worker sub_8bit_hi))>, 1577*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 1578*9880d681SAndroid Build Coastguard Workerdef : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)), 1579*9880d681SAndroid Build Coastguard Worker (MOVZX32rr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, 1580*9880d681SAndroid Build Coastguard Worker GR32_ABCD)), 1581*9880d681SAndroid Build Coastguard Worker sub_8bit_hi))>, 1582*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 1583*9880d681SAndroid Build Coastguard Workerdef : Pat<(srl (and_su GR32:$src, 0xff00), (i8 8)), 1584*9880d681SAndroid Build Coastguard Worker (MOVZX32rr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, 1585*9880d681SAndroid Build Coastguard Worker GR32_ABCD)), 1586*9880d681SAndroid Build Coastguard Worker sub_8bit_hi))>, 1587*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 1588*9880d681SAndroid Build Coastguard Worker 1589*9880d681SAndroid Build Coastguard Worker// h-register tricks. 1590*9880d681SAndroid Build Coastguard Worker// For now, be conservative on x86-64 and use an h-register extract only if the 1591*9880d681SAndroid Build Coastguard Worker// value is immediately zero-extended or stored, which are somewhat common 1592*9880d681SAndroid Build Coastguard Worker// cases. This uses a bunch of code to prevent a register requiring a REX prefix 1593*9880d681SAndroid Build Coastguard Worker// from being allocated in the same instruction as the h register, as there's 1594*9880d681SAndroid Build Coastguard Worker// currently no way to describe this requirement to the register allocator. 1595*9880d681SAndroid Build Coastguard Worker 1596*9880d681SAndroid Build Coastguard Worker// h-register extract and zero-extend. 1597*9880d681SAndroid Build Coastguard Workerdef : Pat<(and (srl_su GR64:$src, (i8 8)), (i64 255)), 1598*9880d681SAndroid Build Coastguard Worker (SUBREG_TO_REG 1599*9880d681SAndroid Build Coastguard Worker (i64 0), 1600*9880d681SAndroid Build Coastguard Worker (MOVZX32_NOREXrr8 1601*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (i64 (COPY_TO_REGCLASS GR64:$src, GR64_ABCD)), 1602*9880d681SAndroid Build Coastguard Worker sub_8bit_hi)), 1603*9880d681SAndroid Build Coastguard Worker sub_32bit)>; 1604*9880d681SAndroid Build Coastguard Workerdef : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)), 1605*9880d681SAndroid Build Coastguard Worker (MOVZX32_NOREXrr8 1606*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), 1607*9880d681SAndroid Build Coastguard Worker sub_8bit_hi))>, 1608*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 1609*9880d681SAndroid Build Coastguard Workerdef : Pat<(srl (and_su GR32:$src, 0xff00), (i8 8)), 1610*9880d681SAndroid Build Coastguard Worker (MOVZX32_NOREXrr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, 1611*9880d681SAndroid Build Coastguard Worker GR32_ABCD)), 1612*9880d681SAndroid Build Coastguard Worker sub_8bit_hi))>, 1613*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 1614*9880d681SAndroid Build Coastguard Workerdef : Pat<(srl GR16:$src, (i8 8)), 1615*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG 1616*9880d681SAndroid Build Coastguard Worker (MOVZX32_NOREXrr8 1617*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), 1618*9880d681SAndroid Build Coastguard Worker sub_8bit_hi)), 1619*9880d681SAndroid Build Coastguard Worker sub_16bit)>, 1620*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 1621*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 (zext (srl_su GR16:$src, (i8 8)))), 1622*9880d681SAndroid Build Coastguard Worker (MOVZX32_NOREXrr8 1623*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), 1624*9880d681SAndroid Build Coastguard Worker sub_8bit_hi))>, 1625*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 1626*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 (anyext (srl_su GR16:$src, (i8 8)))), 1627*9880d681SAndroid Build Coastguard Worker (MOVZX32_NOREXrr8 1628*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), 1629*9880d681SAndroid Build Coastguard Worker sub_8bit_hi))>, 1630*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 1631*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (zext (srl_su GR16:$src, (i8 8)))), 1632*9880d681SAndroid Build Coastguard Worker (SUBREG_TO_REG 1633*9880d681SAndroid Build Coastguard Worker (i64 0), 1634*9880d681SAndroid Build Coastguard Worker (MOVZX32_NOREXrr8 1635*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), 1636*9880d681SAndroid Build Coastguard Worker sub_8bit_hi)), 1637*9880d681SAndroid Build Coastguard Worker sub_32bit)>; 1638*9880d681SAndroid Build Coastguard Workerdef : Pat<(i64 (anyext (srl_su GR16:$src, (i8 8)))), 1639*9880d681SAndroid Build Coastguard Worker (SUBREG_TO_REG 1640*9880d681SAndroid Build Coastguard Worker (i64 0), 1641*9880d681SAndroid Build Coastguard Worker (MOVZX32_NOREXrr8 1642*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), 1643*9880d681SAndroid Build Coastguard Worker sub_8bit_hi)), 1644*9880d681SAndroid Build Coastguard Worker sub_32bit)>; 1645*9880d681SAndroid Build Coastguard Worker 1646*9880d681SAndroid Build Coastguard Worker// h-register extract and store. 1647*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (i8 (trunc_su (srl_su GR64:$src, (i8 8)))), addr:$dst), 1648*9880d681SAndroid Build Coastguard Worker (MOV8mr_NOREX 1649*9880d681SAndroid Build Coastguard Worker addr:$dst, 1650*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (i64 (COPY_TO_REGCLASS GR64:$src, GR64_ABCD)), 1651*9880d681SAndroid Build Coastguard Worker sub_8bit_hi))>; 1652*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (i8 (trunc_su (srl_su GR32:$src, (i8 8)))), addr:$dst), 1653*9880d681SAndroid Build Coastguard Worker (MOV8mr_NOREX 1654*9880d681SAndroid Build Coastguard Worker addr:$dst, 1655*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), 1656*9880d681SAndroid Build Coastguard Worker sub_8bit_hi))>, 1657*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 1658*9880d681SAndroid Build Coastguard Workerdef : Pat<(store (i8 (trunc_su (srl_su GR16:$src, (i8 8)))), addr:$dst), 1659*9880d681SAndroid Build Coastguard Worker (MOV8mr_NOREX 1660*9880d681SAndroid Build Coastguard Worker addr:$dst, 1661*9880d681SAndroid Build Coastguard Worker (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), 1662*9880d681SAndroid Build Coastguard Worker sub_8bit_hi))>, 1663*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 1664*9880d681SAndroid Build Coastguard Worker 1665*9880d681SAndroid Build Coastguard Worker 1666*9880d681SAndroid Build Coastguard Worker// (shl x, 1) ==> (add x, x) 1667*9880d681SAndroid Build Coastguard Worker// Note that if x is undef (immediate or otherwise), we could theoretically 1668*9880d681SAndroid Build Coastguard Worker// end up with the two uses of x getting different values, producing a result 1669*9880d681SAndroid Build Coastguard Worker// where the least significant bit is not 0. However, the probability of this 1670*9880d681SAndroid Build Coastguard Worker// happening is considered low enough that this is officially not a 1671*9880d681SAndroid Build Coastguard Worker// "real problem". 1672*9880d681SAndroid Build Coastguard Workerdef : Pat<(shl GR8 :$src1, (i8 1)), (ADD8rr GR8 :$src1, GR8 :$src1)>; 1673*9880d681SAndroid Build Coastguard Workerdef : Pat<(shl GR16:$src1, (i8 1)), (ADD16rr GR16:$src1, GR16:$src1)>; 1674*9880d681SAndroid Build Coastguard Workerdef : Pat<(shl GR32:$src1, (i8 1)), (ADD32rr GR32:$src1, GR32:$src1)>; 1675*9880d681SAndroid Build Coastguard Workerdef : Pat<(shl GR64:$src1, (i8 1)), (ADD64rr GR64:$src1, GR64:$src1)>; 1676*9880d681SAndroid Build Coastguard Worker 1677*9880d681SAndroid Build Coastguard Worker// Helper imms that check if a mask doesn't change significant shift bits. 1678*9880d681SAndroid Build Coastguard Workerdef immShift32 : ImmLeaf<i8, [{ 1679*9880d681SAndroid Build Coastguard Worker return countTrailingOnes<uint64_t>(Imm) >= 5; 1680*9880d681SAndroid Build Coastguard Worker}]>; 1681*9880d681SAndroid Build Coastguard Workerdef immShift64 : ImmLeaf<i8, [{ 1682*9880d681SAndroid Build Coastguard Worker return countTrailingOnes<uint64_t>(Imm) >= 6; 1683*9880d681SAndroid Build Coastguard Worker}]>; 1684*9880d681SAndroid Build Coastguard Worker 1685*9880d681SAndroid Build Coastguard Worker// Shift amount is implicitly masked. 1686*9880d681SAndroid Build Coastguard Workermulticlass MaskedShiftAmountPats<SDNode frag, string name> { 1687*9880d681SAndroid Build Coastguard Worker // (shift x (and y, 31)) ==> (shift x, y) 1688*9880d681SAndroid Build Coastguard Worker def : Pat<(frag GR8:$src1, (and CL, immShift32)), 1689*9880d681SAndroid Build Coastguard Worker (!cast<Instruction>(name # "8rCL") GR8:$src1)>; 1690*9880d681SAndroid Build Coastguard Worker def : Pat<(frag GR16:$src1, (and CL, immShift32)), 1691*9880d681SAndroid Build Coastguard Worker (!cast<Instruction>(name # "16rCL") GR16:$src1)>; 1692*9880d681SAndroid Build Coastguard Worker def : Pat<(frag GR32:$src1, (and CL, immShift32)), 1693*9880d681SAndroid Build Coastguard Worker (!cast<Instruction>(name # "32rCL") GR32:$src1)>; 1694*9880d681SAndroid Build Coastguard Worker def : Pat<(store (frag (loadi8 addr:$dst), (and CL, immShift32)), addr:$dst), 1695*9880d681SAndroid Build Coastguard Worker (!cast<Instruction>(name # "8mCL") addr:$dst)>; 1696*9880d681SAndroid Build Coastguard Worker def : Pat<(store (frag (loadi16 addr:$dst), (and CL, immShift32)), addr:$dst), 1697*9880d681SAndroid Build Coastguard Worker (!cast<Instruction>(name # "16mCL") addr:$dst)>; 1698*9880d681SAndroid Build Coastguard Worker def : Pat<(store (frag (loadi32 addr:$dst), (and CL, immShift32)), addr:$dst), 1699*9880d681SAndroid Build Coastguard Worker (!cast<Instruction>(name # "32mCL") addr:$dst)>; 1700*9880d681SAndroid Build Coastguard Worker 1701*9880d681SAndroid Build Coastguard Worker // (shift x (and y, 63)) ==> (shift x, y) 1702*9880d681SAndroid Build Coastguard Worker def : Pat<(frag GR64:$src1, (and CL, immShift64)), 1703*9880d681SAndroid Build Coastguard Worker (!cast<Instruction>(name # "64rCL") GR64:$src1)>; 1704*9880d681SAndroid Build Coastguard Worker def : Pat<(store (frag (loadi64 addr:$dst), (and CL, 63)), addr:$dst), 1705*9880d681SAndroid Build Coastguard Worker (!cast<Instruction>(name # "64mCL") addr:$dst)>; 1706*9880d681SAndroid Build Coastguard Worker} 1707*9880d681SAndroid Build Coastguard Worker 1708*9880d681SAndroid Build Coastguard Workerdefm : MaskedShiftAmountPats<shl, "SHL">; 1709*9880d681SAndroid Build Coastguard Workerdefm : MaskedShiftAmountPats<srl, "SHR">; 1710*9880d681SAndroid Build Coastguard Workerdefm : MaskedShiftAmountPats<sra, "SAR">; 1711*9880d681SAndroid Build Coastguard Workerdefm : MaskedShiftAmountPats<rotl, "ROL">; 1712*9880d681SAndroid Build Coastguard Workerdefm : MaskedShiftAmountPats<rotr, "ROR">; 1713*9880d681SAndroid Build Coastguard Worker 1714*9880d681SAndroid Build Coastguard Worker// (anyext (setcc_carry)) -> (setcc_carry) 1715*9880d681SAndroid Build Coastguard Workerdef : Pat<(i16 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), 1716*9880d681SAndroid Build Coastguard Worker (SETB_C16r)>; 1717*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), 1718*9880d681SAndroid Build Coastguard Worker (SETB_C32r)>; 1719*9880d681SAndroid Build Coastguard Workerdef : Pat<(i32 (anyext (i16 (X86setcc_c X86_COND_B, EFLAGS)))), 1720*9880d681SAndroid Build Coastguard Worker (SETB_C32r)>; 1721*9880d681SAndroid Build Coastguard Worker 1722*9880d681SAndroid Build Coastguard Worker 1723*9880d681SAndroid Build Coastguard Worker 1724*9880d681SAndroid Build Coastguard Worker 1725*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 1726*9880d681SAndroid Build Coastguard Worker// EFLAGS-defining Patterns 1727*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 1728*9880d681SAndroid Build Coastguard Worker 1729*9880d681SAndroid Build Coastguard Worker// add reg, reg 1730*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR8 :$src1, GR8 :$src2), (ADD8rr GR8 :$src1, GR8 :$src2)>; 1731*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR16:$src1, GR16:$src2), (ADD16rr GR16:$src1, GR16:$src2)>; 1732*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR32:$src1, GR32:$src2), (ADD32rr GR32:$src1, GR32:$src2)>; 1733*9880d681SAndroid Build Coastguard Worker 1734*9880d681SAndroid Build Coastguard Worker// add reg, mem 1735*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR8:$src1, (loadi8 addr:$src2)), 1736*9880d681SAndroid Build Coastguard Worker (ADD8rm GR8:$src1, addr:$src2)>; 1737*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR16:$src1, (loadi16 addr:$src2)), 1738*9880d681SAndroid Build Coastguard Worker (ADD16rm GR16:$src1, addr:$src2)>; 1739*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR32:$src1, (loadi32 addr:$src2)), 1740*9880d681SAndroid Build Coastguard Worker (ADD32rm GR32:$src1, addr:$src2)>; 1741*9880d681SAndroid Build Coastguard Worker 1742*9880d681SAndroid Build Coastguard Worker// add reg, imm 1743*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR8 :$src1, imm:$src2), (ADD8ri GR8:$src1 , imm:$src2)>; 1744*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR16:$src1, imm:$src2), (ADD16ri GR16:$src1, imm:$src2)>; 1745*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR32:$src1, imm:$src2), (ADD32ri GR32:$src1, imm:$src2)>; 1746*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR16:$src1, i16immSExt8:$src2), 1747*9880d681SAndroid Build Coastguard Worker (ADD16ri8 GR16:$src1, i16immSExt8:$src2)>; 1748*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR32:$src1, i32immSExt8:$src2), 1749*9880d681SAndroid Build Coastguard Worker (ADD32ri8 GR32:$src1, i32immSExt8:$src2)>; 1750*9880d681SAndroid Build Coastguard Worker 1751*9880d681SAndroid Build Coastguard Worker// sub reg, reg 1752*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR8 :$src1, GR8 :$src2), (SUB8rr GR8 :$src1, GR8 :$src2)>; 1753*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR16:$src1, GR16:$src2), (SUB16rr GR16:$src1, GR16:$src2)>; 1754*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR32:$src1, GR32:$src2), (SUB32rr GR32:$src1, GR32:$src2)>; 1755*9880d681SAndroid Build Coastguard Worker 1756*9880d681SAndroid Build Coastguard Worker// sub reg, mem 1757*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR8:$src1, (loadi8 addr:$src2)), 1758*9880d681SAndroid Build Coastguard Worker (SUB8rm GR8:$src1, addr:$src2)>; 1759*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR16:$src1, (loadi16 addr:$src2)), 1760*9880d681SAndroid Build Coastguard Worker (SUB16rm GR16:$src1, addr:$src2)>; 1761*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR32:$src1, (loadi32 addr:$src2)), 1762*9880d681SAndroid Build Coastguard Worker (SUB32rm GR32:$src1, addr:$src2)>; 1763*9880d681SAndroid Build Coastguard Worker 1764*9880d681SAndroid Build Coastguard Worker// sub reg, imm 1765*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR8:$src1, imm:$src2), 1766*9880d681SAndroid Build Coastguard Worker (SUB8ri GR8:$src1, imm:$src2)>; 1767*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR16:$src1, imm:$src2), 1768*9880d681SAndroid Build Coastguard Worker (SUB16ri GR16:$src1, imm:$src2)>; 1769*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR32:$src1, imm:$src2), 1770*9880d681SAndroid Build Coastguard Worker (SUB32ri GR32:$src1, imm:$src2)>; 1771*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR16:$src1, i16immSExt8:$src2), 1772*9880d681SAndroid Build Coastguard Worker (SUB16ri8 GR16:$src1, i16immSExt8:$src2)>; 1773*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR32:$src1, i32immSExt8:$src2), 1774*9880d681SAndroid Build Coastguard Worker (SUB32ri8 GR32:$src1, i32immSExt8:$src2)>; 1775*9880d681SAndroid Build Coastguard Worker 1776*9880d681SAndroid Build Coastguard Worker// sub 0, reg 1777*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86sub_flag 0, GR8 :$src), (NEG8r GR8 :$src)>; 1778*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86sub_flag 0, GR16:$src), (NEG16r GR16:$src)>; 1779*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86sub_flag 0, GR32:$src), (NEG32r GR32:$src)>; 1780*9880d681SAndroid Build Coastguard Workerdef : Pat<(X86sub_flag 0, GR64:$src), (NEG64r GR64:$src)>; 1781*9880d681SAndroid Build Coastguard Worker 1782*9880d681SAndroid Build Coastguard Worker// mul reg, reg 1783*9880d681SAndroid Build Coastguard Workerdef : Pat<(mul GR16:$src1, GR16:$src2), 1784*9880d681SAndroid Build Coastguard Worker (IMUL16rr GR16:$src1, GR16:$src2)>; 1785*9880d681SAndroid Build Coastguard Workerdef : Pat<(mul GR32:$src1, GR32:$src2), 1786*9880d681SAndroid Build Coastguard Worker (IMUL32rr GR32:$src1, GR32:$src2)>; 1787*9880d681SAndroid Build Coastguard Worker 1788*9880d681SAndroid Build Coastguard Worker// mul reg, mem 1789*9880d681SAndroid Build Coastguard Workerdef : Pat<(mul GR16:$src1, (loadi16 addr:$src2)), 1790*9880d681SAndroid Build Coastguard Worker (IMUL16rm GR16:$src1, addr:$src2)>; 1791*9880d681SAndroid Build Coastguard Workerdef : Pat<(mul GR32:$src1, (loadi32 addr:$src2)), 1792*9880d681SAndroid Build Coastguard Worker (IMUL32rm GR32:$src1, addr:$src2)>; 1793*9880d681SAndroid Build Coastguard Worker 1794*9880d681SAndroid Build Coastguard Worker// mul reg, imm 1795*9880d681SAndroid Build Coastguard Workerdef : Pat<(mul GR16:$src1, imm:$src2), 1796*9880d681SAndroid Build Coastguard Worker (IMUL16rri GR16:$src1, imm:$src2)>; 1797*9880d681SAndroid Build Coastguard Workerdef : Pat<(mul GR32:$src1, imm:$src2), 1798*9880d681SAndroid Build Coastguard Worker (IMUL32rri GR32:$src1, imm:$src2)>; 1799*9880d681SAndroid Build Coastguard Workerdef : Pat<(mul GR16:$src1, i16immSExt8:$src2), 1800*9880d681SAndroid Build Coastguard Worker (IMUL16rri8 GR16:$src1, i16immSExt8:$src2)>; 1801*9880d681SAndroid Build Coastguard Workerdef : Pat<(mul GR32:$src1, i32immSExt8:$src2), 1802*9880d681SAndroid Build Coastguard Worker (IMUL32rri8 GR32:$src1, i32immSExt8:$src2)>; 1803*9880d681SAndroid Build Coastguard Worker 1804*9880d681SAndroid Build Coastguard Worker// reg = mul mem, imm 1805*9880d681SAndroid Build Coastguard Workerdef : Pat<(mul (loadi16 addr:$src1), imm:$src2), 1806*9880d681SAndroid Build Coastguard Worker (IMUL16rmi addr:$src1, imm:$src2)>; 1807*9880d681SAndroid Build Coastguard Workerdef : Pat<(mul (loadi32 addr:$src1), imm:$src2), 1808*9880d681SAndroid Build Coastguard Worker (IMUL32rmi addr:$src1, imm:$src2)>; 1809*9880d681SAndroid Build Coastguard Workerdef : Pat<(mul (loadi16 addr:$src1), i16immSExt8:$src2), 1810*9880d681SAndroid Build Coastguard Worker (IMUL16rmi8 addr:$src1, i16immSExt8:$src2)>; 1811*9880d681SAndroid Build Coastguard Workerdef : Pat<(mul (loadi32 addr:$src1), i32immSExt8:$src2), 1812*9880d681SAndroid Build Coastguard Worker (IMUL32rmi8 addr:$src1, i32immSExt8:$src2)>; 1813*9880d681SAndroid Build Coastguard Worker 1814*9880d681SAndroid Build Coastguard Worker// Patterns for nodes that do not produce flags, for instructions that do. 1815*9880d681SAndroid Build Coastguard Worker 1816*9880d681SAndroid Build Coastguard Worker// addition 1817*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR64:$src1, GR64:$src2), 1818*9880d681SAndroid Build Coastguard Worker (ADD64rr GR64:$src1, GR64:$src2)>; 1819*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR64:$src1, i64immSExt8:$src2), 1820*9880d681SAndroid Build Coastguard Worker (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>; 1821*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR64:$src1, i64immSExt32:$src2), 1822*9880d681SAndroid Build Coastguard Worker (ADD64ri32 GR64:$src1, i64immSExt32:$src2)>; 1823*9880d681SAndroid Build Coastguard Workerdef : Pat<(add GR64:$src1, (loadi64 addr:$src2)), 1824*9880d681SAndroid Build Coastguard Worker (ADD64rm GR64:$src1, addr:$src2)>; 1825*9880d681SAndroid Build Coastguard Worker 1826*9880d681SAndroid Build Coastguard Worker// subtraction 1827*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR64:$src1, GR64:$src2), 1828*9880d681SAndroid Build Coastguard Worker (SUB64rr GR64:$src1, GR64:$src2)>; 1829*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR64:$src1, (loadi64 addr:$src2)), 1830*9880d681SAndroid Build Coastguard Worker (SUB64rm GR64:$src1, addr:$src2)>; 1831*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR64:$src1, i64immSExt8:$src2), 1832*9880d681SAndroid Build Coastguard Worker (SUB64ri8 GR64:$src1, i64immSExt8:$src2)>; 1833*9880d681SAndroid Build Coastguard Workerdef : Pat<(sub GR64:$src1, i64immSExt32:$src2), 1834*9880d681SAndroid Build Coastguard Worker (SUB64ri32 GR64:$src1, i64immSExt32:$src2)>; 1835*9880d681SAndroid Build Coastguard Worker 1836*9880d681SAndroid Build Coastguard Worker// Multiply 1837*9880d681SAndroid Build Coastguard Workerdef : Pat<(mul GR64:$src1, GR64:$src2), 1838*9880d681SAndroid Build Coastguard Worker (IMUL64rr GR64:$src1, GR64:$src2)>; 1839*9880d681SAndroid Build Coastguard Workerdef : Pat<(mul GR64:$src1, (loadi64 addr:$src2)), 1840*9880d681SAndroid Build Coastguard Worker (IMUL64rm GR64:$src1, addr:$src2)>; 1841*9880d681SAndroid Build Coastguard Workerdef : Pat<(mul GR64:$src1, i64immSExt8:$src2), 1842*9880d681SAndroid Build Coastguard Worker (IMUL64rri8 GR64:$src1, i64immSExt8:$src2)>; 1843*9880d681SAndroid Build Coastguard Workerdef : Pat<(mul GR64:$src1, i64immSExt32:$src2), 1844*9880d681SAndroid Build Coastguard Worker (IMUL64rri32 GR64:$src1, i64immSExt32:$src2)>; 1845*9880d681SAndroid Build Coastguard Workerdef : Pat<(mul (loadi64 addr:$src1), i64immSExt8:$src2), 1846*9880d681SAndroid Build Coastguard Worker (IMUL64rmi8 addr:$src1, i64immSExt8:$src2)>; 1847*9880d681SAndroid Build Coastguard Workerdef : Pat<(mul (loadi64 addr:$src1), i64immSExt32:$src2), 1848*9880d681SAndroid Build Coastguard Worker (IMUL64rmi32 addr:$src1, i64immSExt32:$src2)>; 1849*9880d681SAndroid Build Coastguard Worker 1850*9880d681SAndroid Build Coastguard Worker// Increment/Decrement reg. 1851*9880d681SAndroid Build Coastguard Worker// Do not make INC/DEC if it is slow 1852*9880d681SAndroid Build Coastguard Workerlet Predicates = [NotSlowIncDec] in { 1853*9880d681SAndroid Build Coastguard Worker def : Pat<(add GR8:$src, 1), (INC8r GR8:$src)>; 1854*9880d681SAndroid Build Coastguard Worker def : Pat<(add GR16:$src, 1), (INC16r GR16:$src)>; 1855*9880d681SAndroid Build Coastguard Worker def : Pat<(add GR32:$src, 1), (INC32r GR32:$src)>; 1856*9880d681SAndroid Build Coastguard Worker def : Pat<(add GR64:$src, 1), (INC64r GR64:$src)>; 1857*9880d681SAndroid Build Coastguard Worker def : Pat<(add GR8:$src, -1), (DEC8r GR8:$src)>; 1858*9880d681SAndroid Build Coastguard Worker def : Pat<(add GR16:$src, -1), (DEC16r GR16:$src)>; 1859*9880d681SAndroid Build Coastguard Worker def : Pat<(add GR32:$src, -1), (DEC32r GR32:$src)>; 1860*9880d681SAndroid Build Coastguard Worker def : Pat<(add GR64:$src, -1), (DEC64r GR64:$src)>; 1861*9880d681SAndroid Build Coastguard Worker} 1862*9880d681SAndroid Build Coastguard Worker 1863*9880d681SAndroid Build Coastguard Worker// or reg/reg. 1864*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GR8 :$src1, GR8 :$src2), (OR8rr GR8 :$src1, GR8 :$src2)>; 1865*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GR16:$src1, GR16:$src2), (OR16rr GR16:$src1, GR16:$src2)>; 1866*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GR32:$src1, GR32:$src2), (OR32rr GR32:$src1, GR32:$src2)>; 1867*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GR64:$src1, GR64:$src2), (OR64rr GR64:$src1, GR64:$src2)>; 1868*9880d681SAndroid Build Coastguard Worker 1869*9880d681SAndroid Build Coastguard Worker// or reg/mem 1870*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GR8:$src1, (loadi8 addr:$src2)), 1871*9880d681SAndroid Build Coastguard Worker (OR8rm GR8:$src1, addr:$src2)>; 1872*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GR16:$src1, (loadi16 addr:$src2)), 1873*9880d681SAndroid Build Coastguard Worker (OR16rm GR16:$src1, addr:$src2)>; 1874*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GR32:$src1, (loadi32 addr:$src2)), 1875*9880d681SAndroid Build Coastguard Worker (OR32rm GR32:$src1, addr:$src2)>; 1876*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GR64:$src1, (loadi64 addr:$src2)), 1877*9880d681SAndroid Build Coastguard Worker (OR64rm GR64:$src1, addr:$src2)>; 1878*9880d681SAndroid Build Coastguard Worker 1879*9880d681SAndroid Build Coastguard Worker// or reg/imm 1880*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GR8:$src1 , imm:$src2), (OR8ri GR8 :$src1, imm:$src2)>; 1881*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GR16:$src1, imm:$src2), (OR16ri GR16:$src1, imm:$src2)>; 1882*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GR32:$src1, imm:$src2), (OR32ri GR32:$src1, imm:$src2)>; 1883*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GR16:$src1, i16immSExt8:$src2), 1884*9880d681SAndroid Build Coastguard Worker (OR16ri8 GR16:$src1, i16immSExt8:$src2)>; 1885*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GR32:$src1, i32immSExt8:$src2), 1886*9880d681SAndroid Build Coastguard Worker (OR32ri8 GR32:$src1, i32immSExt8:$src2)>; 1887*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GR64:$src1, i64immSExt8:$src2), 1888*9880d681SAndroid Build Coastguard Worker (OR64ri8 GR64:$src1, i64immSExt8:$src2)>; 1889*9880d681SAndroid Build Coastguard Workerdef : Pat<(or GR64:$src1, i64immSExt32:$src2), 1890*9880d681SAndroid Build Coastguard Worker (OR64ri32 GR64:$src1, i64immSExt32:$src2)>; 1891*9880d681SAndroid Build Coastguard Worker 1892*9880d681SAndroid Build Coastguard Worker// xor reg/reg 1893*9880d681SAndroid Build Coastguard Workerdef : Pat<(xor GR8 :$src1, GR8 :$src2), (XOR8rr GR8 :$src1, GR8 :$src2)>; 1894*9880d681SAndroid Build Coastguard Workerdef : Pat<(xor GR16:$src1, GR16:$src2), (XOR16rr GR16:$src1, GR16:$src2)>; 1895*9880d681SAndroid Build Coastguard Workerdef : Pat<(xor GR32:$src1, GR32:$src2), (XOR32rr GR32:$src1, GR32:$src2)>; 1896*9880d681SAndroid Build Coastguard Workerdef : Pat<(xor GR64:$src1, GR64:$src2), (XOR64rr GR64:$src1, GR64:$src2)>; 1897*9880d681SAndroid Build Coastguard Worker 1898*9880d681SAndroid Build Coastguard Worker// xor reg/mem 1899*9880d681SAndroid Build Coastguard Workerdef : Pat<(xor GR8:$src1, (loadi8 addr:$src2)), 1900*9880d681SAndroid Build Coastguard Worker (XOR8rm GR8:$src1, addr:$src2)>; 1901*9880d681SAndroid Build Coastguard Workerdef : Pat<(xor GR16:$src1, (loadi16 addr:$src2)), 1902*9880d681SAndroid Build Coastguard Worker (XOR16rm GR16:$src1, addr:$src2)>; 1903*9880d681SAndroid Build Coastguard Workerdef : Pat<(xor GR32:$src1, (loadi32 addr:$src2)), 1904*9880d681SAndroid Build Coastguard Worker (XOR32rm GR32:$src1, addr:$src2)>; 1905*9880d681SAndroid Build Coastguard Workerdef : Pat<(xor GR64:$src1, (loadi64 addr:$src2)), 1906*9880d681SAndroid Build Coastguard Worker (XOR64rm GR64:$src1, addr:$src2)>; 1907*9880d681SAndroid Build Coastguard Worker 1908*9880d681SAndroid Build Coastguard Worker// xor reg/imm 1909*9880d681SAndroid Build Coastguard Workerdef : Pat<(xor GR8:$src1, imm:$src2), 1910*9880d681SAndroid Build Coastguard Worker (XOR8ri GR8:$src1, imm:$src2)>; 1911*9880d681SAndroid Build Coastguard Workerdef : Pat<(xor GR16:$src1, imm:$src2), 1912*9880d681SAndroid Build Coastguard Worker (XOR16ri GR16:$src1, imm:$src2)>; 1913*9880d681SAndroid Build Coastguard Workerdef : Pat<(xor GR32:$src1, imm:$src2), 1914*9880d681SAndroid Build Coastguard Worker (XOR32ri GR32:$src1, imm:$src2)>; 1915*9880d681SAndroid Build Coastguard Workerdef : Pat<(xor GR16:$src1, i16immSExt8:$src2), 1916*9880d681SAndroid Build Coastguard Worker (XOR16ri8 GR16:$src1, i16immSExt8:$src2)>; 1917*9880d681SAndroid Build Coastguard Workerdef : Pat<(xor GR32:$src1, i32immSExt8:$src2), 1918*9880d681SAndroid Build Coastguard Worker (XOR32ri8 GR32:$src1, i32immSExt8:$src2)>; 1919*9880d681SAndroid Build Coastguard Workerdef : Pat<(xor GR64:$src1, i64immSExt8:$src2), 1920*9880d681SAndroid Build Coastguard Worker (XOR64ri8 GR64:$src1, i64immSExt8:$src2)>; 1921*9880d681SAndroid Build Coastguard Workerdef : Pat<(xor GR64:$src1, i64immSExt32:$src2), 1922*9880d681SAndroid Build Coastguard Worker (XOR64ri32 GR64:$src1, i64immSExt32:$src2)>; 1923*9880d681SAndroid Build Coastguard Worker 1924*9880d681SAndroid Build Coastguard Worker// and reg/reg 1925*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR8 :$src1, GR8 :$src2), (AND8rr GR8 :$src1, GR8 :$src2)>; 1926*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR16:$src1, GR16:$src2), (AND16rr GR16:$src1, GR16:$src2)>; 1927*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR32:$src1, GR32:$src2), (AND32rr GR32:$src1, GR32:$src2)>; 1928*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR64:$src1, GR64:$src2), (AND64rr GR64:$src1, GR64:$src2)>; 1929*9880d681SAndroid Build Coastguard Worker 1930*9880d681SAndroid Build Coastguard Worker// and reg/mem 1931*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR8:$src1, (loadi8 addr:$src2)), 1932*9880d681SAndroid Build Coastguard Worker (AND8rm GR8:$src1, addr:$src2)>; 1933*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR16:$src1, (loadi16 addr:$src2)), 1934*9880d681SAndroid Build Coastguard Worker (AND16rm GR16:$src1, addr:$src2)>; 1935*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR32:$src1, (loadi32 addr:$src2)), 1936*9880d681SAndroid Build Coastguard Worker (AND32rm GR32:$src1, addr:$src2)>; 1937*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR64:$src1, (loadi64 addr:$src2)), 1938*9880d681SAndroid Build Coastguard Worker (AND64rm GR64:$src1, addr:$src2)>; 1939*9880d681SAndroid Build Coastguard Worker 1940*9880d681SAndroid Build Coastguard Worker// and reg/imm 1941*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR8:$src1, imm:$src2), 1942*9880d681SAndroid Build Coastguard Worker (AND8ri GR8:$src1, imm:$src2)>; 1943*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR16:$src1, imm:$src2), 1944*9880d681SAndroid Build Coastguard Worker (AND16ri GR16:$src1, imm:$src2)>; 1945*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR32:$src1, imm:$src2), 1946*9880d681SAndroid Build Coastguard Worker (AND32ri GR32:$src1, imm:$src2)>; 1947*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR16:$src1, i16immSExt8:$src2), 1948*9880d681SAndroid Build Coastguard Worker (AND16ri8 GR16:$src1, i16immSExt8:$src2)>; 1949*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR32:$src1, i32immSExt8:$src2), 1950*9880d681SAndroid Build Coastguard Worker (AND32ri8 GR32:$src1, i32immSExt8:$src2)>; 1951*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR64:$src1, i64immSExt8:$src2), 1952*9880d681SAndroid Build Coastguard Worker (AND64ri8 GR64:$src1, i64immSExt8:$src2)>; 1953*9880d681SAndroid Build Coastguard Workerdef : Pat<(and GR64:$src1, i64immSExt32:$src2), 1954*9880d681SAndroid Build Coastguard Worker (AND64ri32 GR64:$src1, i64immSExt32:$src2)>; 1955*9880d681SAndroid Build Coastguard Worker 1956*9880d681SAndroid Build Coastguard Worker// Bit scan instruction patterns to match explicit zero-undef behavior. 1957*9880d681SAndroid Build Coastguard Workerdef : Pat<(cttz_zero_undef GR16:$src), (BSF16rr GR16:$src)>; 1958*9880d681SAndroid Build Coastguard Workerdef : Pat<(cttz_zero_undef GR32:$src), (BSF32rr GR32:$src)>; 1959*9880d681SAndroid Build Coastguard Workerdef : Pat<(cttz_zero_undef GR64:$src), (BSF64rr GR64:$src)>; 1960*9880d681SAndroid Build Coastguard Workerdef : Pat<(cttz_zero_undef (loadi16 addr:$src)), (BSF16rm addr:$src)>; 1961*9880d681SAndroid Build Coastguard Workerdef : Pat<(cttz_zero_undef (loadi32 addr:$src)), (BSF32rm addr:$src)>; 1962*9880d681SAndroid Build Coastguard Workerdef : Pat<(cttz_zero_undef (loadi64 addr:$src)), (BSF64rm addr:$src)>; 1963*9880d681SAndroid Build Coastguard Worker 1964*9880d681SAndroid Build Coastguard Worker// When HasMOVBE is enabled it is possible to get a non-legalized 1965*9880d681SAndroid Build Coastguard Worker// register-register 16 bit bswap. This maps it to a ROL instruction. 1966*9880d681SAndroid Build Coastguard Workerlet Predicates = [HasMOVBE] in { 1967*9880d681SAndroid Build Coastguard Worker def : Pat<(bswap GR16:$src), (ROL16ri GR16:$src, (i8 8))>; 1968*9880d681SAndroid Build Coastguard Worker} 1969