1*9880d681SAndroid Build Coastguard Worker//===-- X86InstrControl.td - Control Flow Instructions -----*- 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 X86 jump, return, call, and related instructions. 11*9880d681SAndroid Build Coastguard Worker// 12*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 15*9880d681SAndroid Build Coastguard Worker// Control Flow Instructions. 16*9880d681SAndroid Build Coastguard Worker// 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Worker// Return instructions. 19*9880d681SAndroid Build Coastguard Worker// 20*9880d681SAndroid Build Coastguard Worker// The X86retflag return instructions are variadic because we may add ST0 and 21*9880d681SAndroid Build Coastguard Worker// ST1 arguments when returning values on the x87 stack. 22*9880d681SAndroid Build Coastguard Workerlet isTerminator = 1, isReturn = 1, isBarrier = 1, 23*9880d681SAndroid Build Coastguard Worker hasCtrlDep = 1, FPForm = SpecialFP, SchedRW = [WriteJumpLd] in { 24*9880d681SAndroid Build Coastguard Worker def RETL : I <0xC3, RawFrm, (outs), (ins variable_ops), 25*9880d681SAndroid Build Coastguard Worker "ret{l}", [], IIC_RET>, OpSize32, 26*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 27*9880d681SAndroid Build Coastguard Worker def RETQ : I <0xC3, RawFrm, (outs), (ins variable_ops), 28*9880d681SAndroid Build Coastguard Worker "ret{q}", [], IIC_RET>, OpSize32, 29*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 30*9880d681SAndroid Build Coastguard Worker def RETW : I <0xC3, RawFrm, (outs), (ins), 31*9880d681SAndroid Build Coastguard Worker "ret{w}", 32*9880d681SAndroid Build Coastguard Worker [], IIC_RET>, OpSize16; 33*9880d681SAndroid Build Coastguard Worker def RETIL : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt, variable_ops), 34*9880d681SAndroid Build Coastguard Worker "ret{l}\t$amt", 35*9880d681SAndroid Build Coastguard Worker [], IIC_RET_IMM>, OpSize32, 36*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 37*9880d681SAndroid Build Coastguard Worker def RETIQ : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt, variable_ops), 38*9880d681SAndroid Build Coastguard Worker "ret{q}\t$amt", 39*9880d681SAndroid Build Coastguard Worker [], IIC_RET_IMM>, OpSize32, 40*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 41*9880d681SAndroid Build Coastguard Worker def RETIW : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt), 42*9880d681SAndroid Build Coastguard Worker "ret{w}\t$amt", 43*9880d681SAndroid Build Coastguard Worker [], IIC_RET_IMM>, OpSize16; 44*9880d681SAndroid Build Coastguard Worker def LRETL : I <0xCB, RawFrm, (outs), (ins), 45*9880d681SAndroid Build Coastguard Worker "{l}ret{l|f}", [], IIC_RET>, OpSize32; 46*9880d681SAndroid Build Coastguard Worker def LRETQ : RI <0xCB, RawFrm, (outs), (ins), 47*9880d681SAndroid Build Coastguard Worker "{l}ret{|f}q", [], IIC_RET>, Requires<[In64BitMode]>; 48*9880d681SAndroid Build Coastguard Worker def LRETW : I <0xCB, RawFrm, (outs), (ins), 49*9880d681SAndroid Build Coastguard Worker "{l}ret{w|f}", [], IIC_RET>, OpSize16; 50*9880d681SAndroid Build Coastguard Worker def LRETIL : Ii16<0xCA, RawFrm, (outs), (ins i16imm:$amt), 51*9880d681SAndroid Build Coastguard Worker "{l}ret{l|f}\t$amt", [], IIC_RET>, OpSize32; 52*9880d681SAndroid Build Coastguard Worker def LRETIQ : RIi16<0xCA, RawFrm, (outs), (ins i16imm:$amt), 53*9880d681SAndroid Build Coastguard Worker "{l}ret{|f}q\t$amt", [], IIC_RET>, Requires<[In64BitMode]>; 54*9880d681SAndroid Build Coastguard Worker def LRETIW : Ii16<0xCA, RawFrm, (outs), (ins i16imm:$amt), 55*9880d681SAndroid Build Coastguard Worker "{l}ret{w|f}\t$amt", [], IIC_RET>, OpSize16; 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Worker // The machine return from interrupt instruction, but sometimes we need to 58*9880d681SAndroid Build Coastguard Worker // perform a post-epilogue stack adjustment. Codegen emits the pseudo form 59*9880d681SAndroid Build Coastguard Worker // which expands to include an SP adjustment if necessary. 60*9880d681SAndroid Build Coastguard Worker def IRET16 : I <0xcf, RawFrm, (outs), (ins), "iret{w}", [], IIC_IRET>, 61*9880d681SAndroid Build Coastguard Worker OpSize16; 62*9880d681SAndroid Build Coastguard Worker def IRET32 : I <0xcf, RawFrm, (outs), (ins), "iret{l|d}", [], 63*9880d681SAndroid Build Coastguard Worker IIC_IRET>, OpSize32; 64*9880d681SAndroid Build Coastguard Worker def IRET64 : RI <0xcf, RawFrm, (outs), (ins), "iretq", [], 65*9880d681SAndroid Build Coastguard Worker IIC_IRET>, Requires<[In64BitMode]>; 66*9880d681SAndroid Build Coastguard Worker let isCodeGenOnly = 1 in 67*9880d681SAndroid Build Coastguard Worker def IRET : PseudoI<(outs), (ins i32imm:$adj), [(X86iret timm:$adj)]>; 68*9880d681SAndroid Build Coastguard Worker def RET : PseudoI<(outs), (ins i32imm:$adj, variable_ops), [(X86retflag timm:$adj)]>; 69*9880d681SAndroid Build Coastguard Worker} 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Worker// Unconditional branches. 72*9880d681SAndroid Build Coastguard Workerlet isBarrier = 1, isBranch = 1, isTerminator = 1, SchedRW = [WriteJump] in { 73*9880d681SAndroid Build Coastguard Worker def JMP_1 : Ii8PCRel<0xEB, RawFrm, (outs), (ins brtarget8:$dst), 74*9880d681SAndroid Build Coastguard Worker "jmp\t$dst", [(br bb:$dst)], IIC_JMP_REL>; 75*9880d681SAndroid Build Coastguard Worker let hasSideEffects = 0, isCodeGenOnly = 1, ForceDisassemble = 1 in { 76*9880d681SAndroid Build Coastguard Worker def JMP_2 : Ii16PCRel<0xE9, RawFrm, (outs), (ins brtarget16:$dst), 77*9880d681SAndroid Build Coastguard Worker "jmp\t$dst", [], IIC_JMP_REL>, OpSize16; 78*9880d681SAndroid Build Coastguard Worker def JMP_4 : Ii32PCRel<0xE9, RawFrm, (outs), (ins brtarget32:$dst), 79*9880d681SAndroid Build Coastguard Worker "jmp\t$dst", [], IIC_JMP_REL>, OpSize32; 80*9880d681SAndroid Build Coastguard Worker } 81*9880d681SAndroid Build Coastguard Worker} 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Worker// Conditional Branches. 84*9880d681SAndroid Build Coastguard Workerlet isBranch = 1, isTerminator = 1, Uses = [EFLAGS], SchedRW = [WriteJump] in { 85*9880d681SAndroid Build Coastguard Worker multiclass ICBr<bits<8> opc1, bits<8> opc4, string asm, PatFrag Cond> { 86*9880d681SAndroid Build Coastguard Worker def _1 : Ii8PCRel <opc1, RawFrm, (outs), (ins brtarget8:$dst), asm, 87*9880d681SAndroid Build Coastguard Worker [(X86brcond bb:$dst, Cond, EFLAGS)], IIC_Jcc>; 88*9880d681SAndroid Build Coastguard Worker let hasSideEffects = 0, isCodeGenOnly = 1, ForceDisassemble = 1 in { 89*9880d681SAndroid Build Coastguard Worker def _2 : Ii16PCRel<opc4, RawFrm, (outs), (ins brtarget16:$dst), asm, 90*9880d681SAndroid Build Coastguard Worker [], IIC_Jcc>, OpSize16, TB; 91*9880d681SAndroid Build Coastguard Worker def _4 : Ii32PCRel<opc4, RawFrm, (outs), (ins brtarget32:$dst), asm, 92*9880d681SAndroid Build Coastguard Worker [], IIC_Jcc>, TB, OpSize32; 93*9880d681SAndroid Build Coastguard Worker } 94*9880d681SAndroid Build Coastguard Worker } 95*9880d681SAndroid Build Coastguard Worker} 96*9880d681SAndroid Build Coastguard Worker 97*9880d681SAndroid Build Coastguard Workerdefm JO : ICBr<0x70, 0x80, "jo\t$dst" , X86_COND_O>; 98*9880d681SAndroid Build Coastguard Workerdefm JNO : ICBr<0x71, 0x81, "jno\t$dst", X86_COND_NO>; 99*9880d681SAndroid Build Coastguard Workerdefm JB : ICBr<0x72, 0x82, "jb\t$dst" , X86_COND_B>; 100*9880d681SAndroid Build Coastguard Workerdefm JAE : ICBr<0x73, 0x83, "jae\t$dst", X86_COND_AE>; 101*9880d681SAndroid Build Coastguard Workerdefm JE : ICBr<0x74, 0x84, "je\t$dst" , X86_COND_E>; 102*9880d681SAndroid Build Coastguard Workerdefm JNE : ICBr<0x75, 0x85, "jne\t$dst", X86_COND_NE>; 103*9880d681SAndroid Build Coastguard Workerdefm JBE : ICBr<0x76, 0x86, "jbe\t$dst", X86_COND_BE>; 104*9880d681SAndroid Build Coastguard Workerdefm JA : ICBr<0x77, 0x87, "ja\t$dst" , X86_COND_A>; 105*9880d681SAndroid Build Coastguard Workerdefm JS : ICBr<0x78, 0x88, "js\t$dst" , X86_COND_S>; 106*9880d681SAndroid Build Coastguard Workerdefm JNS : ICBr<0x79, 0x89, "jns\t$dst", X86_COND_NS>; 107*9880d681SAndroid Build Coastguard Workerdefm JP : ICBr<0x7A, 0x8A, "jp\t$dst" , X86_COND_P>; 108*9880d681SAndroid Build Coastguard Workerdefm JNP : ICBr<0x7B, 0x8B, "jnp\t$dst", X86_COND_NP>; 109*9880d681SAndroid Build Coastguard Workerdefm JL : ICBr<0x7C, 0x8C, "jl\t$dst" , X86_COND_L>; 110*9880d681SAndroid Build Coastguard Workerdefm JGE : ICBr<0x7D, 0x8D, "jge\t$dst", X86_COND_GE>; 111*9880d681SAndroid Build Coastguard Workerdefm JLE : ICBr<0x7E, 0x8E, "jle\t$dst", X86_COND_LE>; 112*9880d681SAndroid Build Coastguard Workerdefm JG : ICBr<0x7F, 0x8F, "jg\t$dst" , X86_COND_G>; 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Worker// jcx/jecx/jrcx instructions. 115*9880d681SAndroid Build Coastguard Workerlet isBranch = 1, isTerminator = 1, hasSideEffects = 0, SchedRW = [WriteJump] in { 116*9880d681SAndroid Build Coastguard Worker // These are the 32-bit versions of this instruction for the asmparser. In 117*9880d681SAndroid Build Coastguard Worker // 32-bit mode, the address size prefix is jcxz and the unprefixed version is 118*9880d681SAndroid Build Coastguard Worker // jecxz. 119*9880d681SAndroid Build Coastguard Worker let Uses = [CX] in 120*9880d681SAndroid Build Coastguard Worker def JCXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst), 121*9880d681SAndroid Build Coastguard Worker "jcxz\t$dst", [], IIC_JCXZ>, AdSize16, 122*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>; 123*9880d681SAndroid Build Coastguard Worker let Uses = [ECX] in 124*9880d681SAndroid Build Coastguard Worker def JECXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst), 125*9880d681SAndroid Build Coastguard Worker "jecxz\t$dst", [], IIC_JCXZ>, AdSize32; 126*9880d681SAndroid Build Coastguard Worker 127*9880d681SAndroid Build Coastguard Worker let Uses = [RCX] in 128*9880d681SAndroid Build Coastguard Worker def JRCXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst), 129*9880d681SAndroid Build Coastguard Worker "jrcxz\t$dst", [], IIC_JCXZ>, AdSize64, 130*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 131*9880d681SAndroid Build Coastguard Worker} 132*9880d681SAndroid Build Coastguard Worker 133*9880d681SAndroid Build Coastguard Worker// Indirect branches 134*9880d681SAndroid Build Coastguard Workerlet isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { 135*9880d681SAndroid Build Coastguard Worker def JMP16r : I<0xFF, MRM4r, (outs), (ins GR16:$dst), "jmp{w}\t{*}$dst", 136*9880d681SAndroid Build Coastguard Worker [(brind GR16:$dst)], IIC_JMP_REG>, Requires<[Not64BitMode]>, 137*9880d681SAndroid Build Coastguard Worker OpSize16, Sched<[WriteJump]>; 138*9880d681SAndroid Build Coastguard Worker def JMP16m : I<0xFF, MRM4m, (outs), (ins i16mem:$dst), "jmp{w}\t{*}$dst", 139*9880d681SAndroid Build Coastguard Worker [(brind (loadi16 addr:$dst))], IIC_JMP_MEM>, 140*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>, OpSize16, Sched<[WriteJumpLd]>; 141*9880d681SAndroid Build Coastguard Worker 142*9880d681SAndroid Build Coastguard Worker def JMP32r : I<0xFF, MRM4r, (outs), (ins GR32:$dst), "jmp{l}\t{*}$dst", 143*9880d681SAndroid Build Coastguard Worker [(brind GR32:$dst)], IIC_JMP_REG>, Requires<[Not64BitMode]>, 144*9880d681SAndroid Build Coastguard Worker OpSize32, Sched<[WriteJump]>; 145*9880d681SAndroid Build Coastguard Worker def JMP32m : I<0xFF, MRM4m, (outs), (ins i32mem:$dst), "jmp{l}\t{*}$dst", 146*9880d681SAndroid Build Coastguard Worker [(brind (loadi32 addr:$dst))], IIC_JMP_MEM>, 147*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>, OpSize32, Sched<[WriteJumpLd]>; 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Worker def JMP64r : I<0xFF, MRM4r, (outs), (ins GR64:$dst), "jmp{q}\t{*}$dst", 150*9880d681SAndroid Build Coastguard Worker [(brind GR64:$dst)], IIC_JMP_REG>, Requires<[In64BitMode]>, 151*9880d681SAndroid Build Coastguard Worker Sched<[WriteJump]>; 152*9880d681SAndroid Build Coastguard Worker def JMP64m : I<0xFF, MRM4m, (outs), (ins i64mem:$dst), "jmp{q}\t{*}$dst", 153*9880d681SAndroid Build Coastguard Worker [(brind (loadi64 addr:$dst))], IIC_JMP_MEM>, 154*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>, Sched<[WriteJumpLd]>; 155*9880d681SAndroid Build Coastguard Worker 156*9880d681SAndroid Build Coastguard Worker let Predicates = [Not64BitMode] in { 157*9880d681SAndroid Build Coastguard Worker def FARJMP16i : Iseg16<0xEA, RawFrmImm16, (outs), 158*9880d681SAndroid Build Coastguard Worker (ins i16imm:$off, i16imm:$seg), 159*9880d681SAndroid Build Coastguard Worker "ljmp{w}\t$seg, $off", [], 160*9880d681SAndroid Build Coastguard Worker IIC_JMP_FAR_PTR>, OpSize16, Sched<[WriteJump]>; 161*9880d681SAndroid Build Coastguard Worker def FARJMP32i : Iseg32<0xEA, RawFrmImm16, (outs), 162*9880d681SAndroid Build Coastguard Worker (ins i32imm:$off, i16imm:$seg), 163*9880d681SAndroid Build Coastguard Worker "ljmp{l}\t$seg, $off", [], 164*9880d681SAndroid Build Coastguard Worker IIC_JMP_FAR_PTR>, OpSize32, Sched<[WriteJump]>; 165*9880d681SAndroid Build Coastguard Worker } 166*9880d681SAndroid Build Coastguard Worker def FARJMP64 : RI<0xFF, MRM5m, (outs), (ins opaque80mem:$dst), 167*9880d681SAndroid Build Coastguard Worker "ljmp{q}\t{*}$dst", [], IIC_JMP_FAR_MEM>, 168*9880d681SAndroid Build Coastguard Worker Sched<[WriteJump]>; 169*9880d681SAndroid Build Coastguard Worker 170*9880d681SAndroid Build Coastguard Worker def FARJMP16m : I<0xFF, MRM5m, (outs), (ins opaque32mem:$dst), 171*9880d681SAndroid Build Coastguard Worker "ljmp{w}\t{*}$dst", [], IIC_JMP_FAR_MEM>, OpSize16, 172*9880d681SAndroid Build Coastguard Worker Sched<[WriteJumpLd]>; 173*9880d681SAndroid Build Coastguard Worker def FARJMP32m : I<0xFF, MRM5m, (outs), (ins opaque48mem:$dst), 174*9880d681SAndroid Build Coastguard Worker "ljmp{l}\t{*}$dst", [], IIC_JMP_FAR_MEM>, OpSize32, 175*9880d681SAndroid Build Coastguard Worker Sched<[WriteJumpLd]>; 176*9880d681SAndroid Build Coastguard Worker} 177*9880d681SAndroid Build Coastguard Worker 178*9880d681SAndroid Build Coastguard Worker 179*9880d681SAndroid Build Coastguard Worker// Loop instructions 180*9880d681SAndroid Build Coastguard Workerlet SchedRW = [WriteJump] in { 181*9880d681SAndroid Build Coastguard Workerdef LOOP : Ii8PCRel<0xE2, RawFrm, (outs), (ins brtarget8:$dst), "loop\t$dst", [], IIC_LOOP>; 182*9880d681SAndroid Build Coastguard Workerdef LOOPE : Ii8PCRel<0xE1, RawFrm, (outs), (ins brtarget8:$dst), "loope\t$dst", [], IIC_LOOPE>; 183*9880d681SAndroid Build Coastguard Workerdef LOOPNE : Ii8PCRel<0xE0, RawFrm, (outs), (ins brtarget8:$dst), "loopne\t$dst", [], IIC_LOOPNE>; 184*9880d681SAndroid Build Coastguard Worker} 185*9880d681SAndroid Build Coastguard Worker 186*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 187*9880d681SAndroid Build Coastguard Worker// Call Instructions... 188*9880d681SAndroid Build Coastguard Worker// 189*9880d681SAndroid Build Coastguard Workerlet isCall = 1 in 190*9880d681SAndroid Build Coastguard Worker // All calls clobber the non-callee saved registers. ESP is marked as 191*9880d681SAndroid Build Coastguard Worker // a use to prevent stack-pointer assignments that appear immediately 192*9880d681SAndroid Build Coastguard Worker // before calls from potentially appearing dead. Uses for argument 193*9880d681SAndroid Build Coastguard Worker // registers are added manually. 194*9880d681SAndroid Build Coastguard Worker let Uses = [ESP] in { 195*9880d681SAndroid Build Coastguard Worker def CALLpcrel32 : Ii32PCRel<0xE8, RawFrm, 196*9880d681SAndroid Build Coastguard Worker (outs), (ins i32imm_pcrel:$dst), 197*9880d681SAndroid Build Coastguard Worker "call{l}\t$dst", [], IIC_CALL_RI>, OpSize32, 198*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode]>, Sched<[WriteJump]>; 199*9880d681SAndroid Build Coastguard Worker let hasSideEffects = 0 in 200*9880d681SAndroid Build Coastguard Worker def CALLpcrel16 : Ii16PCRel<0xE8, RawFrm, 201*9880d681SAndroid Build Coastguard Worker (outs), (ins i16imm_pcrel:$dst), 202*9880d681SAndroid Build Coastguard Worker "call{w}\t$dst", [], IIC_CALL_RI>, OpSize16, 203*9880d681SAndroid Build Coastguard Worker Sched<[WriteJump]>; 204*9880d681SAndroid Build Coastguard Worker def CALL16r : I<0xFF, MRM2r, (outs), (ins GR16:$dst), 205*9880d681SAndroid Build Coastguard Worker "call{w}\t{*}$dst", [(X86call GR16:$dst)], IIC_CALL_RI>, 206*9880d681SAndroid Build Coastguard Worker OpSize16, Requires<[Not64BitMode]>, Sched<[WriteJump]>; 207*9880d681SAndroid Build Coastguard Worker def CALL16m : I<0xFF, MRM2m, (outs), (ins i16mem:$dst), 208*9880d681SAndroid Build Coastguard Worker "call{w}\t{*}$dst", [(X86call (loadi16 addr:$dst))], 209*9880d681SAndroid Build Coastguard Worker IIC_CALL_MEM>, OpSize16, 210*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode,FavorMemIndirectCall]>, 211*9880d681SAndroid Build Coastguard Worker Sched<[WriteJumpLd]>; 212*9880d681SAndroid Build Coastguard Worker def CALL32r : I<0xFF, MRM2r, (outs), (ins GR32:$dst), 213*9880d681SAndroid Build Coastguard Worker "call{l}\t{*}$dst", [(X86call GR32:$dst)], IIC_CALL_RI>, 214*9880d681SAndroid Build Coastguard Worker OpSize32, Requires<[Not64BitMode]>, Sched<[WriteJump]>; 215*9880d681SAndroid Build Coastguard Worker def CALL32m : I<0xFF, MRM2m, (outs), (ins i32mem:$dst), 216*9880d681SAndroid Build Coastguard Worker "call{l}\t{*}$dst", [(X86call (loadi32 addr:$dst))], 217*9880d681SAndroid Build Coastguard Worker IIC_CALL_MEM>, OpSize32, 218*9880d681SAndroid Build Coastguard Worker Requires<[Not64BitMode,FavorMemIndirectCall]>, 219*9880d681SAndroid Build Coastguard Worker Sched<[WriteJumpLd]>; 220*9880d681SAndroid Build Coastguard Worker 221*9880d681SAndroid Build Coastguard Worker let Predicates = [Not64BitMode] in { 222*9880d681SAndroid Build Coastguard Worker def FARCALL16i : Iseg16<0x9A, RawFrmImm16, (outs), 223*9880d681SAndroid Build Coastguard Worker (ins i16imm:$off, i16imm:$seg), 224*9880d681SAndroid Build Coastguard Worker "lcall{w}\t$seg, $off", [], 225*9880d681SAndroid Build Coastguard Worker IIC_CALL_FAR_PTR>, OpSize16, Sched<[WriteJump]>; 226*9880d681SAndroid Build Coastguard Worker def FARCALL32i : Iseg32<0x9A, RawFrmImm16, (outs), 227*9880d681SAndroid Build Coastguard Worker (ins i32imm:$off, i16imm:$seg), 228*9880d681SAndroid Build Coastguard Worker "lcall{l}\t$seg, $off", [], 229*9880d681SAndroid Build Coastguard Worker IIC_CALL_FAR_PTR>, OpSize32, Sched<[WriteJump]>; 230*9880d681SAndroid Build Coastguard Worker } 231*9880d681SAndroid Build Coastguard Worker 232*9880d681SAndroid Build Coastguard Worker def FARCALL16m : I<0xFF, MRM3m, (outs), (ins opaque32mem:$dst), 233*9880d681SAndroid Build Coastguard Worker "lcall{w}\t{*}$dst", [], IIC_CALL_FAR_MEM>, OpSize16, 234*9880d681SAndroid Build Coastguard Worker Sched<[WriteJumpLd]>; 235*9880d681SAndroid Build Coastguard Worker def FARCALL32m : I<0xFF, MRM3m, (outs), (ins opaque48mem:$dst), 236*9880d681SAndroid Build Coastguard Worker "lcall{l}\t{*}$dst", [], IIC_CALL_FAR_MEM>, OpSize32, 237*9880d681SAndroid Build Coastguard Worker Sched<[WriteJumpLd]>; 238*9880d681SAndroid Build Coastguard Worker } 239*9880d681SAndroid Build Coastguard Worker 240*9880d681SAndroid Build Coastguard Worker 241*9880d681SAndroid Build Coastguard Worker// Tail call stuff. 242*9880d681SAndroid Build Coastguard Worker 243*9880d681SAndroid Build Coastguard Workerlet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, 244*9880d681SAndroid Build Coastguard Worker isCodeGenOnly = 1, SchedRW = [WriteJumpLd] in 245*9880d681SAndroid Build Coastguard Worker let Uses = [ESP] in { 246*9880d681SAndroid Build Coastguard Worker def TCRETURNdi : PseudoI<(outs), 247*9880d681SAndroid Build Coastguard Worker (ins i32imm_pcrel:$dst, i32imm:$offset), []>; 248*9880d681SAndroid Build Coastguard Worker def TCRETURNri : PseudoI<(outs), 249*9880d681SAndroid Build Coastguard Worker (ins ptr_rc_tailcall:$dst, i32imm:$offset), []>; 250*9880d681SAndroid Build Coastguard Worker let mayLoad = 1 in 251*9880d681SAndroid Build Coastguard Worker def TCRETURNmi : PseudoI<(outs), 252*9880d681SAndroid Build Coastguard Worker (ins i32mem_TC:$dst, i32imm:$offset), []>; 253*9880d681SAndroid Build Coastguard Worker 254*9880d681SAndroid Build Coastguard Worker // FIXME: The should be pseudo instructions that are lowered when going to 255*9880d681SAndroid Build Coastguard Worker // mcinst. 256*9880d681SAndroid Build Coastguard Worker def TAILJMPd : Ii32PCRel<0xE9, RawFrm, (outs), 257*9880d681SAndroid Build Coastguard Worker (ins i32imm_pcrel:$dst), 258*9880d681SAndroid Build Coastguard Worker "jmp\t$dst", 259*9880d681SAndroid Build Coastguard Worker [], IIC_JMP_REL>; 260*9880d681SAndroid Build Coastguard Worker def TAILJMPr : I<0xFF, MRM4r, (outs), (ins ptr_rc_tailcall:$dst), 261*9880d681SAndroid Build Coastguard Worker "", [], IIC_JMP_REG>; // FIXME: Remove encoding when JIT is dead. 262*9880d681SAndroid Build Coastguard Worker let mayLoad = 1 in 263*9880d681SAndroid Build Coastguard Worker def TAILJMPm : I<0xFF, MRM4m, (outs), (ins i32mem_TC:$dst), 264*9880d681SAndroid Build Coastguard Worker "jmp{l}\t{*}$dst", [], IIC_JMP_MEM>; 265*9880d681SAndroid Build Coastguard Worker} 266*9880d681SAndroid Build Coastguard Worker 267*9880d681SAndroid Build Coastguard Worker 268*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===// 269*9880d681SAndroid Build Coastguard Worker// Call Instructions... 270*9880d681SAndroid Build Coastguard Worker// 271*9880d681SAndroid Build Coastguard Worker 272*9880d681SAndroid Build Coastguard Worker// RSP is marked as a use to prevent stack-pointer assignments that appear 273*9880d681SAndroid Build Coastguard Worker// immediately before calls from potentially appearing dead. Uses for argument 274*9880d681SAndroid Build Coastguard Worker// registers are added manually. 275*9880d681SAndroid Build Coastguard Workerlet isCall = 1, Uses = [RSP], SchedRW = [WriteJump] in { 276*9880d681SAndroid Build Coastguard Worker // NOTE: this pattern doesn't match "X86call imm", because we do not know 277*9880d681SAndroid Build Coastguard Worker // that the offset between an arbitrary immediate and the call will fit in 278*9880d681SAndroid Build Coastguard Worker // the 32-bit pcrel field that we have. 279*9880d681SAndroid Build Coastguard Worker def CALL64pcrel32 : Ii32PCRel<0xE8, RawFrm, 280*9880d681SAndroid Build Coastguard Worker (outs), (ins i64i32imm_pcrel:$dst), 281*9880d681SAndroid Build Coastguard Worker "call{q}\t$dst", [], IIC_CALL_RI>, OpSize32, 282*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 283*9880d681SAndroid Build Coastguard Worker def CALL64r : I<0xFF, MRM2r, (outs), (ins GR64:$dst), 284*9880d681SAndroid Build Coastguard Worker "call{q}\t{*}$dst", [(X86call GR64:$dst)], 285*9880d681SAndroid Build Coastguard Worker IIC_CALL_RI>, 286*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode]>; 287*9880d681SAndroid Build Coastguard Worker def CALL64m : I<0xFF, MRM2m, (outs), (ins i64mem:$dst), 288*9880d681SAndroid Build Coastguard Worker "call{q}\t{*}$dst", [(X86call (loadi64 addr:$dst))], 289*9880d681SAndroid Build Coastguard Worker IIC_CALL_MEM>, 290*9880d681SAndroid Build Coastguard Worker Requires<[In64BitMode,FavorMemIndirectCall]>; 291*9880d681SAndroid Build Coastguard Worker 292*9880d681SAndroid Build Coastguard Worker def FARCALL64 : RI<0xFF, MRM3m, (outs), (ins opaque80mem:$dst), 293*9880d681SAndroid Build Coastguard Worker "lcall{q}\t{*}$dst", [], IIC_CALL_FAR_MEM>; 294*9880d681SAndroid Build Coastguard Worker} 295*9880d681SAndroid Build Coastguard Worker 296*9880d681SAndroid Build Coastguard Workerlet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, 297*9880d681SAndroid Build Coastguard Worker isCodeGenOnly = 1, Uses = [RSP], usesCustomInserter = 1, 298*9880d681SAndroid Build Coastguard Worker SchedRW = [WriteJump] in { 299*9880d681SAndroid Build Coastguard Worker def TCRETURNdi64 : PseudoI<(outs), 300*9880d681SAndroid Build Coastguard Worker (ins i64i32imm_pcrel:$dst, i32imm:$offset), 301*9880d681SAndroid Build Coastguard Worker []>; 302*9880d681SAndroid Build Coastguard Worker def TCRETURNri64 : PseudoI<(outs), 303*9880d681SAndroid Build Coastguard Worker (ins ptr_rc_tailcall:$dst, i32imm:$offset), []>; 304*9880d681SAndroid Build Coastguard Worker let mayLoad = 1 in 305*9880d681SAndroid Build Coastguard Worker def TCRETURNmi64 : PseudoI<(outs), 306*9880d681SAndroid Build Coastguard Worker (ins i64mem_TC:$dst, i32imm:$offset), []>; 307*9880d681SAndroid Build Coastguard Worker 308*9880d681SAndroid Build Coastguard Worker def TAILJMPd64 : Ii32PCRel<0xE9, RawFrm, (outs), (ins i64i32imm_pcrel:$dst), 309*9880d681SAndroid Build Coastguard Worker "jmp\t$dst", [], IIC_JMP_REL>; 310*9880d681SAndroid Build Coastguard Worker def TAILJMPr64 : I<0xFF, MRM4r, (outs), (ins ptr_rc_tailcall:$dst), 311*9880d681SAndroid Build Coastguard Worker "jmp{q}\t{*}$dst", [], IIC_JMP_MEM>; 312*9880d681SAndroid Build Coastguard Worker 313*9880d681SAndroid Build Coastguard Worker let mayLoad = 1 in 314*9880d681SAndroid Build Coastguard Worker def TAILJMPm64 : I<0xFF, MRM4m, (outs), (ins i64mem_TC:$dst), 315*9880d681SAndroid Build Coastguard Worker "jmp{q}\t{*}$dst", [], IIC_JMP_MEM>; 316*9880d681SAndroid Build Coastguard Worker 317*9880d681SAndroid Build Coastguard Worker // Win64 wants jumps leaving the function to have a REX_W prefix. 318*9880d681SAndroid Build Coastguard Worker let hasREX_WPrefix = 1 in { 319*9880d681SAndroid Build Coastguard Worker def TAILJMPd64_REX : Ii32PCRel<0xE9, RawFrm, (outs), 320*9880d681SAndroid Build Coastguard Worker (ins i64i32imm_pcrel:$dst), 321*9880d681SAndroid Build Coastguard Worker "rex64 jmp\t$dst", [], IIC_JMP_REL>; 322*9880d681SAndroid Build Coastguard Worker def TAILJMPr64_REX : I<0xFF, MRM4r, (outs), (ins ptr_rc_tailcall:$dst), 323*9880d681SAndroid Build Coastguard Worker "rex64 jmp{q}\t{*}$dst", [], IIC_JMP_MEM>; 324*9880d681SAndroid Build Coastguard Worker 325*9880d681SAndroid Build Coastguard Worker let mayLoad = 1 in 326*9880d681SAndroid Build Coastguard Worker def TAILJMPm64_REX : I<0xFF, MRM4m, (outs), (ins i64mem_TC:$dst), 327*9880d681SAndroid Build Coastguard Worker "rex64 jmp{q}\t{*}$dst", [], IIC_JMP_MEM>; 328*9880d681SAndroid Build Coastguard Worker } 329*9880d681SAndroid Build Coastguard Worker} 330