454 lines · plain
1//===-- X86InstrControl.td - Control Flow Instructions -----*- tablegen -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file describes the X86 jump, return, call, and related instructions.10//11//===----------------------------------------------------------------------===//12 13//===----------------------------------------------------------------------===//14// Control Flow Instructions.15//16 17// Return instructions.18//19// The X86retglue return instructions are variadic because we may add ST0 and20// ST1 arguments when returning values on the x87 stack.21let isTerminator = 1, isReturn = 1, isBarrier = 1,22 hasCtrlDep = 1, FPForm = SpecialFP, SchedRW = [WriteJumpLd] in {23 def RET32 : I <0xC3, RawFrm, (outs), (ins variable_ops),24 "ret{l}", []>, OpSize32, Requires<[Not64BitMode]>;25 def RET64 : I <0xC3, RawFrm, (outs), (ins variable_ops),26 "ret{q}", []>, OpSize32, Requires<[In64BitMode]>;27 def RET16 : I <0xC3, RawFrm, (outs), (ins),28 "ret{w}", []>, OpSize16;29 def RETI32 : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt, variable_ops),30 "ret{l}\t$amt", []>, OpSize32, Requires<[Not64BitMode]>;31 def RETI64 : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt, variable_ops),32 "ret{q}\t$amt", []>, OpSize32, Requires<[In64BitMode]>;33 def RETI16 : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt),34 "ret{w}\t$amt", []>, OpSize16;35 def LRET32 : I <0xCB, RawFrm, (outs), (ins),36 "{l}ret{l|f}", []>, OpSize32;37 def LRET64 : RI <0xCB, RawFrm, (outs), (ins),38 "{l}ret{|f}q", []>, Requires<[In64BitMode]>;39 def LRET16 : I <0xCB, RawFrm, (outs), (ins),40 "{l}ret{w|f}", []>, OpSize16;41 def LRETI32 : Ii16<0xCA, RawFrm, (outs), (ins i16imm:$amt),42 "{l}ret{l|f}\t$amt", []>, OpSize32;43 def LRETI64 : RIi16<0xCA, RawFrm, (outs), (ins i16imm:$amt),44 "{l}ret{|f}q\t$amt", []>, Requires<[In64BitMode]>;45 def LRETI16 : Ii16<0xCA, RawFrm, (outs), (ins i16imm:$amt),46 "{l}ret{w|f}\t$amt", []>, OpSize16;47 48 // The machine return from interrupt instruction, but sometimes we need to49 // perform a post-epilogue stack adjustment. Codegen emits the pseudo form50 // which expands to include an SP adjustment if necessary.51 def IRET16 : I <0xcf, RawFrm, (outs), (ins), "iret{w}", []>,52 OpSize16;53 def IRET32 : I <0xcf, RawFrm, (outs), (ins), "iret{l|d}", []>, OpSize32;54 def IRET64 : RI <0xcf, RawFrm, (outs), (ins), "iretq", []>, Requires<[In64BitMode]>;55 let isCodeGenOnly = 1 in56 def IRET : PseudoI<(outs), (ins i32imm:$adj), [(X86iret timm:$adj)]>;57 def RET : PseudoI<(outs), (ins i32imm:$adj, variable_ops), [(X86retglue timm:$adj)]>;58}59 60// Unconditional branches.61let isBarrier = 1, isBranch = 1, isTerminator = 1, SchedRW = [WriteJump] in {62 def JMP_1 : Ii8PCRel<0xEB, RawFrm, (outs), (ins brtarget8:$dst),63 "jmp\t$dst", [(br bb:$dst)]>;64 let hasSideEffects = 0, isCodeGenOnly = 1, ForceDisassemble = 1 in {65 def JMP_2 : Ii16PCRel<0xE9, RawFrm, (outs), (ins brtarget16:$dst),66 "jmp\t$dst", []>, OpSize16;67 def JMP_4 : Ii32PCRel<0xE9, RawFrm, (outs), (ins brtarget32:$dst),68 "jmp\t$dst", []>, OpSize32;69 }70}71 72// Conditional Branches.73let isBranch = 1, isTerminator = 1, Uses = [EFLAGS], SchedRW = [WriteJump],74 isCodeGenOnly = 1, ForceDisassemble = 1 in {75 def JCC_1 : Ii8PCRel <0x70, AddCCFrm, (outs),76 (ins brtarget8:$dst, ccode:$cond),77 "j${cond}\t$dst",78 [(X86brcond bb:$dst, timm:$cond, EFLAGS)]>;79 let hasSideEffects = 0 in {80 def JCC_2 : Ii16PCRel<0x80, AddCCFrm, (outs),81 (ins brtarget16:$dst, ccode:$cond),82 "j${cond}\t$dst",83 []>, OpSize16, TB;84 def JCC_4 : Ii32PCRel<0x80, AddCCFrm, (outs),85 (ins brtarget32:$dst, ccode:$cond),86 "j${cond}\t$dst",87 []>, TB, OpSize32;88 }89}90 91// jcx/jecx/jrcx instructions.92let isBranch = 1, isTerminator = 1, hasSideEffects = 0, SchedRW = [WriteJump] in {93 // These are the 32-bit versions of this instruction for the asmparser. In94 // 32-bit mode, the address size prefix is jcxz and the unprefixed version is95 // jecxz.96 let Uses = [CX] in97 def JCXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins i8imm_brtarget:$dst),98 "jcxz\t$dst", []>, AdSize16, Requires<[Not64BitMode]>;99 let Uses = [ECX] in100 def JECXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins i8imm_brtarget:$dst),101 "jecxz\t$dst", []>, AdSize32;102 103 let Uses = [RCX] in104 def JRCXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins i8imm_brtarget:$dst),105 "jrcxz\t$dst", []>, AdSize64, Requires<[In64BitMode]>;106}107 108// Indirect branches109let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {110 def JMP16r : I<0xFF, MRM4r, (outs), (ins GR16:$dst), "jmp{w}\t{*}$dst",111 [(brind GR16:$dst)]>, Requires<[Not64BitMode]>,112 OpSize16, Sched<[WriteJump]>;113 def JMP16m : I<0xFF, MRM4m, (outs), (ins i16mem:$dst), "jmp{w}\t{*}$dst",114 [(brind (loadi16 addr:$dst))]>, Requires<[Not64BitMode]>,115 OpSize16, Sched<[WriteJumpLd]>;116 117 def JMP32r : I<0xFF, MRM4r, (outs), (ins GR32:$dst), "jmp{l}\t{*}$dst",118 [(brind GR32:$dst)]>, Requires<[Not64BitMode]>,119 OpSize32, Sched<[WriteJump]>;120 def JMP32m : I<0xFF, MRM4m, (outs), (ins i32mem:$dst), "jmp{l}\t{*}$dst",121 [(brind (loadi32 addr:$dst))]>, Requires<[Not64BitMode]>,122 OpSize32, Sched<[WriteJumpLd]>;123 124 def JMP64r : I<0xFF, MRM4r, (outs), (ins GR64:$dst), "jmp{q}\t{*}$dst",125 [(brind GR64:$dst)]>, Requires<[In64BitMode]>,126 Sched<[WriteJump]>;127 def JMP64m : I<0xFF, MRM4m, (outs), (ins i64mem:$dst), "jmp{q}\t{*}$dst",128 [(brind (loadi64 addr:$dst))]>, Requires<[In64BitMode]>,129 Sched<[WriteJumpLd]>;130 131 // Win64 wants indirect jumps leaving the function to have a REX_W prefix.132 // These are switched from TAILJMPr/m64_REX in MCInstLower.133 let isCodeGenOnly = 1, hasREX_W = 1 in {134 def JMP64r_REX : I<0xFF, MRM4r, (outs), (ins GR64:$dst),135 "rex64 jmp{q}\t{*}$dst", []>, Sched<[WriteJump]>;136 let mayLoad = 1 in137 def JMP64m_REX : I<0xFF, MRM4m, (outs), (ins i64mem:$dst),138 "rex64 jmp{q}\t{*}$dst", []>, Sched<[WriteJumpLd]>;139 140 }141 142 // Non-tracking jumps for IBT, use with caution.143 let isCodeGenOnly = 1 in {144 def JMP16r_NT : I<0xFF, MRM4r, (outs), (ins GR16 : $dst), "jmp{w}\t{*}$dst",145 [(X86NoTrackBrind GR16 : $dst)]>, Requires<[Not64BitMode]>,146 OpSize16, Sched<[WriteJump]>, NOTRACK;147 148 def JMP16m_NT : I<0xFF, MRM4m, (outs), (ins i16mem : $dst), "jmp{w}\t{*}$dst",149 [(X86NoTrackBrind (loadi16 addr : $dst))]>,150 Requires<[Not64BitMode]>, OpSize16, Sched<[WriteJumpLd]>,151 NOTRACK;152 153 def JMP32r_NT : I<0xFF, MRM4r, (outs), (ins GR32 : $dst), "jmp{l}\t{*}$dst",154 [(X86NoTrackBrind GR32 : $dst)]>, Requires<[Not64BitMode]>,155 OpSize32, Sched<[WriteJump]>, NOTRACK;156 def JMP32m_NT : I<0xFF, MRM4m, (outs), (ins i32mem : $dst), "jmp{l}\t{*}$dst",157 [(X86NoTrackBrind (loadi32 addr : $dst))]>,158 Requires<[Not64BitMode]>, OpSize32, Sched<[WriteJumpLd]>,159 NOTRACK;160 161 def JMP64r_NT : I<0xFF, MRM4r, (outs), (ins GR64 : $dst), "jmp{q}\t{*}$dst",162 [(X86NoTrackBrind GR64 : $dst)]>, Requires<[In64BitMode]>,163 Sched<[WriteJump]>, NOTRACK;164 def JMP64m_NT : I<0xFF, MRM4m, (outs), (ins i64mem : $dst), "jmp{q}\t{*}$dst",165 [(X86NoTrackBrind(loadi64 addr : $dst))]>,166 Requires<[In64BitMode]>, Sched<[WriteJumpLd]>, NOTRACK;167 }168 169 let Predicates = [Not64BitMode], AsmVariantName = "att" in {170 def FARJMP32i : Iseg32<0xEA, RawFrmImm16, (outs),171 (ins i32imm:$off, i16imm:$seg),172 "ljmp{l}\t$seg, $off", []>,173 OpSize32, Sched<[WriteJump]>;174 def FARJMP16i : Iseg16<0xEA, RawFrmImm16, (outs),175 (ins i16imm:$off, i16imm:$seg),176 "ljmp{w}\t$seg, $off", []>,177 OpSize16, Sched<[WriteJump]>;178 }179 let mayLoad = 1 in {180 def FARJMP64m : RI<0xFF, MRM5m, (outs), (ins opaquemem:$dst),181 "ljmp{q}\t{*}$dst", []>, Sched<[WriteJump]>, Requires<[In64BitMode]>;182 183 def FARJMP32m : I<0xFF, MRM5m, (outs), (ins opaquemem:$dst),184 "{l}jmp{l}\t{*}$dst", []>, OpSize32, Sched<[WriteJumpLd]>;185 let AsmVariantName = "att" in186 def FARJMP16m : I<0xFF, MRM5m, (outs), (ins opaquemem:$dst),187 "ljmp{w}\t{*}$dst", []>, OpSize16, Sched<[WriteJumpLd]>;188 }189}190 191def JMPABS64i : Ii64<0xA1, RawFrm, (outs), (ins i64imm:$dst), "jmpabs\t$dst", []>,192 ExplicitREX2Prefix, Requires<[In64BitMode]>, Sched<[WriteJumpLd]>;193 194// Loop instructions195let isBranch = 1, isTerminator = 1, SchedRW = [WriteJump] in {196 def LOOP : Ii8PCRel<0xE2, RawFrm, (outs), (ins i8imm_brtarget:$dst),197 "loop\t$dst", []>;198 def LOOPE : Ii8PCRel<0xE1, RawFrm, (outs), (ins i8imm_brtarget:$dst),199 "loope\t$dst", []>;200 def LOOPNE : Ii8PCRel<0xE0, RawFrm, (outs), (ins i8imm_brtarget:$dst),201 "loopne\t$dst", []>;202}203 204//===----------------------------------------------------------------------===//205// Call Instructions...206//207let isCall = 1 in208 // All calls clobber the non-callee saved registers. ESP is marked as209 // a use to prevent stack-pointer assignments that appear immediately210 // before calls from potentially appearing dead. Uses for argument211 // registers are added manually.212 let Uses = [ESP, SSP] in {213 def CALLpcrel32 : Ii32PCRel<0xE8, RawFrm,214 (outs), (ins i32imm_brtarget:$dst),215 "call{l}\t$dst", []>, OpSize32,216 Requires<[Not64BitMode]>, Sched<[WriteJump]>;217 let hasSideEffects = 0 in218 def CALLpcrel16 : Ii16PCRel<0xE8, RawFrm,219 (outs), (ins i16imm_brtarget:$dst),220 "call{w}\t$dst", []>, OpSize16,221 Requires<[Not64BitMode]>, Sched<[WriteJump]>;222 def CALL16r : I<0xFF, MRM2r, (outs), (ins GR16:$dst),223 "call{w}\t{*}$dst", [(X86call GR16:$dst)]>,224 OpSize16, Requires<[Not64BitMode]>, Sched<[WriteJump]>;225 def CALL16m : I<0xFF, MRM2m, (outs), (ins i16mem:$dst),226 "call{w}\t{*}$dst", [(X86call (loadi16 addr:$dst))]>,227 OpSize16, Requires<[Not64BitMode,FavorMemIndirectCall]>,228 Sched<[WriteJumpLd]>;229 def CALL32r : I<0xFF, MRM2r, (outs), (ins GR32:$dst),230 "call{l}\t{*}$dst", [(X86call GR32:$dst)]>, OpSize32,231 Requires<[Not64BitMode,NotUseIndirectThunkCalls]>,232 Sched<[WriteJump]>;233 def CALL32m : I<0xFF, MRM2m, (outs), (ins i32mem:$dst),234 "call{l}\t{*}$dst", [(X86call (loadi32 addr:$dst))]>,235 OpSize32,236 Requires<[Not64BitMode,FavorMemIndirectCall,237 NotUseIndirectThunkCalls]>,238 Sched<[WriteJumpLd]>;239 240 // Non-tracking calls for IBT, use with caution.241 let isCodeGenOnly = 1 in {242 def CALL16r_NT : I<0xFF, MRM2r, (outs), (ins GR16 : $dst),243 "call{w}\t{*}$dst",[(X86NoTrackCall GR16 : $dst)]>,244 OpSize16, Requires<[Not64BitMode]>, Sched<[WriteJump]>, NOTRACK;245 def CALL16m_NT : I<0xFF, MRM2m, (outs), (ins i16mem : $dst),246 "call{w}\t{*}$dst",[(X86NoTrackCall(loadi16 addr : $dst))]>,247 OpSize16, Requires<[Not64BitMode,FavorMemIndirectCall]>,248 Sched<[WriteJumpLd]>, NOTRACK;249 def CALL32r_NT : I<0xFF, MRM2r, (outs), (ins GR32 : $dst),250 "call{l}\t{*}$dst",[(X86NoTrackCall GR32 : $dst)]>,251 OpSize32, Requires<[Not64BitMode]>, Sched<[WriteJump]>, NOTRACK;252 def CALL32m_NT : I<0xFF, MRM2m, (outs), (ins i32mem : $dst),253 "call{l}\t{*}$dst",[(X86NoTrackCall(loadi32 addr : $dst))]>,254 OpSize32, Requires<[Not64BitMode,FavorMemIndirectCall]>,255 Sched<[WriteJumpLd]>, NOTRACK;256 }257 258 let Predicates = [Not64BitMode], AsmVariantName = "att" in {259 def FARCALL32i : Iseg32<0x9A, RawFrmImm16, (outs),260 (ins i32imm:$off, i16imm:$seg),261 "lcall{l}\t$seg, $off", []>,262 OpSize32, Sched<[WriteJump]>;263 def FARCALL16i : Iseg16<0x9A, RawFrmImm16, (outs),264 (ins i16imm:$off, i16imm:$seg),265 "lcall{w}\t$seg, $off", []>,266 OpSize16, Sched<[WriteJump]>;267 }268 269 let mayLoad = 1 in {270 def FARCALL32m : I<0xFF, MRM3m, (outs), (ins opaquemem:$dst),271 "{l}call{l}\t{*}$dst", []>, OpSize32, Sched<[WriteJumpLd]>;272 def FARCALL16m : I<0xFF, MRM3m, (outs), (ins opaquemem:$dst),273 "lcall{w}\t{*}$dst", []>, OpSize16, Sched<[WriteJumpLd]>;274 }275 }276 277 278// Tail call stuff.279let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,280 isCodeGenOnly = 1, Uses = [ESP, SSP] in {281 def TCRETURNdi : PseudoI<(outs), (ins i32imm_brtarget:$dst, i32imm:$offset),282 []>, Sched<[WriteJump]>;283 def TCRETURNri : PseudoI<(outs), (ins GR32_TC:$dst, i32imm:$offset),284 []>, Sched<[WriteJump]>;285 286 def TCRETURN_HIPE32ri : PseudoI<(outs), (ins GR32:$dst, i32imm:$offset),287 []>, Sched<[WriteJump]>;288 289 let mayLoad = 1 in290 def TCRETURNmi : PseudoI<(outs), (ins i32mem_TC:$dst, i32imm:$offset),291 []>, Sched<[WriteJumpLd]>;292 293 def TAILJMPd : PseudoI<(outs), (ins i32imm_brtarget:$dst),294 []>, Sched<[WriteJump]>;295 296 def TAILJMPr : PseudoI<(outs), (ins ptr_rc_tailcall:$dst),297 []>, Sched<[WriteJump]>;298 let mayLoad = 1 in299 def TAILJMPm : PseudoI<(outs), (ins i32mem_TC:$dst),300 []>, Sched<[WriteJumpLd]>;301}302 303// Conditional tail calls are similar to the above, but they are branches304// rather than barriers, and they use EFLAGS.305let isCall = 1, isTerminator = 1, isReturn = 1, isBranch = 1,306 isCodeGenOnly = 1, SchedRW = [WriteJump] in307 let Uses = [ESP, EFLAGS, SSP] in {308 def TCRETURNdicc : PseudoI<(outs),309 (ins i32imm_brtarget:$dst, i32imm:$offset, i32imm:$cond),310 []>;311 312 // This gets substituted to a conditional jump instruction in MC lowering.313 def TAILJMPd_CC : PseudoI<(outs), (ins i32imm_brtarget:$dst, i32imm:$cond), []>;314}315 316 317//===----------------------------------------------------------------------===//318// Call Instructions...319//320 321// RSP is marked as a use to prevent stack-pointer assignments that appear322// immediately before calls from potentially appearing dead. Uses for argument323// registers are added manually.324let isCall = 1, Uses = [RSP, SSP], SchedRW = [WriteJump] in {325 // NOTE: this pattern doesn't match "X86call imm", because we do not know326 // that the offset between an arbitrary immediate and the call will fit in327 // the 32-bit pcrel field that we have.328 def CALL64pcrel32 : Ii32PCRel<0xE8, RawFrm,329 (outs), (ins i64i32imm_brtarget:$dst),330 "call{q}\t$dst", []>, OpSize32,331 Requires<[In64BitMode]>;332 def CALL64r : I<0xFF, MRM2r, (outs), (ins GR64:$dst),333 "call{q}\t{*}$dst", [(X86call GR64:$dst)]>,334 Requires<[In64BitMode,NotUseIndirectThunkCalls,ImportCallOptimizationDisabled]>;335 def CALL64m : I<0xFF, MRM2m, (outs), (ins i64mem:$dst),336 "call{q}\t{*}$dst", [(X86call (loadi64 addr:$dst))]>,337 Requires<[In64BitMode,FavorMemIndirectCall,338 NotUseIndirectThunkCalls]>;339 340 // Non-tracking calls for IBT, use with caution.341 let isCodeGenOnly = 1 in {342 def CALL64r_NT : I<0xFF, MRM2r, (outs), (ins GR64 : $dst),343 "call{q}\t{*}$dst",[(X86NoTrackCall GR64 : $dst)]>,344 Requires<[In64BitMode]>, NOTRACK;345 def CALL64m_NT : I<0xFF, MRM2m, (outs), (ins i64mem : $dst),346 "call{q}\t{*}$dst",347 [(X86NoTrackCall(loadi64 addr : $dst))]>,348 Requires<[In64BitMode,FavorMemIndirectCall]>, NOTRACK;349 }350 351 let mayLoad = 1 in352 def FARCALL64m : RI<0xFF, MRM3m, (outs), (ins opaquemem:$dst),353 "lcall{q}\t{*}$dst", []>;354}355 356let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,357 isCodeGenOnly = 1, Uses = [RSP, SSP] in {358 def TCRETURNdi64 : PseudoI<(outs),359 (ins i64i32imm_brtarget:$dst, i32imm:$offset),360 []>, Sched<[WriteJump]>;361 def TCRETURNri64 : PseudoI<(outs),362 (ins GR64_TC:$dst, i32imm:$offset),363 []>, Sched<[WriteJump]>;364 def TCRETURN_WIN64ri : PseudoI<(outs), (ins GR64_TCW64:$dst, i32imm:$offset),365 []>, Sched<[WriteJump]>;366 367 def TCRETURNri64_ImpCall : PseudoI<(outs),368 (ins GR64_A:$dst, i32imm:$offset),369 []>, Sched<[WriteJump]>;370 371 let mayLoad = 1 in372 def TCRETURNmi64 : PseudoI<(outs),373 (ins i64mem_TC:$dst, i32imm:$offset),374 []>, Sched<[WriteJumpLd]>;375 def TCRETURN_WINmi64 : PseudoI<(outs),376 (ins i64mem_w64TC:$dst, i32imm:$offset),377 []>, Sched<[WriteJumpLd]>;378 379 def TAILJMPd64 : PseudoI<(outs), (ins i64i32imm_brtarget:$dst),380 []>, Sched<[WriteJump]>;381 382 def TAILJMPr64 : PseudoI<(outs), (ins ptr_rc_tailcall:$dst),383 []>, Sched<[WriteJump]>;384 385 let mayLoad = 1 in386 def TAILJMPm64 : PseudoI<(outs), (ins i64mem_TC:$dst),387 []>, Sched<[WriteJumpLd]>;388 389 // Win64 wants indirect jumps leaving the function to have a REX_W prefix.390 let hasREX_W = 1 in {391 def TAILJMPr64_REX : PseudoI<(outs), (ins ptr_rc_tailcall:$dst),392 []>, Sched<[WriteJump]>;393 394 let mayLoad = 1 in395 def TAILJMPm64_REX : PseudoI<(outs), (ins i64mem_TC:$dst),396 []>, Sched<[WriteJumpLd]>;397 }398}399 400let isPseudo = 1, isCall = 1, isCodeGenOnly = 1,401 Uses = [RSP, SSP],402 usesCustomInserter = 1,403 SchedRW = [WriteJump] in {404 def INDIRECT_THUNK_CALL32 :405 PseudoI<(outs), (ins GR32:$dst), [(X86call GR32:$dst)]>,406 Requires<[Not64BitMode,UseIndirectThunkCalls]>;407 408 def INDIRECT_THUNK_CALL64 :409 PseudoI<(outs), (ins GR64:$dst), [(X86call GR64:$dst)]>,410 Requires<[In64BitMode,UseIndirectThunkCalls]>;411 412 // Indirect thunk variant of indirect tail calls.413 let isTerminator = 1, isReturn = 1, isBarrier = 1 in {414 def INDIRECT_THUNK_TCRETURN64 :415 PseudoI<(outs), (ins GR64:$dst, i32imm:$offset), []>;416 def INDIRECT_THUNK_TCRETURN32 :417 PseudoI<(outs), (ins GR32:$dst, i32imm:$offset), []>;418 }419}420 421let isPseudo = 1, isCall = 1, isCodeGenOnly = 1,422 Uses = [RSP, SSP],423 SchedRW = [WriteJump] in {424 def CALL64m_RVMARKER :425 PseudoI<(outs), (ins i64imm:$rvfunc, i64mem:$dst), [(X86call_rvmarker tglobaladdr:$rvfunc, (loadi64 addr:$dst))]>,426 Requires<[In64BitMode]>;427 428 def CALL64r_RVMARKER :429 PseudoI<(outs), (ins i64imm:$rvfunc, GR64:$dst), [(X86call_rvmarker tglobaladdr:$rvfunc, GR64:$dst)]>,430 Requires<[In64BitMode]>;431 432 def CALL64pcrel32_RVMARKER :433 PseudoI<(outs), (ins i64imm:$rvfunc, i64i32imm_brtarget:$dst), []>,434 Requires<[In64BitMode]>;435 436 def CALL64r_ImpCall :437 PseudoI<(outs), (ins GR64_A:$dst), [(X86call GR64_A:$dst)]>,438 Requires<[In64BitMode,NotUseIndirectThunkCalls,ImportCallOptimizationEnabled]>;439}440 441// Conditional tail calls are similar to the above, but they are branches442// rather than barriers, and they use EFLAGS.443let isCall = 1, isTerminator = 1, isReturn = 1, isBranch = 1,444 isCodeGenOnly = 1, SchedRW = [WriteJump] in445 let Uses = [RSP, EFLAGS, SSP] in {446 def TCRETURNdi64cc : PseudoI<(outs),447 (ins i64i32imm_brtarget:$dst, i32imm:$offset,448 i32imm:$cond), []>;449 450 // This gets substituted to a conditional jump instruction in MC lowering.451 def TAILJMPd64_CC : PseudoI<(outs),452 (ins i64i32imm_brtarget:$dst, i32imm:$cond), []>;453}454