| OLD | NEW |
| 1 //===- X86InstrCompiler.td - Compiler Pseudos and Patterns -*- tablegen -*-===// | 1 //===- X86InstrCompiler.td - Compiler Pseudos and Patterns -*- 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 various pseudo instructions used by the compiler, | 10 // This file describes the various pseudo instructions used by the compiler, |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 | 86 |
| 87 // The VAARG_64 pseudo-instruction takes the address of the va_list, | 87 // The VAARG_64 pseudo-instruction takes the address of the va_list, |
| 88 // and places the address of the next argument into a register. | 88 // and places the address of the next argument into a register. |
| 89 let Defs = [EFLAGS] in | 89 let Defs = [EFLAGS] in |
| 90 def VAARG_64 : I<0, Pseudo, | 90 def VAARG_64 : I<0, Pseudo, |
| 91 (outs GR64:$dst), | 91 (outs GR64:$dst), |
| 92 (ins i8mem:$ap, i32imm:$size, i8imm:$mode, i32imm:$align), | 92 (ins i8mem:$ap, i32imm:$size, i8imm:$mode, i32imm:$align), |
| 93 "#VAARG_64 $dst, $ap, $size, $mode, $align", | 93 "#VAARG_64 $dst, $ap, $size, $mode, $align", |
| 94 [(set GR64:$dst, | 94 [(set GR64:$dst, |
| 95 (X86vaarg64 addr:$ap, imm:$size, imm:$mode, imm:$align)), | 95 (X86vaarg64 addr:$ap, imm:$size, imm:$mode, imm:$align)), |
| 96 (implicit EFLAGS)]>; | 96 (implicit EFLAGS)]>, |
| 97 | 97 Requires<[IsNotNaCl]>; |
| 98 // Dynamic stack allocation yields a _chkstk or _alloca call for all Windows | 98 // Dynamic stack allocation yields a _chkstk or _alloca call for all Windows |
| 99 // targets. These calls are needed to probe the stack when allocating more than | 99 // targets. These calls are needed to probe the stack when allocating more than |
| 100 // 4k bytes in one go. Touching the stack at 4K increments is necessary to | 100 // 4k bytes in one go. Touching the stack at 4K increments is necessary to |
| 101 // ensure that the guard pages used by the OS virtual memory manager are | 101 // ensure that the guard pages used by the OS virtual memory manager are |
| 102 // allocated in correct sequence. | 102 // allocated in correct sequence. |
| 103 // The main point of having separate instruction are extra unmodelled effects | 103 // The main point of having separate instruction are extra unmodelled effects |
| 104 // (compared to ordinary calls) like stack pointer change. | 104 // (compared to ordinary calls) like stack pointer change. |
| 105 | 105 |
| 106 let Defs = [EAX, ESP, EFLAGS], Uses = [ESP] in | 106 let Defs = [EAX, ESP, EFLAGS], Uses = [ESP] in |
| 107 def WIN_ALLOCA : I<0, Pseudo, (outs), (ins), | 107 def WIN_ALLOCA : I<0, Pseudo, (outs), (ins), |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 def TLS_addr64 : I<0, Pseudo, (outs), (ins i64mem:$sym), | 438 def TLS_addr64 : I<0, Pseudo, (outs), (ins i64mem:$sym), |
| 439 "# TLS_addr64", | 439 "# TLS_addr64", |
| 440 [(X86tlsaddr tls64addr:$sym)]>, | 440 [(X86tlsaddr tls64addr:$sym)]>, |
| 441 Requires<[In64BitMode]>; | 441 Requires<[In64BitMode]>; |
| 442 def TLS_base_addr64 : I<0, Pseudo, (outs), (ins i64mem:$sym), | 442 def TLS_base_addr64 : I<0, Pseudo, (outs), (ins i64mem:$sym), |
| 443 "# TLS_base_addr64", | 443 "# TLS_base_addr64", |
| 444 [(X86tlsbaseaddr tls64baseaddr:$sym)]>, | 444 [(X86tlsbaseaddr tls64baseaddr:$sym)]>, |
| 445 Requires<[In64BitMode]>; | 445 Requires<[In64BitMode]>; |
| 446 } | 446 } |
| 447 | 447 |
| 448 // @LOCALMOD-BEGIN |
| 449 // NaCl TLS support |
| 450 let usesCustomInserter = 1 in { |
| 451 def THREAD_POINTER_FROM_GS : |
| 452 I<0, Pseudo, (outs GR32:$dst), (ins), |
| 453 "# get thread pointer from %gs:0", |
| 454 [(set GR32:$dst, (X86thread_pointer_from_gs))]>; |
| 455 } |
| 456 // @LOCALMOD-END |
| 457 |
| 448 // Darwin TLS Support | 458 // Darwin TLS Support |
| 449 // For i386, the address of the thunk is passed on the stack, on return the | 459 // For i386, the address of the thunk is passed on the stack, on return the |
| 450 // address of the variable is in %eax. %ecx is trashed during the function | 460 // address of the variable is in %eax. %ecx is trashed during the function |
| 451 // call. All other registers are preserved. | 461 // call. All other registers are preserved. |
| 452 let Defs = [EAX, ECX, EFLAGS], | 462 let Defs = [EAX, ECX, EFLAGS], |
| 453 Uses = [ESP], | 463 Uses = [ESP], |
| 454 usesCustomInserter = 1 in | 464 usesCustomInserter = 1 in |
| 455 def TLSCall_32 : I<0, Pseudo, (outs), (ins i32mem:$sym), | 465 def TLSCall_32 : I<0, Pseudo, (outs), (ins i32mem:$sym), |
| 456 "# TLSCall_32", | 466 "# TLSCall_32", |
| 457 [(X86TLSCall addr:$sym)]>, | 467 [(X86TLSCall addr:$sym)]>, |
| (...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1017 def : Pat<(i64 (X86Wrapper tglobaltlsaddr :$dst)), | 1027 def : Pat<(i64 (X86Wrapper tglobaltlsaddr :$dst)), |
| 1018 (MOV64ri32 tglobaltlsaddr :$dst)>; | 1028 (MOV64ri32 tglobaltlsaddr :$dst)>; |
| 1019 // This corresponds to add $foo@tpoff, %rax | 1029 // This corresponds to add $foo@tpoff, %rax |
| 1020 def : Pat<(add GR64:$src1, (X86Wrapper tglobaltlsaddr :$dst)), | 1030 def : Pat<(add GR64:$src1, (X86Wrapper tglobaltlsaddr :$dst)), |
| 1021 (ADD64ri32 GR64:$src1, tglobaltlsaddr :$dst)>; | 1031 (ADD64ri32 GR64:$src1, tglobaltlsaddr :$dst)>; |
| 1022 | 1032 |
| 1023 | 1033 |
| 1024 // Direct PC relative function call for small code model. 32-bit displacement | 1034 // Direct PC relative function call for small code model. 32-bit displacement |
| 1025 // sign extended to 64-bit. | 1035 // sign extended to 64-bit. |
| 1026 def : Pat<(X86call (i64 tglobaladdr:$dst)), | 1036 def : Pat<(X86call (i64 tglobaladdr:$dst)), |
| 1027 (CALL64pcrel32 tglobaladdr:$dst)>; | 1037 (CALL64pcrel32 tglobaladdr:$dst)>, Requires<[IsNotNaCl]>; |
| 1028 def : Pat<(X86call (i64 texternalsym:$dst)), | 1038 def : Pat<(X86call (i64 texternalsym:$dst)), |
| 1029 (CALL64pcrel32 texternalsym:$dst)>; | 1039 (CALL64pcrel32 texternalsym:$dst)>, Requires<[IsNotNaCl]>; |
| 1030 | 1040 |
| 1031 // Tailcall stuff. The TCRETURN instructions execute after the epilog, so they | 1041 // Tailcall stuff. The TCRETURN instructions execute after the epilog, so they |
| 1032 // can never use callee-saved registers. That is the purpose of the GR64_TC | 1042 // can never use callee-saved registers. That is the purpose of the GR64_TC |
| 1033 // register classes. | 1043 // register classes. |
| 1034 // | 1044 // |
| 1035 // The only volatile register that is never used by the calling convention is | 1045 // The only volatile register that is never used by the calling convention is |
| 1036 // %r11. This happens when calling a vararg function with 6 arguments. | 1046 // %r11. This happens when calling a vararg function with 6 arguments. |
| 1037 // | 1047 // |
| 1038 // Match an X86tcret that uses less than 7 volatile registers. | 1048 // Match an X86tcret that uses less than 7 volatile registers. |
| 1039 def X86tcret_6regs : PatFrag<(ops node:$ptr, node:$off), | 1049 def X86tcret_6regs : PatFrag<(ops node:$ptr, node:$off), |
| 1040 (X86tcret node:$ptr, node:$off), [{ | 1050 (X86tcret node:$ptr, node:$off), [{ |
| 1041 // X86tcret args: (*chain, ptr, imm, regs..., glue) | 1051 // X86tcret args: (*chain, ptr, imm, regs..., glue) |
| 1042 unsigned NumRegs = 0; | 1052 unsigned NumRegs = 0; |
| 1043 for (unsigned i = 3, e = N->getNumOperands(); i != e; ++i) | 1053 for (unsigned i = 3, e = N->getNumOperands(); i != e; ++i) |
| 1044 if (isa<RegisterSDNode>(N->getOperand(i)) && ++NumRegs > 6) | 1054 if (isa<RegisterSDNode>(N->getOperand(i)) && ++NumRegs > 6) |
| 1045 return false; | 1055 return false; |
| 1046 return true; | 1056 return true; |
| 1047 }]>; | 1057 }]>; |
| 1048 | 1058 |
| 1049 def : Pat<(X86tcret ptr_rc_tailcall:$dst, imm:$off), | 1059 def : Pat<(X86tcret ptr_rc_tailcall:$dst, imm:$off), |
| 1050 (TCRETURNri ptr_rc_tailcall:$dst, imm:$off)>, | 1060 (TCRETURNri ptr_rc_tailcall:$dst, imm:$off)>, |
| 1051 Requires<[Not64BitMode]>; | 1061 Requires<[Not64BitMode]>; |
| 1052 | 1062 |
| 1053 // FIXME: This is disabled for 32-bit PIC mode because the global base | 1063 // FIXME: This is disabled for 32-bit PIC mode because the global base |
| 1054 // register which is part of the address mode may be assigned a | 1064 // register which is part of the address mode may be assigned a |
| 1055 // callee-saved register. | 1065 // callee-saved register. |
| 1056 def : Pat<(X86tcret (load addr:$dst), imm:$off), | 1066 def : Pat<(X86tcret (load addr:$dst), imm:$off), |
| 1057 (TCRETURNmi addr:$dst, imm:$off)>, | 1067 (TCRETURNmi addr:$dst, imm:$off)>, |
| 1058 Requires<[Not64BitMode, IsNotPIC]>; | 1068 Requires<[Not64BitMode, IsNotPIC, IsNotNaCl]>; // @LOCALMOD |
| 1059 | 1069 |
| 1060 def : Pat<(X86tcret (i32 tglobaladdr:$dst), imm:$off), | 1070 def : Pat<(X86tcret (i32 tglobaladdr:$dst), imm:$off), |
| 1061 (TCRETURNdi texternalsym:$dst, imm:$off)>, | 1071 (TCRETURNdi texternalsym:$dst, imm:$off)>, |
| 1062 Requires<[Not64BitMode]>; | 1072 Requires<[Not64BitMode]>; |
| 1063 | 1073 |
| 1064 def : Pat<(X86tcret (i32 texternalsym:$dst), imm:$off), | 1074 def : Pat<(X86tcret (i32 texternalsym:$dst), imm:$off), |
| 1065 (TCRETURNdi texternalsym:$dst, imm:$off)>, | 1075 (TCRETURNdi texternalsym:$dst, imm:$off)>, |
| 1066 Requires<[Not64BitMode]>; | 1076 Requires<[Not64BitMode]>; |
| 1067 | 1077 |
| 1068 def : Pat<(X86tcret ptr_rc_tailcall:$dst, imm:$off), | 1078 def : Pat<(X86tcret ptr_rc_tailcall:$dst, imm:$off), |
| 1069 (TCRETURNri64 ptr_rc_tailcall:$dst, imm:$off)>, | 1079 (TCRETURNri64 ptr_rc_tailcall:$dst, imm:$off)>, |
| 1070 Requires<[In64BitMode]>; | 1080 Requires<[In64BitMode]>; |
| 1071 | 1081 |
| 1072 // Don't fold loads into X86tcret requiring more than 6 regs. | 1082 // Don't fold loads into X86tcret requiring more than 6 regs. |
| 1073 // There wouldn't be enough scratch registers for base+index. | 1083 // There wouldn't be enough scratch registers for base+index. |
| 1074 def : Pat<(X86tcret_6regs (load addr:$dst), imm:$off), | 1084 def : Pat<(X86tcret_6regs (load addr:$dst), imm:$off), |
| 1075 (TCRETURNmi64 addr:$dst, imm:$off)>, | 1085 (TCRETURNmi64 addr:$dst, imm:$off)>, |
| 1076 Requires<[In64BitMode]>; | 1086 Requires<[In64BitMode, IsNotNaCl]>; |
| 1077 | 1087 |
| 1078 def : Pat<(X86tcret (i64 tglobaladdr:$dst), imm:$off), | 1088 def : Pat<(X86tcret (i64 tglobaladdr:$dst), imm:$off), |
| 1079 (TCRETURNdi64 tglobaladdr:$dst, imm:$off)>, | 1089 (TCRETURNdi64 tglobaladdr:$dst, imm:$off)>, |
| 1080 Requires<[In64BitMode]>; | 1090 Requires<[In64BitMode, IsNotNaCl]>; |
| 1081 | 1091 |
| 1082 def : Pat<(X86tcret (i64 texternalsym:$dst), imm:$off), | 1092 def : Pat<(X86tcret (i64 texternalsym:$dst), imm:$off), |
| 1083 (TCRETURNdi64 texternalsym:$dst, imm:$off)>, | 1093 (TCRETURNdi64 texternalsym:$dst, imm:$off)>, |
| 1084 Requires<[In64BitMode]>; | 1094 Requires<[In64BitMode, IsNotNaCl]>; |
| 1085 | 1095 |
| 1086 // Normal calls, with various flavors of addresses. | 1096 // Normal calls, with various flavors of addresses. |
| 1087 def : Pat<(X86call (i32 tglobaladdr:$dst)), | 1097 def : Pat<(X86call (i32 tglobaladdr:$dst)), |
| 1088 (CALLpcrel32 tglobaladdr:$dst)>; | 1098 (CALLpcrel32 tglobaladdr:$dst)>; |
| 1089 def : Pat<(X86call (i32 texternalsym:$dst)), | 1099 def : Pat<(X86call (i32 texternalsym:$dst)), |
| 1090 (CALLpcrel32 texternalsym:$dst)>; | 1100 (CALLpcrel32 texternalsym:$dst)>; |
| 1091 def : Pat<(X86call (i32 imm:$dst)), | 1101 def : Pat<(X86call (i32 imm:$dst)), |
| 1092 (CALLpcrel32 imm:$dst)>, Requires<[CallImmAddr]>; | 1102 (CALLpcrel32 imm:$dst)>, Requires<[CallImmAddr]>; |
| 1093 | 1103 |
| 1094 // Comparisons. | 1104 // Comparisons. |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1522 (MOVZX32_NOREXrr8 | 1532 (MOVZX32_NOREXrr8 |
| 1523 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), | 1533 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), |
| 1524 sub_8bit_hi)), | 1534 sub_8bit_hi)), |
| 1525 sub_32bit)>; | 1535 sub_32bit)>; |
| 1526 | 1536 |
| 1527 // h-register extract and store. | 1537 // h-register extract and store. |
| 1528 def : Pat<(store (i8 (trunc_su (srl_su GR64:$src, (i8 8)))), addr:$dst), | 1538 def : Pat<(store (i8 (trunc_su (srl_su GR64:$src, (i8 8)))), addr:$dst), |
| 1529 (MOV8mr_NOREX | 1539 (MOV8mr_NOREX |
| 1530 addr:$dst, | 1540 addr:$dst, |
| 1531 (EXTRACT_SUBREG (i64 (COPY_TO_REGCLASS GR64:$src, GR64_ABCD)), | 1541 (EXTRACT_SUBREG (i64 (COPY_TO_REGCLASS GR64:$src, GR64_ABCD)), |
| 1532 sub_8bit_hi))>; | 1542 sub_8bit_hi))>, Requires<[IsNotNaCl]>; // @LOCALMOD |
| 1533 def : Pat<(store (i8 (trunc_su (srl_su GR32:$src, (i8 8)))), addr:$dst), | 1543 def : Pat<(store (i8 (trunc_su (srl_su GR32:$src, (i8 8)))), addr:$dst), |
| 1534 (MOV8mr_NOREX | 1544 (MOV8mr_NOREX |
| 1535 addr:$dst, | 1545 addr:$dst, |
| 1536 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), | 1546 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)), |
| 1537 sub_8bit_hi))>, | 1547 sub_8bit_hi))>, |
| 1538 Requires<[In64BitMode]>; | 1548 Requires<[In64BitMode, IsNotNaCl]>; // @LOCALMOD |
| 1539 def : Pat<(store (i8 (trunc_su (srl_su GR16:$src, (i8 8)))), addr:$dst), | 1549 def : Pat<(store (i8 (trunc_su (srl_su GR16:$src, (i8 8)))), addr:$dst), |
| 1540 (MOV8mr_NOREX | 1550 (MOV8mr_NOREX |
| 1541 addr:$dst, | 1551 addr:$dst, |
| 1542 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), | 1552 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)), |
| 1543 sub_8bit_hi))>, | 1553 sub_8bit_hi))>, |
| 1544 Requires<[In64BitMode]>; | 1554 Requires<[In64BitMode, IsNotNaCl]>; // @LOCALMOD |
| 1545 | 1555 |
| 1546 | 1556 |
| 1547 // (shl x, 1) ==> (add x, x) | 1557 // (shl x, 1) ==> (add x, x) |
| 1548 // Note that if x is undef (immediate or otherwise), we could theoretically | 1558 // Note that if x is undef (immediate or otherwise), we could theoretically |
| 1549 // end up with the two uses of x getting different values, producing a result | 1559 // end up with the two uses of x getting different values, producing a result |
| 1550 // where the least significant bit is not 0. However, the probability of this | 1560 // where the least significant bit is not 0. However, the probability of this |
| 1551 // happening is considered low enough that this is officially not a | 1561 // happening is considered low enough that this is officially not a |
| 1552 // "real problem". | 1562 // "real problem". |
| 1553 def : Pat<(shl GR8 :$src1, (i8 1)), (ADD8rr GR8 :$src1, GR8 :$src1)>; | 1563 def : Pat<(shl GR8 :$src1, (i8 1)), (ADD8rr GR8 :$src1, GR8 :$src1)>; |
| 1554 def : Pat<(shl GR16:$src1, (i8 1)), (ADD16rr GR16:$src1, GR16:$src1)>; | 1564 def : Pat<(shl GR16:$src1, (i8 1)), (ADD16rr GR16:$src1, GR16:$src1)>; |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1853 def : Pat<(cttz_zero_undef GR64:$src), (BSF64rr GR64:$src)>; | 1863 def : Pat<(cttz_zero_undef GR64:$src), (BSF64rr GR64:$src)>; |
| 1854 def : Pat<(cttz_zero_undef (loadi16 addr:$src)), (BSF16rm addr:$src)>; | 1864 def : Pat<(cttz_zero_undef (loadi16 addr:$src)), (BSF16rm addr:$src)>; |
| 1855 def : Pat<(cttz_zero_undef (loadi32 addr:$src)), (BSF32rm addr:$src)>; | 1865 def : Pat<(cttz_zero_undef (loadi32 addr:$src)), (BSF32rm addr:$src)>; |
| 1856 def : Pat<(cttz_zero_undef (loadi64 addr:$src)), (BSF64rm addr:$src)>; | 1866 def : Pat<(cttz_zero_undef (loadi64 addr:$src)), (BSF64rm addr:$src)>; |
| 1857 | 1867 |
| 1858 // When HasMOVBE is enabled it is possible to get a non-legalized | 1868 // When HasMOVBE is enabled it is possible to get a non-legalized |
| 1859 // register-register 16 bit bswap. This maps it to a ROL instruction. | 1869 // register-register 16 bit bswap. This maps it to a ROL instruction. |
| 1860 let Predicates = [HasMOVBE] in { | 1870 let Predicates = [HasMOVBE] in { |
| 1861 def : Pat<(bswap GR16:$src), (ROL16ri GR16:$src, (i8 8))>; | 1871 def : Pat<(bswap GR16:$src), (ROL16ri GR16:$src, (i8 8))>; |
| 1862 } | 1872 } |
| OLD | NEW |