OLD | NEW |
1 //===-- X86InstrControl.td - Control Flow Instructions -----*- tablegen -*-===// | 1 //===-- X86InstrControl.td - Control Flow Instructions -----*- tablegen -*-===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file describes the X86 jump, return, call, and related instructions. | 10 // This file describes the X86 jump, return, call, and related instructions. |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 OpSize16, Sched<[WriteJump]>; | 129 OpSize16, Sched<[WriteJump]>; |
130 def JMP16m : I<0xFF, MRM4m, (outs), (ins i16mem:$dst), "jmp{w}\t{*}$dst", | 130 def JMP16m : I<0xFF, MRM4m, (outs), (ins i16mem:$dst), "jmp{w}\t{*}$dst", |
131 [(brind (loadi16 addr:$dst))], IIC_JMP_MEM>, | 131 [(brind (loadi16 addr:$dst))], IIC_JMP_MEM>, |
132 Requires<[Not64BitMode]>, OpSize16, Sched<[WriteJumpLd]>; | 132 Requires<[Not64BitMode]>, OpSize16, Sched<[WriteJumpLd]>; |
133 | 133 |
134 def JMP32r : I<0xFF, MRM4r, (outs), (ins GR32:$dst), "jmp{l}\t{*}$dst", | 134 def JMP32r : I<0xFF, MRM4r, (outs), (ins GR32:$dst), "jmp{l}\t{*}$dst", |
135 [(brind GR32:$dst)], IIC_JMP_REG>, Requires<[Not64BitMode]>
, | 135 [(brind GR32:$dst)], IIC_JMP_REG>, Requires<[Not64BitMode]>
, |
136 OpSize32, Sched<[WriteJump]>; | 136 OpSize32, Sched<[WriteJump]>; |
137 def JMP32m : I<0xFF, MRM4m, (outs), (ins i32mem:$dst), "jmp{l}\t{*}$dst", | 137 def JMP32m : I<0xFF, MRM4m, (outs), (ins i32mem:$dst), "jmp{l}\t{*}$dst", |
138 [(brind (loadi32 addr:$dst))], IIC_JMP_MEM>, | 138 [(brind (loadi32 addr:$dst))], IIC_JMP_MEM>, |
139 Requires<[Not64BitMode]>, OpSize32, Sched<[WriteJumpLd]>; | 139 Requires<[Not64BitMode,IsNotNaCl]>, OpSize32, Sched<[WriteJum
pLd]>; |
140 | 140 |
141 def JMP64r : I<0xFF, MRM4r, (outs), (ins GR64:$dst), "jmp{q}\t{*}$dst", | 141 def JMP64r : I<0xFF, MRM4r, (outs), (ins GR64:$dst), "jmp{q}\t{*}$dst", |
142 [(brind GR64:$dst)], IIC_JMP_REG>, Requires<[In64BitMode]>, | 142 [(brind GR64:$dst)], IIC_JMP_REG>, Requires<[In64BitMode]>, |
143 Sched<[WriteJump]>; | 143 Sched<[WriteJump]>; |
144 def JMP64m : I<0xFF, MRM4m, (outs), (ins i64mem:$dst), "jmp{q}\t{*}$dst", | 144 def JMP64m : I<0xFF, MRM4m, (outs), (ins i64mem:$dst), "jmp{q}\t{*}$dst", |
145 [(brind (loadi64 addr:$dst))], IIC_JMP_MEM>, | 145 [(brind (loadi64 addr:$dst))], IIC_JMP_MEM>, |
146 Requires<[In64BitMode]>, Sched<[WriteJumpLd]>; | 146 Requires<[In64BitMode]>, Sched<[WriteJumpLd]>; |
147 | 147 |
148 def FARJMP16i : Iseg16<0xEA, RawFrmImm16, (outs), | 148 def FARJMP16i : Iseg16<0xEA, RawFrmImm16, (outs), |
149 (ins i16imm:$off, i16imm:$seg), | 149 (ins i16imm:$off, i16imm:$seg), |
150 "ljmp{w}\t{$seg, $off|$off, $seg}", [], | 150 "ljmp{w}\t{$seg, $off|$off, $seg}", [], |
151 IIC_JMP_FAR_PTR>, OpSize16, Sched<[WriteJump]>; | 151 IIC_JMP_FAR_PTR>, OpSize16, Sched<[WriteJump]>; |
152 def FARJMP32i : Iseg32<0xEA, RawFrmImm16, (outs), | 152 def FARJMP32i : Iseg32<0xEA, RawFrmImm16, (outs), |
153 (ins i32imm:$off, i16imm:$seg), | 153 (ins i32imm:$off, i16imm:$seg), |
154 "ljmp{l}\t{$seg, $off|$off, $seg}", [], | 154 "ljmp{l}\t{$seg, $off|$off, $seg}", [], |
155 IIC_JMP_FAR_PTR>, OpSize32, Sched<[WriteJump]>; | 155 IIC_JMP_FAR_PTR>, OpSize32, Sched<[WriteJump]>; |
156 def FARJMP64 : RI<0xFF, MRM5m, (outs), (ins opaque80mem:$dst), | 156 def FARJMP64 : RI<0xFF, MRM5m, (outs), (ins opaque80mem:$dst), |
157 "ljmp{q}\t{*}$dst", [], IIC_JMP_FAR_MEM>, | 157 "ljmp{q}\t{*}$dst", [], IIC_JMP_FAR_MEM>, Requires<[IsNotN
aCl]>, |
158 Sched<[WriteJump]>; | 158 Sched<[WriteJump]>; |
159 | 159 |
160 def FARJMP16m : I<0xFF, MRM5m, (outs), (ins opaque32mem:$dst), | 160 def FARJMP16m : I<0xFF, MRM5m, (outs), (ins opaque32mem:$dst), |
161 "ljmp{w}\t{*}$dst", [], IIC_JMP_FAR_MEM>, OpSize16, | 161 "ljmp{w}\t{*}$dst", [], IIC_JMP_FAR_MEM>, OpSize16, |
162 Sched<[WriteJumpLd]>; | 162 Sched<[WriteJumpLd]>; |
163 def FARJMP32m : I<0xFF, MRM5m, (outs), (ins opaque48mem:$dst), | 163 def FARJMP32m : I<0xFF, MRM5m, (outs), (ins opaque48mem:$dst), |
164 "ljmp{l}\t{*}$dst", [], IIC_JMP_FAR_MEM>, OpSize32, | 164 "ljmp{l}\t{*}$dst", [], IIC_JMP_FAR_MEM>, OpSize32, |
165 Sched<[WriteJumpLd]>; | 165 Sched<[WriteJumpLd]>; |
166 } | 166 } |
167 | 167 |
(...skipping 14 matching lines...) Expand all Loading... |
182 // before calls from potentially appearing dead. Uses for argument | 182 // before calls from potentially appearing dead. Uses for argument |
183 // registers are added manually. | 183 // registers are added manually. |
184 let Uses = [ESP] in { | 184 let Uses = [ESP] in { |
185 def CALLpcrel32 : Ii32PCRel<0xE8, RawFrm, | 185 def CALLpcrel32 : Ii32PCRel<0xE8, RawFrm, |
186 (outs), (ins i32imm_pcrel:$dst), | 186 (outs), (ins i32imm_pcrel:$dst), |
187 "call{l}\t$dst", [], IIC_CALL_RI>, OpSize32, | 187 "call{l}\t$dst", [], IIC_CALL_RI>, OpSize32, |
188 Requires<[Not64BitMode]>, Sched<[WriteJump]>; | 188 Requires<[Not64BitMode]>, Sched<[WriteJump]>; |
189 def CALLpcrel16 : Ii16PCRel<0xE8, RawFrm, | 189 def CALLpcrel16 : Ii16PCRel<0xE8, RawFrm, |
190 (outs), (ins i16imm_pcrel:$dst), | 190 (outs), (ins i16imm_pcrel:$dst), |
191 "call{w}\t$dst", [], IIC_CALL_RI>, OpSize16, | 191 "call{w}\t$dst", [], IIC_CALL_RI>, OpSize16, |
| 192 Requires<[IsNotNaCl]>, // @LOCALMOD |
192 Sched<[WriteJump]>; | 193 Sched<[WriteJump]>; |
193 def CALL16r : I<0xFF, MRM2r, (outs), (ins GR16:$dst), | 194 def CALL16r : I<0xFF, MRM2r, (outs), (ins GR16:$dst), |
194 "call{w}\t{*}$dst", [(X86call GR16:$dst)], IIC_CALL_RI>, | 195 "call{w}\t{*}$dst", [(X86call GR16:$dst)], IIC_CALL_RI>, |
195 OpSize16, Requires<[Not64BitMode]>, Sched<[WriteJump]>; | 196 OpSize16, Requires<[Not64BitMode]>, Sched<[WriteJump]>; |
196 def CALL16m : I<0xFF, MRM2m, (outs), (ins i16mem:$dst), | 197 def CALL16m : I<0xFF, MRM2m, (outs), (ins i16mem:$dst), |
197 "call{w}\t{*}$dst", [(X86call (loadi16 addr:$dst))], | 198 "call{w}\t{*}$dst", [(X86call (loadi16 addr:$dst))], |
198 IIC_CALL_MEM>, OpSize16, | 199 IIC_CALL_MEM>, OpSize16, |
199 Requires<[Not64BitMode,FavorMemIndirectCall]>, | 200 Requires<[Not64BitMode,FavorMemIndirectCall]>, |
200 Sched<[WriteJumpLd]>; | 201 Sched<[WriteJumpLd]>; |
201 def CALL32r : I<0xFF, MRM2r, (outs), (ins GR32:$dst), | 202 def CALL32r : I<0xFF, MRM2r, (outs), (ins GR32:$dst), |
202 "call{l}\t{*}$dst", [(X86call GR32:$dst)], IIC_CALL_RI>, | 203 "call{l}\t{*}$dst", [(X86call GR32:$dst)], IIC_CALL_RI>, |
203 OpSize32, Requires<[Not64BitMode]>, Sched<[WriteJump]>; | 204 OpSize32, Requires<[Not64BitMode]>, Sched<[WriteJump]>; |
| 205 // @LOCALMOD to disallow load-folded calls in NaCl (need to sandbox |
| 206 // the destination address first). |
204 def CALL32m : I<0xFF, MRM2m, (outs), (ins i32mem:$dst), | 207 def CALL32m : I<0xFF, MRM2m, (outs), (ins i32mem:$dst), |
205 "call{l}\t{*}$dst", [(X86call (loadi32 addr:$dst))], | 208 "call{l}\t{*}$dst", [(X86call (loadi32 addr:$dst))], |
206 IIC_CALL_MEM>, OpSize32, | 209 IIC_CALL_MEM>, OpSize32, |
207 Requires<[Not64BitMode,FavorMemIndirectCall]>, | 210 Requires<[Not64BitMode,IsNotNaCl,FavorMemIndirectCall]>, |
208 Sched<[WriteJumpLd]>; | 211 Sched<[WriteJumpLd]>; |
209 | 212 |
210 def FARCALL16i : Iseg16<0x9A, RawFrmImm16, (outs), | 213 def FARCALL16i : Iseg16<0x9A, RawFrmImm16, (outs), |
211 (ins i16imm:$off, i16imm:$seg), | 214 (ins i16imm:$off, i16imm:$seg), |
212 "lcall{w}\t{$seg, $off|$off, $seg}", [], | 215 "lcall{w}\t{$seg, $off|$off, $seg}", [], |
213 IIC_CALL_FAR_PTR>, OpSize16, Sched<[WriteJump]>; | 216 IIC_CALL_FAR_PTR>, OpSize16, Sched<[WriteJump]>; |
214 def FARCALL32i : Iseg32<0x9A, RawFrmImm16, (outs), | 217 def FARCALL32i : Iseg32<0x9A, RawFrmImm16, (outs), |
215 (ins i32imm:$off, i16imm:$seg), | 218 (ins i32imm:$off, i16imm:$seg), |
216 "lcall{l}\t{$seg, $off|$off, $seg}", [], | 219 "lcall{l}\t{$seg, $off|$off, $seg}", [], |
217 IIC_CALL_FAR_PTR>, OpSize32, Sched<[WriteJump]>; | 220 IIC_CALL_FAR_PTR>, OpSize32, Sched<[WriteJump]>; |
218 | 221 |
219 def FARCALL16m : I<0xFF, MRM3m, (outs), (ins opaque32mem:$dst), | 222 def FARCALL16m : I<0xFF, MRM3m, (outs), (ins opaque32mem:$dst), |
220 "lcall{w}\t{*}$dst", [], IIC_CALL_FAR_MEM>, OpSize16, | 223 "lcall{w}\t{*}$dst", [], IIC_CALL_FAR_MEM>, OpSize16, |
221 Sched<[WriteJumpLd]>; | 224 Sched<[WriteJumpLd]>; |
222 def FARCALL32m : I<0xFF, MRM3m, (outs), (ins opaque48mem:$dst), | 225 def FARCALL32m : I<0xFF, MRM3m, (outs), (ins opaque48mem:$dst), |
223 "lcall{l}\t{*}$dst", [], IIC_CALL_FAR_MEM>, OpSize32, | 226 "lcall{l}\t{*}$dst", [], IIC_CALL_FAR_MEM>, OpSize32, |
224 Sched<[WriteJumpLd]>; | 227 Sched<[WriteJumpLd]>; |
225 } | 228 } |
226 | 229 |
227 | |
228 // Tail call stuff. | 230 // Tail call stuff. |
229 | 231 |
230 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, | 232 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, |
231 isCodeGenOnly = 1, SchedRW = [WriteJumpLd] in | 233 isCodeGenOnly = 1, SchedRW = [WriteJumpLd] in |
232 let Uses = [ESP] in { | 234 let Uses = [ESP] in { |
233 def TCRETURNdi : PseudoI<(outs), | 235 def TCRETURNdi : PseudoI<(outs), |
234 (ins i32imm_pcrel:$dst, i32imm:$offset), []>; | 236 (ins i32imm_pcrel:$dst, i32imm:$offset), []>; |
235 def TCRETURNri : PseudoI<(outs), | 237 def TCRETURNri : PseudoI<(outs), |
236 (ins ptr_rc_tailcall:$dst, i32imm:$offset), []>; | 238 (ins ptr_rc_tailcall:$dst, i32imm:$offset), []>; |
237 let mayLoad = 1 in | 239 let mayLoad = 1 in |
238 def TCRETURNmi : PseudoI<(outs), | 240 def TCRETURNmi : PseudoI<(outs), |
239 (ins i32mem_TC:$dst, i32imm:$offset), []>; | 241 (ins i32mem_TC:$dst, i32imm:$offset), []>; |
240 | 242 |
241 // FIXME: The should be pseudo instructions that are lowered when going to | 243 // FIXME: The should be pseudo instructions that are lowered when going to |
242 // mcinst. | 244 // mcinst. |
243 def TAILJMPd : Ii32PCRel<0xE9, RawFrm, (outs), | 245 def TAILJMPd : Ii32PCRel<0xE9, RawFrm, (outs), |
244 (ins i32imm_pcrel:$dst), | 246 (ins i32imm_pcrel:$dst), |
245 "jmp\t$dst # TAILCALL", | 247 "jmp\t$dst # TAILCALL", |
246 [], IIC_JMP_REL>; | 248 [], IIC_JMP_REL>; |
247 def TAILJMPr : I<0xFF, MRM4r, (outs), (ins ptr_rc_tailcall:$dst), | 249 def TAILJMPr : I<0xFF, MRM4r, (outs), (ins ptr_rc_tailcall:$dst), |
248 "", [], IIC_JMP_REG>; // FIXME: Remove encoding when JIT is
dead. | 250 "", [], IIC_JMP_REG>; // FIXME: Remove encoding when JIT is
dead. |
249 let mayLoad = 1 in | 251 let mayLoad = 1 in |
250 def TAILJMPm : I<0xFF, MRM4m, (outs), (ins i32mem_TC:$dst), | 252 def TAILJMPm : I<0xFF, MRM4m, (outs), (ins i32mem_TC:$dst), |
251 "jmp{l}\t{*}$dst # TAILCALL", [], IIC_JMP_MEM>; | 253 "jmp{l}\t{*}$dst # TAILCALL", [], IIC_JMP_MEM>, Requires<[Is
NotNaCl]>; // @LOCALMOD |
252 } | 254 } |
253 | 255 |
254 | 256 |
255 //===----------------------------------------------------------------------===// | 257 //===----------------------------------------------------------------------===// |
256 // Call Instructions... | 258 // Call Instructions... |
257 // | 259 // |
258 | 260 |
259 // RSP is marked as a use to prevent stack-pointer assignments that appear | 261 // RSP is marked as a use to prevent stack-pointer assignments that appear |
260 // immediately before calls from potentially appearing dead. Uses for argument | 262 // immediately before calls from potentially appearing dead. Uses for argument |
261 // registers are added manually. | 263 // registers are added manually. |
262 let isCall = 1, Uses = [RSP], SchedRW = [WriteJump] in { | 264 let isCall = 1, Uses = [RSP], SchedRW = [WriteJump] in { |
263 // NOTE: this pattern doesn't match "X86call imm", because we do not know | 265 // NOTE: this pattern doesn't match "X86call imm", because we do not know |
264 // that the offset between an arbitrary immediate and the call will fit in | 266 // that the offset between an arbitrary immediate and the call will fit in |
265 // the 32-bit pcrel field that we have. | 267 // the 32-bit pcrel field that we have. |
266 def CALL64pcrel32 : Ii32PCRel<0xE8, RawFrm, | 268 def CALL64pcrel32 : Ii32PCRel<0xE8, RawFrm, |
267 (outs), (ins i64i32imm_pcrel:$dst), | 269 (outs), (ins i64i32imm_pcrel:$dst), |
268 "call{q}\t$dst", [], IIC_CALL_RI>, OpSize32, | 270 "call{q}\t$dst", [], IIC_CALL_RI>, OpSize32, |
269 Requires<[In64BitMode]>; | 271 Requires<[In64BitMode, IsNotNaCl]>; // @LOCALMOD |
270 def CALL64r : I<0xFF, MRM2r, (outs), (ins GR64:$dst), | 272 def CALL64r : I<0xFF, MRM2r, (outs), (ins GR64:$dst), |
271 "call{q}\t{*}$dst", [(X86call GR64:$dst)], | 273 "call{q}\t{*}$dst", [(X86call GR64:$dst)], |
272 IIC_CALL_RI>, | 274 IIC_CALL_RI>, |
273 Requires<[In64BitMode]>; | 275 Requires<[In64BitMode]>; |
274 def CALL64m : I<0xFF, MRM2m, (outs), (ins i64mem:$dst), | 276 def CALL64m : I<0xFF, MRM2m, (outs), (ins i64mem:$dst), |
275 "call{q}\t{*}$dst", [(X86call (loadi64 addr:$dst))], | 277 "call{q}\t{*}$dst", [(X86call (loadi64 addr:$dst))], |
276 IIC_CALL_MEM>, | 278 IIC_CALL_MEM>, |
277 Requires<[In64BitMode,FavorMemIndirectCall]>; | 279 Requires<[In64BitMode, IsNotNaCl, FavorMemIndirectCall]>; |
278 | 280 |
279 def FARCALL64 : RI<0xFF, MRM3m, (outs), (ins opaque80mem:$dst), | 281 def FARCALL64 : RI<0xFF, MRM3m, (outs), (ins opaque80mem:$dst), |
280 "lcall{q}\t{*}$dst", [], IIC_CALL_FAR_MEM>; | 282 "lcall{q}\t{*}$dst", [], IIC_CALL_FAR_MEM>, Requires<[IsN
otNaCl]>; // @LOCALMOD |
281 } | 283 } |
282 | 284 |
283 let isCall = 1, isCodeGenOnly = 1 in | 285 let isCall = 1, isCodeGenOnly = 1 in |
284 // __chkstk(MSVC): clobber R10, R11 and EFLAGS. | 286 // __chkstk(MSVC): clobber R10, R11 and EFLAGS. |
285 // ___chkstk(Mingw64): clobber R10, R11, RAX and EFLAGS, and update RSP. | 287 // ___chkstk(Mingw64): clobber R10, R11, RAX and EFLAGS, and update RSP. |
286 let Defs = [RAX, R10, R11, RSP, EFLAGS], | 288 let Defs = [RAX, R10, R11, RSP, EFLAGS], |
287 Uses = [RSP] in { | 289 Uses = [RSP] in { |
288 def W64ALLOCA : Ii32PCRel<0xE8, RawFrm, | 290 def W64ALLOCA : Ii32PCRel<0xE8, RawFrm, |
289 (outs), (ins i64i32imm_pcrel:$dst), | 291 (outs), (ins i64i32imm_pcrel:$dst), |
290 "call{q}\t$dst", [], IIC_CALL_RI>, | 292 "call{q}\t$dst", [], IIC_CALL_RI>, |
(...skipping 13 matching lines...) Expand all Loading... |
304 (ins i64mem_TC:$dst, i32imm:$offset), []>; | 306 (ins i64mem_TC:$dst, i32imm:$offset), []>; |
305 | 307 |
306 def TAILJMPd64 : Ii32PCRel<0xE9, RawFrm, (outs), | 308 def TAILJMPd64 : Ii32PCRel<0xE9, RawFrm, (outs), |
307 (ins i64i32imm_pcrel:$dst), | 309 (ins i64i32imm_pcrel:$dst), |
308 "jmp\t$dst # TAILCALL", [], IIC_JMP_REL>; | 310 "jmp\t$dst # TAILCALL", [], IIC_JMP_REL>; |
309 def TAILJMPr64 : I<0xFF, MRM4r, (outs), (ins ptr_rc_tailcall:$dst), | 311 def TAILJMPr64 : I<0xFF, MRM4r, (outs), (ins ptr_rc_tailcall:$dst), |
310 "jmp{q}\t{*}$dst # TAILCALL", [], IIC_JMP_MEM>; | 312 "jmp{q}\t{*}$dst # TAILCALL", [], IIC_JMP_MEM>; |
311 | 313 |
312 let mayLoad = 1 in | 314 let mayLoad = 1 in |
313 def TAILJMPm64 : I<0xFF, MRM4m, (outs), (ins i64mem_TC:$dst), | 315 def TAILJMPm64 : I<0xFF, MRM4m, (outs), (ins i64mem_TC:$dst), |
314 "jmp{q}\t{*}$dst # TAILCALL", [], IIC_JMP_MEM>; | 316 "jmp{q}\t{*}$dst # TAILCALL", [], IIC_JMP_MEM>, |
| 317 Requires<[IsNotNaCl]>; // @LOCALMOD |
315 } | 318 } |
OLD | NEW |