| 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 |