blob: 650bce74dcf243bca7cc1175ee603e9a1a8580b3 [file] [log] [blame]
Jia Liub22310f2012-02-18 12:03:15 +00001//===-- X86InstrControl.td - Control Flow Instructions -----*- tablegen -*-===//
NAKAMURA Takumi9d29eff2011-01-26 02:03:37 +00002//
Chris Lattnerae33f5d2010-10-05 06:04:14 +00003// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
NAKAMURA Takumi9d29eff2011-01-26 02:03:37 +00007//
Chris Lattnerae33f5d2010-10-05 06:04:14 +00008//===----------------------------------------------------------------------===//
9//
10// This file describes the X86 jump, return, call, and related instructions.
11//
12//===----------------------------------------------------------------------===//
13
14//===----------------------------------------------------------------------===//
15// Control Flow Instructions.
16//
17
18// Return instructions.
Jakob Stoklund Olesenb50cf8b2012-08-24 20:52:44 +000019//
20// The X86retflag return instructions are variadic because we may add ST0 and
21// ST1 arguments when returning values on the x87 stack.
Chris Lattnerae33f5d2010-10-05 06:04:14 +000022let isTerminator = 1, isReturn = 1, isBarrier = 1,
Jakob Stoklund Olesend59419eb2013-03-26 18:24:17 +000023 hasCtrlDep = 1, FPForm = SpecialFP, SchedRW = [WriteJumpLd] in {
David Woodhouse79dd5052014-01-08 12:58:07 +000024 def RETL : I <0xC3, RawFrm, (outs), (ins variable_ops),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000025 "ret{l}", []>, OpSize32, Requires<[Not64BitMode]>;
David Woodhouse79dd5052014-01-08 12:58:07 +000026 def RETQ : I <0xC3, RawFrm, (outs), (ins variable_ops),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000027 "ret{q}", []>, OpSize32, Requires<[In64BitMode]>;
Jakob Stoklund Olesend14101e2012-07-04 23:53:27 +000028 def RETW : I <0xC3, RawFrm, (outs), (ins),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000029 "ret{w}", []>, OpSize16;
David Woodhouse4e033b02014-01-13 14:05:59 +000030 def RETIL : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt, variable_ops),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000031 "ret{l}\t$amt", []>, OpSize32, Requires<[Not64BitMode]>;
David Woodhouse4e033b02014-01-13 14:05:59 +000032 def RETIQ : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt, variable_ops),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000033 "ret{q}\t$amt", []>, OpSize32, Requires<[In64BitMode]>;
Jakob Stoklund Olesend14101e2012-07-04 23:53:27 +000034 def RETIW : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000035 "ret{w}\t$amt", []>, OpSize16;
Chris Lattner87cf7f72010-11-12 18:54:56 +000036 def LRETL : I <0xCB, RawFrm, (outs), (ins),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000037 "{l}ret{l|f}", []>, OpSize32;
David Woodhouse4e033b02014-01-13 14:05:59 +000038 def LRETQ : RI <0xCB, RawFrm, (outs), (ins),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000039 "{l}ret{|f}q", []>, Requires<[In64BitMode]>;
Charles Davis74c282b2012-04-11 01:10:53 +000040 def LRETW : I <0xCB, RawFrm, (outs), (ins),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000041 "{l}ret{w|f}", []>, OpSize16;
David Woodhouse4e033b02014-01-13 14:05:59 +000042 def LRETIL : Ii16<0xCA, RawFrm, (outs), (ins i16imm:$amt),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000043 "{l}ret{l|f}\t$amt", []>, OpSize32;
David Woodhouse4e033b02014-01-13 14:05:59 +000044 def LRETIQ : RIi16<0xCA, RawFrm, (outs), (ins i16imm:$amt),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000045 "{l}ret{|f}q\t$amt", []>, Requires<[In64BitMode]>;
Kevin Enderbyb9783dd2010-10-18 17:04:36 +000046 def LRETIW : Ii16<0xCA, RawFrm, (outs), (ins i16imm:$amt),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000047 "{l}ret{w|f}\t$amt", []>, OpSize16;
Amjad Aboud60b5e1b2015-12-21 14:07:14 +000048
49 // The machine return from interrupt instruction, but sometimes we need to
50 // perform a post-epilogue stack adjustment. Codegen emits the pseudo form
51 // which expands to include an SP adjustment if necessary.
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000052 def IRET16 : I <0xcf, RawFrm, (outs), (ins), "iret{w}", []>,
Amjad Aboud60b5e1b2015-12-21 14:07:14 +000053 OpSize16;
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000054 def IRET32 : I <0xcf, RawFrm, (outs), (ins), "iret{l|d}", []>, OpSize32;
55 def IRET64 : RI <0xcf, RawFrm, (outs), (ins), "iretq", []>, Requires<[In64BitMode]>;
Amjad Aboud60b5e1b2015-12-21 14:07:14 +000056 let isCodeGenOnly = 1 in
David Majnemerd2f767d2016-03-04 22:56:17 +000057 def IRET : PseudoI<(outs), (ins i32imm:$adj), [(X86iret timm:$adj)]>;
58 def RET : PseudoI<(outs), (ins i32imm:$adj, variable_ops), [(X86retflag timm:$adj)]>;
Chris Lattnerae33f5d2010-10-05 06:04:14 +000059}
60
61// Unconditional branches.
Jakob Stoklund Olesend59419eb2013-03-26 18:24:17 +000062let isBarrier = 1, isBranch = 1, isTerminator = 1, SchedRW = [WriteJump] in {
Chris Lattnerae33f5d2010-10-05 06:04:14 +000063 def JMP_1 : Ii8PCRel<0xEB, RawFrm, (outs), (ins brtarget8:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000064 "jmp\t$dst", [(br bb:$dst)]>;
Craig Topper0f2c4ac2015-01-06 04:23:57 +000065 let hasSideEffects = 0, isCodeGenOnly = 1, ForceDisassemble = 1 in {
Craig Topper63944542015-01-06 08:59:30 +000066 def JMP_2 : Ii16PCRel<0xE9, RawFrm, (outs), (ins brtarget16:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000067 "jmp\t$dst", []>, OpSize16;
Craig Topper63944542015-01-06 08:59:30 +000068 def JMP_4 : Ii32PCRel<0xE9, RawFrm, (outs), (ins brtarget32:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000069 "jmp\t$dst", []>, OpSize32;
Craig Topper49758aa2015-01-06 04:23:53 +000070 }
Chris Lattnerae33f5d2010-10-05 06:04:14 +000071}
72
73// Conditional Branches.
Jakob Stoklund Olesend59419eb2013-03-26 18:24:17 +000074let isBranch = 1, isTerminator = 1, Uses = [EFLAGS], SchedRW = [WriteJump] in {
Chris Lattnerae33f5d2010-10-05 06:04:14 +000075 multiclass ICBr<bits<8> opc1, bits<8> opc4, string asm, PatFrag Cond> {
Craig Topper49758aa2015-01-06 04:23:53 +000076 def _1 : Ii8PCRel <opc1, RawFrm, (outs), (ins brtarget8:$dst), asm,
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000077 [(X86brcond bb:$dst, Cond, EFLAGS)]>;
Craig Topper0f2c4ac2015-01-06 04:23:57 +000078 let hasSideEffects = 0, isCodeGenOnly = 1, ForceDisassemble = 1 in {
Craig Topper63944542015-01-06 08:59:30 +000079 def _2 : Ii16PCRel<opc4, RawFrm, (outs), (ins brtarget16:$dst), asm,
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000080 []>, OpSize16, TB;
Craig Topper63944542015-01-06 08:59:30 +000081 def _4 : Ii32PCRel<opc4, RawFrm, (outs), (ins brtarget32:$dst), asm,
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +000082 []>, TB, OpSize32;
Craig Topper49758aa2015-01-06 04:23:53 +000083 }
Chris Lattnerae33f5d2010-10-05 06:04:14 +000084 }
85}
86
87defm JO : ICBr<0x70, 0x80, "jo\t$dst" , X86_COND_O>;
Craig Topper49758aa2015-01-06 04:23:53 +000088defm JNO : ICBr<0x71, 0x81, "jno\t$dst", X86_COND_NO>;
Chris Lattnerae33f5d2010-10-05 06:04:14 +000089defm JB : ICBr<0x72, 0x82, "jb\t$dst" , X86_COND_B>;
90defm JAE : ICBr<0x73, 0x83, "jae\t$dst", X86_COND_AE>;
91defm JE : ICBr<0x74, 0x84, "je\t$dst" , X86_COND_E>;
92defm JNE : ICBr<0x75, 0x85, "jne\t$dst", X86_COND_NE>;
93defm JBE : ICBr<0x76, 0x86, "jbe\t$dst", X86_COND_BE>;
94defm JA : ICBr<0x77, 0x87, "ja\t$dst" , X86_COND_A>;
95defm JS : ICBr<0x78, 0x88, "js\t$dst" , X86_COND_S>;
96defm JNS : ICBr<0x79, 0x89, "jns\t$dst", X86_COND_NS>;
97defm JP : ICBr<0x7A, 0x8A, "jp\t$dst" , X86_COND_P>;
98defm JNP : ICBr<0x7B, 0x8B, "jnp\t$dst", X86_COND_NP>;
99defm JL : ICBr<0x7C, 0x8C, "jl\t$dst" , X86_COND_L>;
100defm JGE : ICBr<0x7D, 0x8D, "jge\t$dst", X86_COND_GE>;
101defm JLE : ICBr<0x7E, 0x8E, "jle\t$dst", X86_COND_LE>;
102defm JG : ICBr<0x7F, 0x8F, "jg\t$dst" , X86_COND_G>;
103
104// jcx/jecx/jrcx instructions.
Craig Topper8a1028f2013-09-03 03:56:17 +0000105let isBranch = 1, isTerminator = 1, hasSideEffects = 0, SchedRW = [WriteJump] in {
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000106 // These are the 32-bit versions of this instruction for the asmparser. In
107 // 32-bit mode, the address size prefix is jcxz and the unprefixed version is
108 // jecxz.
109 let Uses = [CX] in
110 def JCXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000111 "jcxz\t$dst", []>, AdSize16, Requires<[Not64BitMode]>;
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000112 let Uses = [ECX] in
Craig Topper055845f2015-01-02 07:02:25 +0000113 def JECXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000114 "jecxz\t$dst", []>, AdSize32;
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000115
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000116 let Uses = [RCX] in
117 def JRCXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000118 "jrcxz\t$dst", []>, AdSize64, Requires<[In64BitMode]>;
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000119}
120
121// Indirect branches
122let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
David Woodhousefd460162014-01-08 12:57:49 +0000123 def JMP16r : I<0xFF, MRM4r, (outs), (ins GR16:$dst), "jmp{w}\t{*}$dst",
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000124 [(brind GR16:$dst)]>, Requires<[Not64BitMode]>,
125 OpSize16, Sched<[WriteJump]>;
David Woodhousefd460162014-01-08 12:57:49 +0000126 def JMP16m : I<0xFF, MRM4m, (outs), (ins i16mem:$dst), "jmp{w}\t{*}$dst",
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000127 [(brind (loadi16 addr:$dst))]>, Requires<[Not64BitMode]>,
128 OpSize16, Sched<[WriteJumpLd]>;
David Woodhousefd460162014-01-08 12:57:49 +0000129
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000130 def JMP32r : I<0xFF, MRM4r, (outs), (ins GR32:$dst), "jmp{l}\t{*}$dst",
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000131 [(brind GR32:$dst)]>, Requires<[Not64BitMode]>,
132 OpSize32, Sched<[WriteJump]>;
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000133 def JMP32m : I<0xFF, MRM4m, (outs), (ins i32mem:$dst), "jmp{l}\t{*}$dst",
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000134 [(brind (loadi32 addr:$dst))]>, Requires<[Not64BitMode]>,
135 OpSize32, Sched<[WriteJumpLd]>;
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000136
137 def JMP64r : I<0xFF, MRM4r, (outs), (ins GR64:$dst), "jmp{q}\t{*}$dst",
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000138 [(brind GR64:$dst)]>, Requires<[In64BitMode]>,
139 Sched<[WriteJump]>;
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000140 def JMP64m : I<0xFF, MRM4m, (outs), (ins i64mem:$dst), "jmp{q}\t{*}$dst",
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000141 [(brind (loadi64 addr:$dst))]>, Requires<[In64BitMode]>,
142 Sched<[WriteJumpLd]>;
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000143
Alexander Ivchenko5c547422018-05-18 11:58:25 +0000144 // Non-tracking jumps for IBT, use with caution.
145 let isCodeGenOnly = 1 in {
Oren Ben Simhonfdd72fd2018-03-17 13:29:46 +0000146 def JMP16r_NT : I<0xFF, MRM4r, (outs), (ins GR16 : $dst), "jmp{w}\t{*}$dst",
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000147 [(X86NoTrackBrind GR16 : $dst)]>, Requires<[Not64BitMode]>,
148 OpSize16, Sched<[WriteJump]>, NOTRACK;
Oren Ben Simhonfdd72fd2018-03-17 13:29:46 +0000149
150 def JMP16m_NT : I<0xFF, MRM4m, (outs), (ins i16mem : $dst), "jmp{w}\t{*}$dst",
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000151 [(X86NoTrackBrind (loadi16 addr : $dst))]>,
152 Requires<[Not64BitMode]>, OpSize16, Sched<[WriteJumpLd]>,
153 NOTRACK;
Oren Ben Simhonfdd72fd2018-03-17 13:29:46 +0000154
155 def JMP32r_NT : I<0xFF, MRM4r, (outs), (ins GR32 : $dst), "jmp{l}\t{*}$dst",
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000156 [(X86NoTrackBrind GR32 : $dst)]>, Requires<[Not64BitMode]>,
157 OpSize32, Sched<[WriteJump]>, NOTRACK;
Oren Ben Simhonfdd72fd2018-03-17 13:29:46 +0000158 def JMP32m_NT : I<0xFF, MRM4m, (outs), (ins i32mem : $dst), "jmp{l}\t{*}$dst",
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000159 [(X86NoTrackBrind (loadi32 addr : $dst))]>,
160 Requires<[Not64BitMode]>, OpSize32, Sched<[WriteJumpLd]>,
161 NOTRACK;
Oren Ben Simhonfdd72fd2018-03-17 13:29:46 +0000162
163 def JMP64r_NT : I<0xFF, MRM4r, (outs), (ins GR64 : $dst), "jmp{q}\t{*}$dst",
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000164 [(X86NoTrackBrind GR64 : $dst)]>, Requires<[In64BitMode]>,
165 Sched<[WriteJump]>, NOTRACK;
Oren Ben Simhonfdd72fd2018-03-17 13:29:46 +0000166 def JMP64m_NT : I<0xFF, MRM4m, (outs), (ins i64mem : $dst), "jmp{q}\t{*}$dst",
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000167 [(X86NoTrackBrind(loadi64 addr : $dst))]>,
168 Requires<[In64BitMode]>, Sched<[WriteJumpLd]>, NOTRACK;
Oren Ben Simhonfdd72fd2018-03-17 13:29:46 +0000169 }
170
Craig Topper429ae3d2018-04-30 06:21:21 +0000171 let Predicates = [Not64BitMode], AsmVariantName = "att" in {
Craig Topper35545fa2014-12-20 07:43:27 +0000172 def FARJMP16i : Iseg16<0xEA, RawFrmImm16, (outs),
173 (ins i16imm:$off, i16imm:$seg),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000174 "ljmp{w}\t$seg, $off", []>,
175 OpSize16, Sched<[WriteJump]>;
Craig Topper35545fa2014-12-20 07:43:27 +0000176 def FARJMP32i : Iseg32<0xEA, RawFrmImm16, (outs),
177 (ins i32imm:$off, i16imm:$seg),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000178 "ljmp{l}\t$seg, $off", []>,
179 OpSize32, Sched<[WriteJump]>;
Craig Topper35545fa2014-12-20 07:43:27 +0000180 }
Craig Topper33dc01d2018-05-01 04:42:00 +0000181 def FARJMP64 : RI<0xFF, MRM5m, (outs), (ins opaquemem:$dst),
Craig Topper5a4c8802018-04-30 06:21:24 +0000182 "ljmp{q}\t{*}$dst", []>, Sched<[WriteJump]>, Requires<[In64BitMode]>;
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000183
Craig Topperd94002c2018-04-30 06:21:23 +0000184 let AsmVariantName = "att" in
Craig Topper33dc01d2018-05-01 04:42:00 +0000185 def FARJMP16m : I<0xFF, MRM5m, (outs), (ins opaquemem:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000186 "ljmp{w}\t{*}$dst", []>, OpSize16, Sched<[WriteJumpLd]>;
Craig Topper33dc01d2018-05-01 04:42:00 +0000187 def FARJMP32m : I<0xFF, MRM5m, (outs), (ins opaquemem:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000188 "{l}jmp{l}\t{*}$dst", []>, OpSize32, Sched<[WriteJumpLd]>;
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000189}
190
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000191// Loop instructions
Jakob Stoklund Olesend59419eb2013-03-26 18:24:17 +0000192let SchedRW = [WriteJump] in {
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000193def LOOP : Ii8PCRel<0xE2, RawFrm, (outs), (ins brtarget8:$dst), "loop\t$dst", []>;
194def LOOPE : Ii8PCRel<0xE1, RawFrm, (outs), (ins brtarget8:$dst), "loope\t$dst", []>;
195def LOOPNE : Ii8PCRel<0xE0, RawFrm, (outs), (ins brtarget8:$dst), "loopne\t$dst", []>;
Jakob Stoklund Olesend59419eb2013-03-26 18:24:17 +0000196}
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000197
198//===----------------------------------------------------------------------===//
199// Call Instructions...
200//
201let isCall = 1 in
202 // All calls clobber the non-callee saved registers. ESP is marked as
203 // a use to prevent stack-pointer assignments that appear immediately
204 // before calls from potentially appearing dead. Uses for argument
205 // registers are added manually.
Oren Ben Simhonfa582b02017-11-26 13:02:45 +0000206 let Uses = [ESP, SSP] in {
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000207 def CALLpcrel32 : Ii32PCRel<0xE8, RawFrm,
Jakob Stoklund Olesend14101e2012-07-04 23:53:27 +0000208 (outs), (ins i32imm_pcrel:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000209 "call{l}\t$dst", []>, OpSize32,
Eric Christopherc0a5aae2013-12-20 02:04:49 +0000210 Requires<[Not64BitMode]>, Sched<[WriteJump]>;
Craig Topper23fd6952014-12-21 20:05:06 +0000211 let hasSideEffects = 0 in
212 def CALLpcrel16 : Ii16PCRel<0xE8, RawFrm,
213 (outs), (ins i16imm_pcrel:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000214 "call{w}\t$dst", []>, OpSize16,
Craig Topper23fd6952014-12-21 20:05:06 +0000215 Sched<[WriteJump]>;
David Woodhousefd460162014-01-08 12:57:49 +0000216 def CALL16r : I<0xFF, MRM2r, (outs), (ins GR16:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000217 "call{w}\t{*}$dst", [(X86call GR16:$dst)]>,
Craig Topperfa6298a2014-02-02 09:25:09 +0000218 OpSize16, Requires<[Not64BitMode]>, Sched<[WriteJump]>;
David Woodhousefd460162014-01-08 12:57:49 +0000219 def CALL16m : I<0xFF, MRM2m, (outs), (ins i16mem:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000220 "call{w}\t{*}$dst", [(X86call (loadi16 addr:$dst))]>,
221 OpSize16, Requires<[Not64BitMode,FavorMemIndirectCall]>,
222 Sched<[WriteJumpLd]>;
Jakob Stoklund Olesend14101e2012-07-04 23:53:27 +0000223 def CALL32r : I<0xFF, MRM2r, (outs), (ins GR32:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000224 "call{l}\t{*}$dst", [(X86call GR32:$dst)]>, OpSize32,
225 Requires<[Not64BitMode,NotUseRetpoline]>, Sched<[WriteJump]>;
Jakob Stoklund Olesend14101e2012-07-04 23:53:27 +0000226 def CALL32m : I<0xFF, MRM2m, (outs), (ins i32mem:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000227 "call{l}\t{*}$dst", [(X86call (loadi32 addr:$dst))]>,
228 OpSize32,
229 Requires<[Not64BitMode,FavorMemIndirectCall,NotUseRetpoline]>,
230 Sched<[WriteJumpLd]>;
NAKAMURA Takumi9d29eff2011-01-26 02:03:37 +0000231
Alexander Ivchenko5c547422018-05-18 11:58:25 +0000232 // Non-tracking calls for IBT, use with caution.
233 let isCodeGenOnly = 1 in {
Oren Ben Simhonfdd72fd2018-03-17 13:29:46 +0000234 def CALL16r_NT : I<0xFF, MRM2r, (outs), (ins GR16 : $dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000235 "call{w}\t{*}$dst",[(X86NoTrackCall GR16 : $dst)]>,
Oren Ben Simhonfdd72fd2018-03-17 13:29:46 +0000236 OpSize16, Requires<[Not64BitMode]>, Sched<[WriteJump]>, NOTRACK;
237 def CALL16m_NT : I<0xFF, MRM2m, (outs), (ins i16mem : $dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000238 "call{w}\t{*}$dst",[(X86NoTrackCall(loadi16 addr : $dst))]>,
239 OpSize16, Requires<[Not64BitMode,FavorMemIndirectCall]>,
Oren Ben Simhonfdd72fd2018-03-17 13:29:46 +0000240 Sched<[WriteJumpLd]>, NOTRACK;
241 def CALL32r_NT : I<0xFF, MRM2r, (outs), (ins GR32 : $dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000242 "call{l}\t{*}$dst",[(X86NoTrackCall GR32 : $dst)]>,
Oren Ben Simhonfdd72fd2018-03-17 13:29:46 +0000243 OpSize32, Requires<[Not64BitMode]>, Sched<[WriteJump]>, NOTRACK;
244 def CALL32m_NT : I<0xFF, MRM2m, (outs), (ins i32mem : $dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000245 "call{l}\t{*}$dst",[(X86NoTrackCall(loadi32 addr : $dst))]>,
246 OpSize32, Requires<[Not64BitMode,FavorMemIndirectCall]>,
Oren Ben Simhonfdd72fd2018-03-17 13:29:46 +0000247 Sched<[WriteJumpLd]>, NOTRACK;
248 }
249
Craig Topper429ae3d2018-04-30 06:21:21 +0000250 let Predicates = [Not64BitMode], AsmVariantName = "att" in {
Craig Topper35545fa2014-12-20 07:43:27 +0000251 def FARCALL16i : Iseg16<0x9A, RawFrmImm16, (outs),
252 (ins i16imm:$off, i16imm:$seg),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000253 "lcall{w}\t$seg, $off", []>,
254 OpSize16, Sched<[WriteJump]>;
Craig Topper35545fa2014-12-20 07:43:27 +0000255 def FARCALL32i : Iseg32<0x9A, RawFrmImm16, (outs),
256 (ins i32imm:$off, i16imm:$seg),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000257 "lcall{l}\t$seg, $off", []>,
258 OpSize32, Sched<[WriteJump]>;
Craig Topper35545fa2014-12-20 07:43:27 +0000259 }
NAKAMURA Takumi9d29eff2011-01-26 02:03:37 +0000260
Craig Topper33dc01d2018-05-01 04:42:00 +0000261 def FARCALL16m : I<0xFF, MRM3m, (outs), (ins opaquemem:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000262 "lcall{w}\t{*}$dst", []>, OpSize16, Sched<[WriteJumpLd]>;
Craig Topper33dc01d2018-05-01 04:42:00 +0000263 def FARCALL32m : I<0xFF, MRM3m, (outs), (ins opaquemem:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000264 "{l}call{l}\t{*}$dst", []>, OpSize32, Sched<[WriteJumpLd]>;
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000265 }
266
267
268// Tail call stuff.
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000269let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
Jakob Stoklund Olesend59419eb2013-03-26 18:24:17 +0000270 isCodeGenOnly = 1, SchedRW = [WriteJumpLd] in
Oren Ben Simhonfa582b02017-11-26 13:02:45 +0000271 let Uses = [ESP, SSP] in {
NAKAMURA Takumi9d29eff2011-01-26 02:03:37 +0000272 def TCRETURNdi : PseudoI<(outs),
Ayman Musa5fc6dc52017-10-08 08:32:56 +0000273 (ins i32imm_pcrel:$dst, i32imm:$offset), []>, NotMemoryFoldable;
NAKAMURA Takumi9d29eff2011-01-26 02:03:37 +0000274 def TCRETURNri : PseudoI<(outs),
Ayman Musa5fc6dc52017-10-08 08:32:56 +0000275 (ins ptr_rc_tailcall:$dst, i32imm:$offset), []>, NotMemoryFoldable;
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000276 let mayLoad = 1 in
NAKAMURA Takumi9d29eff2011-01-26 02:03:37 +0000277 def TCRETURNmi : PseudoI<(outs),
Jakob Stoklund Olesend14101e2012-07-04 23:53:27 +0000278 (ins i32mem_TC:$dst, i32imm:$offset), []>;
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000279
280 // FIXME: The should be pseudo instructions that are lowered when going to
281 // mcinst.
282 def TAILJMPd : Ii32PCRel<0xE9, RawFrm, (outs),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000283 (ins i32imm_pcrel:$dst), "jmp\t$dst", []>;
Hans Wennborg75e25f62016-09-07 17:52:14 +0000284
Jakob Stoklund Olesend14101e2012-07-04 23:53:27 +0000285 def TAILJMPr : I<0xFF, MRM4r, (outs), (ins ptr_rc_tailcall:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000286 "", []>; // FIXME: Remove encoding when JIT is dead.
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000287 let mayLoad = 1 in
Jakob Stoklund Olesend14101e2012-07-04 23:53:27 +0000288 def TAILJMPm : I<0xFF, MRM4m, (outs), (ins i32mem_TC:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000289 "jmp{l}\t{*}$dst", []>;
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000290}
291
Hans Wennborga4686012017-02-16 00:04:05 +0000292// Conditional tail calls are similar to the above, but they are branches
293// rather than barriers, and they use EFLAGS.
294let isCall = 1, isTerminator = 1, isReturn = 1, isBranch = 1,
295 isCodeGenOnly = 1, SchedRW = [WriteJumpLd] in
Oren Ben Simhonfa582b02017-11-26 13:02:45 +0000296 let Uses = [ESP, EFLAGS, SSP] in {
Hans Wennborga4686012017-02-16 00:04:05 +0000297 def TCRETURNdicc : PseudoI<(outs),
298 (ins i32imm_pcrel:$dst, i32imm:$offset, i32imm:$cond), []>;
299
300 // This gets substituted to a conditional jump instruction in MC lowering.
301 def TAILJMPd_CC : Ii32PCRel<0x80, RawFrm, (outs),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000302 (ins i32imm_pcrel:$dst, i32imm:$cond), "", []>;
Hans Wennborga4686012017-02-16 00:04:05 +0000303}
304
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000305
306//===----------------------------------------------------------------------===//
307// Call Instructions...
308//
NAKAMURA Takumi9d29eff2011-01-26 02:03:37 +0000309
Jakob Stoklund Olesen97e31152012-02-16 17:56:02 +0000310// RSP is marked as a use to prevent stack-pointer assignments that appear
311// immediately before calls from potentially appearing dead. Uses for argument
312// registers are added manually.
Oren Ben Simhonfa582b02017-11-26 13:02:45 +0000313let isCall = 1, Uses = [RSP, SSP], SchedRW = [WriteJump] in {
Jakob Stoklund Olesen97e31152012-02-16 17:56:02 +0000314 // NOTE: this pattern doesn't match "X86call imm", because we do not know
315 // that the offset between an arbitrary immediate and the call will fit in
316 // the 32-bit pcrel field that we have.
317 def CALL64pcrel32 : Ii32PCRel<0xE8, RawFrm,
Jakob Stoklund Olesend14101e2012-07-04 23:53:27 +0000318 (outs), (ins i64i32imm_pcrel:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000319 "call{q}\t$dst", []>, OpSize32,
Jakob Stoklund Olesen97e31152012-02-16 17:56:02 +0000320 Requires<[In64BitMode]>;
Jakob Stoklund Olesend14101e2012-07-04 23:53:27 +0000321 def CALL64r : I<0xFF, MRM2r, (outs), (ins GR64:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000322 "call{q}\t{*}$dst", [(X86call GR64:$dst)]>,
Chandler Carruthc58f2162018-01-22 22:05:25 +0000323 Requires<[In64BitMode,NotUseRetpoline]>;
Jakob Stoklund Olesend14101e2012-07-04 23:53:27 +0000324 def CALL64m : I<0xFF, MRM2m, (outs), (ins i64mem:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000325 "call{q}\t{*}$dst", [(X86call (loadi64 addr:$dst))]>,
Chandler Carruthc58f2162018-01-22 22:05:25 +0000326 Requires<[In64BitMode,FavorMemIndirectCall,
327 NotUseRetpoline]>;
NAKAMURA Takumi9d29eff2011-01-26 02:03:37 +0000328
Alexander Ivchenko5c547422018-05-18 11:58:25 +0000329 // Non-tracking calls for IBT, use with caution.
330 let isCodeGenOnly = 1 in {
Oren Ben Simhonfdd72fd2018-03-17 13:29:46 +0000331 def CALL64r_NT : I<0xFF, MRM2r, (outs), (ins GR64 : $dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000332 "call{q}\t{*}$dst",[(X86NoTrackCall GR64 : $dst)]>,
Oren Ben Simhonfdd72fd2018-03-17 13:29:46 +0000333 Requires<[In64BitMode]>, NOTRACK;
334 def CALL64m_NT : I<0xFF, MRM2m, (outs), (ins i64mem : $dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000335 "call{q}\t{*}$dst",
336 [(X86NoTrackCall(loadi64 addr : $dst))]>,
337 Requires<[In64BitMode,FavorMemIndirectCall]>, NOTRACK;
Oren Ben Simhonfdd72fd2018-03-17 13:29:46 +0000338 }
339
Craig Topper33dc01d2018-05-01 04:42:00 +0000340 def FARCALL64 : RI<0xFF, MRM3m, (outs), (ins opaquemem:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000341 "lcall{q}\t{*}$dst", []>;
Jakob Stoklund Olesen97e31152012-02-16 17:56:02 +0000342}
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000343
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000344let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
Craig Topper8232e882018-01-03 18:20:36 +0000345 isCodeGenOnly = 1, Uses = [RSP, SSP], SchedRW = [WriteJump] in {
Hans Wennborg6ecf6192016-09-09 22:37:27 +0000346 def TCRETURNdi64 : PseudoI<(outs),
347 (ins i64i32imm_pcrel:$dst, i32imm:$offset),
348 []>;
Hans Wennborg6ecf6192016-09-09 22:37:27 +0000349 def TCRETURNri64 : PseudoI<(outs),
Ayman Musa5fc6dc52017-10-08 08:32:56 +0000350 (ins ptr_rc_tailcall:$dst, i32imm:$offset), []>, NotMemoryFoldable;
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000351 let mayLoad = 1 in
Hans Wennborg6ecf6192016-09-09 22:37:27 +0000352 def TCRETURNmi64 : PseudoI<(outs),
Ayman Musa5fc6dc52017-10-08 08:32:56 +0000353 (ins i64mem_TC:$dst, i32imm:$offset), []>, NotMemoryFoldable;
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000354
Reid Klecknera580b6e2015-01-30 21:03:31 +0000355 def TAILJMPd64 : Ii32PCRel<0xE9, RawFrm, (outs), (ins i64i32imm_pcrel:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000356 "jmp\t$dst", []>;
Hans Wennborg6ecf6192016-09-09 22:37:27 +0000357
Jakob Stoklund Olesend14101e2012-07-04 23:53:27 +0000358 def TAILJMPr64 : I<0xFF, MRM4r, (outs), (ins ptr_rc_tailcall:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000359 "jmp{q}\t{*}$dst", []>;
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000360
361 let mayLoad = 1 in
Jakob Stoklund Olesend14101e2012-07-04 23:53:27 +0000362 def TAILJMPm64 : I<0xFF, MRM4m, (outs), (ins i64mem_TC:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000363 "jmp{q}\t{*}$dst", []>;
Reid Klecknera580b6e2015-01-30 21:03:31 +0000364
Hans Wennborgc39ef772016-09-08 23:35:10 +0000365 // Win64 wants indirect jumps leaving the function to have a REX_W prefix.
Reid Klecknera580b6e2015-01-30 21:03:31 +0000366 let hasREX_WPrefix = 1 in {
Reid Klecknera580b6e2015-01-30 21:03:31 +0000367 def TAILJMPr64_REX : I<0xFF, MRM4r, (outs), (ins ptr_rc_tailcall:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000368 "rex64 jmp{q}\t{*}$dst", []>;
Reid Klecknera580b6e2015-01-30 21:03:31 +0000369
370 let mayLoad = 1 in
371 def TAILJMPm64_REX : I<0xFF, MRM4m, (outs), (ins i64mem_TC:$dst),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000372 "rex64 jmp{q}\t{*}$dst", []>;
Reid Klecknera580b6e2015-01-30 21:03:31 +0000373 }
Chris Lattnerae33f5d2010-10-05 06:04:14 +0000374}
Hans Wennborga4686012017-02-16 00:04:05 +0000375
Chandler Carruthc58f2162018-01-22 22:05:25 +0000376let isPseudo = 1, isCall = 1, isCodeGenOnly = 1,
377 Uses = [RSP, SSP],
378 usesCustomInserter = 1,
379 SchedRW = [WriteJump] in {
380 def RETPOLINE_CALL32 :
381 PseudoI<(outs), (ins GR32:$dst), [(X86call GR32:$dst)]>,
382 Requires<[Not64BitMode,UseRetpoline]>;
383
384 def RETPOLINE_CALL64 :
385 PseudoI<(outs), (ins GR64:$dst), [(X86call GR64:$dst)]>,
386 Requires<[In64BitMode,UseRetpoline]>;
387
388 // Retpoline variant of indirect tail calls.
389 let isTerminator = 1, isReturn = 1, isBarrier = 1 in {
390 def RETPOLINE_TCRETURN64 :
391 PseudoI<(outs), (ins GR64:$dst, i32imm:$offset), []>;
392 def RETPOLINE_TCRETURN32 :
393 PseudoI<(outs), (ins GR32:$dst, i32imm:$offset), []>;
394 }
395}
396
Hans Wennborga4686012017-02-16 00:04:05 +0000397// Conditional tail calls are similar to the above, but they are branches
398// rather than barriers, and they use EFLAGS.
399let isCall = 1, isTerminator = 1, isReturn = 1, isBranch = 1,
400 isCodeGenOnly = 1, SchedRW = [WriteJumpLd] in
Oren Ben Simhonfa582b02017-11-26 13:02:45 +0000401 let Uses = [RSP, EFLAGS, SSP] in {
Hans Wennborga4686012017-02-16 00:04:05 +0000402 def TCRETURNdi64cc : PseudoI<(outs),
403 (ins i64i32imm_pcrel:$dst, i32imm:$offset,
404 i32imm:$cond), []>;
405
406 // This gets substituted to a conditional jump instruction in MC lowering.
407 def TAILJMPd64_CC : Ii32PCRel<0x80, RawFrm, (outs),
Simon Pilgrim0cd0fbd2018-04-12 12:09:24 +0000408 (ins i64i32imm_pcrel:$dst, i32imm:$cond), "", []>;
Hans Wennborga4686012017-02-16 00:04:05 +0000409}