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 |