| Jia Liu | b22310f | 2012-02-18 12:03:15 +0000 | [diff] [blame] | 1 | //===-- X86InstrInfo.cpp - X86 Instruction Information --------------------===// | 
| Misha Brukman | c88330a | 2005-04-21 23:38:14 +0000 | [diff] [blame] | 2 | // | 
| John Criswell | 482202a | 2003-10-20 19:43:21 +0000 | [diff] [blame] | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
| Chris Lattner | f3ebc3f | 2007-12-29 20:36:04 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
| Misha Brukman | c88330a | 2005-04-21 23:38:14 +0000 | [diff] [blame] | 7 | // | 
| John Criswell | 482202a | 2003-10-20 19:43:21 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | d92fb00 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 9 | // | 
| Chris Lattner | b4d58d7 | 2003-01-14 22:00:31 +0000 | [diff] [blame] | 10 | // This file contains the X86 implementation of the TargetInstrInfo class. | 
| Chris Lattner | d92fb00 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
| Chris Lattner | 27d2479 | 2002-10-29 21:05:24 +0000 | [diff] [blame] | 14 | #include "X86InstrInfo.h" | 
| Chris Lattner | 0d80874 | 2002-12-03 05:42:53 +0000 | [diff] [blame] | 15 | #include "X86.h" | 
| Evan Cheng | c8c172e | 2006-05-30 21:45:53 +0000 | [diff] [blame] | 16 | #include "X86InstrBuilder.h" | 
| Owen Anderson | 6bb0c52 | 2008-01-04 23:57:37 +0000 | [diff] [blame] | 17 | #include "X86MachineFunctionInfo.h" | 
| Evan Cheng | c8c172e | 2006-05-30 21:45:53 +0000 | [diff] [blame] | 18 | #include "X86Subtarget.h" | 
|  | 19 | #include "X86TargetMachine.h" | 
| Owen Anderson | e2f23a3 | 2007-09-07 04:06:50 +0000 | [diff] [blame] | 20 | #include "llvm/ADT/STLExtras.h" | 
| Quentin Colombet | 2b3a4e7 | 2016-04-26 23:14:32 +0000 | [diff] [blame] | 21 | #include "llvm/CodeGen/LivePhysRegs.h" | 
| Chandler Carruth | ed0881b | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 22 | #include "llvm/CodeGen/LiveVariables.h" | 
| Dan Gohman | cc78cdf | 2008-12-03 05:21:24 +0000 | [diff] [blame] | 23 | #include "llvm/CodeGen/MachineConstantPool.h" | 
| Hans Wennborg | 789acfb | 2012-06-01 16:27:21 +0000 | [diff] [blame] | 24 | #include "llvm/CodeGen/MachineDominators.h" | 
| Owen Anderson | 6bb0c52 | 2008-01-04 23:57:37 +0000 | [diff] [blame] | 25 | #include "llvm/CodeGen/MachineFrameInfo.h" | 
| Evan Cheng | c8c172e | 2006-05-30 21:45:53 +0000 | [diff] [blame] | 26 | #include "llvm/CodeGen/MachineInstrBuilder.h" | 
| Hans Wennborg | 4ae5119 | 2016-03-25 01:10:56 +0000 | [diff] [blame] | 27 | #include "llvm/CodeGen/MachineModuleInfo.h" | 
| Chris Lattner | a10fff5 | 2007-12-31 04:13:23 +0000 | [diff] [blame] | 28 | #include "llvm/CodeGen/MachineRegisterInfo.h" | 
| Andrew Trick | 153ebe6 | 2013-10-31 22:11:56 +0000 | [diff] [blame] | 29 | #include "llvm/CodeGen/StackMaps.h" | 
| Chandler Carruth | 9fb823b | 2013-01-02 11:36:10 +0000 | [diff] [blame] | 30 | #include "llvm/IR/DerivedTypes.h" | 
| Eric Christopher | 79cc1e3 | 2014-09-02 22:28:02 +0000 | [diff] [blame] | 31 | #include "llvm/IR/Function.h" | 
| Chandler Carruth | 9fb823b | 2013-01-02 11:36:10 +0000 | [diff] [blame] | 32 | #include "llvm/IR/LLVMContext.h" | 
| Craig Topper | b25fda9 | 2012-03-17 18:46:09 +0000 | [diff] [blame] | 33 | #include "llvm/MC/MCAsmInfo.h" | 
| Tom Roeder | 44cb65f | 2014-06-05 19:29:43 +0000 | [diff] [blame] | 34 | #include "llvm/MC/MCExpr.h" | 
| Chris Lattner | 6a5e706 | 2010-04-26 23:37:21 +0000 | [diff] [blame] | 35 | #include "llvm/MC/MCInst.h" | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 36 | #include "llvm/Support/CommandLine.h" | 
| David Greene | d589daf | 2010-01-05 01:29:29 +0000 | [diff] [blame] | 37 | #include "llvm/Support/Debug.h" | 
| Torok Edwin | 6dd2730 | 2009-07-08 18:01:40 +0000 | [diff] [blame] | 38 | #include "llvm/Support/ErrorHandling.h" | 
|  | 39 | #include "llvm/Support/raw_ostream.h" | 
| Evan Cheng | e95f391 | 2007-09-25 01:57:46 +0000 | [diff] [blame] | 40 | #include "llvm/Target/TargetOptions.h" | 
| David Greene | 70fdd57 | 2009-11-12 20:55:29 +0000 | [diff] [blame] | 41 |  | 
| Chandler Carruth | d174b72 | 2014-04-22 02:03:14 +0000 | [diff] [blame] | 42 | using namespace llvm; | 
|  | 43 |  | 
| Chandler Carruth | e96dd89 | 2014-04-21 22:55:11 +0000 | [diff] [blame] | 44 | #define DEBUG_TYPE "x86-instr-info" | 
|  | 45 |  | 
| Juergen Ributzka | d12ccbd | 2013-11-19 00:57:56 +0000 | [diff] [blame] | 46 | #define GET_INSTRINFO_CTOR_DTOR | 
| Evan Cheng | 1e210d0 | 2011-06-28 20:07:07 +0000 | [diff] [blame] | 47 | #include "X86GenInstrInfo.inc" | 
|  | 48 |  | 
| Chris Lattner | a6f074f | 2009-08-23 03:41:05 +0000 | [diff] [blame] | 49 | static cl::opt<bool> | 
|  | 50 | NoFusing("disable-spill-fusing", | 
|  | 51 | cl::desc("Disable fusing of spill code into instructions")); | 
|  | 52 | static cl::opt<bool> | 
|  | 53 | PrintFailedFusing("print-failed-fuse-candidates", | 
|  | 54 | cl::desc("Print instructions that the allocator wants to" | 
|  | 55 | " fuse, but the X86 backend currently can't"), | 
|  | 56 | cl::Hidden); | 
|  | 57 | static cl::opt<bool> | 
|  | 58 | ReMatPICStubLoad("remat-pic-stub-load", | 
|  | 59 | cl::desc("Re-materialize load from stub in PIC mode"), | 
|  | 60 | cl::init(false), cl::Hidden); | 
| Dehao Chen | 8cd84aa | 2016-06-28 21:19:34 +0000 | [diff] [blame] | 61 | static cl::opt<unsigned> | 
|  | 62 | PartialRegUpdateClearance("partial-reg-update-clearance", | 
|  | 63 | cl::desc("Clearance between two register writes " | 
|  | 64 | "for inserting XOR to avoid partial " | 
|  | 65 | "register update"), | 
|  | 66 | cl::init(64), cl::Hidden); | 
|  | 67 | static cl::opt<unsigned> | 
|  | 68 | UndefRegClearance("undef-reg-clearance", | 
|  | 69 | cl::desc("How many idle instructions we would like before " | 
|  | 70 | "certain undef register reads"), | 
|  | 71 | cl::init(64), cl::Hidden); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 72 |  | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 73 | enum { | 
|  | 74 | // Select which memory operand is being unfolded. | 
| Craig Topper | 1cac50b | 2012-06-23 08:01:18 +0000 | [diff] [blame] | 75 | // (stored in bits 0 - 3) | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 76 | TB_INDEX_0    = 0, | 
|  | 77 | TB_INDEX_1    = 1, | 
|  | 78 | TB_INDEX_2    = 2, | 
| Elena Demikhovsky | 602f3a2 | 2012-05-31 09:20:20 +0000 | [diff] [blame] | 79 | TB_INDEX_3    = 3, | 
| Robert Khasanov | 79fb729 | 2014-12-18 12:28:22 +0000 | [diff] [blame] | 80 | TB_INDEX_4    = 4, | 
| Craig Topper | 1cac50b | 2012-06-23 08:01:18 +0000 | [diff] [blame] | 81 | TB_INDEX_MASK = 0xf, | 
|  | 82 |  | 
|  | 83 | // Do not insert the reverse map (MemOp -> RegOp) into the table. | 
|  | 84 | // This may be needed because there is a many -> one mapping. | 
|  | 85 | TB_NO_REVERSE   = 1 << 4, | 
|  | 86 |  | 
|  | 87 | // Do not insert the forward map (RegOp -> MemOp) into the table. | 
|  | 88 | // This is needed for Native Client, which prohibits branch | 
|  | 89 | // instructions from using a memory operand. | 
|  | 90 | TB_NO_FORWARD   = 1 << 5, | 
|  | 91 |  | 
|  | 92 | TB_FOLDED_LOAD  = 1 << 6, | 
|  | 93 | TB_FOLDED_STORE = 1 << 7, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 94 |  | 
|  | 95 | // Minimum alignment required for load/store. | 
|  | 96 | // Used for RegOp->MemOp conversion. | 
|  | 97 | // (stored in bits 8 - 15) | 
|  | 98 | TB_ALIGN_SHIFT = 8, | 
|  | 99 | TB_ALIGN_NONE  =    0 << TB_ALIGN_SHIFT, | 
|  | 100 | TB_ALIGN_16    =   16 << TB_ALIGN_SHIFT, | 
|  | 101 | TB_ALIGN_32    =   32 << TB_ALIGN_SHIFT, | 
| Elena Demikhovsky | cf5b145 | 2013-08-11 07:55:09 +0000 | [diff] [blame] | 102 | TB_ALIGN_64    =   64 << TB_ALIGN_SHIFT, | 
| Craig Topper | 1cac50b | 2012-06-23 08:01:18 +0000 | [diff] [blame] | 103 | TB_ALIGN_MASK  = 0xff << TB_ALIGN_SHIFT | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 104 | }; | 
|  | 105 |  | 
| Sanjay Patel | e951a38 | 2015-02-17 22:38:06 +0000 | [diff] [blame] | 106 | struct X86MemoryFoldTableEntry { | 
| Craig Topper | 2dac962 | 2012-03-09 07:45:21 +0000 | [diff] [blame] | 107 | uint16_t RegOp; | 
|  | 108 | uint16_t MemOp; | 
| Craig Topper | 1cac50b | 2012-06-23 08:01:18 +0000 | [diff] [blame] | 109 | uint16_t Flags; | 
| Craig Topper | 2dac962 | 2012-03-09 07:45:21 +0000 | [diff] [blame] | 110 | }; | 
|  | 111 |  | 
| Juergen Ributzka | d12ccbd | 2013-11-19 00:57:56 +0000 | [diff] [blame] | 112 | // Pin the vtable to this file. | 
|  | 113 | void X86InstrInfo::anchor() {} | 
|  | 114 |  | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 115 | X86InstrInfo::X86InstrInfo(X86Subtarget &STI) | 
| David Majnemer | f828a0c | 2015-10-01 18:44:59 +0000 | [diff] [blame] | 116 | : X86GenInstrInfo((STI.isTarget64BitLP64() ? X86::ADJCALLSTACKDOWN64 | 
|  | 117 | : X86::ADJCALLSTACKDOWN32), | 
|  | 118 | (STI.isTarget64BitLP64() ? X86::ADJCALLSTACKUP64 | 
|  | 119 | : X86::ADJCALLSTACKUP32), | 
| Dean Michael Berris | 52735fc | 2016-07-14 04:06:33 +0000 | [diff] [blame] | 120 | X86::CATCHRET, | 
|  | 121 | (STI.is64Bit() ? X86::RETQ : X86::RETL)), | 
| Eric Christopher | ed6a446 | 2015-03-12 17:54:19 +0000 | [diff] [blame] | 122 | Subtarget(STI), RI(STI.getTargetTriple()) { | 
| NAKAMURA Takumi | 9d29eff | 2011-01-26 02:03:37 +0000 | [diff] [blame] | 123 |  | 
| Sanjay Patel | e951a38 | 2015-02-17 22:38:06 +0000 | [diff] [blame] | 124 | static const X86MemoryFoldTableEntry MemoryFoldTable2Addr[] = { | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 125 | { X86::ADC32ri,     X86::ADC32mi,    0 }, | 
|  | 126 | { X86::ADC32ri8,    X86::ADC32mi8,   0 }, | 
|  | 127 | { X86::ADC32rr,     X86::ADC32mr,    0 }, | 
|  | 128 | { X86::ADC64ri32,   X86::ADC64mi32,  0 }, | 
|  | 129 | { X86::ADC64ri8,    X86::ADC64mi8,   0 }, | 
|  | 130 | { X86::ADC64rr,     X86::ADC64mr,    0 }, | 
|  | 131 | { X86::ADD16ri,     X86::ADD16mi,    0 }, | 
|  | 132 | { X86::ADD16ri8,    X86::ADD16mi8,   0 }, | 
|  | 133 | { X86::ADD16ri_DB,  X86::ADD16mi,    TB_NO_REVERSE }, | 
|  | 134 | { X86::ADD16ri8_DB, X86::ADD16mi8,   TB_NO_REVERSE }, | 
|  | 135 | { X86::ADD16rr,     X86::ADD16mr,    0 }, | 
|  | 136 | { X86::ADD16rr_DB,  X86::ADD16mr,    TB_NO_REVERSE }, | 
|  | 137 | { X86::ADD32ri,     X86::ADD32mi,    0 }, | 
|  | 138 | { X86::ADD32ri8,    X86::ADD32mi8,   0 }, | 
|  | 139 | { X86::ADD32ri_DB,  X86::ADD32mi,    TB_NO_REVERSE }, | 
|  | 140 | { X86::ADD32ri8_DB, X86::ADD32mi8,   TB_NO_REVERSE }, | 
|  | 141 | { X86::ADD32rr,     X86::ADD32mr,    0 }, | 
|  | 142 | { X86::ADD32rr_DB,  X86::ADD32mr,    TB_NO_REVERSE }, | 
|  | 143 | { X86::ADD64ri32,   X86::ADD64mi32,  0 }, | 
|  | 144 | { X86::ADD64ri8,    X86::ADD64mi8,   0 }, | 
|  | 145 | { X86::ADD64ri32_DB,X86::ADD64mi32,  TB_NO_REVERSE }, | 
|  | 146 | { X86::ADD64ri8_DB, X86::ADD64mi8,   TB_NO_REVERSE }, | 
|  | 147 | { X86::ADD64rr,     X86::ADD64mr,    0 }, | 
|  | 148 | { X86::ADD64rr_DB,  X86::ADD64mr,    TB_NO_REVERSE }, | 
|  | 149 | { X86::ADD8ri,      X86::ADD8mi,     0 }, | 
|  | 150 | { X86::ADD8rr,      X86::ADD8mr,     0 }, | 
|  | 151 | { X86::AND16ri,     X86::AND16mi,    0 }, | 
|  | 152 | { X86::AND16ri8,    X86::AND16mi8,   0 }, | 
|  | 153 | { X86::AND16rr,     X86::AND16mr,    0 }, | 
|  | 154 | { X86::AND32ri,     X86::AND32mi,    0 }, | 
|  | 155 | { X86::AND32ri8,    X86::AND32mi8,   0 }, | 
|  | 156 | { X86::AND32rr,     X86::AND32mr,    0 }, | 
|  | 157 | { X86::AND64ri32,   X86::AND64mi32,  0 }, | 
|  | 158 | { X86::AND64ri8,    X86::AND64mi8,   0 }, | 
|  | 159 | { X86::AND64rr,     X86::AND64mr,    0 }, | 
|  | 160 | { X86::AND8ri,      X86::AND8mi,     0 }, | 
|  | 161 | { X86::AND8rr,      X86::AND8mr,     0 }, | 
|  | 162 | { X86::DEC16r,      X86::DEC16m,     0 }, | 
|  | 163 | { X86::DEC32r,      X86::DEC32m,     0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 164 | { X86::DEC64r,      X86::DEC64m,     0 }, | 
|  | 165 | { X86::DEC8r,       X86::DEC8m,      0 }, | 
|  | 166 | { X86::INC16r,      X86::INC16m,     0 }, | 
|  | 167 | { X86::INC32r,      X86::INC32m,     0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 168 | { X86::INC64r,      X86::INC64m,     0 }, | 
|  | 169 | { X86::INC8r,       X86::INC8m,      0 }, | 
|  | 170 | { X86::NEG16r,      X86::NEG16m,     0 }, | 
|  | 171 | { X86::NEG32r,      X86::NEG32m,     0 }, | 
|  | 172 | { X86::NEG64r,      X86::NEG64m,     0 }, | 
|  | 173 | { X86::NEG8r,       X86::NEG8m,      0 }, | 
|  | 174 | { X86::NOT16r,      X86::NOT16m,     0 }, | 
|  | 175 | { X86::NOT32r,      X86::NOT32m,     0 }, | 
|  | 176 | { X86::NOT64r,      X86::NOT64m,     0 }, | 
|  | 177 | { X86::NOT8r,       X86::NOT8m,      0 }, | 
|  | 178 | { X86::OR16ri,      X86::OR16mi,     0 }, | 
|  | 179 | { X86::OR16ri8,     X86::OR16mi8,    0 }, | 
|  | 180 | { X86::OR16rr,      X86::OR16mr,     0 }, | 
|  | 181 | { X86::OR32ri,      X86::OR32mi,     0 }, | 
|  | 182 | { X86::OR32ri8,     X86::OR32mi8,    0 }, | 
|  | 183 | { X86::OR32rr,      X86::OR32mr,     0 }, | 
|  | 184 | { X86::OR64ri32,    X86::OR64mi32,   0 }, | 
|  | 185 | { X86::OR64ri8,     X86::OR64mi8,    0 }, | 
|  | 186 | { X86::OR64rr,      X86::OR64mr,     0 }, | 
|  | 187 | { X86::OR8ri,       X86::OR8mi,      0 }, | 
|  | 188 | { X86::OR8rr,       X86::OR8mr,      0 }, | 
|  | 189 | { X86::ROL16r1,     X86::ROL16m1,    0 }, | 
|  | 190 | { X86::ROL16rCL,    X86::ROL16mCL,   0 }, | 
|  | 191 | { X86::ROL16ri,     X86::ROL16mi,    0 }, | 
|  | 192 | { X86::ROL32r1,     X86::ROL32m1,    0 }, | 
|  | 193 | { X86::ROL32rCL,    X86::ROL32mCL,   0 }, | 
|  | 194 | { X86::ROL32ri,     X86::ROL32mi,    0 }, | 
|  | 195 | { X86::ROL64r1,     X86::ROL64m1,    0 }, | 
|  | 196 | { X86::ROL64rCL,    X86::ROL64mCL,   0 }, | 
|  | 197 | { X86::ROL64ri,     X86::ROL64mi,    0 }, | 
|  | 198 | { X86::ROL8r1,      X86::ROL8m1,     0 }, | 
|  | 199 | { X86::ROL8rCL,     X86::ROL8mCL,    0 }, | 
|  | 200 | { X86::ROL8ri,      X86::ROL8mi,     0 }, | 
|  | 201 | { X86::ROR16r1,     X86::ROR16m1,    0 }, | 
|  | 202 | { X86::ROR16rCL,    X86::ROR16mCL,   0 }, | 
|  | 203 | { X86::ROR16ri,     X86::ROR16mi,    0 }, | 
|  | 204 | { X86::ROR32r1,     X86::ROR32m1,    0 }, | 
|  | 205 | { X86::ROR32rCL,    X86::ROR32mCL,   0 }, | 
|  | 206 | { X86::ROR32ri,     X86::ROR32mi,    0 }, | 
|  | 207 | { X86::ROR64r1,     X86::ROR64m1,    0 }, | 
|  | 208 | { X86::ROR64rCL,    X86::ROR64mCL,   0 }, | 
|  | 209 | { X86::ROR64ri,     X86::ROR64mi,    0 }, | 
|  | 210 | { X86::ROR8r1,      X86::ROR8m1,     0 }, | 
|  | 211 | { X86::ROR8rCL,     X86::ROR8mCL,    0 }, | 
|  | 212 | { X86::ROR8ri,      X86::ROR8mi,     0 }, | 
|  | 213 | { X86::SAR16r1,     X86::SAR16m1,    0 }, | 
|  | 214 | { X86::SAR16rCL,    X86::SAR16mCL,   0 }, | 
|  | 215 | { X86::SAR16ri,     X86::SAR16mi,    0 }, | 
|  | 216 | { X86::SAR32r1,     X86::SAR32m1,    0 }, | 
|  | 217 | { X86::SAR32rCL,    X86::SAR32mCL,   0 }, | 
|  | 218 | { X86::SAR32ri,     X86::SAR32mi,    0 }, | 
|  | 219 | { X86::SAR64r1,     X86::SAR64m1,    0 }, | 
|  | 220 | { X86::SAR64rCL,    X86::SAR64mCL,   0 }, | 
|  | 221 | { X86::SAR64ri,     X86::SAR64mi,    0 }, | 
|  | 222 | { X86::SAR8r1,      X86::SAR8m1,     0 }, | 
|  | 223 | { X86::SAR8rCL,     X86::SAR8mCL,    0 }, | 
|  | 224 | { X86::SAR8ri,      X86::SAR8mi,     0 }, | 
|  | 225 | { X86::SBB32ri,     X86::SBB32mi,    0 }, | 
|  | 226 | { X86::SBB32ri8,    X86::SBB32mi8,   0 }, | 
|  | 227 | { X86::SBB32rr,     X86::SBB32mr,    0 }, | 
|  | 228 | { X86::SBB64ri32,   X86::SBB64mi32,  0 }, | 
|  | 229 | { X86::SBB64ri8,    X86::SBB64mi8,   0 }, | 
|  | 230 | { X86::SBB64rr,     X86::SBB64mr,    0 }, | 
|  | 231 | { X86::SHL16rCL,    X86::SHL16mCL,   0 }, | 
|  | 232 | { X86::SHL16ri,     X86::SHL16mi,    0 }, | 
|  | 233 | { X86::SHL32rCL,    X86::SHL32mCL,   0 }, | 
|  | 234 | { X86::SHL32ri,     X86::SHL32mi,    0 }, | 
|  | 235 | { X86::SHL64rCL,    X86::SHL64mCL,   0 }, | 
|  | 236 | { X86::SHL64ri,     X86::SHL64mi,    0 }, | 
|  | 237 | { X86::SHL8rCL,     X86::SHL8mCL,    0 }, | 
|  | 238 | { X86::SHL8ri,      X86::SHL8mi,     0 }, | 
|  | 239 | { X86::SHLD16rrCL,  X86::SHLD16mrCL, 0 }, | 
|  | 240 | { X86::SHLD16rri8,  X86::SHLD16mri8, 0 }, | 
|  | 241 | { X86::SHLD32rrCL,  X86::SHLD32mrCL, 0 }, | 
|  | 242 | { X86::SHLD32rri8,  X86::SHLD32mri8, 0 }, | 
|  | 243 | { X86::SHLD64rrCL,  X86::SHLD64mrCL, 0 }, | 
|  | 244 | { X86::SHLD64rri8,  X86::SHLD64mri8, 0 }, | 
|  | 245 | { X86::SHR16r1,     X86::SHR16m1,    0 }, | 
|  | 246 | { X86::SHR16rCL,    X86::SHR16mCL,   0 }, | 
|  | 247 | { X86::SHR16ri,     X86::SHR16mi,    0 }, | 
|  | 248 | { X86::SHR32r1,     X86::SHR32m1,    0 }, | 
|  | 249 | { X86::SHR32rCL,    X86::SHR32mCL,   0 }, | 
|  | 250 | { X86::SHR32ri,     X86::SHR32mi,    0 }, | 
|  | 251 | { X86::SHR64r1,     X86::SHR64m1,    0 }, | 
|  | 252 | { X86::SHR64rCL,    X86::SHR64mCL,   0 }, | 
|  | 253 | { X86::SHR64ri,     X86::SHR64mi,    0 }, | 
|  | 254 | { X86::SHR8r1,      X86::SHR8m1,     0 }, | 
|  | 255 | { X86::SHR8rCL,     X86::SHR8mCL,    0 }, | 
|  | 256 | { X86::SHR8ri,      X86::SHR8mi,     0 }, | 
|  | 257 | { X86::SHRD16rrCL,  X86::SHRD16mrCL, 0 }, | 
|  | 258 | { X86::SHRD16rri8,  X86::SHRD16mri8, 0 }, | 
|  | 259 | { X86::SHRD32rrCL,  X86::SHRD32mrCL, 0 }, | 
|  | 260 | { X86::SHRD32rri8,  X86::SHRD32mri8, 0 }, | 
|  | 261 | { X86::SHRD64rrCL,  X86::SHRD64mrCL, 0 }, | 
|  | 262 | { X86::SHRD64rri8,  X86::SHRD64mri8, 0 }, | 
|  | 263 | { X86::SUB16ri,     X86::SUB16mi,    0 }, | 
|  | 264 | { X86::SUB16ri8,    X86::SUB16mi8,   0 }, | 
|  | 265 | { X86::SUB16rr,     X86::SUB16mr,    0 }, | 
|  | 266 | { X86::SUB32ri,     X86::SUB32mi,    0 }, | 
|  | 267 | { X86::SUB32ri8,    X86::SUB32mi8,   0 }, | 
|  | 268 | { X86::SUB32rr,     X86::SUB32mr,    0 }, | 
|  | 269 | { X86::SUB64ri32,   X86::SUB64mi32,  0 }, | 
|  | 270 | { X86::SUB64ri8,    X86::SUB64mi8,   0 }, | 
|  | 271 | { X86::SUB64rr,     X86::SUB64mr,    0 }, | 
|  | 272 | { X86::SUB8ri,      X86::SUB8mi,     0 }, | 
|  | 273 | { X86::SUB8rr,      X86::SUB8mr,     0 }, | 
|  | 274 | { X86::XOR16ri,     X86::XOR16mi,    0 }, | 
|  | 275 | { X86::XOR16ri8,    X86::XOR16mi8,   0 }, | 
|  | 276 | { X86::XOR16rr,     X86::XOR16mr,    0 }, | 
|  | 277 | { X86::XOR32ri,     X86::XOR32mi,    0 }, | 
|  | 278 | { X86::XOR32ri8,    X86::XOR32mi8,   0 }, | 
|  | 279 | { X86::XOR32rr,     X86::XOR32mr,    0 }, | 
|  | 280 | { X86::XOR64ri32,   X86::XOR64mi32,  0 }, | 
|  | 281 | { X86::XOR64ri8,    X86::XOR64mi8,   0 }, | 
|  | 282 | { X86::XOR64rr,     X86::XOR64mr,    0 }, | 
|  | 283 | { X86::XOR8ri,      X86::XOR8mi,     0 }, | 
|  | 284 | { X86::XOR8rr,      X86::XOR8mr,     0 } | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 285 | }; | 
|  | 286 |  | 
| Sanjay Patel | cf0a807 | 2015-07-07 15:03:53 +0000 | [diff] [blame] | 287 | for (X86MemoryFoldTableEntry Entry : MemoryFoldTable2Addr) { | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 288 | AddTableEntry(RegOp2MemOpTable2Addr, MemOp2RegOpTable, | 
| Sanjay Patel | cf0a807 | 2015-07-07 15:03:53 +0000 | [diff] [blame] | 289 | Entry.RegOp, Entry.MemOp, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 290 | // Index 0, folded load and store, no alignment requirement. | 
| Sanjay Patel | cf0a807 | 2015-07-07 15:03:53 +0000 | [diff] [blame] | 291 | Entry.Flags | TB_INDEX_0 | TB_FOLDED_LOAD | TB_FOLDED_STORE); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 292 | } | 
|  | 293 |  | 
| Sanjay Patel | e951a38 | 2015-02-17 22:38:06 +0000 | [diff] [blame] | 294 | static const X86MemoryFoldTableEntry MemoryFoldTable0[] = { | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 295 | { X86::BT16ri8,     X86::BT16mi8,       TB_FOLDED_LOAD }, | 
|  | 296 | { X86::BT32ri8,     X86::BT32mi8,       TB_FOLDED_LOAD }, | 
|  | 297 | { X86::BT64ri8,     X86::BT64mi8,       TB_FOLDED_LOAD }, | 
|  | 298 | { X86::CALL32r,     X86::CALL32m,       TB_FOLDED_LOAD }, | 
|  | 299 | { X86::CALL64r,     X86::CALL64m,       TB_FOLDED_LOAD }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 300 | { X86::CMP16ri,     X86::CMP16mi,       TB_FOLDED_LOAD }, | 
|  | 301 | { X86::CMP16ri8,    X86::CMP16mi8,      TB_FOLDED_LOAD }, | 
|  | 302 | { X86::CMP16rr,     X86::CMP16mr,       TB_FOLDED_LOAD }, | 
|  | 303 | { X86::CMP32ri,     X86::CMP32mi,       TB_FOLDED_LOAD }, | 
|  | 304 | { X86::CMP32ri8,    X86::CMP32mi8,      TB_FOLDED_LOAD }, | 
|  | 305 | { X86::CMP32rr,     X86::CMP32mr,       TB_FOLDED_LOAD }, | 
|  | 306 | { X86::CMP64ri32,   X86::CMP64mi32,     TB_FOLDED_LOAD }, | 
|  | 307 | { X86::CMP64ri8,    X86::CMP64mi8,      TB_FOLDED_LOAD }, | 
|  | 308 | { X86::CMP64rr,     X86::CMP64mr,       TB_FOLDED_LOAD }, | 
|  | 309 | { X86::CMP8ri,      X86::CMP8mi,        TB_FOLDED_LOAD }, | 
|  | 310 | { X86::CMP8rr,      X86::CMP8mr,        TB_FOLDED_LOAD }, | 
|  | 311 | { X86::DIV16r,      X86::DIV16m,        TB_FOLDED_LOAD }, | 
|  | 312 | { X86::DIV32r,      X86::DIV32m,        TB_FOLDED_LOAD }, | 
|  | 313 | { X86::DIV64r,      X86::DIV64m,        TB_FOLDED_LOAD }, | 
|  | 314 | { X86::DIV8r,       X86::DIV8m,         TB_FOLDED_LOAD }, | 
| Craig Topper | d09a9af | 2012-12-26 01:47:12 +0000 | [diff] [blame] | 315 | { X86::EXTRACTPSrr, X86::EXTRACTPSmr,   TB_FOLDED_STORE }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 316 | { X86::IDIV16r,     X86::IDIV16m,       TB_FOLDED_LOAD }, | 
|  | 317 | { X86::IDIV32r,     X86::IDIV32m,       TB_FOLDED_LOAD }, | 
|  | 318 | { X86::IDIV64r,     X86::IDIV64m,       TB_FOLDED_LOAD }, | 
|  | 319 | { X86::IDIV8r,      X86::IDIV8m,        TB_FOLDED_LOAD }, | 
|  | 320 | { X86::IMUL16r,     X86::IMUL16m,       TB_FOLDED_LOAD }, | 
|  | 321 | { X86::IMUL32r,     X86::IMUL32m,       TB_FOLDED_LOAD }, | 
|  | 322 | { X86::IMUL64r,     X86::IMUL64m,       TB_FOLDED_LOAD }, | 
|  | 323 | { X86::IMUL8r,      X86::IMUL8m,        TB_FOLDED_LOAD }, | 
|  | 324 | { X86::JMP32r,      X86::JMP32m,        TB_FOLDED_LOAD }, | 
|  | 325 | { X86::JMP64r,      X86::JMP64m,        TB_FOLDED_LOAD }, | 
|  | 326 | { X86::MOV16ri,     X86::MOV16mi,       TB_FOLDED_STORE }, | 
|  | 327 | { X86::MOV16rr,     X86::MOV16mr,       TB_FOLDED_STORE }, | 
|  | 328 | { X86::MOV32ri,     X86::MOV32mi,       TB_FOLDED_STORE }, | 
|  | 329 | { X86::MOV32rr,     X86::MOV32mr,       TB_FOLDED_STORE }, | 
|  | 330 | { X86::MOV64ri32,   X86::MOV64mi32,     TB_FOLDED_STORE }, | 
|  | 331 | { X86::MOV64rr,     X86::MOV64mr,       TB_FOLDED_STORE }, | 
|  | 332 | { X86::MOV8ri,      X86::MOV8mi,        TB_FOLDED_STORE }, | 
|  | 333 | { X86::MOV8rr,      X86::MOV8mr,        TB_FOLDED_STORE }, | 
|  | 334 | { X86::MOV8rr_NOREX, X86::MOV8mr_NOREX, TB_FOLDED_STORE }, | 
|  | 335 | { X86::MOVAPDrr,    X86::MOVAPDmr,      TB_FOLDED_STORE | TB_ALIGN_16 }, | 
|  | 336 | { X86::MOVAPSrr,    X86::MOVAPSmr,      TB_FOLDED_STORE | TB_ALIGN_16 }, | 
|  | 337 | { X86::MOVDQArr,    X86::MOVDQAmr,      TB_FOLDED_STORE | TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 338 | { X86::MOVPDI2DIrr, X86::MOVPDI2DImr,   TB_FOLDED_STORE }, | 
|  | 339 | { X86::MOVPQIto64rr,X86::MOVPQI2QImr,   TB_FOLDED_STORE }, | 
|  | 340 | { X86::MOVSDto64rr, X86::MOVSDto64mr,   TB_FOLDED_STORE }, | 
|  | 341 | { X86::MOVSS2DIrr,  X86::MOVSS2DImr,    TB_FOLDED_STORE }, | 
|  | 342 | { X86::MOVUPDrr,    X86::MOVUPDmr,      TB_FOLDED_STORE }, | 
|  | 343 | { X86::MOVUPSrr,    X86::MOVUPSmr,      TB_FOLDED_STORE }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 344 | { X86::MUL16r,      X86::MUL16m,        TB_FOLDED_LOAD }, | 
|  | 345 | { X86::MUL32r,      X86::MUL32m,        TB_FOLDED_LOAD }, | 
|  | 346 | { X86::MUL64r,      X86::MUL64m,        TB_FOLDED_LOAD }, | 
|  | 347 | { X86::MUL8r,       X86::MUL8m,         TB_FOLDED_LOAD }, | 
| Simon Pilgrim | 5fa0fb2 | 2015-01-21 23:43:30 +0000 | [diff] [blame] | 348 | { X86::PEXTRDrr,    X86::PEXTRDmr,      TB_FOLDED_STORE }, | 
|  | 349 | { X86::PEXTRQrr,    X86::PEXTRQmr,      TB_FOLDED_STORE }, | 
| Michael Kuperstein | 454d145 | 2015-07-23 12:23:45 +0000 | [diff] [blame] | 350 | { X86::PUSH16r,     X86::PUSH16rmm,     TB_FOLDED_LOAD }, | 
|  | 351 | { X86::PUSH32r,     X86::PUSH32rmm,     TB_FOLDED_LOAD }, | 
|  | 352 | { X86::PUSH64r,     X86::PUSH64rmm,     TB_FOLDED_LOAD }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 353 | { X86::SETAEr,      X86::SETAEm,        TB_FOLDED_STORE }, | 
|  | 354 | { X86::SETAr,       X86::SETAm,         TB_FOLDED_STORE }, | 
|  | 355 | { X86::SETBEr,      X86::SETBEm,        TB_FOLDED_STORE }, | 
|  | 356 | { X86::SETBr,       X86::SETBm,         TB_FOLDED_STORE }, | 
|  | 357 | { X86::SETEr,       X86::SETEm,         TB_FOLDED_STORE }, | 
|  | 358 | { X86::SETGEr,      X86::SETGEm,        TB_FOLDED_STORE }, | 
|  | 359 | { X86::SETGr,       X86::SETGm,         TB_FOLDED_STORE }, | 
|  | 360 | { X86::SETLEr,      X86::SETLEm,        TB_FOLDED_STORE }, | 
|  | 361 | { X86::SETLr,       X86::SETLm,         TB_FOLDED_STORE }, | 
|  | 362 | { X86::SETNEr,      X86::SETNEm,        TB_FOLDED_STORE }, | 
|  | 363 | { X86::SETNOr,      X86::SETNOm,        TB_FOLDED_STORE }, | 
|  | 364 | { X86::SETNPr,      X86::SETNPm,        TB_FOLDED_STORE }, | 
|  | 365 | { X86::SETNSr,      X86::SETNSm,        TB_FOLDED_STORE }, | 
|  | 366 | { X86::SETOr,       X86::SETOm,         TB_FOLDED_STORE }, | 
|  | 367 | { X86::SETPr,       X86::SETPm,         TB_FOLDED_STORE }, | 
|  | 368 | { X86::SETSr,       X86::SETSm,         TB_FOLDED_STORE }, | 
|  | 369 | { X86::TAILJMPr,    X86::TAILJMPm,      TB_FOLDED_LOAD }, | 
|  | 370 | { X86::TAILJMPr64,  X86::TAILJMPm64,    TB_FOLDED_LOAD }, | 
| Reid Kleckner | a580b6e | 2015-01-30 21:03:31 +0000 | [diff] [blame] | 371 | { X86::TAILJMPr64_REX, X86::TAILJMPm64_REX, TB_FOLDED_LOAD }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 372 | { X86::TEST16ri,    X86::TEST16mi,      TB_FOLDED_LOAD }, | 
|  | 373 | { X86::TEST32ri,    X86::TEST32mi,      TB_FOLDED_LOAD }, | 
|  | 374 | { X86::TEST64ri32,  X86::TEST64mi32,    TB_FOLDED_LOAD }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 375 | { X86::TEST8ri,     X86::TEST8mi,       TB_FOLDED_LOAD }, | 
| Simon Pilgrim | d142ab7 | 2015-02-10 13:22:57 +0000 | [diff] [blame] | 376 |  | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 377 | // AVX 128-bit versions of foldable instructions | 
| Craig Topper | d09a9af | 2012-12-26 01:47:12 +0000 | [diff] [blame] | 378 | { X86::VEXTRACTPSrr,X86::VEXTRACTPSmr,  TB_FOLDED_STORE  }, | 
| Craig Topper | d78429f | 2012-01-14 18:14:53 +0000 | [diff] [blame] | 379 | { X86::VEXTRACTF128rr, X86::VEXTRACTF128mr, TB_FOLDED_STORE | TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 380 | { X86::VMOVAPDrr,   X86::VMOVAPDmr,     TB_FOLDED_STORE | TB_ALIGN_16 }, | 
|  | 381 | { X86::VMOVAPSrr,   X86::VMOVAPSmr,     TB_FOLDED_STORE | TB_ALIGN_16 }, | 
|  | 382 | { X86::VMOVDQArr,   X86::VMOVDQAmr,     TB_FOLDED_STORE | TB_ALIGN_16 }, | 
|  | 383 | { X86::VMOVPDI2DIrr,X86::VMOVPDI2DImr,  TB_FOLDED_STORE }, | 
|  | 384 | { X86::VMOVPQIto64rr, X86::VMOVPQI2QImr,TB_FOLDED_STORE }, | 
|  | 385 | { X86::VMOVSDto64rr,X86::VMOVSDto64mr,  TB_FOLDED_STORE }, | 
|  | 386 | { X86::VMOVSS2DIrr, X86::VMOVSS2DImr,   TB_FOLDED_STORE }, | 
|  | 387 | { X86::VMOVUPDrr,   X86::VMOVUPDmr,     TB_FOLDED_STORE }, | 
|  | 388 | { X86::VMOVUPSrr,   X86::VMOVUPSmr,     TB_FOLDED_STORE }, | 
| Simon Pilgrim | 5fa0fb2 | 2015-01-21 23:43:30 +0000 | [diff] [blame] | 389 | { X86::VPEXTRDrr,   X86::VPEXTRDmr,     TB_FOLDED_STORE }, | 
|  | 390 | { X86::VPEXTRQrr,   X86::VPEXTRQmr,     TB_FOLDED_STORE }, | 
| Simon Pilgrim | d142ab7 | 2015-02-10 13:22:57 +0000 | [diff] [blame] | 391 |  | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 392 | // AVX 256-bit foldable instructions | 
| Craig Topper | d78429f | 2012-01-14 18:14:53 +0000 | [diff] [blame] | 393 | { X86::VEXTRACTI128rr, X86::VEXTRACTI128mr, TB_FOLDED_STORE | TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 394 | { X86::VMOVAPDYrr,  X86::VMOVAPDYmr,    TB_FOLDED_STORE | TB_ALIGN_32 }, | 
|  | 395 | { X86::VMOVAPSYrr,  X86::VMOVAPSYmr,    TB_FOLDED_STORE | TB_ALIGN_32 }, | 
|  | 396 | { X86::VMOVDQAYrr,  X86::VMOVDQAYmr,    TB_FOLDED_STORE | TB_ALIGN_32 }, | 
|  | 397 | { X86::VMOVUPDYrr,  X86::VMOVUPDYmr,    TB_FOLDED_STORE }, | 
| Elena Demikhovsky | 534015e | 2013-09-02 07:12:29 +0000 | [diff] [blame] | 398 | { X86::VMOVUPSYrr,  X86::VMOVUPSYmr,    TB_FOLDED_STORE }, | 
| Simon Pilgrim | d142ab7 | 2015-02-10 13:22:57 +0000 | [diff] [blame] | 399 |  | 
| Elena Demikhovsky | 534015e | 2013-09-02 07:12:29 +0000 | [diff] [blame] | 400 | // AVX-512 foldable instructions | 
| Robert Khasanov | 3c30c4b | 2014-08-06 15:40:34 +0000 | [diff] [blame] | 401 | { X86::VMOVPDI2DIZrr,   X86::VMOVPDI2DIZmr, TB_FOLDED_STORE }, | 
|  | 402 | { X86::VMOVAPDZrr,      X86::VMOVAPDZmr,    TB_FOLDED_STORE | TB_ALIGN_64 }, | 
|  | 403 | { X86::VMOVAPSZrr,      X86::VMOVAPSZmr,    TB_FOLDED_STORE | TB_ALIGN_64 }, | 
|  | 404 | { X86::VMOVDQA32Zrr,    X86::VMOVDQA32Zmr,  TB_FOLDED_STORE | TB_ALIGN_64 }, | 
|  | 405 | { X86::VMOVDQA64Zrr,    X86::VMOVDQA64Zmr,  TB_FOLDED_STORE | TB_ALIGN_64 }, | 
|  | 406 | { X86::VMOVUPDZrr,      X86::VMOVUPDZmr,    TB_FOLDED_STORE }, | 
|  | 407 | { X86::VMOVUPSZrr,      X86::VMOVUPSZmr,    TB_FOLDED_STORE }, | 
| Robert Khasanov | 6d62c02 | 2014-09-26 09:48:50 +0000 | [diff] [blame] | 408 | { X86::VMOVDQU8Zrr,     X86::VMOVDQU8Zmr,   TB_FOLDED_STORE }, | 
|  | 409 | { X86::VMOVDQU16Zrr,    X86::VMOVDQU16Zmr,  TB_FOLDED_STORE }, | 
| Robert Khasanov | 3c30c4b | 2014-08-06 15:40:34 +0000 | [diff] [blame] | 410 | { X86::VMOVDQU32Zrr,    X86::VMOVDQU32Zmr,  TB_FOLDED_STORE }, | 
| Robert Khasanov | 6d62c02 | 2014-09-26 09:48:50 +0000 | [diff] [blame] | 411 | { X86::VMOVDQU64Zrr,    X86::VMOVDQU64Zmr,  TB_FOLDED_STORE }, | 
| Simon Pilgrim | d142ab7 | 2015-02-10 13:22:57 +0000 | [diff] [blame] | 412 |  | 
| Robert Khasanov | 6d62c02 | 2014-09-26 09:48:50 +0000 | [diff] [blame] | 413 | // AVX-512 foldable instructions (256-bit versions) | 
|  | 414 | { X86::VMOVAPDZ256rr,      X86::VMOVAPDZ256mr,    TB_FOLDED_STORE | TB_ALIGN_32 }, | 
|  | 415 | { X86::VMOVAPSZ256rr,      X86::VMOVAPSZ256mr,    TB_FOLDED_STORE | TB_ALIGN_32 }, | 
|  | 416 | { X86::VMOVDQA32Z256rr,    X86::VMOVDQA32Z256mr,  TB_FOLDED_STORE | TB_ALIGN_32 }, | 
|  | 417 | { X86::VMOVDQA64Z256rr,    X86::VMOVDQA64Z256mr,  TB_FOLDED_STORE | TB_ALIGN_32 }, | 
|  | 418 | { X86::VMOVUPDZ256rr,      X86::VMOVUPDZ256mr,    TB_FOLDED_STORE }, | 
|  | 419 | { X86::VMOVUPSZ256rr,      X86::VMOVUPSZ256mr,    TB_FOLDED_STORE }, | 
|  | 420 | { X86::VMOVDQU8Z256rr,     X86::VMOVDQU8Z256mr,   TB_FOLDED_STORE }, | 
|  | 421 | { X86::VMOVDQU16Z256rr,    X86::VMOVDQU16Z256mr,  TB_FOLDED_STORE }, | 
|  | 422 | { X86::VMOVDQU32Z256rr,    X86::VMOVDQU32Z256mr,  TB_FOLDED_STORE }, | 
|  | 423 | { X86::VMOVDQU64Z256rr,    X86::VMOVDQU64Z256mr,  TB_FOLDED_STORE }, | 
| Simon Pilgrim | d142ab7 | 2015-02-10 13:22:57 +0000 | [diff] [blame] | 424 |  | 
| Robert Khasanov | 6d62c02 | 2014-09-26 09:48:50 +0000 | [diff] [blame] | 425 | // AVX-512 foldable instructions (128-bit versions) | 
|  | 426 | { X86::VMOVAPDZ128rr,      X86::VMOVAPDZ128mr,    TB_FOLDED_STORE | TB_ALIGN_16 }, | 
|  | 427 | { X86::VMOVAPSZ128rr,      X86::VMOVAPSZ128mr,    TB_FOLDED_STORE | TB_ALIGN_16 }, | 
|  | 428 | { X86::VMOVDQA32Z128rr,    X86::VMOVDQA32Z128mr,  TB_FOLDED_STORE | TB_ALIGN_16 }, | 
|  | 429 | { X86::VMOVDQA64Z128rr,    X86::VMOVDQA64Z128mr,  TB_FOLDED_STORE | TB_ALIGN_16 }, | 
|  | 430 | { X86::VMOVUPDZ128rr,      X86::VMOVUPDZ128mr,    TB_FOLDED_STORE }, | 
|  | 431 | { X86::VMOVUPSZ128rr,      X86::VMOVUPSZ128mr,    TB_FOLDED_STORE }, | 
|  | 432 | { X86::VMOVDQU8Z128rr,     X86::VMOVDQU8Z128mr,   TB_FOLDED_STORE }, | 
|  | 433 | { X86::VMOVDQU16Z128rr,    X86::VMOVDQU16Z128mr,  TB_FOLDED_STORE }, | 
|  | 434 | { X86::VMOVDQU32Z128rr,    X86::VMOVDQU32Z128mr,  TB_FOLDED_STORE }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 435 | { X86::VMOVDQU64Z128rr,    X86::VMOVDQU64Z128mr,  TB_FOLDED_STORE }, | 
| Simon Pilgrim | d142ab7 | 2015-02-10 13:22:57 +0000 | [diff] [blame] | 436 |  | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 437 | // F16C foldable instructions | 
|  | 438 | { X86::VCVTPS2PHrr,        X86::VCVTPS2PHmr,      TB_FOLDED_STORE }, | 
|  | 439 | { X86::VCVTPS2PHYrr,       X86::VCVTPS2PHYmr,     TB_FOLDED_STORE } | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 440 | }; | 
|  | 441 |  | 
| Sanjay Patel | cf0a807 | 2015-07-07 15:03:53 +0000 | [diff] [blame] | 442 | for (X86MemoryFoldTableEntry Entry : MemoryFoldTable0) { | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 443 | AddTableEntry(RegOp2MemOpTable0, MemOp2RegOpTable, | 
| Sanjay Patel | cf0a807 | 2015-07-07 15:03:53 +0000 | [diff] [blame] | 444 | Entry.RegOp, Entry.MemOp, TB_INDEX_0 | Entry.Flags); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 445 | } | 
|  | 446 |  | 
| Sanjay Patel | e951a38 | 2015-02-17 22:38:06 +0000 | [diff] [blame] | 447 | static const X86MemoryFoldTableEntry MemoryFoldTable1[] = { | 
| Simon Pilgrim | 3a77180 | 2015-06-07 18:34:25 +0000 | [diff] [blame] | 448 | { X86::BSF16rr,         X86::BSF16rm,             0 }, | 
|  | 449 | { X86::BSF32rr,         X86::BSF32rm,             0 }, | 
|  | 450 | { X86::BSF64rr,         X86::BSF64rm,             0 }, | 
|  | 451 | { X86::BSR16rr,         X86::BSR16rm,             0 }, | 
|  | 452 | { X86::BSR32rr,         X86::BSR32rm,             0 }, | 
|  | 453 | { X86::BSR64rr,         X86::BSR64rm,             0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 454 | { X86::CMP16rr,         X86::CMP16rm,             0 }, | 
|  | 455 | { X86::CMP32rr,         X86::CMP32rm,             0 }, | 
|  | 456 | { X86::CMP64rr,         X86::CMP64rm,             0 }, | 
|  | 457 | { X86::CMP8rr,          X86::CMP8rm,              0 }, | 
|  | 458 | { X86::CVTSD2SSrr,      X86::CVTSD2SSrm,          0 }, | 
|  | 459 | { X86::CVTSI2SD64rr,    X86::CVTSI2SD64rm,        0 }, | 
|  | 460 | { X86::CVTSI2SDrr,      X86::CVTSI2SDrm,          0 }, | 
|  | 461 | { X86::CVTSI2SS64rr,    X86::CVTSI2SS64rm,        0 }, | 
|  | 462 | { X86::CVTSI2SSrr,      X86::CVTSI2SSrm,          0 }, | 
|  | 463 | { X86::CVTSS2SDrr,      X86::CVTSS2SDrm,          0 }, | 
|  | 464 | { X86::CVTTSD2SI64rr,   X86::CVTTSD2SI64rm,       0 }, | 
|  | 465 | { X86::CVTTSD2SIrr,     X86::CVTTSD2SIrm,         0 }, | 
|  | 466 | { X86::CVTTSS2SI64rr,   X86::CVTTSS2SI64rm,       0 }, | 
|  | 467 | { X86::CVTTSS2SIrr,     X86::CVTTSS2SIrm,         0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 468 | { X86::IMUL16rri,       X86::IMUL16rmi,           0 }, | 
|  | 469 | { X86::IMUL16rri8,      X86::IMUL16rmi8,          0 }, | 
|  | 470 | { X86::IMUL32rri,       X86::IMUL32rmi,           0 }, | 
|  | 471 | { X86::IMUL32rri8,      X86::IMUL32rmi8,          0 }, | 
|  | 472 | { X86::IMUL64rri32,     X86::IMUL64rmi32,         0 }, | 
|  | 473 | { X86::IMUL64rri8,      X86::IMUL64rmi8,          0 }, | 
|  | 474 | { X86::Int_COMISDrr,    X86::Int_COMISDrm,        0 }, | 
|  | 475 | { X86::Int_COMISSrr,    X86::Int_COMISSrm,        0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 476 | { X86::CVTSD2SI64rr,    X86::CVTSD2SI64rm,        0 }, | 
|  | 477 | { X86::CVTSD2SIrr,      X86::CVTSD2SIrm,          0 }, | 
| Craig Topper | 1191305 | 2012-06-15 07:02:58 +0000 | [diff] [blame] | 478 | { X86::CVTSS2SI64rr,    X86::CVTSS2SI64rm,        0 }, | 
|  | 479 | { X86::CVTSS2SIrr,      X86::CVTSS2SIrm,          0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 480 | { X86::CVTDQ2PDrr,      X86::CVTDQ2PDrm,          TB_ALIGN_16 }, | 
| Simon Pilgrim | 1fc483d | 2014-11-05 22:28:25 +0000 | [diff] [blame] | 481 | { X86::CVTDQ2PSrr,      X86::CVTDQ2PSrm,          TB_ALIGN_16 }, | 
| Simon Pilgrim | 615ab8e | 2014-11-06 22:15:41 +0000 | [diff] [blame] | 482 | { X86::CVTPD2DQrr,      X86::CVTPD2DQrm,          TB_ALIGN_16 }, | 
| Simon Pilgrim | bf1e079 | 2014-12-16 22:30:10 +0000 | [diff] [blame] | 483 | { X86::CVTPD2PSrr,      X86::CVTPD2PSrm,          TB_ALIGN_16 }, | 
| Simon Pilgrim | 615ab8e | 2014-11-06 22:15:41 +0000 | [diff] [blame] | 484 | { X86::CVTPS2DQrr,      X86::CVTPS2DQrm,          TB_ALIGN_16 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 485 | { X86::CVTPS2PDrr,      X86::CVTPS2PDrm,          TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 486 | { X86::CVTTPD2DQrr,     X86::CVTTPD2DQrm,         TB_ALIGN_16 }, | 
|  | 487 | { X86::CVTTPS2DQrr,     X86::CVTTPS2DQrm,         TB_ALIGN_16 }, | 
|  | 488 | { X86::Int_CVTTSD2SI64rr,X86::Int_CVTTSD2SI64rm,  0 }, | 
|  | 489 | { X86::Int_CVTTSD2SIrr, X86::Int_CVTTSD2SIrm,     0 }, | 
|  | 490 | { X86::Int_CVTTSS2SI64rr,X86::Int_CVTTSS2SI64rm,  0 }, | 
|  | 491 | { X86::Int_CVTTSS2SIrr, X86::Int_CVTTSS2SIrm,     0 }, | 
|  | 492 | { X86::Int_UCOMISDrr,   X86::Int_UCOMISDrm,       0 }, | 
|  | 493 | { X86::Int_UCOMISSrr,   X86::Int_UCOMISSrm,       0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 494 | { X86::MOV16rr,         X86::MOV16rm,             0 }, | 
|  | 495 | { X86::MOV32rr,         X86::MOV32rm,             0 }, | 
|  | 496 | { X86::MOV64rr,         X86::MOV64rm,             0 }, | 
|  | 497 | { X86::MOV64toPQIrr,    X86::MOVQI2PQIrm,         0 }, | 
|  | 498 | { X86::MOV64toSDrr,     X86::MOV64toSDrm,         0 }, | 
|  | 499 | { X86::MOV8rr,          X86::MOV8rm,              0 }, | 
|  | 500 | { X86::MOVAPDrr,        X86::MOVAPDrm,            TB_ALIGN_16 }, | 
|  | 501 | { X86::MOVAPSrr,        X86::MOVAPSrm,            TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 502 | { X86::MOVDDUPrr,       X86::MOVDDUPrm,           0 }, | 
|  | 503 | { X86::MOVDI2PDIrr,     X86::MOVDI2PDIrm,         0 }, | 
|  | 504 | { X86::MOVDI2SSrr,      X86::MOVDI2SSrm,          0 }, | 
|  | 505 | { X86::MOVDQArr,        X86::MOVDQArm,            TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 506 | { X86::MOVSHDUPrr,      X86::MOVSHDUPrm,          TB_ALIGN_16 }, | 
|  | 507 | { X86::MOVSLDUPrr,      X86::MOVSLDUPrm,          TB_ALIGN_16 }, | 
|  | 508 | { X86::MOVSX16rr8,      X86::MOVSX16rm8,          0 }, | 
|  | 509 | { X86::MOVSX32rr16,     X86::MOVSX32rm16,         0 }, | 
|  | 510 | { X86::MOVSX32rr8,      X86::MOVSX32rm8,          0 }, | 
|  | 511 | { X86::MOVSX64rr16,     X86::MOVSX64rm16,         0 }, | 
|  | 512 | { X86::MOVSX64rr32,     X86::MOVSX64rm32,         0 }, | 
|  | 513 | { X86::MOVSX64rr8,      X86::MOVSX64rm8,          0 }, | 
|  | 514 | { X86::MOVUPDrr,        X86::MOVUPDrm,            TB_ALIGN_16 }, | 
|  | 515 | { X86::MOVUPSrr,        X86::MOVUPSrm,            0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 516 | { X86::MOVZPQILo2PQIrr, X86::MOVZPQILo2PQIrm,     TB_ALIGN_16 }, | 
|  | 517 | { X86::MOVZX16rr8,      X86::MOVZX16rm8,          0 }, | 
|  | 518 | { X86::MOVZX32rr16,     X86::MOVZX32rm16,         0 }, | 
|  | 519 | { X86::MOVZX32_NOREXrr8, X86::MOVZX32_NOREXrm8,   0 }, | 
|  | 520 | { X86::MOVZX32rr8,      X86::MOVZX32rm8,          0 }, | 
| Craig Topper | 182b00a | 2011-11-14 08:07:55 +0000 | [diff] [blame] | 521 | { X86::PABSBrr128,      X86::PABSBrm128,          TB_ALIGN_16 }, | 
|  | 522 | { X86::PABSDrr128,      X86::PABSDrm128,          TB_ALIGN_16 }, | 
|  | 523 | { X86::PABSWrr128,      X86::PABSWrm128,          TB_ALIGN_16 }, | 
| Simon Pilgrim | 5fa0fb2 | 2015-01-21 23:43:30 +0000 | [diff] [blame] | 524 | { X86::PCMPESTRIrr,     X86::PCMPESTRIrm,         TB_ALIGN_16 }, | 
|  | 525 | { X86::PCMPESTRM128rr,  X86::PCMPESTRM128rm,      TB_ALIGN_16 }, | 
|  | 526 | { X86::PCMPISTRIrr,     X86::PCMPISTRIrm,         TB_ALIGN_16 }, | 
|  | 527 | { X86::PCMPISTRM128rr,  X86::PCMPISTRM128rm,      TB_ALIGN_16 }, | 
|  | 528 | { X86::PHMINPOSUWrr128, X86::PHMINPOSUWrm128,     TB_ALIGN_16 }, | 
|  | 529 | { X86::PMOVSXBDrr,      X86::PMOVSXBDrm,          TB_ALIGN_16 }, | 
|  | 530 | { X86::PMOVSXBQrr,      X86::PMOVSXBQrm,          TB_ALIGN_16 }, | 
|  | 531 | { X86::PMOVSXBWrr,      X86::PMOVSXBWrm,          TB_ALIGN_16 }, | 
|  | 532 | { X86::PMOVSXDQrr,      X86::PMOVSXDQrm,          TB_ALIGN_16 }, | 
|  | 533 | { X86::PMOVSXWDrr,      X86::PMOVSXWDrm,          TB_ALIGN_16 }, | 
|  | 534 | { X86::PMOVSXWQrr,      X86::PMOVSXWQrm,          TB_ALIGN_16 }, | 
|  | 535 | { X86::PMOVZXBDrr,      X86::PMOVZXBDrm,          TB_ALIGN_16 }, | 
|  | 536 | { X86::PMOVZXBQrr,      X86::PMOVZXBQrm,          TB_ALIGN_16 }, | 
|  | 537 | { X86::PMOVZXBWrr,      X86::PMOVZXBWrm,          TB_ALIGN_16 }, | 
|  | 538 | { X86::PMOVZXDQrr,      X86::PMOVZXDQrm,          TB_ALIGN_16 }, | 
|  | 539 | { X86::PMOVZXWDrr,      X86::PMOVZXWDrm,          TB_ALIGN_16 }, | 
|  | 540 | { X86::PMOVZXWQrr,      X86::PMOVZXWQrm,          TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 541 | { X86::PSHUFDri,        X86::PSHUFDmi,            TB_ALIGN_16 }, | 
|  | 542 | { X86::PSHUFHWri,       X86::PSHUFHWmi,           TB_ALIGN_16 }, | 
|  | 543 | { X86::PSHUFLWri,       X86::PSHUFLWmi,           TB_ALIGN_16 }, | 
| Simon Pilgrim | 5fa0fb2 | 2015-01-21 23:43:30 +0000 | [diff] [blame] | 544 | { X86::PTESTrr,         X86::PTESTrm,             TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 545 | { X86::RCPPSr,          X86::RCPPSm,              TB_ALIGN_16 }, | 
| Sanjay Patel | a9f6d35 | 2015-05-07 15:48:53 +0000 | [diff] [blame] | 546 | { X86::RCPSSr,          X86::RCPSSm,              0 }, | 
|  | 547 | { X86::RCPSSr_Int,      X86::RCPSSm_Int,          0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 548 | { X86::ROUNDPDr,        X86::ROUNDPDm,            TB_ALIGN_16 }, | 
|  | 549 | { X86::ROUNDPSr,        X86::ROUNDPSm,            TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 550 | { X86::RSQRTPSr,        X86::RSQRTPSm,            TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 551 | { X86::RSQRTSSr,        X86::RSQRTSSm,            0 }, | 
|  | 552 | { X86::RSQRTSSr_Int,    X86::RSQRTSSm_Int,        0 }, | 
|  | 553 | { X86::SQRTPDr,         X86::SQRTPDm,             TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 554 | { X86::SQRTPSr,         X86::SQRTPSm,             TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 555 | { X86::SQRTSDr,         X86::SQRTSDm,             0 }, | 
|  | 556 | { X86::SQRTSDr_Int,     X86::SQRTSDm_Int,         0 }, | 
|  | 557 | { X86::SQRTSSr,         X86::SQRTSSm,             0 }, | 
|  | 558 | { X86::SQRTSSr_Int,     X86::SQRTSSm_Int,         0 }, | 
|  | 559 | { X86::TEST16rr,        X86::TEST16rm,            0 }, | 
|  | 560 | { X86::TEST32rr,        X86::TEST32rm,            0 }, | 
|  | 561 | { X86::TEST64rr,        X86::TEST64rm,            0 }, | 
|  | 562 | { X86::TEST8rr,         X86::TEST8rm,             0 }, | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 563 | // FIXME: TEST*rr EAX,EAX ---> CMP [mem], 0 | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 564 | { X86::UCOMISDrr,       X86::UCOMISDrm,           0 }, | 
|  | 565 | { X86::UCOMISSrr,       X86::UCOMISSrm,           0 }, | 
| Simon Pilgrim | d142ab7 | 2015-02-10 13:22:57 +0000 | [diff] [blame] | 566 |  | 
| Bruno Cardoso Lopes | ab7afa9 | 2015-02-25 15:14:02 +0000 | [diff] [blame] | 567 | // MMX version of foldable instructions | 
|  | 568 | { X86::MMX_CVTPD2PIirr,   X86::MMX_CVTPD2PIirm,   0 }, | 
|  | 569 | { X86::MMX_CVTPI2PDirr,   X86::MMX_CVTPI2PDirm,   0 }, | 
|  | 570 | { X86::MMX_CVTPS2PIirr,   X86::MMX_CVTPS2PIirm,   0 }, | 
|  | 571 | { X86::MMX_CVTTPD2PIirr,  X86::MMX_CVTTPD2PIirm,  0 }, | 
|  | 572 | { X86::MMX_CVTTPS2PIirr,  X86::MMX_CVTTPS2PIirm,  0 }, | 
|  | 573 | { X86::MMX_MOVD64to64rr,  X86::MMX_MOVQ64rm,      0 }, | 
|  | 574 | { X86::MMX_PABSBrr64,     X86::MMX_PABSBrm64,     0 }, | 
|  | 575 | { X86::MMX_PABSDrr64,     X86::MMX_PABSDrm64,     0 }, | 
|  | 576 | { X86::MMX_PABSWrr64,     X86::MMX_PABSWrm64,     0 }, | 
|  | 577 | { X86::MMX_PSHUFWri,      X86::MMX_PSHUFWmi,      0 }, | 
|  | 578 |  | 
| Simon Pilgrim | 8dba5da | 2015-04-03 11:50:30 +0000 | [diff] [blame] | 579 | // 3DNow! version of foldable instructions | 
|  | 580 | { X86::PF2IDrr,         X86::PF2IDrm,             0 }, | 
|  | 581 | { X86::PF2IWrr,         X86::PF2IWrm,             0 }, | 
|  | 582 | { X86::PFRCPrr,         X86::PFRCPrm,             0 }, | 
|  | 583 | { X86::PFRSQRTrr,       X86::PFRSQRTrm,           0 }, | 
|  | 584 | { X86::PI2FDrr,         X86::PI2FDrm,             0 }, | 
|  | 585 | { X86::PI2FWrr,         X86::PI2FWrm,             0 }, | 
|  | 586 | { X86::PSWAPDrr,        X86::PSWAPDrm,            0 }, | 
|  | 587 |  | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 588 | // AVX 128-bit versions of foldable instructions | 
|  | 589 | { X86::Int_VCOMISDrr,   X86::Int_VCOMISDrm,       0 }, | 
|  | 590 | { X86::Int_VCOMISSrr,   X86::Int_VCOMISSrm,       0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 591 | { X86::Int_VUCOMISDrr,  X86::Int_VUCOMISDrm,      0 }, | 
|  | 592 | { X86::Int_VUCOMISSrr,  X86::Int_VUCOMISSrm,      0 }, | 
| Craig Topper | 1191305 | 2012-06-15 07:02:58 +0000 | [diff] [blame] | 593 | { X86::VCVTTSD2SI64rr,  X86::VCVTTSD2SI64rm,      0 }, | 
|  | 594 | { X86::Int_VCVTTSD2SI64rr,X86::Int_VCVTTSD2SI64rm,0 }, | 
| Pete Cooper | 8bbce76 | 2012-06-14 22:12:58 +0000 | [diff] [blame] | 595 | { X86::VCVTTSD2SIrr,    X86::VCVTTSD2SIrm,        0 }, | 
| Craig Topper | 1191305 | 2012-06-15 07:02:58 +0000 | [diff] [blame] | 596 | { X86::Int_VCVTTSD2SIrr,X86::Int_VCVTTSD2SIrm,    0 }, | 
|  | 597 | { X86::VCVTTSS2SI64rr,  X86::VCVTTSS2SI64rm,      0 }, | 
|  | 598 | { X86::Int_VCVTTSS2SI64rr,X86::Int_VCVTTSS2SI64rm,0 }, | 
|  | 599 | { X86::VCVTTSS2SIrr,    X86::VCVTTSS2SIrm,        0 }, | 
|  | 600 | { X86::Int_VCVTTSS2SIrr,X86::Int_VCVTTSS2SIrm,    0 }, | 
|  | 601 | { X86::VCVTSD2SI64rr,   X86::VCVTSD2SI64rm,       0 }, | 
|  | 602 | { X86::VCVTSD2SIrr,     X86::VCVTSD2SIrm,         0 }, | 
|  | 603 | { X86::VCVTSS2SI64rr,   X86::VCVTSS2SI64rm,       0 }, | 
|  | 604 | { X86::VCVTSS2SIrr,     X86::VCVTSS2SIrm,         0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 605 | { X86::VCVTDQ2PDrr,     X86::VCVTDQ2PDrm,         0 }, | 
| Simon Pilgrim | 1fc483d | 2014-11-05 22:28:25 +0000 | [diff] [blame] | 606 | { X86::VCVTDQ2PSrr,     X86::VCVTDQ2PSrm,         0 }, | 
| Simon Pilgrim | 615ab8e | 2014-11-06 22:15:41 +0000 | [diff] [blame] | 607 | { X86::VCVTPD2DQrr,     X86::VCVTPD2DQXrm,        0 }, | 
| Simon Pilgrim | bf1e079 | 2014-12-16 22:30:10 +0000 | [diff] [blame] | 608 | { X86::VCVTPD2PSrr,     X86::VCVTPD2PSXrm,        0 }, | 
| Simon Pilgrim | 615ab8e | 2014-11-06 22:15:41 +0000 | [diff] [blame] | 609 | { X86::VCVTPS2DQrr,     X86::VCVTPS2DQrm,         0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 610 | { X86::VCVTPS2PDrr,     X86::VCVTPS2PDrm,         0 }, | 
| Simon Pilgrim | 615ab8e | 2014-11-06 22:15:41 +0000 | [diff] [blame] | 611 | { X86::VCVTTPD2DQrr,    X86::VCVTTPD2DQXrm,       0 }, | 
|  | 612 | { X86::VCVTTPS2DQrr,    X86::VCVTTPS2DQrm,        0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 613 | { X86::VMOV64toPQIrr,   X86::VMOVQI2PQIrm,        0 }, | 
|  | 614 | { X86::VMOV64toSDrr,    X86::VMOV64toSDrm,        0 }, | 
|  | 615 | { X86::VMOVAPDrr,       X86::VMOVAPDrm,           TB_ALIGN_16 }, | 
|  | 616 | { X86::VMOVAPSrr,       X86::VMOVAPSrm,           TB_ALIGN_16 }, | 
|  | 617 | { X86::VMOVDDUPrr,      X86::VMOVDDUPrm,          0 }, | 
|  | 618 | { X86::VMOVDI2PDIrr,    X86::VMOVDI2PDIrm,        0 }, | 
|  | 619 | { X86::VMOVDI2SSrr,     X86::VMOVDI2SSrm,         0 }, | 
|  | 620 | { X86::VMOVDQArr,       X86::VMOVDQArm,           TB_ALIGN_16 }, | 
| Simon Pilgrim | 7e6d573 | 2015-01-22 22:39:59 +0000 | [diff] [blame] | 621 | { X86::VMOVSLDUPrr,     X86::VMOVSLDUPrm,         0 }, | 
|  | 622 | { X86::VMOVSHDUPrr,     X86::VMOVSHDUPrm,         0 }, | 
| Craig Topper | b292216 | 2012-12-26 02:14:19 +0000 | [diff] [blame] | 623 | { X86::VMOVUPDrr,       X86::VMOVUPDrm,           0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 624 | { X86::VMOVUPSrr,       X86::VMOVUPSrm,           0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 625 | { X86::VMOVZPQILo2PQIrr,X86::VMOVZPQILo2PQIrm,    TB_ALIGN_16 }, | 
| Craig Topper | 81d1e59 | 2012-12-26 02:44:47 +0000 | [diff] [blame] | 626 | { X86::VPABSBrr128,     X86::VPABSBrm128,         0 }, | 
|  | 627 | { X86::VPABSDrr128,     X86::VPABSDrm128,         0 }, | 
|  | 628 | { X86::VPABSWrr128,     X86::VPABSWrm128,         0 }, | 
| Simon Pilgrim | 5fa0fb2 | 2015-01-21 23:43:30 +0000 | [diff] [blame] | 629 | { X86::VPCMPESTRIrr,    X86::VPCMPESTRIrm,        0 }, | 
|  | 630 | { X86::VPCMPESTRM128rr, X86::VPCMPESTRM128rm,     0 }, | 
|  | 631 | { X86::VPCMPISTRIrr,    X86::VPCMPISTRIrm,        0 }, | 
|  | 632 | { X86::VPCMPISTRM128rr, X86::VPCMPISTRM128rm,     0 }, | 
|  | 633 | { X86::VPHMINPOSUWrr128, X86::VPHMINPOSUWrm128,   0 }, | 
| Craig Topper | 81d1e59 | 2012-12-26 02:44:47 +0000 | [diff] [blame] | 634 | { X86::VPERMILPDri,     X86::VPERMILPDmi,         0 }, | 
|  | 635 | { X86::VPERMILPSri,     X86::VPERMILPSmi,         0 }, | 
| Simon Pilgrim | 5fa0fb2 | 2015-01-21 23:43:30 +0000 | [diff] [blame] | 636 | { X86::VPMOVSXBDrr,     X86::VPMOVSXBDrm,         0 }, | 
|  | 637 | { X86::VPMOVSXBQrr,     X86::VPMOVSXBQrm,         0 }, | 
|  | 638 | { X86::VPMOVSXBWrr,     X86::VPMOVSXBWrm,         0 }, | 
|  | 639 | { X86::VPMOVSXDQrr,     X86::VPMOVSXDQrm,         0 }, | 
|  | 640 | { X86::VPMOVSXWDrr,     X86::VPMOVSXWDrm,         0 }, | 
|  | 641 | { X86::VPMOVSXWQrr,     X86::VPMOVSXWQrm,         0 }, | 
|  | 642 | { X86::VPMOVZXBDrr,     X86::VPMOVZXBDrm,         0 }, | 
|  | 643 | { X86::VPMOVZXBQrr,     X86::VPMOVZXBQrm,         0 }, | 
|  | 644 | { X86::VPMOVZXBWrr,     X86::VPMOVZXBWrm,         0 }, | 
|  | 645 | { X86::VPMOVZXDQrr,     X86::VPMOVZXDQrm,         0 }, | 
|  | 646 | { X86::VPMOVZXWDrr,     X86::VPMOVZXWDrm,         0 }, | 
|  | 647 | { X86::VPMOVZXWQrr,     X86::VPMOVZXWQrm,         0 }, | 
| Craig Topper | 81d1e59 | 2012-12-26 02:44:47 +0000 | [diff] [blame] | 648 | { X86::VPSHUFDri,       X86::VPSHUFDmi,           0 }, | 
|  | 649 | { X86::VPSHUFHWri,      X86::VPSHUFHWmi,          0 }, | 
|  | 650 | { X86::VPSHUFLWri,      X86::VPSHUFLWmi,          0 }, | 
| Simon Pilgrim | 5fa0fb2 | 2015-01-21 23:43:30 +0000 | [diff] [blame] | 651 | { X86::VPTESTrr,        X86::VPTESTrm,            0 }, | 
| Craig Topper | 81d1e59 | 2012-12-26 02:44:47 +0000 | [diff] [blame] | 652 | { X86::VRCPPSr,         X86::VRCPPSm,             0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 653 | { X86::VROUNDPDr,       X86::VROUNDPDm,           0 }, | 
|  | 654 | { X86::VROUNDPSr,       X86::VROUNDPSm,           0 }, | 
| Craig Topper | 81d1e59 | 2012-12-26 02:44:47 +0000 | [diff] [blame] | 655 | { X86::VRSQRTPSr,       X86::VRSQRTPSm,           0 }, | 
| Craig Topper | 81d1e59 | 2012-12-26 02:44:47 +0000 | [diff] [blame] | 656 | { X86::VSQRTPDr,        X86::VSQRTPDm,            0 }, | 
| Craig Topper | 81d1e59 | 2012-12-26 02:44:47 +0000 | [diff] [blame] | 657 | { X86::VSQRTPSr,        X86::VSQRTPSm,            0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 658 | { X86::VTESTPDrr,       X86::VTESTPDrm,           0 }, | 
|  | 659 | { X86::VTESTPSrr,       X86::VTESTPSrm,           0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 660 | { X86::VUCOMISDrr,      X86::VUCOMISDrm,          0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 661 | { X86::VUCOMISSrr,      X86::VUCOMISSrm,          0 }, | 
| Nadav Rotem | ee3552f | 2012-07-15 12:26:30 +0000 | [diff] [blame] | 662 |  | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 663 | // AVX 256-bit foldable instructions | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 664 | { X86::VCVTDQ2PDYrr,    X86::VCVTDQ2PDYrm,        0 }, | 
| Simon Pilgrim | 1fc483d | 2014-11-05 22:28:25 +0000 | [diff] [blame] | 665 | { X86::VCVTDQ2PSYrr,    X86::VCVTDQ2PSYrm,        0 }, | 
| Simon Pilgrim | 615ab8e | 2014-11-06 22:15:41 +0000 | [diff] [blame] | 666 | { X86::VCVTPD2DQYrr,    X86::VCVTPD2DQYrm,        0 }, | 
| Simon Pilgrim | bf1e079 | 2014-12-16 22:30:10 +0000 | [diff] [blame] | 667 | { X86::VCVTPD2PSYrr,    X86::VCVTPD2PSYrm,        0 }, | 
| Simon Pilgrim | 615ab8e | 2014-11-06 22:15:41 +0000 | [diff] [blame] | 668 | { X86::VCVTPS2DQYrr,    X86::VCVTPS2DQYrm,        0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 669 | { X86::VCVTPS2PDYrr,    X86::VCVTPS2PDYrm,        0 }, | 
| Simon Pilgrim | 615ab8e | 2014-11-06 22:15:41 +0000 | [diff] [blame] | 670 | { X86::VCVTTPD2DQYrr,   X86::VCVTTPD2DQYrm,       0 }, | 
|  | 671 | { X86::VCVTTPS2DQYrr,   X86::VCVTTPS2DQYrm,       0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 672 | { X86::VMOVAPDYrr,      X86::VMOVAPDYrm,          TB_ALIGN_32 }, | 
|  | 673 | { X86::VMOVAPSYrr,      X86::VMOVAPSYrm,          TB_ALIGN_32 }, | 
| Simon Pilgrim | 7e6d573 | 2015-01-22 22:39:59 +0000 | [diff] [blame] | 674 | { X86::VMOVDDUPYrr,     X86::VMOVDDUPYrm,         0 }, | 
| Craig Topper | a875b7c | 2012-01-19 08:50:38 +0000 | [diff] [blame] | 675 | { X86::VMOVDQAYrr,      X86::VMOVDQAYrm,          TB_ALIGN_32 }, | 
| Simon Pilgrim | 7e6d573 | 2015-01-22 22:39:59 +0000 | [diff] [blame] | 676 | { X86::VMOVSLDUPYrr,    X86::VMOVSLDUPYrm,        0 }, | 
|  | 677 | { X86::VMOVSHDUPYrr,    X86::VMOVSHDUPYrm,        0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 678 | { X86::VMOVUPDYrr,      X86::VMOVUPDYrm,          0 }, | 
| Craig Topper | 182b00a | 2011-11-14 08:07:55 +0000 | [diff] [blame] | 679 | { X86::VMOVUPSYrr,      X86::VMOVUPSYrm,          0 }, | 
| Craig Topper | 81d1e59 | 2012-12-26 02:44:47 +0000 | [diff] [blame] | 680 | { X86::VPERMILPDYri,    X86::VPERMILPDYmi,        0 }, | 
|  | 681 | { X86::VPERMILPSYri,    X86::VPERMILPSYmi,        0 }, | 
| Simon Pilgrim | a261867 | 2015-02-07 21:44:06 +0000 | [diff] [blame] | 682 | { X86::VPTESTYrr,       X86::VPTESTYrm,           0 }, | 
| Simon Pilgrim | a636726 | 2014-10-25 08:11:20 +0000 | [diff] [blame] | 683 | { X86::VRCPPSYr,        X86::VRCPPSYm,            0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 684 | { X86::VROUNDYPDr,      X86::VROUNDYPDm,          0 }, | 
|  | 685 | { X86::VROUNDYPSr,      X86::VROUNDYPSm,          0 }, | 
| Simon Pilgrim | a636726 | 2014-10-25 08:11:20 +0000 | [diff] [blame] | 686 | { X86::VRSQRTPSYr,      X86::VRSQRTPSYm,          0 }, | 
|  | 687 | { X86::VSQRTPDYr,       X86::VSQRTPDYm,           0 }, | 
|  | 688 | { X86::VSQRTPSYr,       X86::VSQRTPSYm,           0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 689 | { X86::VTESTPDYrr,      X86::VTESTPDYrm,          0 }, | 
|  | 690 | { X86::VTESTPSYrr,      X86::VTESTPSYrm,          0 }, | 
| Nadav Rotem | ee3552f | 2012-07-15 12:26:30 +0000 | [diff] [blame] | 691 |  | 
| Craig Topper | 182b00a | 2011-11-14 08:07:55 +0000 | [diff] [blame] | 692 | // AVX2 foldable instructions | 
| Sanjay Patel | 1a20fdf | 2015-02-17 22:09:54 +0000 | [diff] [blame] | 693 |  | 
|  | 694 | // VBROADCASTS{SD}rr register instructions were an AVX2 addition while the | 
|  | 695 | // VBROADCASTS{SD}rm memory instructions were available from AVX1. | 
|  | 696 | // TB_NO_REVERSE prevents unfolding from introducing an illegal instruction | 
|  | 697 | // on AVX1 targets. The VPBROADCAST instructions are all AVX2 instructions | 
|  | 698 | // so they don't need an equivalent limitation. | 
| Simon Pilgrim | d11b013 | 2015-02-08 17:13:54 +0000 | [diff] [blame] | 699 | { X86::VBROADCASTSSrr,  X86::VBROADCASTSSrm,      TB_NO_REVERSE }, | 
|  | 700 | { X86::VBROADCASTSSYrr, X86::VBROADCASTSSYrm,     TB_NO_REVERSE }, | 
|  | 701 | { X86::VBROADCASTSDYrr, X86::VBROADCASTSDYrm,     TB_NO_REVERSE }, | 
| Craig Topper | 81d1e59 | 2012-12-26 02:44:47 +0000 | [diff] [blame] | 702 | { X86::VPABSBrr256,     X86::VPABSBrm256,         0 }, | 
|  | 703 | { X86::VPABSDrr256,     X86::VPABSDrm256,         0 }, | 
|  | 704 | { X86::VPABSWrr256,     X86::VPABSWrm256,         0 }, | 
| Simon Pilgrim | d142ab7 | 2015-02-10 13:22:57 +0000 | [diff] [blame] | 705 | { X86::VPBROADCASTBrr,  X86::VPBROADCASTBrm,      0 }, | 
|  | 706 | { X86::VPBROADCASTBYrr, X86::VPBROADCASTBYrm,     0 }, | 
|  | 707 | { X86::VPBROADCASTDrr,  X86::VPBROADCASTDrm,      0 }, | 
|  | 708 | { X86::VPBROADCASTDYrr, X86::VPBROADCASTDYrm,     0 }, | 
|  | 709 | { X86::VPBROADCASTQrr,  X86::VPBROADCASTQrm,      0 }, | 
|  | 710 | { X86::VPBROADCASTQYrr, X86::VPBROADCASTQYrm,     0 }, | 
|  | 711 | { X86::VPBROADCASTWrr,  X86::VPBROADCASTWrm,      0 }, | 
|  | 712 | { X86::VPBROADCASTWYrr, X86::VPBROADCASTWYrm,     0 }, | 
|  | 713 | { X86::VPERMPDYri,      X86::VPERMPDYmi,          0 }, | 
|  | 714 | { X86::VPERMQYri,       X86::VPERMQYmi,           0 }, | 
|  | 715 | { X86::VPMOVSXBDYrr,    X86::VPMOVSXBDYrm,        0 }, | 
|  | 716 | { X86::VPMOVSXBQYrr,    X86::VPMOVSXBQYrm,        0 }, | 
|  | 717 | { X86::VPMOVSXBWYrr,    X86::VPMOVSXBWYrm,        0 }, | 
|  | 718 | { X86::VPMOVSXDQYrr,    X86::VPMOVSXDQYrm,        0 }, | 
|  | 719 | { X86::VPMOVSXWDYrr,    X86::VPMOVSXWDYrm,        0 }, | 
|  | 720 | { X86::VPMOVSXWQYrr,    X86::VPMOVSXWQYrm,        0 }, | 
|  | 721 | { X86::VPMOVZXBDYrr,    X86::VPMOVZXBDYrm,        0 }, | 
|  | 722 | { X86::VPMOVZXBQYrr,    X86::VPMOVZXBQYrm,        0 }, | 
|  | 723 | { X86::VPMOVZXBWYrr,    X86::VPMOVZXBWYrm,        0 }, | 
|  | 724 | { X86::VPMOVZXDQYrr,    X86::VPMOVZXDQYrm,        0 }, | 
|  | 725 | { X86::VPMOVZXWDYrr,    X86::VPMOVZXWDYrm,        0 }, | 
|  | 726 | { X86::VPMOVZXWQYrr,    X86::VPMOVZXWQYrm,        0 }, | 
| Craig Topper | 81d1e59 | 2012-12-26 02:44:47 +0000 | [diff] [blame] | 727 | { X86::VPSHUFDYri,      X86::VPSHUFDYmi,          0 }, | 
|  | 728 | { X86::VPSHUFHWYri,     X86::VPSHUFHWYmi,         0 }, | 
|  | 729 | { X86::VPSHUFLWYri,     X86::VPSHUFLWYmi,         0 }, | 
| Michael Liao | 2de86af | 2012-09-26 08:24:51 +0000 | [diff] [blame] | 730 |  | 
| Simon Pilgrim | cd32254 | 2015-02-10 12:57:17 +0000 | [diff] [blame] | 731 | // XOP foldable instructions | 
|  | 732 | { X86::VFRCZPDrr,          X86::VFRCZPDrm,        0 }, | 
|  | 733 | { X86::VFRCZPDrrY,         X86::VFRCZPDrmY,       0 }, | 
|  | 734 | { X86::VFRCZPSrr,          X86::VFRCZPSrm,        0 }, | 
|  | 735 | { X86::VFRCZPSrrY,         X86::VFRCZPSrmY,       0 }, | 
|  | 736 | { X86::VFRCZSDrr,          X86::VFRCZSDrm,        0 }, | 
|  | 737 | { X86::VFRCZSSrr,          X86::VFRCZSSrm,        0 }, | 
|  | 738 | { X86::VPHADDBDrr,         X86::VPHADDBDrm,       0 }, | 
|  | 739 | { X86::VPHADDBQrr,         X86::VPHADDBQrm,       0 }, | 
|  | 740 | { X86::VPHADDBWrr,         X86::VPHADDBWrm,       0 }, | 
|  | 741 | { X86::VPHADDDQrr,         X86::VPHADDDQrm,       0 }, | 
|  | 742 | { X86::VPHADDWDrr,         X86::VPHADDWDrm,       0 }, | 
|  | 743 | { X86::VPHADDWQrr,         X86::VPHADDWQrm,       0 }, | 
|  | 744 | { X86::VPHADDUBDrr,        X86::VPHADDUBDrm,      0 }, | 
|  | 745 | { X86::VPHADDUBQrr,        X86::VPHADDUBQrm,      0 }, | 
|  | 746 | { X86::VPHADDUBWrr,        X86::VPHADDUBWrm,      0 }, | 
|  | 747 | { X86::VPHADDUDQrr,        X86::VPHADDUDQrm,      0 }, | 
|  | 748 | { X86::VPHADDUWDrr,        X86::VPHADDUWDrm,      0 }, | 
|  | 749 | { X86::VPHADDUWQrr,        X86::VPHADDUWQrm,      0 }, | 
|  | 750 | { X86::VPHSUBBWrr,         X86::VPHSUBBWrm,       0 }, | 
|  | 751 | { X86::VPHSUBDQrr,         X86::VPHSUBDQrm,       0 }, | 
|  | 752 | { X86::VPHSUBWDrr,         X86::VPHSUBWDrm,       0 }, | 
|  | 753 | { X86::VPROTBri,           X86::VPROTBmi,         0 }, | 
|  | 754 | { X86::VPROTBrr,           X86::VPROTBmr,         0 }, | 
|  | 755 | { X86::VPROTDri,           X86::VPROTDmi,         0 }, | 
|  | 756 | { X86::VPROTDrr,           X86::VPROTDmr,         0 }, | 
|  | 757 | { X86::VPROTQri,           X86::VPROTQmi,         0 }, | 
|  | 758 | { X86::VPROTQrr,           X86::VPROTQmr,         0 }, | 
|  | 759 | { X86::VPROTWri,           X86::VPROTWmi,         0 }, | 
|  | 760 | { X86::VPROTWrr,           X86::VPROTWmr,         0 }, | 
|  | 761 | { X86::VPSHABrr,           X86::VPSHABmr,         0 }, | 
|  | 762 | { X86::VPSHADrr,           X86::VPSHADmr,         0 }, | 
|  | 763 | { X86::VPSHAQrr,           X86::VPSHAQmr,         0 }, | 
|  | 764 | { X86::VPSHAWrr,           X86::VPSHAWmr,         0 }, | 
|  | 765 | { X86::VPSHLBrr,           X86::VPSHLBmr,         0 }, | 
|  | 766 | { X86::VPSHLDrr,           X86::VPSHLDmr,         0 }, | 
|  | 767 | { X86::VPSHLQrr,           X86::VPSHLQmr,         0 }, | 
|  | 768 | { X86::VPSHLWrr,           X86::VPSHLWmr,         0 }, | 
|  | 769 |  | 
| Craig Topper | c81e294 | 2013-10-05 20:20:51 +0000 | [diff] [blame] | 770 | // BMI/BMI2/LZCNT/POPCNT/TBM foldable instructions | 
| Craig Topper | f924a58 | 2012-12-17 05:02:29 +0000 | [diff] [blame] | 771 | { X86::BEXTR32rr,       X86::BEXTR32rm,           0 }, | 
|  | 772 | { X86::BEXTR64rr,       X86::BEXTR64rm,           0 }, | 
| Craig Topper | c81e294 | 2013-10-05 20:20:51 +0000 | [diff] [blame] | 773 | { X86::BEXTRI32ri,      X86::BEXTRI32mi,          0 }, | 
|  | 774 | { X86::BEXTRI64ri,      X86::BEXTRI64mi,          0 }, | 
|  | 775 | { X86::BLCFILL32rr,     X86::BLCFILL32rm,         0 }, | 
|  | 776 | { X86::BLCFILL64rr,     X86::BLCFILL64rm,         0 }, | 
|  | 777 | { X86::BLCI32rr,        X86::BLCI32rm,            0 }, | 
|  | 778 | { X86::BLCI64rr,        X86::BLCI64rm,            0 }, | 
|  | 779 | { X86::BLCIC32rr,       X86::BLCIC32rm,           0 }, | 
|  | 780 | { X86::BLCIC64rr,       X86::BLCIC64rm,           0 }, | 
|  | 781 | { X86::BLCMSK32rr,      X86::BLCMSK32rm,          0 }, | 
|  | 782 | { X86::BLCMSK64rr,      X86::BLCMSK64rm,          0 }, | 
|  | 783 | { X86::BLCS32rr,        X86::BLCS32rm,            0 }, | 
|  | 784 | { X86::BLCS64rr,        X86::BLCS64rm,            0 }, | 
|  | 785 | { X86::BLSFILL32rr,     X86::BLSFILL32rm,         0 }, | 
|  | 786 | { X86::BLSFILL64rr,     X86::BLSFILL64rm,         0 }, | 
| Craig Topper | f924a58 | 2012-12-17 05:02:29 +0000 | [diff] [blame] | 787 | { X86::BLSI32rr,        X86::BLSI32rm,            0 }, | 
|  | 788 | { X86::BLSI64rr,        X86::BLSI64rm,            0 }, | 
| Craig Topper | c81e294 | 2013-10-05 20:20:51 +0000 | [diff] [blame] | 789 | { X86::BLSIC32rr,       X86::BLSIC32rm,           0 }, | 
|  | 790 | { X86::BLSIC64rr,       X86::BLSIC64rm,           0 }, | 
| Craig Topper | f924a58 | 2012-12-17 05:02:29 +0000 | [diff] [blame] | 791 | { X86::BLSMSK32rr,      X86::BLSMSK32rm,          0 }, | 
|  | 792 | { X86::BLSMSK64rr,      X86::BLSMSK64rm,          0 }, | 
|  | 793 | { X86::BLSR32rr,        X86::BLSR32rm,            0 }, | 
|  | 794 | { X86::BLSR64rr,        X86::BLSR64rm,            0 }, | 
|  | 795 | { X86::BZHI32rr,        X86::BZHI32rm,            0 }, | 
|  | 796 | { X86::BZHI64rr,        X86::BZHI64rm,            0 }, | 
|  | 797 | { X86::LZCNT16rr,       X86::LZCNT16rm,           0 }, | 
|  | 798 | { X86::LZCNT32rr,       X86::LZCNT32rm,           0 }, | 
|  | 799 | { X86::LZCNT64rr,       X86::LZCNT64rm,           0 }, | 
|  | 800 | { X86::POPCNT16rr,      X86::POPCNT16rm,          0 }, | 
|  | 801 | { X86::POPCNT32rr,      X86::POPCNT32rm,          0 }, | 
|  | 802 | { X86::POPCNT64rr,      X86::POPCNT64rm,          0 }, | 
| Michael Liao | 2de86af | 2012-09-26 08:24:51 +0000 | [diff] [blame] | 803 | { X86::RORX32ri,        X86::RORX32mi,            0 }, | 
|  | 804 | { X86::RORX64ri,        X86::RORX64mi,            0 }, | 
| Michael Liao | 2b425e1 | 2012-09-26 08:26:25 +0000 | [diff] [blame] | 805 | { X86::SARX32rr,        X86::SARX32rm,            0 }, | 
|  | 806 | { X86::SARX64rr,        X86::SARX64rm,            0 }, | 
|  | 807 | { X86::SHRX32rr,        X86::SHRX32rm,            0 }, | 
|  | 808 | { X86::SHRX64rr,        X86::SHRX64rm,            0 }, | 
|  | 809 | { X86::SHLX32rr,        X86::SHLX32rm,            0 }, | 
|  | 810 | { X86::SHLX64rr,        X86::SHLX64rm,            0 }, | 
| Craig Topper | c81e294 | 2013-10-05 20:20:51 +0000 | [diff] [blame] | 811 | { X86::T1MSKC32rr,      X86::T1MSKC32rm,          0 }, | 
|  | 812 | { X86::T1MSKC64rr,      X86::T1MSKC64rm,          0 }, | 
| Craig Topper | f924a58 | 2012-12-17 05:02:29 +0000 | [diff] [blame] | 813 | { X86::TZCNT16rr,       X86::TZCNT16rm,           0 }, | 
|  | 814 | { X86::TZCNT32rr,       X86::TZCNT32rm,           0 }, | 
|  | 815 | { X86::TZCNT64rr,       X86::TZCNT64rm,           0 }, | 
| Craig Topper | c81e294 | 2013-10-05 20:20:51 +0000 | [diff] [blame] | 816 | { X86::TZMSK32rr,       X86::TZMSK32rm,           0 }, | 
|  | 817 | { X86::TZMSK64rr,       X86::TZMSK64rm,           0 }, | 
| Elena Demikhovsky | 534015e | 2013-09-02 07:12:29 +0000 | [diff] [blame] | 818 |  | 
|  | 819 | // AVX-512 foldable instructions | 
| Igor Breger | 131008f | 2016-05-01 08:40:00 +0000 | [diff] [blame] | 820 | { X86::VMOV64toPQIZrr,   X86::VMOVQI2PQIZrm,      0 }, | 
|  | 821 | { X86::VMOVDI2SSZrr,     X86::VMOVDI2SSZrm,       0 }, | 
|  | 822 | { X86::VMOVAPDZrr,       X86::VMOVAPDZrm,         TB_ALIGN_64 }, | 
|  | 823 | { X86::VMOVAPSZrr,       X86::VMOVAPSZrm,         TB_ALIGN_64 }, | 
|  | 824 | { X86::VMOVDQA32Zrr,     X86::VMOVDQA32Zrm,       TB_ALIGN_64 }, | 
|  | 825 | { X86::VMOVDQA64Zrr,     X86::VMOVDQA64Zrm,       TB_ALIGN_64 }, | 
|  | 826 | { X86::VMOVDQU8Zrr,      X86::VMOVDQU8Zrm,        0 }, | 
|  | 827 | { X86::VMOVDQU16Zrr,     X86::VMOVDQU16Zrm,       0 }, | 
|  | 828 | { X86::VMOVDQU32Zrr,     X86::VMOVDQU32Zrm,       0 }, | 
|  | 829 | { X86::VMOVDQU64Zrr,     X86::VMOVDQU64Zrm,       0 }, | 
|  | 830 | { X86::VMOVUPDZrr,       X86::VMOVUPDZrm,         0 }, | 
|  | 831 | { X86::VMOVUPSZrr,       X86::VMOVUPSZrm,         0 }, | 
|  | 832 | { X86::VPABSDZrr,        X86::VPABSDZrm,          0 }, | 
|  | 833 | { X86::VPABSQZrr,        X86::VPABSQZrm,          0 }, | 
|  | 834 | { X86::VBROADCASTSSZr,   X86::VBROADCASTSSZm,     TB_NO_REVERSE }, | 
|  | 835 | { X86::VBROADCASTSSZr_s, X86::VBROADCASTSSZm,     TB_NO_REVERSE }, | 
|  | 836 | { X86::VBROADCASTSDZr,   X86::VBROADCASTSDZm,     TB_NO_REVERSE }, | 
|  | 837 | { X86::VBROADCASTSDZr_s, X86::VBROADCASTSDZm,     TB_NO_REVERSE }, | 
| Simon Pilgrim | d142ab7 | 2015-02-10 13:22:57 +0000 | [diff] [blame] | 838 |  | 
| Robert Khasanov | 6d62c02 | 2014-09-26 09:48:50 +0000 | [diff] [blame] | 839 | // AVX-512 foldable instructions (256-bit versions) | 
| Igor Breger | 131008f | 2016-05-01 08:40:00 +0000 | [diff] [blame] | 840 | { X86::VMOVAPDZ256rr,        X86::VMOVAPDZ256rm,        TB_ALIGN_32 }, | 
|  | 841 | { X86::VMOVAPSZ256rr,        X86::VMOVAPSZ256rm,        TB_ALIGN_32 }, | 
|  | 842 | { X86::VMOVDQA32Z256rr,      X86::VMOVDQA32Z256rm,      TB_ALIGN_32 }, | 
|  | 843 | { X86::VMOVDQA64Z256rr,      X86::VMOVDQA64Z256rm,      TB_ALIGN_32 }, | 
|  | 844 | { X86::VMOVDQU8Z256rr,       X86::VMOVDQU8Z256rm,       0 }, | 
|  | 845 | { X86::VMOVDQU16Z256rr,      X86::VMOVDQU16Z256rm,      0 }, | 
|  | 846 | { X86::VMOVDQU32Z256rr,      X86::VMOVDQU32Z256rm,      0 }, | 
|  | 847 | { X86::VMOVDQU64Z256rr,      X86::VMOVDQU64Z256rm,      0 }, | 
|  | 848 | { X86::VMOVUPDZ256rr,        X86::VMOVUPDZ256rm,        0 }, | 
|  | 849 | { X86::VMOVUPSZ256rr,        X86::VMOVUPSZ256rm,        0 }, | 
|  | 850 | { X86::VBROADCASTSSZ256r,    X86::VBROADCASTSSZ256m,    TB_NO_REVERSE }, | 
|  | 851 | { X86::VBROADCASTSSZ256r_s,  X86::VBROADCASTSSZ256m,    TB_NO_REVERSE }, | 
|  | 852 | { X86::VBROADCASTSDZ256r,    X86::VBROADCASTSDZ256m,    TB_NO_REVERSE }, | 
|  | 853 | { X86::VBROADCASTSDZ256r_s,  X86::VBROADCASTSDZ256m,    TB_NO_REVERSE }, | 
| Simon Pilgrim | d142ab7 | 2015-02-10 13:22:57 +0000 | [diff] [blame] | 854 |  | 
| Igor Breger | 131008f | 2016-05-01 08:40:00 +0000 | [diff] [blame] | 855 | // AVX-512 foldable instructions (128-bit versions) | 
|  | 856 | { X86::VMOVAPDZ128rr,        X86::VMOVAPDZ128rm,        TB_ALIGN_16 }, | 
|  | 857 | { X86::VMOVAPSZ128rr,        X86::VMOVAPSZ128rm,        TB_ALIGN_16 }, | 
|  | 858 | { X86::VMOVDQA32Z128rr,      X86::VMOVDQA32Z128rm,      TB_ALIGN_16 }, | 
|  | 859 | { X86::VMOVDQA64Z128rr,      X86::VMOVDQA64Z128rm,      TB_ALIGN_16 }, | 
|  | 860 | { X86::VMOVDQU8Z128rr,       X86::VMOVDQU8Z128rm,       0 }, | 
|  | 861 | { X86::VMOVDQU16Z128rr,      X86::VMOVDQU16Z128rm,      0 }, | 
|  | 862 | { X86::VMOVDQU32Z128rr,      X86::VMOVDQU32Z128rm,      0 }, | 
|  | 863 | { X86::VMOVDQU64Z128rr,      X86::VMOVDQU64Z128rm,      0 }, | 
|  | 864 | { X86::VMOVUPDZ128rr,        X86::VMOVUPDZ128rm,        0 }, | 
|  | 865 | { X86::VMOVUPSZ128rr,        X86::VMOVUPSZ128rm,        0 }, | 
|  | 866 | { X86::VBROADCASTSSZ128r,    X86::VBROADCASTSSZ128m,    TB_NO_REVERSE }, | 
|  | 867 | { X86::VBROADCASTSSZ128r_s,  X86::VBROADCASTSSZ128m,    TB_NO_REVERSE }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 868 | // F16C foldable instructions | 
|  | 869 | { X86::VCVTPH2PSrr,        X86::VCVTPH2PSrm,            0 }, | 
|  | 870 | { X86::VCVTPH2PSYrr,       X86::VCVTPH2PSYrm,           0 }, | 
| Simon Pilgrim | cd32254 | 2015-02-10 12:57:17 +0000 | [diff] [blame] | 871 |  | 
| Craig Topper | 514f02c | 2013-09-17 06:50:11 +0000 | [diff] [blame] | 872 | // AES foldable instructions | 
|  | 873 | { X86::AESIMCrr,              X86::AESIMCrm,              TB_ALIGN_16 }, | 
|  | 874 | { X86::AESKEYGENASSIST128rr,  X86::AESKEYGENASSIST128rm,  TB_ALIGN_16 }, | 
| Simon Pilgrim | 295eaad | 2015-02-12 20:01:03 +0000 | [diff] [blame] | 875 | { X86::VAESIMCrr,             X86::VAESIMCrm,             0 }, | 
|  | 876 | { X86::VAESKEYGENASSIST128rr, X86::VAESKEYGENASSIST128rm, 0 } | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 877 | }; | 
|  | 878 |  | 
| Sanjay Patel | cf0a807 | 2015-07-07 15:03:53 +0000 | [diff] [blame] | 879 | for (X86MemoryFoldTableEntry Entry : MemoryFoldTable1) { | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 880 | AddTableEntry(RegOp2MemOpTable1, MemOp2RegOpTable, | 
| Sanjay Patel | cf0a807 | 2015-07-07 15:03:53 +0000 | [diff] [blame] | 881 | Entry.RegOp, Entry.MemOp, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 882 | // Index 1, folded load | 
| Sanjay Patel | cf0a807 | 2015-07-07 15:03:53 +0000 | [diff] [blame] | 883 | Entry.Flags | TB_INDEX_1 | TB_FOLDED_LOAD); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 884 | } | 
|  | 885 |  | 
| Sanjay Patel | e951a38 | 2015-02-17 22:38:06 +0000 | [diff] [blame] | 886 | static const X86MemoryFoldTableEntry MemoryFoldTable2[] = { | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 887 | { X86::ADC32rr,         X86::ADC32rm,       0 }, | 
|  | 888 | { X86::ADC64rr,         X86::ADC64rm,       0 }, | 
|  | 889 | { X86::ADD16rr,         X86::ADD16rm,       0 }, | 
|  | 890 | { X86::ADD16rr_DB,      X86::ADD16rm,       TB_NO_REVERSE }, | 
|  | 891 | { X86::ADD32rr,         X86::ADD32rm,       0 }, | 
|  | 892 | { X86::ADD32rr_DB,      X86::ADD32rm,       TB_NO_REVERSE }, | 
|  | 893 | { X86::ADD64rr,         X86::ADD64rm,       0 }, | 
|  | 894 | { X86::ADD64rr_DB,      X86::ADD64rm,       TB_NO_REVERSE }, | 
|  | 895 | { X86::ADD8rr,          X86::ADD8rm,        0 }, | 
|  | 896 | { X86::ADDPDrr,         X86::ADDPDrm,       TB_ALIGN_16 }, | 
|  | 897 | { X86::ADDPSrr,         X86::ADDPSrm,       TB_ALIGN_16 }, | 
|  | 898 | { X86::ADDSDrr,         X86::ADDSDrm,       0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 899 | { X86::ADDSDrr_Int,     X86::ADDSDrm_Int,   0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 900 | { X86::ADDSSrr,         X86::ADDSSrm,       0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 901 | { X86::ADDSSrr_Int,     X86::ADDSSrm_Int,   0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 902 | { X86::ADDSUBPDrr,      X86::ADDSUBPDrm,    TB_ALIGN_16 }, | 
|  | 903 | { X86::ADDSUBPSrr,      X86::ADDSUBPSrm,    TB_ALIGN_16 }, | 
|  | 904 | { X86::AND16rr,         X86::AND16rm,       0 }, | 
|  | 905 | { X86::AND32rr,         X86::AND32rm,       0 }, | 
|  | 906 | { X86::AND64rr,         X86::AND64rm,       0 }, | 
|  | 907 | { X86::AND8rr,          X86::AND8rm,        0 }, | 
|  | 908 | { X86::ANDNPDrr,        X86::ANDNPDrm,      TB_ALIGN_16 }, | 
|  | 909 | { X86::ANDNPSrr,        X86::ANDNPSrm,      TB_ALIGN_16 }, | 
|  | 910 | { X86::ANDPDrr,         X86::ANDPDrm,       TB_ALIGN_16 }, | 
|  | 911 | { X86::ANDPSrr,         X86::ANDPSrm,       TB_ALIGN_16 }, | 
| Craig Topper | d78429f | 2012-01-14 18:14:53 +0000 | [diff] [blame] | 912 | { X86::BLENDPDrri,      X86::BLENDPDrmi,    TB_ALIGN_16 }, | 
|  | 913 | { X86::BLENDPSrri,      X86::BLENDPSrmi,    TB_ALIGN_16 }, | 
|  | 914 | { X86::BLENDVPDrr0,     X86::BLENDVPDrm0,   TB_ALIGN_16 }, | 
|  | 915 | { X86::BLENDVPSrr0,     X86::BLENDVPSrm0,   TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 916 | { X86::CMOVA16rr,       X86::CMOVA16rm,     0 }, | 
|  | 917 | { X86::CMOVA32rr,       X86::CMOVA32rm,     0 }, | 
|  | 918 | { X86::CMOVA64rr,       X86::CMOVA64rm,     0 }, | 
|  | 919 | { X86::CMOVAE16rr,      X86::CMOVAE16rm,    0 }, | 
|  | 920 | { X86::CMOVAE32rr,      X86::CMOVAE32rm,    0 }, | 
|  | 921 | { X86::CMOVAE64rr,      X86::CMOVAE64rm,    0 }, | 
|  | 922 | { X86::CMOVB16rr,       X86::CMOVB16rm,     0 }, | 
|  | 923 | { X86::CMOVB32rr,       X86::CMOVB32rm,     0 }, | 
|  | 924 | { X86::CMOVB64rr,       X86::CMOVB64rm,     0 }, | 
|  | 925 | { X86::CMOVBE16rr,      X86::CMOVBE16rm,    0 }, | 
|  | 926 | { X86::CMOVBE32rr,      X86::CMOVBE32rm,    0 }, | 
|  | 927 | { X86::CMOVBE64rr,      X86::CMOVBE64rm,    0 }, | 
|  | 928 | { X86::CMOVE16rr,       X86::CMOVE16rm,     0 }, | 
|  | 929 | { X86::CMOVE32rr,       X86::CMOVE32rm,     0 }, | 
|  | 930 | { X86::CMOVE64rr,       X86::CMOVE64rm,     0 }, | 
|  | 931 | { X86::CMOVG16rr,       X86::CMOVG16rm,     0 }, | 
|  | 932 | { X86::CMOVG32rr,       X86::CMOVG32rm,     0 }, | 
|  | 933 | { X86::CMOVG64rr,       X86::CMOVG64rm,     0 }, | 
|  | 934 | { X86::CMOVGE16rr,      X86::CMOVGE16rm,    0 }, | 
|  | 935 | { X86::CMOVGE32rr,      X86::CMOVGE32rm,    0 }, | 
|  | 936 | { X86::CMOVGE64rr,      X86::CMOVGE64rm,    0 }, | 
|  | 937 | { X86::CMOVL16rr,       X86::CMOVL16rm,     0 }, | 
|  | 938 | { X86::CMOVL32rr,       X86::CMOVL32rm,     0 }, | 
|  | 939 | { X86::CMOVL64rr,       X86::CMOVL64rm,     0 }, | 
|  | 940 | { X86::CMOVLE16rr,      X86::CMOVLE16rm,    0 }, | 
|  | 941 | { X86::CMOVLE32rr,      X86::CMOVLE32rm,    0 }, | 
|  | 942 | { X86::CMOVLE64rr,      X86::CMOVLE64rm,    0 }, | 
|  | 943 | { X86::CMOVNE16rr,      X86::CMOVNE16rm,    0 }, | 
|  | 944 | { X86::CMOVNE32rr,      X86::CMOVNE32rm,    0 }, | 
|  | 945 | { X86::CMOVNE64rr,      X86::CMOVNE64rm,    0 }, | 
|  | 946 | { X86::CMOVNO16rr,      X86::CMOVNO16rm,    0 }, | 
|  | 947 | { X86::CMOVNO32rr,      X86::CMOVNO32rm,    0 }, | 
|  | 948 | { X86::CMOVNO64rr,      X86::CMOVNO64rm,    0 }, | 
|  | 949 | { X86::CMOVNP16rr,      X86::CMOVNP16rm,    0 }, | 
|  | 950 | { X86::CMOVNP32rr,      X86::CMOVNP32rm,    0 }, | 
|  | 951 | { X86::CMOVNP64rr,      X86::CMOVNP64rm,    0 }, | 
|  | 952 | { X86::CMOVNS16rr,      X86::CMOVNS16rm,    0 }, | 
|  | 953 | { X86::CMOVNS32rr,      X86::CMOVNS32rm,    0 }, | 
|  | 954 | { X86::CMOVNS64rr,      X86::CMOVNS64rm,    0 }, | 
|  | 955 | { X86::CMOVO16rr,       X86::CMOVO16rm,     0 }, | 
|  | 956 | { X86::CMOVO32rr,       X86::CMOVO32rm,     0 }, | 
|  | 957 | { X86::CMOVO64rr,       X86::CMOVO64rm,     0 }, | 
|  | 958 | { X86::CMOVP16rr,       X86::CMOVP16rm,     0 }, | 
|  | 959 | { X86::CMOVP32rr,       X86::CMOVP32rm,     0 }, | 
|  | 960 | { X86::CMOVP64rr,       X86::CMOVP64rm,     0 }, | 
|  | 961 | { X86::CMOVS16rr,       X86::CMOVS16rm,     0 }, | 
|  | 962 | { X86::CMOVS32rr,       X86::CMOVS32rm,     0 }, | 
|  | 963 | { X86::CMOVS64rr,       X86::CMOVS64rm,     0 }, | 
|  | 964 | { X86::CMPPDrri,        X86::CMPPDrmi,      TB_ALIGN_16 }, | 
|  | 965 | { X86::CMPPSrri,        X86::CMPPSrmi,      TB_ALIGN_16 }, | 
|  | 966 | { X86::CMPSDrr,         X86::CMPSDrm,       0 }, | 
|  | 967 | { X86::CMPSSrr,         X86::CMPSSrm,       0 }, | 
| Simon Pilgrim | 0184622 | 2015-04-03 14:24:40 +0000 | [diff] [blame] | 968 | { X86::CRC32r32r32,     X86::CRC32r32m32,   0 }, | 
|  | 969 | { X86::CRC32r64r64,     X86::CRC32r64m64,   0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 970 | { X86::DIVPDrr,         X86::DIVPDrm,       TB_ALIGN_16 }, | 
|  | 971 | { X86::DIVPSrr,         X86::DIVPSrm,       TB_ALIGN_16 }, | 
|  | 972 | { X86::DIVSDrr,         X86::DIVSDrm,       0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 973 | { X86::DIVSDrr_Int,     X86::DIVSDrm_Int,   0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 974 | { X86::DIVSSrr,         X86::DIVSSrm,       0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 975 | { X86::DIVSSrr_Int,     X86::DIVSSrm_Int,   0 }, | 
|  | 976 | { X86::DPPDrri,         X86::DPPDrmi,       TB_ALIGN_16 }, | 
|  | 977 | { X86::DPPSrri,         X86::DPPSrmi,       TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 978 | { X86::HADDPDrr,        X86::HADDPDrm,      TB_ALIGN_16 }, | 
|  | 979 | { X86::HADDPSrr,        X86::HADDPSrm,      TB_ALIGN_16 }, | 
|  | 980 | { X86::HSUBPDrr,        X86::HSUBPDrm,      TB_ALIGN_16 }, | 
|  | 981 | { X86::HSUBPSrr,        X86::HSUBPSrm,      TB_ALIGN_16 }, | 
|  | 982 | { X86::IMUL16rr,        X86::IMUL16rm,      0 }, | 
|  | 983 | { X86::IMUL32rr,        X86::IMUL32rm,      0 }, | 
|  | 984 | { X86::IMUL64rr,        X86::IMUL64rm,      0 }, | 
|  | 985 | { X86::Int_CMPSDrr,     X86::Int_CMPSDrm,   0 }, | 
|  | 986 | { X86::Int_CMPSSrr,     X86::Int_CMPSSrm,   0 }, | 
| Manman Ren | 959acb1 | 2012-08-13 18:29:41 +0000 | [diff] [blame] | 987 | { X86::Int_CVTSD2SSrr,  X86::Int_CVTSD2SSrm,      0 }, | 
|  | 988 | { X86::Int_CVTSI2SD64rr,X86::Int_CVTSI2SD64rm,    0 }, | 
|  | 989 | { X86::Int_CVTSI2SDrr,  X86::Int_CVTSI2SDrm,      0 }, | 
|  | 990 | { X86::Int_CVTSI2SS64rr,X86::Int_CVTSI2SS64rm,    0 }, | 
|  | 991 | { X86::Int_CVTSI2SSrr,  X86::Int_CVTSI2SSrm,      0 }, | 
|  | 992 | { X86::Int_CVTSS2SDrr,  X86::Int_CVTSS2SDrm,      0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 993 | { X86::MAXPDrr,         X86::MAXPDrm,       TB_ALIGN_16 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 994 | { X86::MAXCPDrr,        X86::MAXCPDrm,      TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 995 | { X86::MAXPSrr,         X86::MAXPSrm,       TB_ALIGN_16 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 996 | { X86::MAXCPSrr,        X86::MAXCPSrm,      TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 997 | { X86::MAXSDrr,         X86::MAXSDrm,       0 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 998 | { X86::MAXCSDrr,        X86::MAXCSDrm,      0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 999 | { X86::MAXSDrr_Int,     X86::MAXSDrm_Int,   0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1000 | { X86::MAXSSrr,         X86::MAXSSrm,       0 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 1001 | { X86::MAXCSSrr,        X86::MAXCSSrm,      0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1002 | { X86::MAXSSrr_Int,     X86::MAXSSrm_Int,   0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1003 | { X86::MINPDrr,         X86::MINPDrm,       TB_ALIGN_16 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 1004 | { X86::MINCPDrr,        X86::MINCPDrm,      TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1005 | { X86::MINPSrr,         X86::MINPSrm,       TB_ALIGN_16 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 1006 | { X86::MINCPSrr,        X86::MINCPSrm,      TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1007 | { X86::MINSDrr,         X86::MINSDrm,       0 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 1008 | { X86::MINCSDrr,        X86::MINCSDrm,      0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1009 | { X86::MINSDrr_Int,     X86::MINSDrm_Int,   0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1010 | { X86::MINSSrr,         X86::MINSSrm,       0 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 1011 | { X86::MINCSSrr,        X86::MINCSSrm,      0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1012 | { X86::MINSSrr_Int,     X86::MINSSrm_Int,   0 }, | 
| Simon Pilgrim | a207436 | 2016-02-08 23:03:46 +0000 | [diff] [blame] | 1013 | { X86::MOVLHPSrr,       X86::MOVHPSrm,      TB_NO_REVERSE }, | 
| Craig Topper | 182b00a | 2011-11-14 08:07:55 +0000 | [diff] [blame] | 1014 | { X86::MPSADBWrri,      X86::MPSADBWrmi,    TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1015 | { X86::MULPDrr,         X86::MULPDrm,       TB_ALIGN_16 }, | 
|  | 1016 | { X86::MULPSrr,         X86::MULPSrm,       TB_ALIGN_16 }, | 
|  | 1017 | { X86::MULSDrr,         X86::MULSDrm,       0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1018 | { X86::MULSDrr_Int,     X86::MULSDrm_Int,   0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1019 | { X86::MULSSrr,         X86::MULSSrm,       0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1020 | { X86::MULSSrr_Int,     X86::MULSSrm_Int,   0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1021 | { X86::OR16rr,          X86::OR16rm,        0 }, | 
|  | 1022 | { X86::OR32rr,          X86::OR32rm,        0 }, | 
|  | 1023 | { X86::OR64rr,          X86::OR64rm,        0 }, | 
|  | 1024 | { X86::OR8rr,           X86::OR8rm,         0 }, | 
|  | 1025 | { X86::ORPDrr,          X86::ORPDrm,        TB_ALIGN_16 }, | 
|  | 1026 | { X86::ORPSrr,          X86::ORPSrm,        TB_ALIGN_16 }, | 
|  | 1027 | { X86::PACKSSDWrr,      X86::PACKSSDWrm,    TB_ALIGN_16 }, | 
|  | 1028 | { X86::PACKSSWBrr,      X86::PACKSSWBrm,    TB_ALIGN_16 }, | 
| Craig Topper | 182b00a | 2011-11-14 08:07:55 +0000 | [diff] [blame] | 1029 | { X86::PACKUSDWrr,      X86::PACKUSDWrm,    TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1030 | { X86::PACKUSWBrr,      X86::PACKUSWBrm,    TB_ALIGN_16 }, | 
|  | 1031 | { X86::PADDBrr,         X86::PADDBrm,       TB_ALIGN_16 }, | 
|  | 1032 | { X86::PADDDrr,         X86::PADDDrm,       TB_ALIGN_16 }, | 
|  | 1033 | { X86::PADDQrr,         X86::PADDQrm,       TB_ALIGN_16 }, | 
|  | 1034 | { X86::PADDSBrr,        X86::PADDSBrm,      TB_ALIGN_16 }, | 
|  | 1035 | { X86::PADDSWrr,        X86::PADDSWrm,      TB_ALIGN_16 }, | 
| Craig Topper | 182b00a | 2011-11-14 08:07:55 +0000 | [diff] [blame] | 1036 | { X86::PADDUSBrr,       X86::PADDUSBrm,     TB_ALIGN_16 }, | 
|  | 1037 | { X86::PADDUSWrr,       X86::PADDUSWrm,     TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1038 | { X86::PADDWrr,         X86::PADDWrm,       TB_ALIGN_16 }, | 
| Craig Topper | 7a29930 | 2016-06-09 07:06:38 +0000 | [diff] [blame] | 1039 | { X86::PALIGNRrri,      X86::PALIGNRrmi,    TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1040 | { X86::PANDNrr,         X86::PANDNrm,       TB_ALIGN_16 }, | 
|  | 1041 | { X86::PANDrr,          X86::PANDrm,        TB_ALIGN_16 }, | 
|  | 1042 | { X86::PAVGBrr,         X86::PAVGBrm,       TB_ALIGN_16 }, | 
|  | 1043 | { X86::PAVGWrr,         X86::PAVGWrm,       TB_ALIGN_16 }, | 
| Simon Pilgrim | 5fa0fb2 | 2015-01-21 23:43:30 +0000 | [diff] [blame] | 1044 | { X86::PBLENDVBrr0,     X86::PBLENDVBrm0,   TB_ALIGN_16 }, | 
| Craig Topper | d78429f | 2012-01-14 18:14:53 +0000 | [diff] [blame] | 1045 | { X86::PBLENDWrri,      X86::PBLENDWrmi,    TB_ALIGN_16 }, | 
| Simon Pilgrim | 5fa0fb2 | 2015-01-21 23:43:30 +0000 | [diff] [blame] | 1046 | { X86::PCLMULQDQrr,     X86::PCLMULQDQrm,   TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1047 | { X86::PCMPEQBrr,       X86::PCMPEQBrm,     TB_ALIGN_16 }, | 
|  | 1048 | { X86::PCMPEQDrr,       X86::PCMPEQDrm,     TB_ALIGN_16 }, | 
| Craig Topper | 182b00a | 2011-11-14 08:07:55 +0000 | [diff] [blame] | 1049 | { X86::PCMPEQQrr,       X86::PCMPEQQrm,     TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1050 | { X86::PCMPEQWrr,       X86::PCMPEQWrm,     TB_ALIGN_16 }, | 
|  | 1051 | { X86::PCMPGTBrr,       X86::PCMPGTBrm,     TB_ALIGN_16 }, | 
|  | 1052 | { X86::PCMPGTDrr,       X86::PCMPGTDrm,     TB_ALIGN_16 }, | 
| Craig Topper | 182b00a | 2011-11-14 08:07:55 +0000 | [diff] [blame] | 1053 | { X86::PCMPGTQrr,       X86::PCMPGTQrm,     TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1054 | { X86::PCMPGTWrr,       X86::PCMPGTWrm,     TB_ALIGN_16 }, | 
| Craig Topper | ce4f9c5 | 2012-01-25 05:37:32 +0000 | [diff] [blame] | 1055 | { X86::PHADDDrr,        X86::PHADDDrm,      TB_ALIGN_16 }, | 
|  | 1056 | { X86::PHADDWrr,        X86::PHADDWrm,      TB_ALIGN_16 }, | 
| Craig Topper | 182b00a | 2011-11-14 08:07:55 +0000 | [diff] [blame] | 1057 | { X86::PHADDSWrr128,    X86::PHADDSWrm128,  TB_ALIGN_16 }, | 
| Craig Topper | ce4f9c5 | 2012-01-25 05:37:32 +0000 | [diff] [blame] | 1058 | { X86::PHSUBDrr,        X86::PHSUBDrm,      TB_ALIGN_16 }, | 
| Craig Topper | 182b00a | 2011-11-14 08:07:55 +0000 | [diff] [blame] | 1059 | { X86::PHSUBSWrr128,    X86::PHSUBSWrm128,  TB_ALIGN_16 }, | 
| Craig Topper | ce4f9c5 | 2012-01-25 05:37:32 +0000 | [diff] [blame] | 1060 | { X86::PHSUBWrr,        X86::PHSUBWrm,      TB_ALIGN_16 }, | 
| Simon Pilgrim | 5fa0fb2 | 2015-01-21 23:43:30 +0000 | [diff] [blame] | 1061 | { X86::PINSRBrr,        X86::PINSRBrm,      0 }, | 
|  | 1062 | { X86::PINSRDrr,        X86::PINSRDrm,      0 }, | 
|  | 1063 | { X86::PINSRQrr,        X86::PINSRQrm,      0 }, | 
|  | 1064 | { X86::PINSRWrri,       X86::PINSRWrmi,     0 }, | 
| Craig Topper | 182b00a | 2011-11-14 08:07:55 +0000 | [diff] [blame] | 1065 | { X86::PMADDUBSWrr128,  X86::PMADDUBSWrm128, TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1066 | { X86::PMADDWDrr,       X86::PMADDWDrm,     TB_ALIGN_16 }, | 
|  | 1067 | { X86::PMAXSWrr,        X86::PMAXSWrm,      TB_ALIGN_16 }, | 
|  | 1068 | { X86::PMAXUBrr,        X86::PMAXUBrm,      TB_ALIGN_16 }, | 
|  | 1069 | { X86::PMINSWrr,        X86::PMINSWrm,      TB_ALIGN_16 }, | 
|  | 1070 | { X86::PMINUBrr,        X86::PMINUBrm,      TB_ALIGN_16 }, | 
| Benjamin Kramer | 4669d18 | 2012-12-21 14:04:55 +0000 | [diff] [blame] | 1071 | { X86::PMINSBrr,        X86::PMINSBrm,      TB_ALIGN_16 }, | 
|  | 1072 | { X86::PMINSDrr,        X86::PMINSDrm,      TB_ALIGN_16 }, | 
|  | 1073 | { X86::PMINUDrr,        X86::PMINUDrm,      TB_ALIGN_16 }, | 
|  | 1074 | { X86::PMINUWrr,        X86::PMINUWrm,      TB_ALIGN_16 }, | 
|  | 1075 | { X86::PMAXSBrr,        X86::PMAXSBrm,      TB_ALIGN_16 }, | 
|  | 1076 | { X86::PMAXSDrr,        X86::PMAXSDrm,      TB_ALIGN_16 }, | 
|  | 1077 | { X86::PMAXUDrr,        X86::PMAXUDrm,      TB_ALIGN_16 }, | 
|  | 1078 | { X86::PMAXUWrr,        X86::PMAXUWrm,      TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1079 | { X86::PMULDQrr,        X86::PMULDQrm,      TB_ALIGN_16 }, | 
| Craig Topper | 182b00a | 2011-11-14 08:07:55 +0000 | [diff] [blame] | 1080 | { X86::PMULHRSWrr128,   X86::PMULHRSWrm128, TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1081 | { X86::PMULHUWrr,       X86::PMULHUWrm,     TB_ALIGN_16 }, | 
|  | 1082 | { X86::PMULHWrr,        X86::PMULHWrm,      TB_ALIGN_16 }, | 
|  | 1083 | { X86::PMULLDrr,        X86::PMULLDrm,      TB_ALIGN_16 }, | 
|  | 1084 | { X86::PMULLWrr,        X86::PMULLWrm,      TB_ALIGN_16 }, | 
|  | 1085 | { X86::PMULUDQrr,       X86::PMULUDQrm,     TB_ALIGN_16 }, | 
|  | 1086 | { X86::PORrr,           X86::PORrm,         TB_ALIGN_16 }, | 
|  | 1087 | { X86::PSADBWrr,        X86::PSADBWrm,      TB_ALIGN_16 }, | 
| Craig Topper | 7834900 | 2012-01-25 06:43:11 +0000 | [diff] [blame] | 1088 | { X86::PSHUFBrr,        X86::PSHUFBrm,      TB_ALIGN_16 }, | 
| Ahmed Bougacha | f3cccab | 2016-02-16 22:14:12 +0000 | [diff] [blame] | 1089 | { X86::PSIGNBrr128,     X86::PSIGNBrm128,   TB_ALIGN_16 }, | 
|  | 1090 | { X86::PSIGNWrr128,     X86::PSIGNWrm128,   TB_ALIGN_16 }, | 
|  | 1091 | { X86::PSIGNDrr128,     X86::PSIGNDrm128,   TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1092 | { X86::PSLLDrr,         X86::PSLLDrm,       TB_ALIGN_16 }, | 
|  | 1093 | { X86::PSLLQrr,         X86::PSLLQrm,       TB_ALIGN_16 }, | 
|  | 1094 | { X86::PSLLWrr,         X86::PSLLWrm,       TB_ALIGN_16 }, | 
|  | 1095 | { X86::PSRADrr,         X86::PSRADrm,       TB_ALIGN_16 }, | 
|  | 1096 | { X86::PSRAWrr,         X86::PSRAWrm,       TB_ALIGN_16 }, | 
|  | 1097 | { X86::PSRLDrr,         X86::PSRLDrm,       TB_ALIGN_16 }, | 
|  | 1098 | { X86::PSRLQrr,         X86::PSRLQrm,       TB_ALIGN_16 }, | 
|  | 1099 | { X86::PSRLWrr,         X86::PSRLWrm,       TB_ALIGN_16 }, | 
|  | 1100 | { X86::PSUBBrr,         X86::PSUBBrm,       TB_ALIGN_16 }, | 
|  | 1101 | { X86::PSUBDrr,         X86::PSUBDrm,       TB_ALIGN_16 }, | 
| Simon Pilgrim | 5fa0fb2 | 2015-01-21 23:43:30 +0000 | [diff] [blame] | 1102 | { X86::PSUBQrr,         X86::PSUBQrm,       TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1103 | { X86::PSUBSBrr,        X86::PSUBSBrm,      TB_ALIGN_16 }, | 
|  | 1104 | { X86::PSUBSWrr,        X86::PSUBSWrm,      TB_ALIGN_16 }, | 
| Simon Pilgrim | 5fa0fb2 | 2015-01-21 23:43:30 +0000 | [diff] [blame] | 1105 | { X86::PSUBUSBrr,       X86::PSUBUSBrm,     TB_ALIGN_16 }, | 
|  | 1106 | { X86::PSUBUSWrr,       X86::PSUBUSWrm,     TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1107 | { X86::PSUBWrr,         X86::PSUBWrm,       TB_ALIGN_16 }, | 
|  | 1108 | { X86::PUNPCKHBWrr,     X86::PUNPCKHBWrm,   TB_ALIGN_16 }, | 
|  | 1109 | { X86::PUNPCKHDQrr,     X86::PUNPCKHDQrm,   TB_ALIGN_16 }, | 
|  | 1110 | { X86::PUNPCKHQDQrr,    X86::PUNPCKHQDQrm,  TB_ALIGN_16 }, | 
|  | 1111 | { X86::PUNPCKHWDrr,     X86::PUNPCKHWDrm,   TB_ALIGN_16 }, | 
|  | 1112 | { X86::PUNPCKLBWrr,     X86::PUNPCKLBWrm,   TB_ALIGN_16 }, | 
|  | 1113 | { X86::PUNPCKLDQrr,     X86::PUNPCKLDQrm,   TB_ALIGN_16 }, | 
|  | 1114 | { X86::PUNPCKLQDQrr,    X86::PUNPCKLQDQrm,  TB_ALIGN_16 }, | 
|  | 1115 | { X86::PUNPCKLWDrr,     X86::PUNPCKLWDrm,   TB_ALIGN_16 }, | 
|  | 1116 | { X86::PXORrr,          X86::PXORrm,        TB_ALIGN_16 }, | 
| Simon Pilgrim | 752de5d | 2015-07-08 08:07:57 +0000 | [diff] [blame] | 1117 | { X86::ROUNDSDr,        X86::ROUNDSDm,      0 }, | 
|  | 1118 | { X86::ROUNDSSr,        X86::ROUNDSSm,      0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1119 | { X86::SBB32rr,         X86::SBB32rm,       0 }, | 
|  | 1120 | { X86::SBB64rr,         X86::SBB64rm,       0 }, | 
|  | 1121 | { X86::SHUFPDrri,       X86::SHUFPDrmi,     TB_ALIGN_16 }, | 
|  | 1122 | { X86::SHUFPSrri,       X86::SHUFPSrmi,     TB_ALIGN_16 }, | 
|  | 1123 | { X86::SUB16rr,         X86::SUB16rm,       0 }, | 
|  | 1124 | { X86::SUB32rr,         X86::SUB32rm,       0 }, | 
|  | 1125 | { X86::SUB64rr,         X86::SUB64rm,       0 }, | 
|  | 1126 | { X86::SUB8rr,          X86::SUB8rm,        0 }, | 
|  | 1127 | { X86::SUBPDrr,         X86::SUBPDrm,       TB_ALIGN_16 }, | 
|  | 1128 | { X86::SUBPSrr,         X86::SUBPSrm,       TB_ALIGN_16 }, | 
|  | 1129 | { X86::SUBSDrr,         X86::SUBSDrm,       0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1130 | { X86::SUBSDrr_Int,     X86::SUBSDrm_Int,   0 }, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1131 | { X86::SUBSSrr,         X86::SUBSSrm,       0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1132 | { X86::SUBSSrr_Int,     X86::SUBSSrm_Int,   0 }, | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 1133 | // FIXME: TEST*rr -> swapped operand of TEST*mr. | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1134 | { X86::UNPCKHPDrr,      X86::UNPCKHPDrm,    TB_ALIGN_16 }, | 
|  | 1135 | { X86::UNPCKHPSrr,      X86::UNPCKHPSrm,    TB_ALIGN_16 }, | 
|  | 1136 | { X86::UNPCKLPDrr,      X86::UNPCKLPDrm,    TB_ALIGN_16 }, | 
|  | 1137 | { X86::UNPCKLPSrr,      X86::UNPCKLPSrm,    TB_ALIGN_16 }, | 
|  | 1138 | { X86::XOR16rr,         X86::XOR16rm,       0 }, | 
|  | 1139 | { X86::XOR32rr,         X86::XOR32rm,       0 }, | 
|  | 1140 | { X86::XOR64rr,         X86::XOR64rm,       0 }, | 
|  | 1141 | { X86::XOR8rr,          X86::XOR8rm,        0 }, | 
|  | 1142 | { X86::XORPDrr,         X86::XORPDrm,       TB_ALIGN_16 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 1143 | { X86::XORPSrr,         X86::XORPSrm,       TB_ALIGN_16 }, | 
| Simon Pilgrim | cd32254 | 2015-02-10 12:57:17 +0000 | [diff] [blame] | 1144 |  | 
| Bruno Cardoso Lopes | ab7afa9 | 2015-02-25 15:14:02 +0000 | [diff] [blame] | 1145 | // MMX version of foldable instructions | 
|  | 1146 | { X86::MMX_CVTPI2PSirr,   X86::MMX_CVTPI2PSirm,   0 }, | 
|  | 1147 | { X86::MMX_PACKSSDWirr,   X86::MMX_PACKSSDWirm,   0 }, | 
|  | 1148 | { X86::MMX_PACKSSWBirr,   X86::MMX_PACKSSWBirm,   0 }, | 
|  | 1149 | { X86::MMX_PACKUSWBirr,   X86::MMX_PACKUSWBirm,   0 }, | 
|  | 1150 | { X86::MMX_PADDBirr,      X86::MMX_PADDBirm,      0 }, | 
|  | 1151 | { X86::MMX_PADDDirr,      X86::MMX_PADDDirm,      0 }, | 
|  | 1152 | { X86::MMX_PADDQirr,      X86::MMX_PADDQirm,      0 }, | 
|  | 1153 | { X86::MMX_PADDSBirr,     X86::MMX_PADDSBirm,     0 }, | 
|  | 1154 | { X86::MMX_PADDSWirr,     X86::MMX_PADDSWirm,     0 }, | 
|  | 1155 | { X86::MMX_PADDUSBirr,    X86::MMX_PADDUSBirm,    0 }, | 
|  | 1156 | { X86::MMX_PADDUSWirr,    X86::MMX_PADDUSWirm,    0 }, | 
|  | 1157 | { X86::MMX_PADDWirr,      X86::MMX_PADDWirm,      0 }, | 
|  | 1158 | { X86::MMX_PALIGNR64irr,  X86::MMX_PALIGNR64irm,  0 }, | 
|  | 1159 | { X86::MMX_PANDNirr,      X86::MMX_PANDNirm,      0 }, | 
|  | 1160 | { X86::MMX_PANDirr,       X86::MMX_PANDirm,       0 }, | 
|  | 1161 | { X86::MMX_PAVGBirr,      X86::MMX_PAVGBirm,      0 }, | 
|  | 1162 | { X86::MMX_PAVGWirr,      X86::MMX_PAVGWirm,      0 }, | 
|  | 1163 | { X86::MMX_PCMPEQBirr,    X86::MMX_PCMPEQBirm,    0 }, | 
|  | 1164 | { X86::MMX_PCMPEQDirr,    X86::MMX_PCMPEQDirm,    0 }, | 
|  | 1165 | { X86::MMX_PCMPEQWirr,    X86::MMX_PCMPEQWirm,    0 }, | 
|  | 1166 | { X86::MMX_PCMPGTBirr,    X86::MMX_PCMPGTBirm,    0 }, | 
|  | 1167 | { X86::MMX_PCMPGTDirr,    X86::MMX_PCMPGTDirm,    0 }, | 
|  | 1168 | { X86::MMX_PCMPGTWirr,    X86::MMX_PCMPGTWirm,    0 }, | 
|  | 1169 | { X86::MMX_PHADDSWrr64,   X86::MMX_PHADDSWrm64,   0 }, | 
|  | 1170 | { X86::MMX_PHADDWrr64,    X86::MMX_PHADDWrm64,    0 }, | 
|  | 1171 | { X86::MMX_PHADDrr64,     X86::MMX_PHADDrm64,     0 }, | 
|  | 1172 | { X86::MMX_PHSUBDrr64,    X86::MMX_PHSUBDrm64,    0 }, | 
|  | 1173 | { X86::MMX_PHSUBSWrr64,   X86::MMX_PHSUBSWrm64,   0 }, | 
|  | 1174 | { X86::MMX_PHSUBWrr64,    X86::MMX_PHSUBWrm64,    0 }, | 
|  | 1175 | { X86::MMX_PINSRWirri,    X86::MMX_PINSRWirmi,    0 }, | 
|  | 1176 | { X86::MMX_PMADDUBSWrr64, X86::MMX_PMADDUBSWrm64, 0 }, | 
|  | 1177 | { X86::MMX_PMADDWDirr,    X86::MMX_PMADDWDirm,    0 }, | 
|  | 1178 | { X86::MMX_PMAXSWirr,     X86::MMX_PMAXSWirm,     0 }, | 
|  | 1179 | { X86::MMX_PMAXUBirr,     X86::MMX_PMAXUBirm,     0 }, | 
|  | 1180 | { X86::MMX_PMINSWirr,     X86::MMX_PMINSWirm,     0 }, | 
|  | 1181 | { X86::MMX_PMINUBirr,     X86::MMX_PMINUBirm,     0 }, | 
|  | 1182 | { X86::MMX_PMULHRSWrr64,  X86::MMX_PMULHRSWrm64,  0 }, | 
|  | 1183 | { X86::MMX_PMULHUWirr,    X86::MMX_PMULHUWirm,    0 }, | 
|  | 1184 | { X86::MMX_PMULHWirr,     X86::MMX_PMULHWirm,     0 }, | 
|  | 1185 | { X86::MMX_PMULLWirr,     X86::MMX_PMULLWirm,     0 }, | 
|  | 1186 | { X86::MMX_PMULUDQirr,    X86::MMX_PMULUDQirm,    0 }, | 
|  | 1187 | { X86::MMX_PORirr,        X86::MMX_PORirm,        0 }, | 
|  | 1188 | { X86::MMX_PSADBWirr,     X86::MMX_PSADBWirm,     0 }, | 
|  | 1189 | { X86::MMX_PSHUFBrr64,    X86::MMX_PSHUFBrm64,    0 }, | 
|  | 1190 | { X86::MMX_PSIGNBrr64,    X86::MMX_PSIGNBrm64,    0 }, | 
|  | 1191 | { X86::MMX_PSIGNDrr64,    X86::MMX_PSIGNDrm64,    0 }, | 
|  | 1192 | { X86::MMX_PSIGNWrr64,    X86::MMX_PSIGNWrm64,    0 }, | 
|  | 1193 | { X86::MMX_PSLLDrr,       X86::MMX_PSLLDrm,       0 }, | 
|  | 1194 | { X86::MMX_PSLLQrr,       X86::MMX_PSLLQrm,       0 }, | 
|  | 1195 | { X86::MMX_PSLLWrr,       X86::MMX_PSLLWrm,       0 }, | 
|  | 1196 | { X86::MMX_PSRADrr,       X86::MMX_PSRADrm,       0 }, | 
|  | 1197 | { X86::MMX_PSRAWrr,       X86::MMX_PSRAWrm,       0 }, | 
|  | 1198 | { X86::MMX_PSRLDrr,       X86::MMX_PSRLDrm,       0 }, | 
|  | 1199 | { X86::MMX_PSRLQrr,       X86::MMX_PSRLQrm,       0 }, | 
|  | 1200 | { X86::MMX_PSRLWrr,       X86::MMX_PSRLWrm,       0 }, | 
|  | 1201 | { X86::MMX_PSUBBirr,      X86::MMX_PSUBBirm,      0 }, | 
|  | 1202 | { X86::MMX_PSUBDirr,      X86::MMX_PSUBDirm,      0 }, | 
|  | 1203 | { X86::MMX_PSUBQirr,      X86::MMX_PSUBQirm,      0 }, | 
|  | 1204 | { X86::MMX_PSUBSBirr,     X86::MMX_PSUBSBirm,     0 }, | 
|  | 1205 | { X86::MMX_PSUBSWirr,     X86::MMX_PSUBSWirm,     0 }, | 
|  | 1206 | { X86::MMX_PSUBUSBirr,    X86::MMX_PSUBUSBirm,    0 }, | 
|  | 1207 | { X86::MMX_PSUBUSWirr,    X86::MMX_PSUBUSWirm,    0 }, | 
|  | 1208 | { X86::MMX_PSUBWirr,      X86::MMX_PSUBWirm,      0 }, | 
|  | 1209 | { X86::MMX_PUNPCKHBWirr,  X86::MMX_PUNPCKHBWirm,  0 }, | 
|  | 1210 | { X86::MMX_PUNPCKHDQirr,  X86::MMX_PUNPCKHDQirm,  0 }, | 
|  | 1211 | { X86::MMX_PUNPCKHWDirr,  X86::MMX_PUNPCKHWDirm,  0 }, | 
|  | 1212 | { X86::MMX_PUNPCKLBWirr,  X86::MMX_PUNPCKLBWirm,  0 }, | 
|  | 1213 | { X86::MMX_PUNPCKLDQirr,  X86::MMX_PUNPCKLDQirm,  0 }, | 
|  | 1214 | { X86::MMX_PUNPCKLWDirr,  X86::MMX_PUNPCKLWDirm,  0 }, | 
|  | 1215 | { X86::MMX_PXORirr,       X86::MMX_PXORirm,       0 }, | 
|  | 1216 |  | 
| Simon Pilgrim | 8dba5da | 2015-04-03 11:50:30 +0000 | [diff] [blame] | 1217 | // 3DNow! version of foldable instructions | 
|  | 1218 | { X86::PAVGUSBrr,         X86::PAVGUSBrm,         0 }, | 
|  | 1219 | { X86::PFACCrr,           X86::PFACCrm,           0 }, | 
|  | 1220 | { X86::PFADDrr,           X86::PFADDrm,           0 }, | 
|  | 1221 | { X86::PFCMPEQrr,         X86::PFCMPEQrm,         0 }, | 
|  | 1222 | { X86::PFCMPGErr,         X86::PFCMPGErm,         0 }, | 
|  | 1223 | { X86::PFCMPGTrr,         X86::PFCMPGTrm,         0 }, | 
|  | 1224 | { X86::PFMAXrr,           X86::PFMAXrm,           0 }, | 
|  | 1225 | { X86::PFMINrr,           X86::PFMINrm,           0 }, | 
|  | 1226 | { X86::PFMULrr,           X86::PFMULrm,           0 }, | 
|  | 1227 | { X86::PFNACCrr,          X86::PFNACCrm,          0 }, | 
|  | 1228 | { X86::PFPNACCrr,         X86::PFPNACCrm,         0 }, | 
|  | 1229 | { X86::PFRCPIT1rr,        X86::PFRCPIT1rm,        0 }, | 
|  | 1230 | { X86::PFRCPIT2rr,        X86::PFRCPIT2rm,        0 }, | 
|  | 1231 | { X86::PFRSQIT1rr,        X86::PFRSQIT1rm,        0 }, | 
|  | 1232 | { X86::PFSUBrr,           X86::PFSUBrm,           0 }, | 
|  | 1233 | { X86::PFSUBRrr,          X86::PFSUBRrm,          0 }, | 
|  | 1234 | { X86::PMULHRWrr,         X86::PMULHRWrm,         0 }, | 
|  | 1235 |  | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 1236 | // AVX 128-bit versions of foldable instructions | 
|  | 1237 | { X86::VCVTSD2SSrr,       X86::VCVTSD2SSrm,        0 }, | 
|  | 1238 | { X86::Int_VCVTSD2SSrr,   X86::Int_VCVTSD2SSrm,    0 }, | 
|  | 1239 | { X86::VCVTSI2SD64rr,     X86::VCVTSI2SD64rm,      0 }, | 
|  | 1240 | { X86::Int_VCVTSI2SD64rr, X86::Int_VCVTSI2SD64rm,  0 }, | 
|  | 1241 | { X86::VCVTSI2SDrr,       X86::VCVTSI2SDrm,        0 }, | 
|  | 1242 | { X86::Int_VCVTSI2SDrr,   X86::Int_VCVTSI2SDrm,    0 }, | 
|  | 1243 | { X86::VCVTSI2SS64rr,     X86::VCVTSI2SS64rm,      0 }, | 
|  | 1244 | { X86::Int_VCVTSI2SS64rr, X86::Int_VCVTSI2SS64rm,  0 }, | 
|  | 1245 | { X86::VCVTSI2SSrr,       X86::VCVTSI2SSrm,        0 }, | 
|  | 1246 | { X86::Int_VCVTSI2SSrr,   X86::Int_VCVTSI2SSrm,    0 }, | 
| Craig Topper | caef1c5 | 2012-12-26 00:35:47 +0000 | [diff] [blame] | 1247 | { X86::VCVTSS2SDrr,       X86::VCVTSS2SDrm,        0 }, | 
|  | 1248 | { X86::Int_VCVTSS2SDrr,   X86::Int_VCVTSS2SDrm,    0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1249 | { X86::VRCPSSr,           X86::VRCPSSm,            0 }, | 
| Sanjay Patel | a9f6d35 | 2015-05-07 15:48:53 +0000 | [diff] [blame] | 1250 | { X86::VRCPSSr_Int,       X86::VRCPSSm_Int,        0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 1251 | { X86::VRSQRTSSr,         X86::VRSQRTSSm,          0 }, | 
| Sanjay Patel | a9f6d35 | 2015-05-07 15:48:53 +0000 | [diff] [blame] | 1252 | { X86::VRSQRTSSr_Int,     X86::VRSQRTSSm_Int,      0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 1253 | { X86::VSQRTSDr,          X86::VSQRTSDm,           0 }, | 
| Sanjay Patel | a9f6d35 | 2015-05-07 15:48:53 +0000 | [diff] [blame] | 1254 | { X86::VSQRTSDr_Int,      X86::VSQRTSDm_Int,       0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 1255 | { X86::VSQRTSSr,          X86::VSQRTSSm,           0 }, | 
| Sanjay Patel | a9f6d35 | 2015-05-07 15:48:53 +0000 | [diff] [blame] | 1256 | { X86::VSQRTSSr_Int,      X86::VSQRTSSm_Int,       0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1257 | { X86::VADDPDrr,          X86::VADDPDrm,           0 }, | 
|  | 1258 | { X86::VADDPSrr,          X86::VADDPSrm,           0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 1259 | { X86::VADDSDrr,          X86::VADDSDrm,           0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1260 | { X86::VADDSDrr_Int,      X86::VADDSDrm_Int,       0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 1261 | { X86::VADDSSrr,          X86::VADDSSrm,           0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1262 | { X86::VADDSSrr_Int,      X86::VADDSSrm_Int,       0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1263 | { X86::VADDSUBPDrr,       X86::VADDSUBPDrm,        0 }, | 
|  | 1264 | { X86::VADDSUBPSrr,       X86::VADDSUBPSrm,        0 }, | 
|  | 1265 | { X86::VANDNPDrr,         X86::VANDNPDrm,          0 }, | 
|  | 1266 | { X86::VANDNPSrr,         X86::VANDNPSrm,          0 }, | 
|  | 1267 | { X86::VANDPDrr,          X86::VANDPDrm,           0 }, | 
|  | 1268 | { X86::VANDPSrr,          X86::VANDPSrm,           0 }, | 
|  | 1269 | { X86::VBLENDPDrri,       X86::VBLENDPDrmi,        0 }, | 
|  | 1270 | { X86::VBLENDPSrri,       X86::VBLENDPSrmi,        0 }, | 
|  | 1271 | { X86::VBLENDVPDrr,       X86::VBLENDVPDrm,        0 }, | 
|  | 1272 | { X86::VBLENDVPSrr,       X86::VBLENDVPSrm,        0 }, | 
|  | 1273 | { X86::VCMPPDrri,         X86::VCMPPDrmi,          0 }, | 
|  | 1274 | { X86::VCMPPSrri,         X86::VCMPPSrmi,          0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 1275 | { X86::VCMPSDrr,          X86::VCMPSDrm,           0 }, | 
|  | 1276 | { X86::VCMPSSrr,          X86::VCMPSSrm,           0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1277 | { X86::VDIVPDrr,          X86::VDIVPDrm,           0 }, | 
|  | 1278 | { X86::VDIVPSrr,          X86::VDIVPSrm,           0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 1279 | { X86::VDIVSDrr,          X86::VDIVSDrm,           0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1280 | { X86::VDIVSDrr_Int,      X86::VDIVSDrm_Int,       0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 1281 | { X86::VDIVSSrr,          X86::VDIVSSrm,           0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1282 | { X86::VDIVSSrr_Int,      X86::VDIVSSrm_Int,       0 }, | 
|  | 1283 | { X86::VDPPDrri,          X86::VDPPDrmi,           0 }, | 
|  | 1284 | { X86::VDPPSrri,          X86::VDPPSrmi,           0 }, | 
| Craig Topper | 81d1e59 | 2012-12-26 02:44:47 +0000 | [diff] [blame] | 1285 | { X86::VHADDPDrr,         X86::VHADDPDrm,          0 }, | 
|  | 1286 | { X86::VHADDPSrr,         X86::VHADDPSrm,          0 }, | 
|  | 1287 | { X86::VHSUBPDrr,         X86::VHSUBPDrm,          0 }, | 
|  | 1288 | { X86::VHSUBPSrr,         X86::VHSUBPSrm,          0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 1289 | { X86::Int_VCMPSDrr,      X86::Int_VCMPSDrm,       0 }, | 
|  | 1290 | { X86::Int_VCMPSSrr,      X86::Int_VCMPSSrm,       0 }, | 
| Craig Topper | 81d1e59 | 2012-12-26 02:44:47 +0000 | [diff] [blame] | 1291 | { X86::VMAXPDrr,          X86::VMAXPDrm,           0 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 1292 | { X86::VMAXCPDrr,         X86::VMAXCPDrm,          0 }, | 
| Craig Topper | 81d1e59 | 2012-12-26 02:44:47 +0000 | [diff] [blame] | 1293 | { X86::VMAXPSrr,          X86::VMAXPSrm,           0 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 1294 | { X86::VMAXCPSrr,         X86::VMAXCPSrm,          0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 1295 | { X86::VMAXSDrr,          X86::VMAXSDrm,           0 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 1296 | { X86::VMAXCSDrr,         X86::VMAXCSDrm,          0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1297 | { X86::VMAXSDrr_Int,      X86::VMAXSDrm_Int,       0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 1298 | { X86::VMAXSSrr,          X86::VMAXSSrm,           0 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 1299 | { X86::VMAXCSSrr,         X86::VMAXCSSrm,          0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1300 | { X86::VMAXSSrr_Int,      X86::VMAXSSrm_Int,       0 }, | 
| Craig Topper | 81d1e59 | 2012-12-26 02:44:47 +0000 | [diff] [blame] | 1301 | { X86::VMINPDrr,          X86::VMINPDrm,           0 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 1302 | { X86::VMINCPDrr,         X86::VMINCPDrm,          0 }, | 
| Craig Topper | 81d1e59 | 2012-12-26 02:44:47 +0000 | [diff] [blame] | 1303 | { X86::VMINPSrr,          X86::VMINPSrm,           0 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 1304 | { X86::VMINCPSrr,         X86::VMINCPSrm,          0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 1305 | { X86::VMINSDrr,          X86::VMINSDrm,           0 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 1306 | { X86::VMINCSDrr,         X86::VMINCSDrm,          0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1307 | { X86::VMINSDrr_Int,      X86::VMINSDrm_Int,       0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 1308 | { X86::VMINSSrr,          X86::VMINSSrm,           0 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 1309 | { X86::VMINCSSrr,         X86::VMINCSSrm,          0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1310 | { X86::VMINSSrr_Int,      X86::VMINSSrm_Int,       0 }, | 
| Simon Pilgrim | a207436 | 2016-02-08 23:03:46 +0000 | [diff] [blame] | 1311 | { X86::VMOVLHPSrr,        X86::VMOVHPSrm,          TB_NO_REVERSE }, | 
| Craig Topper | 81d1e59 | 2012-12-26 02:44:47 +0000 | [diff] [blame] | 1312 | { X86::VMPSADBWrri,       X86::VMPSADBWrmi,        0 }, | 
|  | 1313 | { X86::VMULPDrr,          X86::VMULPDrm,           0 }, | 
|  | 1314 | { X86::VMULPSrr,          X86::VMULPSrm,           0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 1315 | { X86::VMULSDrr,          X86::VMULSDrm,           0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1316 | { X86::VMULSDrr_Int,      X86::VMULSDrm_Int,       0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 1317 | { X86::VMULSSrr,          X86::VMULSSrm,           0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1318 | { X86::VMULSSrr_Int,      X86::VMULSSrm_Int,       0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1319 | { X86::VORPDrr,           X86::VORPDrm,            0 }, | 
|  | 1320 | { X86::VORPSrr,           X86::VORPSrm,            0 }, | 
|  | 1321 | { X86::VPACKSSDWrr,       X86::VPACKSSDWrm,        0 }, | 
|  | 1322 | { X86::VPACKSSWBrr,       X86::VPACKSSWBrm,        0 }, | 
|  | 1323 | { X86::VPACKUSDWrr,       X86::VPACKUSDWrm,        0 }, | 
|  | 1324 | { X86::VPACKUSWBrr,       X86::VPACKUSWBrm,        0 }, | 
|  | 1325 | { X86::VPADDBrr,          X86::VPADDBrm,           0 }, | 
|  | 1326 | { X86::VPADDDrr,          X86::VPADDDrm,           0 }, | 
|  | 1327 | { X86::VPADDQrr,          X86::VPADDQrm,           0 }, | 
|  | 1328 | { X86::VPADDSBrr,         X86::VPADDSBrm,          0 }, | 
|  | 1329 | { X86::VPADDSWrr,         X86::VPADDSWrm,          0 }, | 
|  | 1330 | { X86::VPADDUSBrr,        X86::VPADDUSBrm,         0 }, | 
|  | 1331 | { X86::VPADDUSWrr,        X86::VPADDUSWrm,         0 }, | 
|  | 1332 | { X86::VPADDWrr,          X86::VPADDWrm,           0 }, | 
| Craig Topper | 7a29930 | 2016-06-09 07:06:38 +0000 | [diff] [blame] | 1333 | { X86::VPALIGNRrri,       X86::VPALIGNRrmi,        0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1334 | { X86::VPANDNrr,          X86::VPANDNrm,           0 }, | 
|  | 1335 | { X86::VPANDrr,           X86::VPANDrm,            0 }, | 
|  | 1336 | { X86::VPAVGBrr,          X86::VPAVGBrm,           0 }, | 
|  | 1337 | { X86::VPAVGWrr,          X86::VPAVGWrm,           0 }, | 
| Simon Pilgrim | 5fa0fb2 | 2015-01-21 23:43:30 +0000 | [diff] [blame] | 1338 | { X86::VPBLENDVBrr,       X86::VPBLENDVBrm,        0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1339 | { X86::VPBLENDWrri,       X86::VPBLENDWrmi,        0 }, | 
| Simon Pilgrim | 5fa0fb2 | 2015-01-21 23:43:30 +0000 | [diff] [blame] | 1340 | { X86::VPCLMULQDQrr,      X86::VPCLMULQDQrm,       0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1341 | { X86::VPCMPEQBrr,        X86::VPCMPEQBrm,         0 }, | 
|  | 1342 | { X86::VPCMPEQDrr,        X86::VPCMPEQDrm,         0 }, | 
|  | 1343 | { X86::VPCMPEQQrr,        X86::VPCMPEQQrm,         0 }, | 
|  | 1344 | { X86::VPCMPEQWrr,        X86::VPCMPEQWrm,         0 }, | 
|  | 1345 | { X86::VPCMPGTBrr,        X86::VPCMPGTBrm,         0 }, | 
|  | 1346 | { X86::VPCMPGTDrr,        X86::VPCMPGTDrm,         0 }, | 
|  | 1347 | { X86::VPCMPGTQrr,        X86::VPCMPGTQrm,         0 }, | 
|  | 1348 | { X86::VPCMPGTWrr,        X86::VPCMPGTWrm,         0 }, | 
|  | 1349 | { X86::VPHADDDrr,         X86::VPHADDDrm,          0 }, | 
|  | 1350 | { X86::VPHADDSWrr128,     X86::VPHADDSWrm128,      0 }, | 
|  | 1351 | { X86::VPHADDWrr,         X86::VPHADDWrm,          0 }, | 
|  | 1352 | { X86::VPHSUBDrr,         X86::VPHSUBDrm,          0 }, | 
|  | 1353 | { X86::VPHSUBSWrr128,     X86::VPHSUBSWrm128,      0 }, | 
|  | 1354 | { X86::VPHSUBWrr,         X86::VPHSUBWrm,          0 }, | 
|  | 1355 | { X86::VPERMILPDrr,       X86::VPERMILPDrm,        0 }, | 
|  | 1356 | { X86::VPERMILPSrr,       X86::VPERMILPSrm,        0 }, | 
| Simon Pilgrim | 5fa0fb2 | 2015-01-21 23:43:30 +0000 | [diff] [blame] | 1357 | { X86::VPINSRBrr,         X86::VPINSRBrm,          0 }, | 
|  | 1358 | { X86::VPINSRDrr,         X86::VPINSRDrm,          0 }, | 
|  | 1359 | { X86::VPINSRQrr,         X86::VPINSRQrm,          0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1360 | { X86::VPINSRWrri,        X86::VPINSRWrmi,         0 }, | 
|  | 1361 | { X86::VPMADDUBSWrr128,   X86::VPMADDUBSWrm128,    0 }, | 
|  | 1362 | { X86::VPMADDWDrr,        X86::VPMADDWDrm,         0 }, | 
|  | 1363 | { X86::VPMAXSWrr,         X86::VPMAXSWrm,          0 }, | 
|  | 1364 | { X86::VPMAXUBrr,         X86::VPMAXUBrm,          0 }, | 
|  | 1365 | { X86::VPMINSWrr,         X86::VPMINSWrm,          0 }, | 
|  | 1366 | { X86::VPMINUBrr,         X86::VPMINUBrm,          0 }, | 
|  | 1367 | { X86::VPMINSBrr,         X86::VPMINSBrm,          0 }, | 
|  | 1368 | { X86::VPMINSDrr,         X86::VPMINSDrm,          0 }, | 
|  | 1369 | { X86::VPMINUDrr,         X86::VPMINUDrm,          0 }, | 
|  | 1370 | { X86::VPMINUWrr,         X86::VPMINUWrm,          0 }, | 
|  | 1371 | { X86::VPMAXSBrr,         X86::VPMAXSBrm,          0 }, | 
|  | 1372 | { X86::VPMAXSDrr,         X86::VPMAXSDrm,          0 }, | 
|  | 1373 | { X86::VPMAXUDrr,         X86::VPMAXUDrm,          0 }, | 
|  | 1374 | { X86::VPMAXUWrr,         X86::VPMAXUWrm,          0 }, | 
|  | 1375 | { X86::VPMULDQrr,         X86::VPMULDQrm,          0 }, | 
|  | 1376 | { X86::VPMULHRSWrr128,    X86::VPMULHRSWrm128,     0 }, | 
|  | 1377 | { X86::VPMULHUWrr,        X86::VPMULHUWrm,         0 }, | 
|  | 1378 | { X86::VPMULHWrr,         X86::VPMULHWrm,          0 }, | 
|  | 1379 | { X86::VPMULLDrr,         X86::VPMULLDrm,          0 }, | 
|  | 1380 | { X86::VPMULLWrr,         X86::VPMULLWrm,          0 }, | 
|  | 1381 | { X86::VPMULUDQrr,        X86::VPMULUDQrm,         0 }, | 
|  | 1382 | { X86::VPORrr,            X86::VPORrm,             0 }, | 
|  | 1383 | { X86::VPSADBWrr,         X86::VPSADBWrm,          0 }, | 
|  | 1384 | { X86::VPSHUFBrr,         X86::VPSHUFBrm,          0 }, | 
| Ahmed Bougacha | f3cccab | 2016-02-16 22:14:12 +0000 | [diff] [blame] | 1385 | { X86::VPSIGNBrr128,      X86::VPSIGNBrm128,       0 }, | 
|  | 1386 | { X86::VPSIGNWrr128,      X86::VPSIGNWrm128,       0 }, | 
|  | 1387 | { X86::VPSIGNDrr128,      X86::VPSIGNDrm128,       0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1388 | { X86::VPSLLDrr,          X86::VPSLLDrm,           0 }, | 
|  | 1389 | { X86::VPSLLQrr,          X86::VPSLLQrm,           0 }, | 
|  | 1390 | { X86::VPSLLWrr,          X86::VPSLLWrm,           0 }, | 
|  | 1391 | { X86::VPSRADrr,          X86::VPSRADrm,           0 }, | 
|  | 1392 | { X86::VPSRAWrr,          X86::VPSRAWrm,           0 }, | 
|  | 1393 | { X86::VPSRLDrr,          X86::VPSRLDrm,           0 }, | 
|  | 1394 | { X86::VPSRLQrr,          X86::VPSRLQrm,           0 }, | 
|  | 1395 | { X86::VPSRLWrr,          X86::VPSRLWrm,           0 }, | 
|  | 1396 | { X86::VPSUBBrr,          X86::VPSUBBrm,           0 }, | 
|  | 1397 | { X86::VPSUBDrr,          X86::VPSUBDrm,           0 }, | 
| Simon Pilgrim | 5fa0fb2 | 2015-01-21 23:43:30 +0000 | [diff] [blame] | 1398 | { X86::VPSUBQrr,          X86::VPSUBQrm,           0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1399 | { X86::VPSUBSBrr,         X86::VPSUBSBrm,          0 }, | 
|  | 1400 | { X86::VPSUBSWrr,         X86::VPSUBSWrm,          0 }, | 
| Simon Pilgrim | 5fa0fb2 | 2015-01-21 23:43:30 +0000 | [diff] [blame] | 1401 | { X86::VPSUBUSBrr,        X86::VPSUBUSBrm,         0 }, | 
|  | 1402 | { X86::VPSUBUSWrr,        X86::VPSUBUSWrm,         0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1403 | { X86::VPSUBWrr,          X86::VPSUBWrm,           0 }, | 
|  | 1404 | { X86::VPUNPCKHBWrr,      X86::VPUNPCKHBWrm,       0 }, | 
|  | 1405 | { X86::VPUNPCKHDQrr,      X86::VPUNPCKHDQrm,       0 }, | 
|  | 1406 | { X86::VPUNPCKHQDQrr,     X86::VPUNPCKHQDQrm,      0 }, | 
|  | 1407 | { X86::VPUNPCKHWDrr,      X86::VPUNPCKHWDrm,       0 }, | 
|  | 1408 | { X86::VPUNPCKLBWrr,      X86::VPUNPCKLBWrm,       0 }, | 
|  | 1409 | { X86::VPUNPCKLDQrr,      X86::VPUNPCKLDQrm,       0 }, | 
|  | 1410 | { X86::VPUNPCKLQDQrr,     X86::VPUNPCKLQDQrm,      0 }, | 
|  | 1411 | { X86::VPUNPCKLWDrr,      X86::VPUNPCKLWDrm,       0 }, | 
|  | 1412 | { X86::VPXORrr,           X86::VPXORrm,            0 }, | 
| Simon Pilgrim | 752de5d | 2015-07-08 08:07:57 +0000 | [diff] [blame] | 1413 | { X86::VROUNDSDr,         X86::VROUNDSDm,          0 }, | 
|  | 1414 | { X86::VROUNDSSr,         X86::VROUNDSSm,          0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1415 | { X86::VSHUFPDrri,        X86::VSHUFPDrmi,         0 }, | 
|  | 1416 | { X86::VSHUFPSrri,        X86::VSHUFPSrmi,         0 }, | 
|  | 1417 | { X86::VSUBPDrr,          X86::VSUBPDrm,           0 }, | 
|  | 1418 | { X86::VSUBPSrr,          X86::VSUBPSrm,           0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 1419 | { X86::VSUBSDrr,          X86::VSUBSDrm,           0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1420 | { X86::VSUBSDrr_Int,      X86::VSUBSDrm_Int,       0 }, | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 1421 | { X86::VSUBSSrr,          X86::VSUBSSrm,           0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1422 | { X86::VSUBSSrr_Int,      X86::VSUBSSrm_Int,       0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1423 | { X86::VUNPCKHPDrr,       X86::VUNPCKHPDrm,        0 }, | 
|  | 1424 | { X86::VUNPCKHPSrr,       X86::VUNPCKHPSrm,        0 }, | 
|  | 1425 | { X86::VUNPCKLPDrr,       X86::VUNPCKLPDrm,        0 }, | 
|  | 1426 | { X86::VUNPCKLPSrr,       X86::VUNPCKLPSrm,        0 }, | 
|  | 1427 | { X86::VXORPDrr,          X86::VXORPDrm,           0 }, | 
|  | 1428 | { X86::VXORPSrr,          X86::VXORPSrm,           0 }, | 
| Simon Pilgrim | cd32254 | 2015-02-10 12:57:17 +0000 | [diff] [blame] | 1429 |  | 
| Craig Topper | d78429f | 2012-01-14 18:14:53 +0000 | [diff] [blame] | 1430 | // AVX 256-bit foldable instructions | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1431 | { X86::VADDPDYrr,         X86::VADDPDYrm,          0 }, | 
|  | 1432 | { X86::VADDPSYrr,         X86::VADDPSYrm,          0 }, | 
|  | 1433 | { X86::VADDSUBPDYrr,      X86::VADDSUBPDYrm,       0 }, | 
|  | 1434 | { X86::VADDSUBPSYrr,      X86::VADDSUBPSYrm,       0 }, | 
|  | 1435 | { X86::VANDNPDYrr,        X86::VANDNPDYrm,         0 }, | 
|  | 1436 | { X86::VANDNPSYrr,        X86::VANDNPSYrm,         0 }, | 
|  | 1437 | { X86::VANDPDYrr,         X86::VANDPDYrm,          0 }, | 
|  | 1438 | { X86::VANDPSYrr,         X86::VANDPSYrm,          0 }, | 
|  | 1439 | { X86::VBLENDPDYrri,      X86::VBLENDPDYrmi,       0 }, | 
|  | 1440 | { X86::VBLENDPSYrri,      X86::VBLENDPSYrmi,       0 }, | 
|  | 1441 | { X86::VBLENDVPDYrr,      X86::VBLENDVPDYrm,       0 }, | 
|  | 1442 | { X86::VBLENDVPSYrr,      X86::VBLENDVPSYrm,       0 }, | 
|  | 1443 | { X86::VCMPPDYrri,        X86::VCMPPDYrmi,         0 }, | 
|  | 1444 | { X86::VCMPPSYrri,        X86::VCMPPSYrmi,         0 }, | 
|  | 1445 | { X86::VDIVPDYrr,         X86::VDIVPDYrm,          0 }, | 
|  | 1446 | { X86::VDIVPSYrr,         X86::VDIVPSYrm,          0 }, | 
| Simon Pilgrim | 20bc37c | 2015-01-19 22:40:45 +0000 | [diff] [blame] | 1447 | { X86::VDPPSYrri,         X86::VDPPSYrmi,          0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1448 | { X86::VHADDPDYrr,        X86::VHADDPDYrm,         0 }, | 
|  | 1449 | { X86::VHADDPSYrr,        X86::VHADDPSYrm,         0 }, | 
|  | 1450 | { X86::VHSUBPDYrr,        X86::VHSUBPDYrm,         0 }, | 
|  | 1451 | { X86::VHSUBPSYrr,        X86::VHSUBPSYrm,         0 }, | 
|  | 1452 | { X86::VINSERTF128rr,     X86::VINSERTF128rm,      0 }, | 
|  | 1453 | { X86::VMAXPDYrr,         X86::VMAXPDYrm,          0 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 1454 | { X86::VMAXCPDYrr,        X86::VMAXCPDYrm,         0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1455 | { X86::VMAXPSYrr,         X86::VMAXPSYrm,          0 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 1456 | { X86::VMAXCPSYrr,        X86::VMAXCPSYrm,         0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1457 | { X86::VMINPDYrr,         X86::VMINPDYrm,          0 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 1458 | { X86::VMINCPDYrr,        X86::VMINCPDYrm,         0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1459 | { X86::VMINPSYrr,         X86::VMINPSYrm,          0 }, | 
| Craig Topper | 49841c3 | 2016-08-07 05:39:51 +0000 | [diff] [blame] | 1460 | { X86::VMINCPSYrr,        X86::VMINCPSYrm,         0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1461 | { X86::VMULPDYrr,         X86::VMULPDYrm,          0 }, | 
|  | 1462 | { X86::VMULPSYrr,         X86::VMULPSYrm,          0 }, | 
|  | 1463 | { X86::VORPDYrr,          X86::VORPDYrm,           0 }, | 
|  | 1464 | { X86::VORPSYrr,          X86::VORPSYrm,           0 }, | 
|  | 1465 | { X86::VPERM2F128rr,      X86::VPERM2F128rm,       0 }, | 
|  | 1466 | { X86::VPERMILPDYrr,      X86::VPERMILPDYrm,       0 }, | 
|  | 1467 | { X86::VPERMILPSYrr,      X86::VPERMILPSYrm,       0 }, | 
|  | 1468 | { X86::VSHUFPDYrri,       X86::VSHUFPDYrmi,        0 }, | 
|  | 1469 | { X86::VSHUFPSYrri,       X86::VSHUFPSYrmi,        0 }, | 
|  | 1470 | { X86::VSUBPDYrr,         X86::VSUBPDYrm,          0 }, | 
|  | 1471 | { X86::VSUBPSYrr,         X86::VSUBPSYrm,          0 }, | 
|  | 1472 | { X86::VUNPCKHPDYrr,      X86::VUNPCKHPDYrm,       0 }, | 
|  | 1473 | { X86::VUNPCKHPSYrr,      X86::VUNPCKHPSYrm,       0 }, | 
|  | 1474 | { X86::VUNPCKLPDYrr,      X86::VUNPCKLPDYrm,       0 }, | 
|  | 1475 | { X86::VUNPCKLPSYrr,      X86::VUNPCKLPSYrm,       0 }, | 
|  | 1476 | { X86::VXORPDYrr,         X86::VXORPDYrm,          0 }, | 
|  | 1477 | { X86::VXORPSYrr,         X86::VXORPSYrm,          0 }, | 
| Simon Pilgrim | cd32254 | 2015-02-10 12:57:17 +0000 | [diff] [blame] | 1478 |  | 
| Craig Topper | 182b00a | 2011-11-14 08:07:55 +0000 | [diff] [blame] | 1479 | // AVX2 foldable instructions | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1480 | { X86::VINSERTI128rr,     X86::VINSERTI128rm,      0 }, | 
|  | 1481 | { X86::VPACKSSDWYrr,      X86::VPACKSSDWYrm,       0 }, | 
|  | 1482 | { X86::VPACKSSWBYrr,      X86::VPACKSSWBYrm,       0 }, | 
|  | 1483 | { X86::VPACKUSDWYrr,      X86::VPACKUSDWYrm,       0 }, | 
|  | 1484 | { X86::VPACKUSWBYrr,      X86::VPACKUSWBYrm,       0 }, | 
|  | 1485 | { X86::VPADDBYrr,         X86::VPADDBYrm,          0 }, | 
|  | 1486 | { X86::VPADDDYrr,         X86::VPADDDYrm,          0 }, | 
|  | 1487 | { X86::VPADDQYrr,         X86::VPADDQYrm,          0 }, | 
|  | 1488 | { X86::VPADDSBYrr,        X86::VPADDSBYrm,         0 }, | 
|  | 1489 | { X86::VPADDSWYrr,        X86::VPADDSWYrm,         0 }, | 
|  | 1490 | { X86::VPADDUSBYrr,       X86::VPADDUSBYrm,        0 }, | 
|  | 1491 | { X86::VPADDUSWYrr,       X86::VPADDUSWYrm,        0 }, | 
|  | 1492 | { X86::VPADDWYrr,         X86::VPADDWYrm,          0 }, | 
| Craig Topper | 7a29930 | 2016-06-09 07:06:38 +0000 | [diff] [blame] | 1493 | { X86::VPALIGNRYrri,      X86::VPALIGNRYrmi,       0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1494 | { X86::VPANDNYrr,         X86::VPANDNYrm,          0 }, | 
|  | 1495 | { X86::VPANDYrr,          X86::VPANDYrm,           0 }, | 
|  | 1496 | { X86::VPAVGBYrr,         X86::VPAVGBYrm,          0 }, | 
|  | 1497 | { X86::VPAVGWYrr,         X86::VPAVGWYrm,          0 }, | 
|  | 1498 | { X86::VPBLENDDrri,       X86::VPBLENDDrmi,        0 }, | 
|  | 1499 | { X86::VPBLENDDYrri,      X86::VPBLENDDYrmi,       0 }, | 
| Simon Pilgrim | d142ab7 | 2015-02-10 13:22:57 +0000 | [diff] [blame] | 1500 | { X86::VPBLENDVBYrr,      X86::VPBLENDVBYrm,       0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1501 | { X86::VPBLENDWYrri,      X86::VPBLENDWYrmi,       0 }, | 
|  | 1502 | { X86::VPCMPEQBYrr,       X86::VPCMPEQBYrm,        0 }, | 
|  | 1503 | { X86::VPCMPEQDYrr,       X86::VPCMPEQDYrm,        0 }, | 
|  | 1504 | { X86::VPCMPEQQYrr,       X86::VPCMPEQQYrm,        0 }, | 
|  | 1505 | { X86::VPCMPEQWYrr,       X86::VPCMPEQWYrm,        0 }, | 
|  | 1506 | { X86::VPCMPGTBYrr,       X86::VPCMPGTBYrm,        0 }, | 
|  | 1507 | { X86::VPCMPGTDYrr,       X86::VPCMPGTDYrm,        0 }, | 
|  | 1508 | { X86::VPCMPGTQYrr,       X86::VPCMPGTQYrm,        0 }, | 
|  | 1509 | { X86::VPCMPGTWYrr,       X86::VPCMPGTWYrm,        0 }, | 
|  | 1510 | { X86::VPERM2I128rr,      X86::VPERM2I128rm,       0 }, | 
|  | 1511 | { X86::VPERMDYrr,         X86::VPERMDYrm,          0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1512 | { X86::VPERMPSYrr,        X86::VPERMPSYrm,         0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1513 | { X86::VPHADDDYrr,        X86::VPHADDDYrm,         0 }, | 
|  | 1514 | { X86::VPHADDSWrr256,     X86::VPHADDSWrm256,      0 }, | 
|  | 1515 | { X86::VPHADDWYrr,        X86::VPHADDWYrm,         0 }, | 
|  | 1516 | { X86::VPHSUBDYrr,        X86::VPHSUBDYrm,         0 }, | 
|  | 1517 | { X86::VPHSUBSWrr256,     X86::VPHSUBSWrm256,      0 }, | 
|  | 1518 | { X86::VPHSUBWYrr,        X86::VPHSUBWYrm,         0 }, | 
|  | 1519 | { X86::VPMADDUBSWrr256,   X86::VPMADDUBSWrm256,    0 }, | 
|  | 1520 | { X86::VPMADDWDYrr,       X86::VPMADDWDYrm,        0 }, | 
|  | 1521 | { X86::VPMAXSWYrr,        X86::VPMAXSWYrm,         0 }, | 
|  | 1522 | { X86::VPMAXUBYrr,        X86::VPMAXUBYrm,         0 }, | 
|  | 1523 | { X86::VPMINSWYrr,        X86::VPMINSWYrm,         0 }, | 
|  | 1524 | { X86::VPMINUBYrr,        X86::VPMINUBYrm,         0 }, | 
|  | 1525 | { X86::VPMINSBYrr,        X86::VPMINSBYrm,         0 }, | 
|  | 1526 | { X86::VPMINSDYrr,        X86::VPMINSDYrm,         0 }, | 
|  | 1527 | { X86::VPMINUDYrr,        X86::VPMINUDYrm,         0 }, | 
|  | 1528 | { X86::VPMINUWYrr,        X86::VPMINUWYrm,         0 }, | 
|  | 1529 | { X86::VPMAXSBYrr,        X86::VPMAXSBYrm,         0 }, | 
|  | 1530 | { X86::VPMAXSDYrr,        X86::VPMAXSDYrm,         0 }, | 
|  | 1531 | { X86::VPMAXUDYrr,        X86::VPMAXUDYrm,         0 }, | 
|  | 1532 | { X86::VPMAXUWYrr,        X86::VPMAXUWYrm,         0 }, | 
|  | 1533 | { X86::VMPSADBWYrri,      X86::VMPSADBWYrmi,       0 }, | 
|  | 1534 | { X86::VPMULDQYrr,        X86::VPMULDQYrm,         0 }, | 
|  | 1535 | { X86::VPMULHRSWrr256,    X86::VPMULHRSWrm256,     0 }, | 
|  | 1536 | { X86::VPMULHUWYrr,       X86::VPMULHUWYrm,        0 }, | 
|  | 1537 | { X86::VPMULHWYrr,        X86::VPMULHWYrm,         0 }, | 
|  | 1538 | { X86::VPMULLDYrr,        X86::VPMULLDYrm,         0 }, | 
|  | 1539 | { X86::VPMULLWYrr,        X86::VPMULLWYrm,         0 }, | 
|  | 1540 | { X86::VPMULUDQYrr,       X86::VPMULUDQYrm,        0 }, | 
|  | 1541 | { X86::VPORYrr,           X86::VPORYrm,            0 }, | 
|  | 1542 | { X86::VPSADBWYrr,        X86::VPSADBWYrm,         0 }, | 
|  | 1543 | { X86::VPSHUFBYrr,        X86::VPSHUFBYrm,         0 }, | 
| Ahmed Bougacha | f3cccab | 2016-02-16 22:14:12 +0000 | [diff] [blame] | 1544 | { X86::VPSIGNBYrr256,     X86::VPSIGNBYrm256,      0 }, | 
|  | 1545 | { X86::VPSIGNWYrr256,     X86::VPSIGNWYrm256,      0 }, | 
|  | 1546 | { X86::VPSIGNDYrr256,     X86::VPSIGNDYrm256,      0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1547 | { X86::VPSLLDYrr,         X86::VPSLLDYrm,          0 }, | 
|  | 1548 | { X86::VPSLLQYrr,         X86::VPSLLQYrm,          0 }, | 
|  | 1549 | { X86::VPSLLWYrr,         X86::VPSLLWYrm,          0 }, | 
|  | 1550 | { X86::VPSLLVDrr,         X86::VPSLLVDrm,          0 }, | 
|  | 1551 | { X86::VPSLLVDYrr,        X86::VPSLLVDYrm,         0 }, | 
|  | 1552 | { X86::VPSLLVQrr,         X86::VPSLLVQrm,          0 }, | 
|  | 1553 | { X86::VPSLLVQYrr,        X86::VPSLLVQYrm,         0 }, | 
|  | 1554 | { X86::VPSRADYrr,         X86::VPSRADYrm,          0 }, | 
|  | 1555 | { X86::VPSRAWYrr,         X86::VPSRAWYrm,          0 }, | 
|  | 1556 | { X86::VPSRAVDrr,         X86::VPSRAVDrm,          0 }, | 
|  | 1557 | { X86::VPSRAVDYrr,        X86::VPSRAVDYrm,         0 }, | 
|  | 1558 | { X86::VPSRLDYrr,         X86::VPSRLDYrm,          0 }, | 
|  | 1559 | { X86::VPSRLQYrr,         X86::VPSRLQYrm,          0 }, | 
|  | 1560 | { X86::VPSRLWYrr,         X86::VPSRLWYrm,          0 }, | 
|  | 1561 | { X86::VPSRLVDrr,         X86::VPSRLVDrm,          0 }, | 
|  | 1562 | { X86::VPSRLVDYrr,        X86::VPSRLVDYrm,         0 }, | 
|  | 1563 | { X86::VPSRLVQrr,         X86::VPSRLVQrm,          0 }, | 
|  | 1564 | { X86::VPSRLVQYrr,        X86::VPSRLVQYrm,         0 }, | 
|  | 1565 | { X86::VPSUBBYrr,         X86::VPSUBBYrm,          0 }, | 
|  | 1566 | { X86::VPSUBDYrr,         X86::VPSUBDYrm,          0 }, | 
| Simon Pilgrim | d142ab7 | 2015-02-10 13:22:57 +0000 | [diff] [blame] | 1567 | { X86::VPSUBQYrr,         X86::VPSUBQYrm,          0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1568 | { X86::VPSUBSBYrr,        X86::VPSUBSBYrm,         0 }, | 
|  | 1569 | { X86::VPSUBSWYrr,        X86::VPSUBSWYrm,         0 }, | 
| Simon Pilgrim | d142ab7 | 2015-02-10 13:22:57 +0000 | [diff] [blame] | 1570 | { X86::VPSUBUSBYrr,       X86::VPSUBUSBYrm,        0 }, | 
|  | 1571 | { X86::VPSUBUSWYrr,       X86::VPSUBUSWYrm,        0 }, | 
| Nadav Rotem | dc0ad92 | 2012-12-24 09:40:33 +0000 | [diff] [blame] | 1572 | { X86::VPSUBWYrr,         X86::VPSUBWYrm,          0 }, | 
|  | 1573 | { X86::VPUNPCKHBWYrr,     X86::VPUNPCKHBWYrm,      0 }, | 
|  | 1574 | { X86::VPUNPCKHDQYrr,     X86::VPUNPCKHDQYrm,      0 }, | 
|  | 1575 | { X86::VPUNPCKHQDQYrr,    X86::VPUNPCKHQDQYrm,     0 }, | 
|  | 1576 | { X86::VPUNPCKHWDYrr,     X86::VPUNPCKHWDYrm,      0 }, | 
|  | 1577 | { X86::VPUNPCKLBWYrr,     X86::VPUNPCKLBWYrm,      0 }, | 
|  | 1578 | { X86::VPUNPCKLDQYrr,     X86::VPUNPCKLDQYrm,      0 }, | 
|  | 1579 | { X86::VPUNPCKLQDQYrr,    X86::VPUNPCKLQDQYrm,     0 }, | 
|  | 1580 | { X86::VPUNPCKLWDYrr,     X86::VPUNPCKLWDYrm,      0 }, | 
|  | 1581 | { X86::VPXORYrr,          X86::VPXORYrm,           0 }, | 
| Craig Topper | 908e685 | 2012-08-31 23:10:34 +0000 | [diff] [blame] | 1582 |  | 
|  | 1583 | // FMA4 foldable patterns | 
| Simon Pilgrim | 616fe50 | 2015-06-22 21:49:41 +0000 | [diff] [blame] | 1584 | { X86::VFMADDSS4rr,       X86::VFMADDSS4mr,        TB_ALIGN_NONE }, | 
|  | 1585 | { X86::VFMADDSD4rr,       X86::VFMADDSD4mr,        TB_ALIGN_NONE }, | 
|  | 1586 | { X86::VFMADDPS4rr,       X86::VFMADDPS4mr,        TB_ALIGN_NONE }, | 
|  | 1587 | { X86::VFMADDPD4rr,       X86::VFMADDPD4mr,        TB_ALIGN_NONE }, | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 1588 | { X86::VFMADDPS4Yrr,      X86::VFMADDPS4Ymr,       TB_ALIGN_NONE }, | 
|  | 1589 | { X86::VFMADDPD4Yrr,      X86::VFMADDPD4Ymr,       TB_ALIGN_NONE }, | 
| Simon Pilgrim | 616fe50 | 2015-06-22 21:49:41 +0000 | [diff] [blame] | 1590 | { X86::VFNMADDSS4rr,      X86::VFNMADDSS4mr,       TB_ALIGN_NONE }, | 
|  | 1591 | { X86::VFNMADDSD4rr,      X86::VFNMADDSD4mr,       TB_ALIGN_NONE }, | 
|  | 1592 | { X86::VFNMADDPS4rr,      X86::VFNMADDPS4mr,       TB_ALIGN_NONE }, | 
|  | 1593 | { X86::VFNMADDPD4rr,      X86::VFNMADDPD4mr,       TB_ALIGN_NONE }, | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 1594 | { X86::VFNMADDPS4Yrr,     X86::VFNMADDPS4Ymr,      TB_ALIGN_NONE }, | 
|  | 1595 | { X86::VFNMADDPD4Yrr,     X86::VFNMADDPD4Ymr,      TB_ALIGN_NONE }, | 
| Simon Pilgrim | 616fe50 | 2015-06-22 21:49:41 +0000 | [diff] [blame] | 1596 | { X86::VFMSUBSS4rr,       X86::VFMSUBSS4mr,        TB_ALIGN_NONE }, | 
|  | 1597 | { X86::VFMSUBSD4rr,       X86::VFMSUBSD4mr,        TB_ALIGN_NONE }, | 
|  | 1598 | { X86::VFMSUBPS4rr,       X86::VFMSUBPS4mr,        TB_ALIGN_NONE }, | 
|  | 1599 | { X86::VFMSUBPD4rr,       X86::VFMSUBPD4mr,        TB_ALIGN_NONE }, | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 1600 | { X86::VFMSUBPS4Yrr,      X86::VFMSUBPS4Ymr,       TB_ALIGN_NONE }, | 
|  | 1601 | { X86::VFMSUBPD4Yrr,      X86::VFMSUBPD4Ymr,       TB_ALIGN_NONE }, | 
| Simon Pilgrim | 616fe50 | 2015-06-22 21:49:41 +0000 | [diff] [blame] | 1602 | { X86::VFNMSUBSS4rr,      X86::VFNMSUBSS4mr,       TB_ALIGN_NONE }, | 
|  | 1603 | { X86::VFNMSUBSD4rr,      X86::VFNMSUBSD4mr,       TB_ALIGN_NONE }, | 
|  | 1604 | { X86::VFNMSUBPS4rr,      X86::VFNMSUBPS4mr,       TB_ALIGN_NONE }, | 
|  | 1605 | { X86::VFNMSUBPD4rr,      X86::VFNMSUBPD4mr,       TB_ALIGN_NONE }, | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 1606 | { X86::VFNMSUBPS4Yrr,     X86::VFNMSUBPS4Ymr,      TB_ALIGN_NONE }, | 
|  | 1607 | { X86::VFNMSUBPD4Yrr,     X86::VFNMSUBPD4Ymr,      TB_ALIGN_NONE }, | 
| Simon Pilgrim | 616fe50 | 2015-06-22 21:49:41 +0000 | [diff] [blame] | 1608 | { X86::VFMADDSUBPS4rr,    X86::VFMADDSUBPS4mr,     TB_ALIGN_NONE }, | 
|  | 1609 | { X86::VFMADDSUBPD4rr,    X86::VFMADDSUBPD4mr,     TB_ALIGN_NONE }, | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 1610 | { X86::VFMADDSUBPS4Yrr,   X86::VFMADDSUBPS4Ymr,    TB_ALIGN_NONE }, | 
|  | 1611 | { X86::VFMADDSUBPD4Yrr,   X86::VFMADDSUBPD4Ymr,    TB_ALIGN_NONE }, | 
| Simon Pilgrim | 616fe50 | 2015-06-22 21:49:41 +0000 | [diff] [blame] | 1612 | { X86::VFMSUBADDPS4rr,    X86::VFMSUBADDPS4mr,     TB_ALIGN_NONE }, | 
|  | 1613 | { X86::VFMSUBADDPD4rr,    X86::VFMSUBADDPD4mr,     TB_ALIGN_NONE }, | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 1614 | { X86::VFMSUBADDPS4Yrr,   X86::VFMSUBADDPS4Ymr,    TB_ALIGN_NONE }, | 
|  | 1615 | { X86::VFMSUBADDPD4Yrr,   X86::VFMSUBADDPD4Ymr,    TB_ALIGN_NONE }, | 
| Michael Liao | f9f7b55 | 2012-09-26 08:22:37 +0000 | [diff] [blame] | 1616 |  | 
| Simon Pilgrim | cd32254 | 2015-02-10 12:57:17 +0000 | [diff] [blame] | 1617 | // XOP foldable instructions | 
| Simon Pilgrim | a6ba27f | 2016-03-24 16:31:30 +0000 | [diff] [blame] | 1618 | { X86::VPCMOVrrr,         X86::VPCMOVrmr,           0 }, | 
|  | 1619 | { X86::VPCMOVrrrY,        X86::VPCMOVrmrY,          0 }, | 
| Simon Pilgrim | cd32254 | 2015-02-10 12:57:17 +0000 | [diff] [blame] | 1620 | { X86::VPCOMBri,          X86::VPCOMBmi,            0 }, | 
|  | 1621 | { X86::VPCOMDri,          X86::VPCOMDmi,            0 }, | 
|  | 1622 | { X86::VPCOMQri,          X86::VPCOMQmi,            0 }, | 
|  | 1623 | { X86::VPCOMWri,          X86::VPCOMWmi,            0 }, | 
|  | 1624 | { X86::VPCOMUBri,         X86::VPCOMUBmi,           0 }, | 
|  | 1625 | { X86::VPCOMUDri,         X86::VPCOMUDmi,           0 }, | 
|  | 1626 | { X86::VPCOMUQri,         X86::VPCOMUQmi,           0 }, | 
|  | 1627 | { X86::VPCOMUWri,         X86::VPCOMUWmi,           0 }, | 
|  | 1628 | { X86::VPERMIL2PDrr,      X86::VPERMIL2PDmr,        0 }, | 
|  | 1629 | { X86::VPERMIL2PDrrY,     X86::VPERMIL2PDmrY,       0 }, | 
|  | 1630 | { X86::VPERMIL2PSrr,      X86::VPERMIL2PSmr,        0 }, | 
|  | 1631 | { X86::VPERMIL2PSrrY,     X86::VPERMIL2PSmrY,       0 }, | 
|  | 1632 | { X86::VPMACSDDrr,        X86::VPMACSDDrm,          0 }, | 
|  | 1633 | { X86::VPMACSDQHrr,       X86::VPMACSDQHrm,         0 }, | 
|  | 1634 | { X86::VPMACSDQLrr,       X86::VPMACSDQLrm,         0 }, | 
|  | 1635 | { X86::VPMACSSDDrr,       X86::VPMACSSDDrm,         0 }, | 
|  | 1636 | { X86::VPMACSSDQHrr,      X86::VPMACSSDQHrm,        0 }, | 
|  | 1637 | { X86::VPMACSSDQLrr,      X86::VPMACSSDQLrm,        0 }, | 
|  | 1638 | { X86::VPMACSSWDrr,       X86::VPMACSSWDrm,         0 }, | 
|  | 1639 | { X86::VPMACSSWWrr,       X86::VPMACSSWWrm,         0 }, | 
|  | 1640 | { X86::VPMACSWDrr,        X86::VPMACSWDrm,          0 }, | 
|  | 1641 | { X86::VPMACSWWrr,        X86::VPMACSWWrm,          0 }, | 
|  | 1642 | { X86::VPMADCSSWDrr,      X86::VPMADCSSWDrm,        0 }, | 
|  | 1643 | { X86::VPMADCSWDrr,       X86::VPMADCSWDrm,         0 }, | 
| Simon Pilgrim | a6ba27f | 2016-03-24 16:31:30 +0000 | [diff] [blame] | 1644 | { X86::VPPERMrrr,         X86::VPPERMrmr,           0 }, | 
| Simon Pilgrim | cd32254 | 2015-02-10 12:57:17 +0000 | [diff] [blame] | 1645 | { X86::VPROTBrr,          X86::VPROTBrm,            0 }, | 
|  | 1646 | { X86::VPROTDrr,          X86::VPROTDrm,            0 }, | 
|  | 1647 | { X86::VPROTQrr,          X86::VPROTQrm,            0 }, | 
|  | 1648 | { X86::VPROTWrr,          X86::VPROTWrm,            0 }, | 
|  | 1649 | { X86::VPSHABrr,          X86::VPSHABrm,            0 }, | 
|  | 1650 | { X86::VPSHADrr,          X86::VPSHADrm,            0 }, | 
|  | 1651 | { X86::VPSHAQrr,          X86::VPSHAQrm,            0 }, | 
|  | 1652 | { X86::VPSHAWrr,          X86::VPSHAWrm,            0 }, | 
|  | 1653 | { X86::VPSHLBrr,          X86::VPSHLBrm,            0 }, | 
|  | 1654 | { X86::VPSHLDrr,          X86::VPSHLDrm,            0 }, | 
|  | 1655 | { X86::VPSHLQrr,          X86::VPSHLQrm,            0 }, | 
|  | 1656 | { X86::VPSHLWrr,          X86::VPSHLWrm,            0 }, | 
|  | 1657 |  | 
| Michael Liao | f9f7b55 | 2012-09-26 08:22:37 +0000 | [diff] [blame] | 1658 | // BMI/BMI2 foldable instructions | 
| Craig Topper | f924a58 | 2012-12-17 05:02:29 +0000 | [diff] [blame] | 1659 | { X86::ANDN32rr,          X86::ANDN32rm,            0 }, | 
|  | 1660 | { X86::ANDN64rr,          X86::ANDN64rm,            0 }, | 
| Michael Liao | f9f7b55 | 2012-09-26 08:22:37 +0000 | [diff] [blame] | 1661 | { X86::MULX32rr,          X86::MULX32rm,            0 }, | 
|  | 1662 | { X86::MULX64rr,          X86::MULX64rm,            0 }, | 
| Craig Topper | f924a58 | 2012-12-17 05:02:29 +0000 | [diff] [blame] | 1663 | { X86::PDEP32rr,          X86::PDEP32rm,            0 }, | 
|  | 1664 | { X86::PDEP64rr,          X86::PDEP64rm,            0 }, | 
|  | 1665 | { X86::PEXT32rr,          X86::PEXT32rm,            0 }, | 
|  | 1666 | { X86::PEXT64rr,          X86::PEXT64rm,            0 }, | 
| Elena Demikhovsky | cf5b145 | 2013-08-11 07:55:09 +0000 | [diff] [blame] | 1667 |  | 
| Simon Pilgrim | 4ba5969 | 2015-12-05 07:27:50 +0000 | [diff] [blame] | 1668 | // ADX foldable instructions | 
|  | 1669 | { X86::ADCX32rr,          X86::ADCX32rm,            0 }, | 
|  | 1670 | { X86::ADCX64rr,          X86::ADCX64rm,            0 }, | 
|  | 1671 | { X86::ADOX32rr,          X86::ADOX32rm,            0 }, | 
|  | 1672 | { X86::ADOX64rr,          X86::ADOX64rm,            0 }, | 
|  | 1673 |  | 
| Elena Demikhovsky | cf5b145 | 2013-08-11 07:55:09 +0000 | [diff] [blame] | 1674 | // AVX-512 foldable instructions | 
| Elena Demikhovsky | 534015e | 2013-09-02 07:12:29 +0000 | [diff] [blame] | 1675 | { X86::VADDPSZrr,         X86::VADDPSZrm,           0 }, | 
|  | 1676 | { X86::VADDPDZrr,         X86::VADDPDZrm,           0 }, | 
| Craig Topper | a3c55f5 | 2016-07-18 06:49:32 +0000 | [diff] [blame] | 1677 | { X86::VADDSSZrr,         X86::VADDSSZrm,           0 }, | 
|  | 1678 | { X86::VADDSSZrr_Int,     X86::VADDSSZrm_Int,       0 }, | 
|  | 1679 | { X86::VADDSDZrr,         X86::VADDSDZrm,           0 }, | 
|  | 1680 | { X86::VADDSDZrr_Int,     X86::VADDSDZrm_Int,       0 }, | 
| Elena Demikhovsky | 534015e | 2013-09-02 07:12:29 +0000 | [diff] [blame] | 1681 | { X86::VSUBPSZrr,         X86::VSUBPSZrm,           0 }, | 
|  | 1682 | { X86::VSUBPDZrr,         X86::VSUBPDZrm,           0 }, | 
| Craig Topper | a3c55f5 | 2016-07-18 06:49:32 +0000 | [diff] [blame] | 1683 | { X86::VSUBSSZrr,         X86::VSUBSSZrm,           0 }, | 
|  | 1684 | { X86::VSUBSSZrr_Int,     X86::VSUBSSZrm_Int,       0 }, | 
|  | 1685 | { X86::VSUBSDZrr,         X86::VSUBSDZrm,           0 }, | 
|  | 1686 | { X86::VSUBSDZrr_Int,     X86::VSUBSDZrm_Int,       0 }, | 
| Elena Demikhovsky | 534015e | 2013-09-02 07:12:29 +0000 | [diff] [blame] | 1687 | { X86::VMULPSZrr,         X86::VMULPSZrm,           0 }, | 
|  | 1688 | { X86::VMULPDZrr,         X86::VMULPDZrm,           0 }, | 
| Craig Topper | a3c55f5 | 2016-07-18 06:49:32 +0000 | [diff] [blame] | 1689 | { X86::VMULSSZrr,         X86::VMULSSZrm,           0 }, | 
|  | 1690 | { X86::VMULSSZrr_Int,     X86::VMULSSZrm_Int,       0 }, | 
|  | 1691 | { X86::VMULSDZrr,         X86::VMULSDZrm,           0 }, | 
|  | 1692 | { X86::VMULSDZrr_Int,     X86::VMULSDZrm_Int,       0 }, | 
| Elena Demikhovsky | 534015e | 2013-09-02 07:12:29 +0000 | [diff] [blame] | 1693 | { X86::VDIVPSZrr,         X86::VDIVPSZrm,           0 }, | 
|  | 1694 | { X86::VDIVPDZrr,         X86::VDIVPDZrm,           0 }, | 
| Craig Topper | a3c55f5 | 2016-07-18 06:49:32 +0000 | [diff] [blame] | 1695 | { X86::VDIVSSZrr,         X86::VDIVSSZrm,           0 }, | 
|  | 1696 | { X86::VDIVSSZrr_Int,     X86::VDIVSSZrm_Int,       0 }, | 
|  | 1697 | { X86::VDIVSDZrr,         X86::VDIVSDZrm,           0 }, | 
|  | 1698 | { X86::VDIVSDZrr_Int,     X86::VDIVSDZrm_Int,       0 }, | 
| Craig Topper | 2c51c74 | 2016-08-07 17:14:09 +0000 | [diff] [blame] | 1699 | { X86::VANDPDZrr,         X86::VANDPDZrm,           0 }, | 
|  | 1700 | { X86::VANDPSZrr,         X86::VANDPSZrm,           0 }, | 
|  | 1701 | { X86::VANDNPDZrr,        X86::VANDNPDZrm,          0 }, | 
|  | 1702 | { X86::VANDNPSZrr,        X86::VANDNPSZrm,          0 }, | 
|  | 1703 | { X86::VORPDZrr,          X86::VORPDZrm,            0 }, | 
|  | 1704 | { X86::VORPSZrr,          X86::VORPSZrm,            0 }, | 
|  | 1705 | { X86::VXORPDZrr,         X86::VXORPDZrm,           0 }, | 
|  | 1706 | { X86::VXORPSZrr,         X86::VXORPSZrm,           0 }, | 
|  | 1707 | { X86::VPANDDZrr,         X86::VPANDDZrm,           0 }, | 
|  | 1708 | { X86::VPANDQZrr,         X86::VPANDQZrm,           0 }, | 
|  | 1709 | { X86::VPANDNDZrr,        X86::VPANDNDZrm,          0 }, | 
|  | 1710 | { X86::VPANDNQZrr,        X86::VPANDNQZrm,          0 }, | 
|  | 1711 | { X86::VPORDZrr,          X86::VPORDZrm,            0 }, | 
|  | 1712 | { X86::VPORQZrr,          X86::VPORQZrm,            0 }, | 
|  | 1713 | { X86::VPXORDZrr,         X86::VPXORDZrm,           0 }, | 
|  | 1714 | { X86::VPXORQZrr,         X86::VPXORQZrm,           0 }, | 
| Elena Demikhovsky | 534015e | 2013-09-02 07:12:29 +0000 | [diff] [blame] | 1715 | { X86::VMAXPDZrr,         X86::VMAXPDZrm,           0 }, | 
| Craig Topper | 938e7ab | 2016-08-07 17:14:05 +0000 | [diff] [blame] | 1716 | { X86::VMAXCPDZrr,        X86::VMAXCPDZrm,          0 }, | 
|  | 1717 | { X86::VMAXPSZrr,         X86::VMAXPSZrm,           0 }, | 
|  | 1718 | { X86::VMAXCPSZrr,        X86::VMAXCPSZrm,          0 }, | 
|  | 1719 | { X86::VMAXSDZrr,         X86::VMAXSDZrm,           0 }, | 
|  | 1720 | { X86::VMAXCSDZrr,        X86::VMAXCSDZrm,          0 }, | 
|  | 1721 | { X86::VMAXSDZrr_Int,     X86::VMAXSDZrm_Int,       0 }, | 
|  | 1722 | { X86::VMAXSSZrr,         X86::VMAXSSZrm,           0 }, | 
|  | 1723 | { X86::VMAXCSSZrr,        X86::VMAXCSSZrm,          0 }, | 
|  | 1724 | { X86::VMAXSSZrr_Int,     X86::VMAXSSZrm_Int,       0 }, | 
|  | 1725 | { X86::VMINPDZrr,         X86::VMINPDZrm,           0 }, | 
|  | 1726 | { X86::VMINCPDZrr,        X86::VMINCPDZrm,          0 }, | 
|  | 1727 | { X86::VMINPSZrr,         X86::VMINPSZrm,           0 }, | 
|  | 1728 | { X86::VMINCPSZrr,        X86::VMINCPSZrm,          0 }, | 
|  | 1729 | { X86::VMINSDZrr,         X86::VMINSDZrm,           0 }, | 
|  | 1730 | { X86::VMINCSDZrr,        X86::VMINCSDZrm,          0 }, | 
|  | 1731 | { X86::VMINSDZrr_Int,     X86::VMINSDZrm_Int,       0 }, | 
|  | 1732 | { X86::VMINSSZrr,         X86::VMINSSZrm,           0 }, | 
|  | 1733 | { X86::VMINCSSZrr,        X86::VMINCSSZrm,          0 }, | 
|  | 1734 | { X86::VMINSSZrr_Int,     X86::VMINSSZrm_Int,       0 }, | 
| Elena Demikhovsky | bb2f6b7 | 2014-03-27 09:45:08 +0000 | [diff] [blame] | 1735 | { X86::VPADDDZrr,         X86::VPADDDZrm,           0 }, | 
|  | 1736 | { X86::VPADDQZrr,         X86::VPADDQZrm,           0 }, | 
| Elena Demikhovsky | cf5b145 | 2013-08-11 07:55:09 +0000 | [diff] [blame] | 1737 | { X86::VPERMPDZri,        X86::VPERMPDZmi,          0 }, | 
|  | 1738 | { X86::VPERMPSZrr,        X86::VPERMPSZrm,          0 }, | 
| Elena Demikhovsky | bb2f6b7 | 2014-03-27 09:45:08 +0000 | [diff] [blame] | 1739 | { X86::VPMAXSDZrr,        X86::VPMAXSDZrm,          0 }, | 
|  | 1740 | { X86::VPMAXSQZrr,        X86::VPMAXSQZrm,          0 }, | 
|  | 1741 | { X86::VPMAXUDZrr,        X86::VPMAXUDZrm,          0 }, | 
|  | 1742 | { X86::VPMAXUQZrr,        X86::VPMAXUQZrm,          0 }, | 
|  | 1743 | { X86::VPMINSDZrr,        X86::VPMINSDZrm,          0 }, | 
|  | 1744 | { X86::VPMINSQZrr,        X86::VPMINSQZrm,          0 }, | 
|  | 1745 | { X86::VPMINUDZrr,        X86::VPMINUDZrm,          0 }, | 
|  | 1746 | { X86::VPMINUQZrr,        X86::VPMINUQZrm,          0 }, | 
|  | 1747 | { X86::VPMULDQZrr,        X86::VPMULDQZrm,          0 }, | 
| Elena Demikhovsky | 534015e | 2013-09-02 07:12:29 +0000 | [diff] [blame] | 1748 | { X86::VPSLLVDZrr,        X86::VPSLLVDZrm,          0 }, | 
|  | 1749 | { X86::VPSLLVQZrr,        X86::VPSLLVQZrm,          0 }, | 
|  | 1750 | { X86::VPSRAVDZrr,        X86::VPSRAVDZrm,          0 }, | 
|  | 1751 | { X86::VPSRLVDZrr,        X86::VPSRLVDZrm,          0 }, | 
|  | 1752 | { X86::VPSRLVQZrr,        X86::VPSRLVQZrm,          0 }, | 
| Elena Demikhovsky | bb2f6b7 | 2014-03-27 09:45:08 +0000 | [diff] [blame] | 1753 | { X86::VPSUBDZrr,         X86::VPSUBDZrm,           0 }, | 
|  | 1754 | { X86::VPSUBQZrr,         X86::VPSUBQZrm,           0 }, | 
| Elena Demikhovsky | 534015e | 2013-09-02 07:12:29 +0000 | [diff] [blame] | 1755 | { X86::VSHUFPDZrri,       X86::VSHUFPDZrmi,         0 }, | 
|  | 1756 | { X86::VSHUFPSZrri,       X86::VSHUFPSZrmi,         0 }, | 
| Igor Breger | 00d9f84 | 2015-06-08 14:03:17 +0000 | [diff] [blame] | 1757 | { X86::VALIGNQZrri,       X86::VALIGNQZrmi,         0 }, | 
|  | 1758 | { X86::VALIGNDZrri,       X86::VALIGNDZrmi,         0 }, | 
| Elena Demikhovsky | bb2f6b7 | 2014-03-27 09:45:08 +0000 | [diff] [blame] | 1759 | { X86::VPMULUDQZrr,       X86::VPMULUDQZrm,         0 }, | 
| Robert Khasanov | 8e8c399 | 2014-12-09 18:45:30 +0000 | [diff] [blame] | 1760 | { X86::VBROADCASTSSZrkz,  X86::VBROADCASTSSZmkz,    TB_NO_REVERSE }, | 
|  | 1761 | { X86::VBROADCASTSDZrkz,  X86::VBROADCASTSDZmkz,    TB_NO_REVERSE }, | 
|  | 1762 |  | 
|  | 1763 | // AVX-512{F,VL} foldable instructions | 
|  | 1764 | { X86::VBROADCASTSSZ256rkz,  X86::VBROADCASTSSZ256mkz,      TB_NO_REVERSE }, | 
|  | 1765 | { X86::VBROADCASTSDZ256rkz,  X86::VBROADCASTSDZ256mkz,      TB_NO_REVERSE }, | 
|  | 1766 | { X86::VBROADCASTSSZ128rkz,  X86::VBROADCASTSSZ128mkz,      TB_NO_REVERSE }, | 
| Craig Topper | 514f02c | 2013-09-17 06:50:11 +0000 | [diff] [blame] | 1767 |  | 
| Robert Khasanov | 79fb729 | 2014-12-18 12:28:22 +0000 | [diff] [blame] | 1768 | // AVX-512{F,VL} foldable instructions | 
|  | 1769 | { X86::VADDPDZ128rr,      X86::VADDPDZ128rm,        0 }, | 
|  | 1770 | { X86::VADDPDZ256rr,      X86::VADDPDZ256rm,        0 }, | 
|  | 1771 | { X86::VADDPSZ128rr,      X86::VADDPSZ128rm,        0 }, | 
|  | 1772 | { X86::VADDPSZ256rr,      X86::VADDPSZ256rm,        0 }, | 
| Craig Topper | 0b90756 | 2016-07-22 05:00:39 +0000 | [diff] [blame] | 1773 | { X86::VANDPDZ128rr,      X86::VANDPDZ128rm,        0 }, | 
|  | 1774 | { X86::VANDPDZ256rr,      X86::VANDPDZ256rm,        0 }, | 
|  | 1775 | { X86::VANDPSZ128rr,      X86::VANDPSZ128rm,        0 }, | 
|  | 1776 | { X86::VANDPSZ256rr,      X86::VANDPSZ256rm,        0 }, | 
|  | 1777 | { X86::VANDNPDZ128rr,     X86::VANDNPDZ128rm,       0 }, | 
|  | 1778 | { X86::VANDNPDZ256rr,     X86::VANDNPDZ256rm,       0 }, | 
|  | 1779 | { X86::VANDNPSZ128rr,     X86::VANDNPSZ128rm,       0 }, | 
|  | 1780 | { X86::VANDNPSZ256rr,     X86::VANDNPSZ256rm,       0 }, | 
|  | 1781 | { X86::VORPDZ128rr,       X86::VORPDZ128rm,         0 }, | 
|  | 1782 | { X86::VORPDZ256rr,       X86::VORPDZ256rm,         0 }, | 
|  | 1783 | { X86::VORPSZ128rr,       X86::VORPSZ128rm,         0 }, | 
|  | 1784 | { X86::VORPSZ256rr,       X86::VORPSZ256rm,         0 }, | 
|  | 1785 | { X86::VPANDDZ128rr,      X86::VPANDDZ128rm,        0 }, | 
|  | 1786 | { X86::VPANDDZ256rr,      X86::VPANDDZ256rm,        0 }, | 
|  | 1787 | { X86::VPANDQZ128rr,      X86::VPANDQZ128rm,        0 }, | 
|  | 1788 | { X86::VPANDQZ256rr,      X86::VPANDQZ256rm,        0 }, | 
|  | 1789 | { X86::VPANDNDZ128rr,     X86::VPANDNDZ128rm,       0 }, | 
|  | 1790 | { X86::VPANDNDZ256rr,     X86::VPANDNDZ256rm,       0 }, | 
|  | 1791 | { X86::VPANDNQZ128rr,     X86::VPANDNQZ128rm,       0 }, | 
|  | 1792 | { X86::VPANDNQZ256rr,     X86::VPANDNQZ256rm,       0 }, | 
|  | 1793 | { X86::VPORDZ128rr,       X86::VPORDZ128rm,         0 }, | 
|  | 1794 | { X86::VPORDZ256rr,       X86::VPORDZ256rm,         0 }, | 
|  | 1795 | { X86::VPORQZ128rr,       X86::VPORQZ128rm,         0 }, | 
|  | 1796 | { X86::VPORQZ256rr,       X86::VPORQZ256rm,         0 }, | 
|  | 1797 | { X86::VPXORDZ128rr,      X86::VPXORDZ128rm,        0 }, | 
|  | 1798 | { X86::VPXORDZ256rr,      X86::VPXORDZ256rm,        0 }, | 
|  | 1799 | { X86::VPXORQZ128rr,      X86::VPXORQZ128rm,        0 }, | 
|  | 1800 | { X86::VPXORQZ256rr,      X86::VPXORQZ256rm,        0 }, | 
|  | 1801 | { X86::VSUBPDZ128rr,      X86::VSUBPDZ128rm,        0 }, | 
|  | 1802 | { X86::VSUBPDZ256rr,      X86::VSUBPDZ256rm,        0 }, | 
|  | 1803 | { X86::VSUBPSZ128rr,      X86::VSUBPSZ128rm,        0 }, | 
|  | 1804 | { X86::VSUBPSZ256rr,      X86::VSUBPSZ256rm,        0 }, | 
|  | 1805 | { X86::VXORPDZ128rr,      X86::VXORPDZ128rm,        0 }, | 
|  | 1806 | { X86::VXORPDZ256rr,      X86::VXORPDZ256rm,        0 }, | 
|  | 1807 | { X86::VXORPSZ128rr,      X86::VXORPSZ128rm,        0 }, | 
|  | 1808 | { X86::VXORPSZ256rr,      X86::VXORPSZ256rm,        0 }, | 
| Craig Topper | 938e7ab | 2016-08-07 17:14:05 +0000 | [diff] [blame] | 1809 | { X86::VMAXPDZ128rr,      X86::VMAXPDZ128rm,        0 }, | 
|  | 1810 | { X86::VMAXPDZ256rr,      X86::VMAXPDZ256rm,        0 }, | 
|  | 1811 | { X86::VMAXCPDZ128rr,     X86::VMAXCPDZ128rm,       0 }, | 
|  | 1812 | { X86::VMAXCPDZ256rr,     X86::VMAXCPDZ256rm,       0 }, | 
|  | 1813 | { X86::VMAXPSZ128rr,      X86::VMAXPSZ128rm,        0 }, | 
|  | 1814 | { X86::VMAXPSZ256rr,      X86::VMAXPSZ256rm,        0 }, | 
|  | 1815 | { X86::VMAXCPSZ128rr,     X86::VMAXCPSZ128rm,       0 }, | 
|  | 1816 | { X86::VMAXCPSZ256rr,     X86::VMAXCPSZ256rm,       0 }, | 
|  | 1817 | { X86::VMINPDZ128rr,      X86::VMINPDZ128rm,        0 }, | 
|  | 1818 | { X86::VMINPDZ256rr,      X86::VMINPDZ256rm,        0 }, | 
|  | 1819 | { X86::VMINCPDZ128rr,     X86::VMINCPDZ128rm,       0 }, | 
|  | 1820 | { X86::VMINCPDZ256rr,     X86::VMINCPDZ256rm,       0 }, | 
|  | 1821 | { X86::VMINPSZ128rr,      X86::VMINPSZ128rm,        0 }, | 
|  | 1822 | { X86::VMINPSZ256rr,      X86::VMINPSZ256rm,        0 }, | 
|  | 1823 | { X86::VMINCPSZ128rr,     X86::VMINCPSZ128rm,       0 }, | 
|  | 1824 | { X86::VMINCPSZ256rr,     X86::VMINCPSZ256rm,       0 }, | 
| Robert Khasanov | 79fb729 | 2014-12-18 12:28:22 +0000 | [diff] [blame] | 1825 |  | 
| Craig Topper | 514f02c | 2013-09-17 06:50:11 +0000 | [diff] [blame] | 1826 | // AES foldable instructions | 
|  | 1827 | { X86::AESDECLASTrr,      X86::AESDECLASTrm,        TB_ALIGN_16 }, | 
|  | 1828 | { X86::AESDECrr,          X86::AESDECrm,            TB_ALIGN_16 }, | 
|  | 1829 | { X86::AESENCLASTrr,      X86::AESENCLASTrm,        TB_ALIGN_16 }, | 
|  | 1830 | { X86::AESENCrr,          X86::AESENCrm,            TB_ALIGN_16 }, | 
| Craig Topper | f7e92f1 | 2015-02-10 05:10:50 +0000 | [diff] [blame] | 1831 | { X86::VAESDECLASTrr,     X86::VAESDECLASTrm,       0 }, | 
|  | 1832 | { X86::VAESDECrr,         X86::VAESDECrm,           0 }, | 
|  | 1833 | { X86::VAESENCLASTrr,     X86::VAESENCLASTrm,       0 }, | 
|  | 1834 | { X86::VAESENCrr,         X86::VAESENCrm,           0 }, | 
| Craig Topper | 514f02c | 2013-09-17 06:50:11 +0000 | [diff] [blame] | 1835 |  | 
|  | 1836 | // SHA foldable instructions | 
|  | 1837 | { X86::SHA1MSG1rr,        X86::SHA1MSG1rm,          TB_ALIGN_16 }, | 
|  | 1838 | { X86::SHA1MSG2rr,        X86::SHA1MSG2rm,          TB_ALIGN_16 }, | 
|  | 1839 | { X86::SHA1NEXTErr,       X86::SHA1NEXTErm,         TB_ALIGN_16 }, | 
|  | 1840 | { X86::SHA1RNDS4rri,      X86::SHA1RNDS4rmi,        TB_ALIGN_16 }, | 
|  | 1841 | { X86::SHA256MSG1rr,      X86::SHA256MSG1rm,        TB_ALIGN_16 }, | 
|  | 1842 | { X86::SHA256MSG2rr,      X86::SHA256MSG2rm,        TB_ALIGN_16 }, | 
| Simon Pilgrim | cd32254 | 2015-02-10 12:57:17 +0000 | [diff] [blame] | 1843 | { X86::SHA256RNDS2rr,     X86::SHA256RNDS2rm,       TB_ALIGN_16 } | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 1844 | }; | 
|  | 1845 |  | 
| Sanjay Patel | cf0a807 | 2015-07-07 15:03:53 +0000 | [diff] [blame] | 1846 | for (X86MemoryFoldTableEntry Entry : MemoryFoldTable2) { | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1847 | AddTableEntry(RegOp2MemOpTable2, MemOp2RegOpTable, | 
| Sanjay Patel | cf0a807 | 2015-07-07 15:03:53 +0000 | [diff] [blame] | 1848 | Entry.RegOp, Entry.MemOp, | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 1849 | // Index 2, folded load | 
| Sanjay Patel | cf0a807 | 2015-07-07 15:03:53 +0000 | [diff] [blame] | 1850 | Entry.Flags | TB_INDEX_2 | TB_FOLDED_LOAD); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 1851 | } | 
| Elena Demikhovsky | 602f3a2 | 2012-05-31 09:20:20 +0000 | [diff] [blame] | 1852 |  | 
| Sanjay Patel | e951a38 | 2015-02-17 22:38:06 +0000 | [diff] [blame] | 1853 | static const X86MemoryFoldTableEntry MemoryFoldTable3[] = { | 
| Elena Demikhovsky | 602f3a2 | 2012-05-31 09:20:20 +0000 | [diff] [blame] | 1854 | // FMA foldable instructions | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 1855 | { X86::VFMADD231SSr,          X86::VFMADD231SSm,          TB_ALIGN_NONE }, | 
|  | 1856 | { X86::VFMADD231SSr_Int,      X86::VFMADD231SSm_Int,      TB_ALIGN_NONE }, | 
|  | 1857 | { X86::VFMADD231SDr,          X86::VFMADD231SDm,          TB_ALIGN_NONE }, | 
|  | 1858 | { X86::VFMADD231SDr_Int,      X86::VFMADD231SDm_Int,      TB_ALIGN_NONE }, | 
|  | 1859 | { X86::VFMADD132SSr,          X86::VFMADD132SSm,          TB_ALIGN_NONE }, | 
|  | 1860 | { X86::VFMADD132SSr_Int,      X86::VFMADD132SSm_Int,      TB_ALIGN_NONE }, | 
|  | 1861 | { X86::VFMADD132SDr,          X86::VFMADD132SDm,          TB_ALIGN_NONE }, | 
|  | 1862 | { X86::VFMADD132SDr_Int,      X86::VFMADD132SDm_Int,      TB_ALIGN_NONE }, | 
|  | 1863 | { X86::VFMADD213SSr,          X86::VFMADD213SSm,          TB_ALIGN_NONE }, | 
|  | 1864 | { X86::VFMADD213SSr_Int,      X86::VFMADD213SSm_Int,      TB_ALIGN_NONE }, | 
|  | 1865 | { X86::VFMADD213SDr,          X86::VFMADD213SDm,          TB_ALIGN_NONE }, | 
|  | 1866 | { X86::VFMADD213SDr_Int,      X86::VFMADD213SDm_Int,      TB_ALIGN_NONE }, | 
| Craig Topper | ce415ff | 2016-07-25 07:20:35 +0000 | [diff] [blame] | 1867 | { X86::VFMADD231SSZr,         X86::VFMADD231SSZm,         TB_ALIGN_NONE }, | 
|  | 1868 | { X86::VFMADD231SSZr_Int,     X86::VFMADD231SSZm_Int,     TB_ALIGN_NONE }, | 
|  | 1869 | { X86::VFMADD231SDZr,         X86::VFMADD231SDZm,         TB_ALIGN_NONE }, | 
|  | 1870 | { X86::VFMADD231SDZr_Int,     X86::VFMADD231SDZm_Int,     TB_ALIGN_NONE }, | 
|  | 1871 | { X86::VFMADD132SSZr,         X86::VFMADD132SSZm,         TB_ALIGN_NONE }, | 
|  | 1872 | { X86::VFMADD132SSZr_Int,     X86::VFMADD132SSZm_Int,     TB_ALIGN_NONE }, | 
|  | 1873 | { X86::VFMADD132SDZr,         X86::VFMADD132SDZm,         TB_ALIGN_NONE }, | 
|  | 1874 | { X86::VFMADD132SDZr_Int,     X86::VFMADD132SDZm_Int,     TB_ALIGN_NONE }, | 
|  | 1875 | { X86::VFMADD213SSZr,         X86::VFMADD213SSZm,         TB_ALIGN_NONE }, | 
|  | 1876 | { X86::VFMADD213SSZr_Int,     X86::VFMADD213SSZm_Int,     TB_ALIGN_NONE }, | 
|  | 1877 | { X86::VFMADD213SDZr,         X86::VFMADD213SDZm,         TB_ALIGN_NONE }, | 
|  | 1878 | { X86::VFMADD213SDZr_Int,     X86::VFMADD213SDZm_Int,     TB_ALIGN_NONE }, | 
| Elena Demikhovsky | 602f3a2 | 2012-05-31 09:20:20 +0000 | [diff] [blame] | 1879 |  | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 1880 | { X86::VFMADD231PSr,          X86::VFMADD231PSm,          TB_ALIGN_NONE }, | 
|  | 1881 | { X86::VFMADD231PDr,          X86::VFMADD231PDm,          TB_ALIGN_NONE }, | 
|  | 1882 | { X86::VFMADD132PSr,          X86::VFMADD132PSm,          TB_ALIGN_NONE }, | 
|  | 1883 | { X86::VFMADD132PDr,          X86::VFMADD132PDm,          TB_ALIGN_NONE }, | 
|  | 1884 | { X86::VFMADD213PSr,          X86::VFMADD213PSm,          TB_ALIGN_NONE }, | 
|  | 1885 | { X86::VFMADD213PDr,          X86::VFMADD213PDm,          TB_ALIGN_NONE }, | 
|  | 1886 | { X86::VFMADD231PSYr,         X86::VFMADD231PSYm,         TB_ALIGN_NONE }, | 
|  | 1887 | { X86::VFMADD231PDYr,         X86::VFMADD231PDYm,         TB_ALIGN_NONE }, | 
|  | 1888 | { X86::VFMADD132PSYr,         X86::VFMADD132PSYm,         TB_ALIGN_NONE }, | 
|  | 1889 | { X86::VFMADD132PDYr,         X86::VFMADD132PDYm,         TB_ALIGN_NONE }, | 
|  | 1890 | { X86::VFMADD213PSYr,         X86::VFMADD213PSYm,         TB_ALIGN_NONE }, | 
|  | 1891 | { X86::VFMADD213PDYr,         X86::VFMADD213PDYm,         TB_ALIGN_NONE }, | 
| Craig Topper | ce415ff | 2016-07-25 07:20:35 +0000 | [diff] [blame] | 1892 | { X86::VFMADD231PSZr,         X86::VFMADD231PSZm,         TB_ALIGN_NONE }, | 
|  | 1893 | { X86::VFMADD231PDZr,         X86::VFMADD231PDZm,         TB_ALIGN_NONE }, | 
|  | 1894 | { X86::VFMADD132PSZr,         X86::VFMADD132PSZm,         TB_ALIGN_NONE }, | 
|  | 1895 | { X86::VFMADD132PDZr,         X86::VFMADD132PDZm,         TB_ALIGN_NONE }, | 
|  | 1896 | { X86::VFMADD213PSZr,         X86::VFMADD213PSZm,         TB_ALIGN_NONE }, | 
|  | 1897 | { X86::VFMADD213PDZr,         X86::VFMADD213PDZm,         TB_ALIGN_NONE }, | 
|  | 1898 | { X86::VFMADD231PSZ128r,      X86::VFMADD231PSZ128m,      TB_ALIGN_NONE }, | 
|  | 1899 | { X86::VFMADD231PDZ128r,      X86::VFMADD231PDZ128m,      TB_ALIGN_NONE }, | 
|  | 1900 | { X86::VFMADD132PSZ128r,      X86::VFMADD132PSZ128m,      TB_ALIGN_NONE }, | 
|  | 1901 | { X86::VFMADD132PDZ128r,      X86::VFMADD132PDZ128m,      TB_ALIGN_NONE }, | 
|  | 1902 | { X86::VFMADD213PSZ128r,      X86::VFMADD213PSZ128m,      TB_ALIGN_NONE }, | 
|  | 1903 | { X86::VFMADD213PDZ128r,      X86::VFMADD213PDZ128m,      TB_ALIGN_NONE }, | 
|  | 1904 | { X86::VFMADD231PSZ256r,      X86::VFMADD231PSZ256m,      TB_ALIGN_NONE }, | 
|  | 1905 | { X86::VFMADD231PDZ256r,      X86::VFMADD231PDZ256m,      TB_ALIGN_NONE }, | 
|  | 1906 | { X86::VFMADD132PSZ256r,      X86::VFMADD132PSZ256m,      TB_ALIGN_NONE }, | 
|  | 1907 | { X86::VFMADD132PDZ256r,      X86::VFMADD132PDZ256m,      TB_ALIGN_NONE }, | 
|  | 1908 | { X86::VFMADD213PSZ256r,      X86::VFMADD213PSZ256m,      TB_ALIGN_NONE }, | 
|  | 1909 | { X86::VFMADD213PDZ256r,      X86::VFMADD213PDZ256m,      TB_ALIGN_NONE }, | 
| Elena Demikhovsky | 602f3a2 | 2012-05-31 09:20:20 +0000 | [diff] [blame] | 1910 |  | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 1911 | { X86::VFNMADD231SSr,         X86::VFNMADD231SSm,         TB_ALIGN_NONE }, | 
|  | 1912 | { X86::VFNMADD231SSr_Int,     X86::VFNMADD231SSm_Int,     TB_ALIGN_NONE }, | 
|  | 1913 | { X86::VFNMADD231SDr,         X86::VFNMADD231SDm,         TB_ALIGN_NONE }, | 
|  | 1914 | { X86::VFNMADD231SDr_Int,     X86::VFNMADD231SDm_Int,     TB_ALIGN_NONE }, | 
|  | 1915 | { X86::VFNMADD132SSr,         X86::VFNMADD132SSm,         TB_ALIGN_NONE }, | 
|  | 1916 | { X86::VFNMADD132SSr_Int,     X86::VFNMADD132SSm_Int,     TB_ALIGN_NONE }, | 
|  | 1917 | { X86::VFNMADD132SDr,         X86::VFNMADD132SDm,         TB_ALIGN_NONE }, | 
|  | 1918 | { X86::VFNMADD132SDr_Int,     X86::VFNMADD132SDm_Int,     TB_ALIGN_NONE }, | 
|  | 1919 | { X86::VFNMADD213SSr,         X86::VFNMADD213SSm,         TB_ALIGN_NONE }, | 
|  | 1920 | { X86::VFNMADD213SSr_Int,     X86::VFNMADD213SSm_Int,     TB_ALIGN_NONE }, | 
|  | 1921 | { X86::VFNMADD213SDr,         X86::VFNMADD213SDm,         TB_ALIGN_NONE }, | 
|  | 1922 | { X86::VFNMADD213SDr_Int,     X86::VFNMADD213SDm_Int,     TB_ALIGN_NONE }, | 
| Craig Topper | ce415ff | 2016-07-25 07:20:35 +0000 | [diff] [blame] | 1923 | { X86::VFNMADD231SSZr,        X86::VFNMADD231SSZm,        TB_ALIGN_NONE }, | 
|  | 1924 | { X86::VFNMADD231SSZr_Int,    X86::VFNMADD231SSZm_Int,    TB_ALIGN_NONE }, | 
|  | 1925 | { X86::VFNMADD231SDZr,        X86::VFNMADD231SDZm,        TB_ALIGN_NONE }, | 
|  | 1926 | { X86::VFNMADD231SDZr_Int,    X86::VFNMADD231SDZm_Int,    TB_ALIGN_NONE }, | 
|  | 1927 | { X86::VFNMADD132SSZr,        X86::VFNMADD132SSZm,        TB_ALIGN_NONE }, | 
|  | 1928 | { X86::VFNMADD132SSZr_Int,    X86::VFNMADD132SSZm_Int,    TB_ALIGN_NONE }, | 
|  | 1929 | { X86::VFNMADD132SDZr,        X86::VFNMADD132SDZm,        TB_ALIGN_NONE }, | 
|  | 1930 | { X86::VFNMADD132SDZr_Int,    X86::VFNMADD132SDZm_Int,    TB_ALIGN_NONE }, | 
|  | 1931 | { X86::VFNMADD213SSZr,        X86::VFNMADD213SSZm,        TB_ALIGN_NONE }, | 
|  | 1932 | { X86::VFNMADD213SSZr_Int,    X86::VFNMADD213SSZm_Int,    TB_ALIGN_NONE }, | 
|  | 1933 | { X86::VFNMADD213SDZr,        X86::VFNMADD213SDZm,        TB_ALIGN_NONE }, | 
|  | 1934 | { X86::VFNMADD213SDZr_Int,    X86::VFNMADD213SDZm_Int,    TB_ALIGN_NONE }, | 
| Elena Demikhovsky | 602f3a2 | 2012-05-31 09:20:20 +0000 | [diff] [blame] | 1935 |  | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 1936 | { X86::VFNMADD231PSr,         X86::VFNMADD231PSm,         TB_ALIGN_NONE }, | 
|  | 1937 | { X86::VFNMADD231PDr,         X86::VFNMADD231PDm,         TB_ALIGN_NONE }, | 
|  | 1938 | { X86::VFNMADD132PSr,         X86::VFNMADD132PSm,         TB_ALIGN_NONE }, | 
|  | 1939 | { X86::VFNMADD132PDr,         X86::VFNMADD132PDm,         TB_ALIGN_NONE }, | 
|  | 1940 | { X86::VFNMADD213PSr,         X86::VFNMADD213PSm,         TB_ALIGN_NONE }, | 
|  | 1941 | { X86::VFNMADD213PDr,         X86::VFNMADD213PDm,         TB_ALIGN_NONE }, | 
|  | 1942 | { X86::VFNMADD231PSYr,        X86::VFNMADD231PSYm,        TB_ALIGN_NONE }, | 
|  | 1943 | { X86::VFNMADD231PDYr,        X86::VFNMADD231PDYm,        TB_ALIGN_NONE }, | 
|  | 1944 | { X86::VFNMADD132PSYr,        X86::VFNMADD132PSYm,        TB_ALIGN_NONE }, | 
|  | 1945 | { X86::VFNMADD132PDYr,        X86::VFNMADD132PDYm,        TB_ALIGN_NONE }, | 
|  | 1946 | { X86::VFNMADD213PSYr,        X86::VFNMADD213PSYm,        TB_ALIGN_NONE }, | 
|  | 1947 | { X86::VFNMADD213PDYr,        X86::VFNMADD213PDYm,        TB_ALIGN_NONE }, | 
| Craig Topper | ce415ff | 2016-07-25 07:20:35 +0000 | [diff] [blame] | 1948 | { X86::VFNMADD231PSZr,        X86::VFNMADD231PSZm,        TB_ALIGN_NONE }, | 
|  | 1949 | { X86::VFNMADD231PDZr,        X86::VFNMADD231PDZm,        TB_ALIGN_NONE }, | 
|  | 1950 | { X86::VFNMADD132PSZr,        X86::VFNMADD132PSZm,        TB_ALIGN_NONE }, | 
|  | 1951 | { X86::VFNMADD132PDZr,        X86::VFNMADD132PDZm,        TB_ALIGN_NONE }, | 
|  | 1952 | { X86::VFNMADD213PSZr,        X86::VFNMADD213PSZm,        TB_ALIGN_NONE }, | 
|  | 1953 | { X86::VFNMADD213PDZr,        X86::VFNMADD213PDZm,        TB_ALIGN_NONE }, | 
|  | 1954 | { X86::VFNMADD231PSZ128r,     X86::VFNMADD231PSZ128m,     TB_ALIGN_NONE }, | 
|  | 1955 | { X86::VFNMADD231PDZ128r,     X86::VFNMADD231PDZ128m,     TB_ALIGN_NONE }, | 
|  | 1956 | { X86::VFNMADD132PSZ128r,     X86::VFNMADD132PSZ128m,     TB_ALIGN_NONE }, | 
|  | 1957 | { X86::VFNMADD132PDZ128r,     X86::VFNMADD132PDZ128m,     TB_ALIGN_NONE }, | 
|  | 1958 | { X86::VFNMADD213PSZ128r,     X86::VFNMADD213PSZ128m,     TB_ALIGN_NONE }, | 
|  | 1959 | { X86::VFNMADD213PDZ128r,     X86::VFNMADD213PDZ128m,     TB_ALIGN_NONE }, | 
|  | 1960 | { X86::VFNMADD231PSZ256r,     X86::VFNMADD231PSZ256m,     TB_ALIGN_NONE }, | 
|  | 1961 | { X86::VFNMADD231PDZ256r,     X86::VFNMADD231PDZ256m,     TB_ALIGN_NONE }, | 
|  | 1962 | { X86::VFNMADD132PSZ256r,     X86::VFNMADD132PSZ256m,     TB_ALIGN_NONE }, | 
|  | 1963 | { X86::VFNMADD132PDZ256r,     X86::VFNMADD132PDZ256m,     TB_ALIGN_NONE }, | 
|  | 1964 | { X86::VFNMADD213PSZ256r,     X86::VFNMADD213PSZ256m,     TB_ALIGN_NONE }, | 
|  | 1965 | { X86::VFNMADD213PDZ256r,     X86::VFNMADD213PDZ256m,     TB_ALIGN_NONE }, | 
| Elena Demikhovsky | 602f3a2 | 2012-05-31 09:20:20 +0000 | [diff] [blame] | 1966 |  | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 1967 | { X86::VFMSUB231SSr,          X86::VFMSUB231SSm,          TB_ALIGN_NONE }, | 
|  | 1968 | { X86::VFMSUB231SSr_Int,      X86::VFMSUB231SSm_Int,      TB_ALIGN_NONE }, | 
|  | 1969 | { X86::VFMSUB231SDr,          X86::VFMSUB231SDm,          TB_ALIGN_NONE }, | 
|  | 1970 | { X86::VFMSUB231SDr_Int,      X86::VFMSUB231SDm_Int,      TB_ALIGN_NONE }, | 
|  | 1971 | { X86::VFMSUB132SSr,          X86::VFMSUB132SSm,          TB_ALIGN_NONE }, | 
|  | 1972 | { X86::VFMSUB132SSr_Int,      X86::VFMSUB132SSm_Int,      TB_ALIGN_NONE }, | 
|  | 1973 | { X86::VFMSUB132SDr,          X86::VFMSUB132SDm,          TB_ALIGN_NONE }, | 
|  | 1974 | { X86::VFMSUB132SDr_Int,      X86::VFMSUB132SDm_Int,      TB_ALIGN_NONE }, | 
|  | 1975 | { X86::VFMSUB213SSr,          X86::VFMSUB213SSm,          TB_ALIGN_NONE }, | 
|  | 1976 | { X86::VFMSUB213SSr_Int,      X86::VFMSUB213SSm_Int,      TB_ALIGN_NONE }, | 
|  | 1977 | { X86::VFMSUB213SDr,          X86::VFMSUB213SDm,          TB_ALIGN_NONE }, | 
|  | 1978 | { X86::VFMSUB213SDr_Int,      X86::VFMSUB213SDm_Int,      TB_ALIGN_NONE }, | 
| Craig Topper | ce415ff | 2016-07-25 07:20:35 +0000 | [diff] [blame] | 1979 | { X86::VFMSUB231SSZr,         X86::VFMSUB231SSZm,         TB_ALIGN_NONE }, | 
|  | 1980 | { X86::VFMSUB231SSZr_Int,     X86::VFMSUB231SSZm_Int,     TB_ALIGN_NONE }, | 
|  | 1981 | { X86::VFMSUB231SDZr,         X86::VFMSUB231SDZm,         TB_ALIGN_NONE }, | 
|  | 1982 | { X86::VFMSUB231SDZr_Int,     X86::VFMSUB231SDZm_Int,     TB_ALIGN_NONE }, | 
|  | 1983 | { X86::VFMSUB132SSZr,         X86::VFMSUB132SSZm,         TB_ALIGN_NONE }, | 
|  | 1984 | { X86::VFMSUB132SSZr_Int,     X86::VFMSUB132SSZm_Int,     TB_ALIGN_NONE }, | 
|  | 1985 | { X86::VFMSUB132SDZr,         X86::VFMSUB132SDZm,         TB_ALIGN_NONE }, | 
|  | 1986 | { X86::VFMSUB132SDZr_Int,     X86::VFMSUB132SDZm_Int,     TB_ALIGN_NONE }, | 
|  | 1987 | { X86::VFMSUB213SSZr,         X86::VFMSUB213SSZm,         TB_ALIGN_NONE }, | 
|  | 1988 | { X86::VFMSUB213SSZr_Int,     X86::VFMSUB213SSZm_Int,     TB_ALIGN_NONE }, | 
|  | 1989 | { X86::VFMSUB213SDZr,         X86::VFMSUB213SDZm,         TB_ALIGN_NONE }, | 
|  | 1990 | { X86::VFMSUB213SDZr_Int,     X86::VFMSUB213SDZm_Int,     TB_ALIGN_NONE }, | 
| Elena Demikhovsky | 602f3a2 | 2012-05-31 09:20:20 +0000 | [diff] [blame] | 1991 |  | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 1992 | { X86::VFMSUB231PSr,          X86::VFMSUB231PSm,          TB_ALIGN_NONE }, | 
|  | 1993 | { X86::VFMSUB231PDr,          X86::VFMSUB231PDm,          TB_ALIGN_NONE }, | 
|  | 1994 | { X86::VFMSUB132PSr,          X86::VFMSUB132PSm,          TB_ALIGN_NONE }, | 
|  | 1995 | { X86::VFMSUB132PDr,          X86::VFMSUB132PDm,          TB_ALIGN_NONE }, | 
|  | 1996 | { X86::VFMSUB213PSr,          X86::VFMSUB213PSm,          TB_ALIGN_NONE }, | 
|  | 1997 | { X86::VFMSUB213PDr,          X86::VFMSUB213PDm,          TB_ALIGN_NONE }, | 
|  | 1998 | { X86::VFMSUB231PSYr,         X86::VFMSUB231PSYm,         TB_ALIGN_NONE }, | 
|  | 1999 | { X86::VFMSUB231PDYr,         X86::VFMSUB231PDYm,         TB_ALIGN_NONE }, | 
|  | 2000 | { X86::VFMSUB132PSYr,         X86::VFMSUB132PSYm,         TB_ALIGN_NONE }, | 
|  | 2001 | { X86::VFMSUB132PDYr,         X86::VFMSUB132PDYm,         TB_ALIGN_NONE }, | 
|  | 2002 | { X86::VFMSUB213PSYr,         X86::VFMSUB213PSYm,         TB_ALIGN_NONE }, | 
|  | 2003 | { X86::VFMSUB213PDYr,         X86::VFMSUB213PDYm,         TB_ALIGN_NONE }, | 
| Craig Topper | ce415ff | 2016-07-25 07:20:35 +0000 | [diff] [blame] | 2004 | { X86::VFMSUB231PSZr,         X86::VFMSUB231PSZm,         TB_ALIGN_NONE }, | 
|  | 2005 | { X86::VFMSUB231PDZr,         X86::VFMSUB231PDZm,         TB_ALIGN_NONE }, | 
|  | 2006 | { X86::VFMSUB132PSZr,         X86::VFMSUB132PSZm,         TB_ALIGN_NONE }, | 
|  | 2007 | { X86::VFMSUB132PDZr,         X86::VFMSUB132PDZm,         TB_ALIGN_NONE }, | 
|  | 2008 | { X86::VFMSUB213PSZr,         X86::VFMSUB213PSZm,         TB_ALIGN_NONE }, | 
|  | 2009 | { X86::VFMSUB213PDZr,         X86::VFMSUB213PDZm,         TB_ALIGN_NONE }, | 
|  | 2010 | { X86::VFMSUB231PSZ128r,      X86::VFMSUB231PSZ128m,      TB_ALIGN_NONE }, | 
|  | 2011 | { X86::VFMSUB231PDZ128r,      X86::VFMSUB231PDZ128m,      TB_ALIGN_NONE }, | 
|  | 2012 | { X86::VFMSUB132PSZ128r,      X86::VFMSUB132PSZ128m,      TB_ALIGN_NONE }, | 
|  | 2013 | { X86::VFMSUB132PDZ128r,      X86::VFMSUB132PDZ128m,      TB_ALIGN_NONE }, | 
|  | 2014 | { X86::VFMSUB213PSZ128r,      X86::VFMSUB213PSZ128m,      TB_ALIGN_NONE }, | 
|  | 2015 | { X86::VFMSUB213PDZ128r,      X86::VFMSUB213PDZ128m,      TB_ALIGN_NONE }, | 
|  | 2016 | { X86::VFMSUB231PSZ256r,      X86::VFMSUB231PSZ256m,      TB_ALIGN_NONE }, | 
|  | 2017 | { X86::VFMSUB231PDZ256r,      X86::VFMSUB231PDZ256m,      TB_ALIGN_NONE }, | 
|  | 2018 | { X86::VFMSUB132PSZ256r,      X86::VFMSUB132PSZ256m,      TB_ALIGN_NONE }, | 
|  | 2019 | { X86::VFMSUB132PDZ256r,      X86::VFMSUB132PDZ256m,      TB_ALIGN_NONE }, | 
|  | 2020 | { X86::VFMSUB213PSZ256r,      X86::VFMSUB213PSZ256m,      TB_ALIGN_NONE }, | 
|  | 2021 | { X86::VFMSUB213PDZ256r,      X86::VFMSUB213PDZ256m,      TB_ALIGN_NONE }, | 
| Elena Demikhovsky | 602f3a2 | 2012-05-31 09:20:20 +0000 | [diff] [blame] | 2022 |  | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 2023 | { X86::VFNMSUB231SSr,         X86::VFNMSUB231SSm,         TB_ALIGN_NONE }, | 
|  | 2024 | { X86::VFNMSUB231SSr_Int,     X86::VFNMSUB231SSm_Int,     TB_ALIGN_NONE }, | 
|  | 2025 | { X86::VFNMSUB231SDr,         X86::VFNMSUB231SDm,         TB_ALIGN_NONE }, | 
|  | 2026 | { X86::VFNMSUB231SDr_Int,     X86::VFNMSUB231SDm_Int,     TB_ALIGN_NONE }, | 
|  | 2027 | { X86::VFNMSUB132SSr,         X86::VFNMSUB132SSm,         TB_ALIGN_NONE }, | 
|  | 2028 | { X86::VFNMSUB132SSr_Int,     X86::VFNMSUB132SSm_Int,     TB_ALIGN_NONE }, | 
|  | 2029 | { X86::VFNMSUB132SDr,         X86::VFNMSUB132SDm,         TB_ALIGN_NONE }, | 
|  | 2030 | { X86::VFNMSUB132SDr_Int,     X86::VFNMSUB132SDm_Int,     TB_ALIGN_NONE }, | 
|  | 2031 | { X86::VFNMSUB213SSr,         X86::VFNMSUB213SSm,         TB_ALIGN_NONE }, | 
|  | 2032 | { X86::VFNMSUB213SSr_Int,     X86::VFNMSUB213SSm_Int,     TB_ALIGN_NONE }, | 
|  | 2033 | { X86::VFNMSUB213SDr,         X86::VFNMSUB213SDm,         TB_ALIGN_NONE }, | 
|  | 2034 | { X86::VFNMSUB213SDr_Int,     X86::VFNMSUB213SDm_Int,     TB_ALIGN_NONE }, | 
| Craig Topper | 2e127b5 | 2012-06-01 05:48:39 +0000 | [diff] [blame] | 2035 |  | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 2036 | { X86::VFNMSUB231PSr,         X86::VFNMSUB231PSm,         TB_ALIGN_NONE }, | 
|  | 2037 | { X86::VFNMSUB231PDr,         X86::VFNMSUB231PDm,         TB_ALIGN_NONE }, | 
|  | 2038 | { X86::VFNMSUB132PSr,         X86::VFNMSUB132PSm,         TB_ALIGN_NONE }, | 
|  | 2039 | { X86::VFNMSUB132PDr,         X86::VFNMSUB132PDm,         TB_ALIGN_NONE }, | 
|  | 2040 | { X86::VFNMSUB213PSr,         X86::VFNMSUB213PSm,         TB_ALIGN_NONE }, | 
|  | 2041 | { X86::VFNMSUB213PDr,         X86::VFNMSUB213PDm,         TB_ALIGN_NONE }, | 
|  | 2042 | { X86::VFNMSUB231PSYr,        X86::VFNMSUB231PSYm,        TB_ALIGN_NONE }, | 
|  | 2043 | { X86::VFNMSUB231PDYr,        X86::VFNMSUB231PDYm,        TB_ALIGN_NONE }, | 
|  | 2044 | { X86::VFNMSUB132PSYr,        X86::VFNMSUB132PSYm,        TB_ALIGN_NONE }, | 
|  | 2045 | { X86::VFNMSUB132PDYr,        X86::VFNMSUB132PDYm,        TB_ALIGN_NONE }, | 
|  | 2046 | { X86::VFNMSUB213PSYr,        X86::VFNMSUB213PSYm,        TB_ALIGN_NONE }, | 
|  | 2047 | { X86::VFNMSUB213PDYr,        X86::VFNMSUB213PDYm,        TB_ALIGN_NONE }, | 
| Craig Topper | ce415ff | 2016-07-25 07:20:35 +0000 | [diff] [blame] | 2048 | { X86::VFNMSUB231PSZr,        X86::VFNMSUB231PSZm,        TB_ALIGN_NONE }, | 
|  | 2049 | { X86::VFNMSUB231PDZr,        X86::VFNMSUB231PDZm,        TB_ALIGN_NONE }, | 
|  | 2050 | { X86::VFNMSUB132PSZr,        X86::VFNMSUB132PSZm,        TB_ALIGN_NONE }, | 
|  | 2051 | { X86::VFNMSUB132PDZr,        X86::VFNMSUB132PDZm,        TB_ALIGN_NONE }, | 
|  | 2052 | { X86::VFNMSUB213PSZr,        X86::VFNMSUB213PSZm,        TB_ALIGN_NONE }, | 
|  | 2053 | { X86::VFNMSUB213PDZr,        X86::VFNMSUB213PDZm,        TB_ALIGN_NONE }, | 
|  | 2054 | { X86::VFNMSUB231PSZ128r,     X86::VFNMSUB231PSZ128m,     TB_ALIGN_NONE }, | 
|  | 2055 | { X86::VFNMSUB231PDZ128r,     X86::VFNMSUB231PDZ128m,     TB_ALIGN_NONE }, | 
|  | 2056 | { X86::VFNMSUB132PSZ128r,     X86::VFNMSUB132PSZ128m,     TB_ALIGN_NONE }, | 
|  | 2057 | { X86::VFNMSUB132PDZ128r,     X86::VFNMSUB132PDZ128m,     TB_ALIGN_NONE }, | 
|  | 2058 | { X86::VFNMSUB213PSZ128r,     X86::VFNMSUB213PSZ128m,     TB_ALIGN_NONE }, | 
|  | 2059 | { X86::VFNMSUB213PDZ128r,     X86::VFNMSUB213PDZ128m,     TB_ALIGN_NONE }, | 
|  | 2060 | { X86::VFNMSUB231PSZ256r,     X86::VFNMSUB231PSZ256m,     TB_ALIGN_NONE }, | 
|  | 2061 | { X86::VFNMSUB231PDZ256r,     X86::VFNMSUB231PDZ256m,     TB_ALIGN_NONE }, | 
|  | 2062 | { X86::VFNMSUB132PSZ256r,     X86::VFNMSUB132PSZ256m,     TB_ALIGN_NONE }, | 
|  | 2063 | { X86::VFNMSUB132PDZ256r,     X86::VFNMSUB132PDZ256m,     TB_ALIGN_NONE }, | 
|  | 2064 | { X86::VFNMSUB213PSZ256r,     X86::VFNMSUB213PSZ256m,     TB_ALIGN_NONE }, | 
|  | 2065 | { X86::VFNMSUB213PDZ256r,     X86::VFNMSUB213PDZ256m,     TB_ALIGN_NONE }, | 
| Craig Topper | 3cb1430 | 2012-06-04 07:08:21 +0000 | [diff] [blame] | 2066 |  | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 2067 | { X86::VFMADDSUB231PSr,       X86::VFMADDSUB231PSm,       TB_ALIGN_NONE }, | 
|  | 2068 | { X86::VFMADDSUB231PDr,       X86::VFMADDSUB231PDm,       TB_ALIGN_NONE }, | 
|  | 2069 | { X86::VFMADDSUB132PSr,       X86::VFMADDSUB132PSm,       TB_ALIGN_NONE }, | 
|  | 2070 | { X86::VFMADDSUB132PDr,       X86::VFMADDSUB132PDm,       TB_ALIGN_NONE }, | 
|  | 2071 | { X86::VFMADDSUB213PSr,       X86::VFMADDSUB213PSm,       TB_ALIGN_NONE }, | 
|  | 2072 | { X86::VFMADDSUB213PDr,       X86::VFMADDSUB213PDm,       TB_ALIGN_NONE }, | 
|  | 2073 | { X86::VFMADDSUB231PSYr,      X86::VFMADDSUB231PSYm,      TB_ALIGN_NONE }, | 
|  | 2074 | { X86::VFMADDSUB231PDYr,      X86::VFMADDSUB231PDYm,      TB_ALIGN_NONE }, | 
|  | 2075 | { X86::VFMADDSUB132PSYr,      X86::VFMADDSUB132PSYm,      TB_ALIGN_NONE }, | 
|  | 2076 | { X86::VFMADDSUB132PDYr,      X86::VFMADDSUB132PDYm,      TB_ALIGN_NONE }, | 
|  | 2077 | { X86::VFMADDSUB213PSYr,      X86::VFMADDSUB213PSYm,      TB_ALIGN_NONE }, | 
|  | 2078 | { X86::VFMADDSUB213PDYr,      X86::VFMADDSUB213PDYm,      TB_ALIGN_NONE }, | 
| Craig Topper | ce415ff | 2016-07-25 07:20:35 +0000 | [diff] [blame] | 2079 | { X86::VFMADDSUB231PSZr,      X86::VFMADDSUB231PSZm,      TB_ALIGN_NONE }, | 
|  | 2080 | { X86::VFMADDSUB231PDZr,      X86::VFMADDSUB231PDZm,      TB_ALIGN_NONE }, | 
|  | 2081 | { X86::VFMADDSUB132PSZr,      X86::VFMADDSUB132PSZm,      TB_ALIGN_NONE }, | 
|  | 2082 | { X86::VFMADDSUB132PDZr,      X86::VFMADDSUB132PDZm,      TB_ALIGN_NONE }, | 
|  | 2083 | { X86::VFMADDSUB213PSZr,      X86::VFMADDSUB213PSZm,      TB_ALIGN_NONE }, | 
|  | 2084 | { X86::VFMADDSUB213PDZr,      X86::VFMADDSUB213PDZm,      TB_ALIGN_NONE }, | 
|  | 2085 | { X86::VFMADDSUB231PSZ128r,   X86::VFMADDSUB231PSZ128m,   TB_ALIGN_NONE }, | 
|  | 2086 | { X86::VFMADDSUB231PDZ128r,   X86::VFMADDSUB231PDZ128m,   TB_ALIGN_NONE }, | 
|  | 2087 | { X86::VFMADDSUB132PSZ128r,   X86::VFMADDSUB132PSZ128m,   TB_ALIGN_NONE }, | 
|  | 2088 | { X86::VFMADDSUB132PDZ128r,   X86::VFMADDSUB132PDZ128m,   TB_ALIGN_NONE }, | 
|  | 2089 | { X86::VFMADDSUB213PSZ128r,   X86::VFMADDSUB213PSZ128m,   TB_ALIGN_NONE }, | 
|  | 2090 | { X86::VFMADDSUB213PDZ128r,   X86::VFMADDSUB213PDZ128m,   TB_ALIGN_NONE }, | 
|  | 2091 | { X86::VFMADDSUB231PSZ256r,   X86::VFMADDSUB231PSZ256m,   TB_ALIGN_NONE }, | 
|  | 2092 | { X86::VFMADDSUB231PDZ256r,   X86::VFMADDSUB231PDZ256m,   TB_ALIGN_NONE }, | 
|  | 2093 | { X86::VFMADDSUB132PSZ256r,   X86::VFMADDSUB132PSZ256m,   TB_ALIGN_NONE }, | 
|  | 2094 | { X86::VFMADDSUB132PDZ256r,   X86::VFMADDSUB132PDZ256m,   TB_ALIGN_NONE }, | 
|  | 2095 | { X86::VFMADDSUB213PSZ256r,   X86::VFMADDSUB213PSZ256m,   TB_ALIGN_NONE }, | 
|  | 2096 | { X86::VFMADDSUB213PDZ256r,   X86::VFMADDSUB213PDZ256m,   TB_ALIGN_NONE }, | 
| Craig Topper | 3cb1430 | 2012-06-04 07:08:21 +0000 | [diff] [blame] | 2097 |  | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 2098 | { X86::VFMSUBADD231PSr,       X86::VFMSUBADD231PSm,       TB_ALIGN_NONE }, | 
|  | 2099 | { X86::VFMSUBADD231PDr,       X86::VFMSUBADD231PDm,       TB_ALIGN_NONE }, | 
|  | 2100 | { X86::VFMSUBADD132PSr,       X86::VFMSUBADD132PSm,       TB_ALIGN_NONE }, | 
|  | 2101 | { X86::VFMSUBADD132PDr,       X86::VFMSUBADD132PDm,       TB_ALIGN_NONE }, | 
|  | 2102 | { X86::VFMSUBADD213PSr,       X86::VFMSUBADD213PSm,       TB_ALIGN_NONE }, | 
|  | 2103 | { X86::VFMSUBADD213PDr,       X86::VFMSUBADD213PDm,       TB_ALIGN_NONE }, | 
|  | 2104 | { X86::VFMSUBADD231PSYr,      X86::VFMSUBADD231PSYm,      TB_ALIGN_NONE }, | 
|  | 2105 | { X86::VFMSUBADD231PDYr,      X86::VFMSUBADD231PDYm,      TB_ALIGN_NONE }, | 
|  | 2106 | { X86::VFMSUBADD132PSYr,      X86::VFMSUBADD132PSYm,      TB_ALIGN_NONE }, | 
|  | 2107 | { X86::VFMSUBADD132PDYr,      X86::VFMSUBADD132PDYm,      TB_ALIGN_NONE }, | 
|  | 2108 | { X86::VFMSUBADD213PSYr,      X86::VFMSUBADD213PSYm,      TB_ALIGN_NONE }, | 
|  | 2109 | { X86::VFMSUBADD213PDYr,      X86::VFMSUBADD213PDYm,      TB_ALIGN_NONE }, | 
| Craig Topper | ce415ff | 2016-07-25 07:20:35 +0000 | [diff] [blame] | 2110 | { X86::VFMSUBADD231PSZr,      X86::VFMSUBADD231PSZm,      TB_ALIGN_NONE }, | 
|  | 2111 | { X86::VFMSUBADD231PDZr,      X86::VFMSUBADD231PDZm,      TB_ALIGN_NONE }, | 
|  | 2112 | { X86::VFMSUBADD132PSZr,      X86::VFMSUBADD132PSZm,      TB_ALIGN_NONE }, | 
|  | 2113 | { X86::VFMSUBADD132PDZr,      X86::VFMSUBADD132PDZm,      TB_ALIGN_NONE }, | 
|  | 2114 | { X86::VFMSUBADD213PSZr,      X86::VFMSUBADD213PSZm,      TB_ALIGN_NONE }, | 
|  | 2115 | { X86::VFMSUBADD213PDZr,      X86::VFMSUBADD213PDZm,      TB_ALIGN_NONE }, | 
|  | 2116 | { X86::VFMSUBADD231PSZ128r,   X86::VFMSUBADD231PSZ128m,   TB_ALIGN_NONE }, | 
|  | 2117 | { X86::VFMSUBADD231PDZ128r,   X86::VFMSUBADD231PDZ128m,   TB_ALIGN_NONE }, | 
|  | 2118 | { X86::VFMSUBADD132PSZ128r,   X86::VFMSUBADD132PSZ128m,   TB_ALIGN_NONE }, | 
|  | 2119 | { X86::VFMSUBADD132PDZ128r,   X86::VFMSUBADD132PDZ128m,   TB_ALIGN_NONE }, | 
|  | 2120 | { X86::VFMSUBADD213PSZ128r,   X86::VFMSUBADD213PSZ128m,   TB_ALIGN_NONE }, | 
|  | 2121 | { X86::VFMSUBADD213PDZ128r,   X86::VFMSUBADD213PDZ128m,   TB_ALIGN_NONE }, | 
|  | 2122 | { X86::VFMSUBADD231PSZ256r,   X86::VFMSUBADD231PSZ256m,   TB_ALIGN_NONE }, | 
|  | 2123 | { X86::VFMSUBADD231PDZ256r,   X86::VFMSUBADD231PDZ256m,   TB_ALIGN_NONE }, | 
|  | 2124 | { X86::VFMSUBADD132PSZ256r,   X86::VFMSUBADD132PSZ256m,   TB_ALIGN_NONE }, | 
|  | 2125 | { X86::VFMSUBADD132PDZ256r,   X86::VFMSUBADD132PDZ256m,   TB_ALIGN_NONE }, | 
|  | 2126 | { X86::VFMSUBADD213PSZ256r,   X86::VFMSUBADD213PSZ256m,   TB_ALIGN_NONE }, | 
|  | 2127 | { X86::VFMSUBADD213PDZ256r,   X86::VFMSUBADD213PDZ256m,   TB_ALIGN_NONE }, | 
| Craig Topper | 908e685 | 2012-08-31 23:10:34 +0000 | [diff] [blame] | 2128 |  | 
|  | 2129 | // FMA4 foldable patterns | 
| Simon Pilgrim | 616fe50 | 2015-06-22 21:49:41 +0000 | [diff] [blame] | 2130 | { X86::VFMADDSS4rr,           X86::VFMADDSS4rm,           TB_ALIGN_NONE }, | 
|  | 2131 | { X86::VFMADDSD4rr,           X86::VFMADDSD4rm,           TB_ALIGN_NONE }, | 
|  | 2132 | { X86::VFMADDPS4rr,           X86::VFMADDPS4rm,           TB_ALIGN_NONE }, | 
|  | 2133 | { X86::VFMADDPD4rr,           X86::VFMADDPD4rm,           TB_ALIGN_NONE }, | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 2134 | { X86::VFMADDPS4Yrr,          X86::VFMADDPS4Yrm,          TB_ALIGN_NONE }, | 
|  | 2135 | { X86::VFMADDPD4Yrr,          X86::VFMADDPD4Yrm,          TB_ALIGN_NONE }, | 
| Simon Pilgrim | 616fe50 | 2015-06-22 21:49:41 +0000 | [diff] [blame] | 2136 | { X86::VFNMADDSS4rr,          X86::VFNMADDSS4rm,          TB_ALIGN_NONE }, | 
|  | 2137 | { X86::VFNMADDSD4rr,          X86::VFNMADDSD4rm,          TB_ALIGN_NONE }, | 
|  | 2138 | { X86::VFNMADDPS4rr,          X86::VFNMADDPS4rm,          TB_ALIGN_NONE }, | 
|  | 2139 | { X86::VFNMADDPD4rr,          X86::VFNMADDPD4rm,          TB_ALIGN_NONE }, | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 2140 | { X86::VFNMADDPS4Yrr,         X86::VFNMADDPS4Yrm,         TB_ALIGN_NONE }, | 
|  | 2141 | { X86::VFNMADDPD4Yrr,         X86::VFNMADDPD4Yrm,         TB_ALIGN_NONE }, | 
| Simon Pilgrim | 616fe50 | 2015-06-22 21:49:41 +0000 | [diff] [blame] | 2142 | { X86::VFMSUBSS4rr,           X86::VFMSUBSS4rm,           TB_ALIGN_NONE }, | 
|  | 2143 | { X86::VFMSUBSD4rr,           X86::VFMSUBSD4rm,           TB_ALIGN_NONE }, | 
|  | 2144 | { X86::VFMSUBPS4rr,           X86::VFMSUBPS4rm,           TB_ALIGN_NONE }, | 
|  | 2145 | { X86::VFMSUBPD4rr,           X86::VFMSUBPD4rm,           TB_ALIGN_NONE }, | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 2146 | { X86::VFMSUBPS4Yrr,          X86::VFMSUBPS4Yrm,          TB_ALIGN_NONE }, | 
|  | 2147 | { X86::VFMSUBPD4Yrr,          X86::VFMSUBPD4Yrm,          TB_ALIGN_NONE }, | 
| Simon Pilgrim | 616fe50 | 2015-06-22 21:49:41 +0000 | [diff] [blame] | 2148 | { X86::VFNMSUBSS4rr,          X86::VFNMSUBSS4rm,          TB_ALIGN_NONE }, | 
|  | 2149 | { X86::VFNMSUBSD4rr,          X86::VFNMSUBSD4rm,          TB_ALIGN_NONE }, | 
|  | 2150 | { X86::VFNMSUBPS4rr,          X86::VFNMSUBPS4rm,          TB_ALIGN_NONE }, | 
|  | 2151 | { X86::VFNMSUBPD4rr,          X86::VFNMSUBPD4rm,          TB_ALIGN_NONE }, | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 2152 | { X86::VFNMSUBPS4Yrr,         X86::VFNMSUBPS4Yrm,         TB_ALIGN_NONE }, | 
|  | 2153 | { X86::VFNMSUBPD4Yrr,         X86::VFNMSUBPD4Yrm,         TB_ALIGN_NONE }, | 
| Simon Pilgrim | 616fe50 | 2015-06-22 21:49:41 +0000 | [diff] [blame] | 2154 | { X86::VFMADDSUBPS4rr,        X86::VFMADDSUBPS4rm,        TB_ALIGN_NONE }, | 
|  | 2155 | { X86::VFMADDSUBPD4rr,        X86::VFMADDSUBPD4rm,        TB_ALIGN_NONE }, | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 2156 | { X86::VFMADDSUBPS4Yrr,       X86::VFMADDSUBPS4Yrm,       TB_ALIGN_NONE }, | 
|  | 2157 | { X86::VFMADDSUBPD4Yrr,       X86::VFMADDSUBPD4Yrm,       TB_ALIGN_NONE }, | 
| Simon Pilgrim | 616fe50 | 2015-06-22 21:49:41 +0000 | [diff] [blame] | 2158 | { X86::VFMSUBADDPS4rr,        X86::VFMSUBADDPS4rm,        TB_ALIGN_NONE }, | 
|  | 2159 | { X86::VFMSUBADDPD4rr,        X86::VFMSUBADDPD4rm,        TB_ALIGN_NONE }, | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 2160 | { X86::VFMSUBADDPS4Yrr,       X86::VFMSUBADDPS4Yrm,       TB_ALIGN_NONE }, | 
|  | 2161 | { X86::VFMSUBADDPD4Yrr,       X86::VFMSUBADDPD4Yrm,       TB_ALIGN_NONE }, | 
| Simon Pilgrim | cd32254 | 2015-02-10 12:57:17 +0000 | [diff] [blame] | 2162 |  | 
|  | 2163 | // XOP foldable instructions | 
| Simon Pilgrim | a6ba27f | 2016-03-24 16:31:30 +0000 | [diff] [blame] | 2164 | { X86::VPCMOVrrr,             X86::VPCMOVrrm,             0 }, | 
|  | 2165 | { X86::VPCMOVrrrY,            X86::VPCMOVrrmY,            0 }, | 
| Simon Pilgrim | cd32254 | 2015-02-10 12:57:17 +0000 | [diff] [blame] | 2166 | { X86::VPERMIL2PDrr,          X86::VPERMIL2PDrm,          0 }, | 
|  | 2167 | { X86::VPERMIL2PDrrY,         X86::VPERMIL2PDrmY,         0 }, | 
|  | 2168 | { X86::VPERMIL2PSrr,          X86::VPERMIL2PSrm,          0 }, | 
|  | 2169 | { X86::VPERMIL2PSrrY,         X86::VPERMIL2PSrmY,         0 }, | 
| Simon Pilgrim | a6ba27f | 2016-03-24 16:31:30 +0000 | [diff] [blame] | 2170 | { X86::VPPERMrrr,             X86::VPPERMrrm,             0 }, | 
| Simon Pilgrim | cd32254 | 2015-02-10 12:57:17 +0000 | [diff] [blame] | 2171 |  | 
| Elena Demikhovsky | 2e408ae | 2013-10-06 13:11:09 +0000 | [diff] [blame] | 2172 | // AVX-512 VPERMI instructions with 3 source operands. | 
|  | 2173 | { X86::VPERMI2Drr,            X86::VPERMI2Drm,            0 }, | 
|  | 2174 | { X86::VPERMI2Qrr,            X86::VPERMI2Qrm,            0 }, | 
|  | 2175 | { X86::VPERMI2PSrr,           X86::VPERMI2PSrm,           0 }, | 
|  | 2176 | { X86::VPERMI2PDrr,           X86::VPERMI2PDrm,           0 }, | 
| Elena Demikhovsky | 172a27c | 2014-01-08 10:54:22 +0000 | [diff] [blame] | 2177 | { X86::VBLENDMPDZrr,          X86::VBLENDMPDZrm,          0 }, | 
|  | 2178 | { X86::VBLENDMPSZrr,          X86::VBLENDMPSZrm,          0 }, | 
|  | 2179 | { X86::VPBLENDMDZrr,          X86::VPBLENDMDZrm,          0 }, | 
| Robert Khasanov | 8e8c399 | 2014-12-09 18:45:30 +0000 | [diff] [blame] | 2180 | { X86::VPBLENDMQZrr,          X86::VPBLENDMQZrm,          0 }, | 
|  | 2181 | { X86::VBROADCASTSSZrk,       X86::VBROADCASTSSZmk,       TB_NO_REVERSE }, | 
|  | 2182 | { X86::VBROADCASTSDZrk,       X86::VBROADCASTSDZmk,       TB_NO_REVERSE }, | 
|  | 2183 | { X86::VBROADCASTSSZ256rk,    X86::VBROADCASTSSZ256mk,    TB_NO_REVERSE }, | 
|  | 2184 | { X86::VBROADCASTSDZ256rk,    X86::VBROADCASTSDZ256mk,    TB_NO_REVERSE }, | 
| Robert Khasanov | 79fb729 | 2014-12-18 12:28:22 +0000 | [diff] [blame] | 2185 | { X86::VBROADCASTSSZ128rk,    X86::VBROADCASTSSZ128mk,    TB_NO_REVERSE }, | 
|  | 2186 | // AVX-512 arithmetic instructions | 
|  | 2187 | { X86::VADDPSZrrkz,           X86::VADDPSZrmkz,           0 }, | 
|  | 2188 | { X86::VADDPDZrrkz,           X86::VADDPDZrmkz,           0 }, | 
|  | 2189 | { X86::VSUBPSZrrkz,           X86::VSUBPSZrmkz,           0 }, | 
|  | 2190 | { X86::VSUBPDZrrkz,           X86::VSUBPDZrmkz,           0 }, | 
|  | 2191 | { X86::VMULPSZrrkz,           X86::VMULPSZrmkz,           0 }, | 
|  | 2192 | { X86::VMULPDZrrkz,           X86::VMULPDZrmkz,           0 }, | 
|  | 2193 | { X86::VDIVPSZrrkz,           X86::VDIVPSZrmkz,           0 }, | 
|  | 2194 | { X86::VDIVPDZrrkz,           X86::VDIVPDZrmkz,           0 }, | 
|  | 2195 | { X86::VMINPSZrrkz,           X86::VMINPSZrmkz,           0 }, | 
|  | 2196 | { X86::VMINPDZrrkz,           X86::VMINPDZrmkz,           0 }, | 
|  | 2197 | { X86::VMAXPSZrrkz,           X86::VMAXPSZrmkz,           0 }, | 
|  | 2198 | { X86::VMAXPDZrrkz,           X86::VMAXPDZrmkz,           0 }, | 
|  | 2199 | // AVX-512{F,VL} arithmetic instructions 256-bit | 
|  | 2200 | { X86::VADDPSZ256rrkz,        X86::VADDPSZ256rmkz,        0 }, | 
|  | 2201 | { X86::VADDPDZ256rrkz,        X86::VADDPDZ256rmkz,        0 }, | 
|  | 2202 | { X86::VSUBPSZ256rrkz,        X86::VSUBPSZ256rmkz,        0 }, | 
|  | 2203 | { X86::VSUBPDZ256rrkz,        X86::VSUBPDZ256rmkz,        0 }, | 
|  | 2204 | { X86::VMULPSZ256rrkz,        X86::VMULPSZ256rmkz,        0 }, | 
|  | 2205 | { X86::VMULPDZ256rrkz,        X86::VMULPDZ256rmkz,        0 }, | 
|  | 2206 | { X86::VDIVPSZ256rrkz,        X86::VDIVPSZ256rmkz,        0 }, | 
|  | 2207 | { X86::VDIVPDZ256rrkz,        X86::VDIVPDZ256rmkz,        0 }, | 
|  | 2208 | { X86::VMINPSZ256rrkz,        X86::VMINPSZ256rmkz,        0 }, | 
|  | 2209 | { X86::VMINPDZ256rrkz,        X86::VMINPDZ256rmkz,        0 }, | 
|  | 2210 | { X86::VMAXPSZ256rrkz,        X86::VMAXPSZ256rmkz,        0 }, | 
|  | 2211 | { X86::VMAXPDZ256rrkz,        X86::VMAXPDZ256rmkz,        0 }, | 
|  | 2212 | // AVX-512{F,VL} arithmetic instructions 128-bit | 
|  | 2213 | { X86::VADDPSZ128rrkz,        X86::VADDPSZ128rmkz,        0 }, | 
|  | 2214 | { X86::VADDPDZ128rrkz,        X86::VADDPDZ128rmkz,        0 }, | 
|  | 2215 | { X86::VSUBPSZ128rrkz,        X86::VSUBPSZ128rmkz,        0 }, | 
|  | 2216 | { X86::VSUBPDZ128rrkz,        X86::VSUBPDZ128rmkz,        0 }, | 
|  | 2217 | { X86::VMULPSZ128rrkz,        X86::VMULPSZ128rmkz,        0 }, | 
|  | 2218 | { X86::VMULPDZ128rrkz,        X86::VMULPDZ128rmkz,        0 }, | 
|  | 2219 | { X86::VDIVPSZ128rrkz,        X86::VDIVPSZ128rmkz,        0 }, | 
|  | 2220 | { X86::VDIVPDZ128rrkz,        X86::VDIVPDZ128rmkz,        0 }, | 
|  | 2221 | { X86::VMINPSZ128rrkz,        X86::VMINPSZ128rmkz,        0 }, | 
|  | 2222 | { X86::VMINPDZ128rrkz,        X86::VMINPDZ128rmkz,        0 }, | 
|  | 2223 | { X86::VMAXPSZ128rrkz,        X86::VMAXPSZ128rmkz,        0 }, | 
|  | 2224 | { X86::VMAXPDZ128rrkz,        X86::VMAXPDZ128rmkz,        0 } | 
| Elena Demikhovsky | 602f3a2 | 2012-05-31 09:20:20 +0000 | [diff] [blame] | 2225 | }; | 
|  | 2226 |  | 
| Sanjay Patel | cf0a807 | 2015-07-07 15:03:53 +0000 | [diff] [blame] | 2227 | for (X86MemoryFoldTableEntry Entry : MemoryFoldTable3) { | 
| Elena Demikhovsky | 602f3a2 | 2012-05-31 09:20:20 +0000 | [diff] [blame] | 2228 | AddTableEntry(RegOp2MemOpTable3, MemOp2RegOpTable, | 
| Sanjay Patel | cf0a807 | 2015-07-07 15:03:53 +0000 | [diff] [blame] | 2229 | Entry.RegOp, Entry.MemOp, | 
| Elena Demikhovsky | 602f3a2 | 2012-05-31 09:20:20 +0000 | [diff] [blame] | 2230 | // Index 3, folded load | 
| Sanjay Patel | cf0a807 | 2015-07-07 15:03:53 +0000 | [diff] [blame] | 2231 | Entry.Flags | TB_INDEX_3 | TB_FOLDED_LOAD); | 
| Elena Demikhovsky | 602f3a2 | 2012-05-31 09:20:20 +0000 | [diff] [blame] | 2232 | } | 
|  | 2233 |  | 
| Sanjay Patel | e951a38 | 2015-02-17 22:38:06 +0000 | [diff] [blame] | 2234 | static const X86MemoryFoldTableEntry MemoryFoldTable4[] = { | 
| Robert Khasanov | 79fb729 | 2014-12-18 12:28:22 +0000 | [diff] [blame] | 2235 | // AVX-512 foldable instructions | 
|  | 2236 | { X86::VADDPSZrrk,         X86::VADDPSZrmk,           0 }, | 
|  | 2237 | { X86::VADDPDZrrk,         X86::VADDPDZrmk,           0 }, | 
|  | 2238 | { X86::VSUBPSZrrk,         X86::VSUBPSZrmk,           0 }, | 
|  | 2239 | { X86::VSUBPDZrrk,         X86::VSUBPDZrmk,           0 }, | 
|  | 2240 | { X86::VMULPSZrrk,         X86::VMULPSZrmk,           0 }, | 
|  | 2241 | { X86::VMULPDZrrk,         X86::VMULPDZrmk,           0 }, | 
|  | 2242 | { X86::VDIVPSZrrk,         X86::VDIVPSZrmk,           0 }, | 
|  | 2243 | { X86::VDIVPDZrrk,         X86::VDIVPDZrmk,           0 }, | 
|  | 2244 | { X86::VMINPSZrrk,         X86::VMINPSZrmk,           0 }, | 
|  | 2245 | { X86::VMINPDZrrk,         X86::VMINPDZrmk,           0 }, | 
|  | 2246 | { X86::VMAXPSZrrk,         X86::VMAXPSZrmk,           0 }, | 
|  | 2247 | { X86::VMAXPDZrrk,         X86::VMAXPDZrmk,           0 }, | 
|  | 2248 | // AVX-512{F,VL} foldable instructions 256-bit | 
|  | 2249 | { X86::VADDPSZ256rrk,      X86::VADDPSZ256rmk,        0 }, | 
|  | 2250 | { X86::VADDPDZ256rrk,      X86::VADDPDZ256rmk,        0 }, | 
|  | 2251 | { X86::VSUBPSZ256rrk,      X86::VSUBPSZ256rmk,        0 }, | 
|  | 2252 | { X86::VSUBPDZ256rrk,      X86::VSUBPDZ256rmk,        0 }, | 
|  | 2253 | { X86::VMULPSZ256rrk,      X86::VMULPSZ256rmk,        0 }, | 
|  | 2254 | { X86::VMULPDZ256rrk,      X86::VMULPDZ256rmk,        0 }, | 
|  | 2255 | { X86::VDIVPSZ256rrk,      X86::VDIVPSZ256rmk,        0 }, | 
|  | 2256 | { X86::VDIVPDZ256rrk,      X86::VDIVPDZ256rmk,        0 }, | 
|  | 2257 | { X86::VMINPSZ256rrk,      X86::VMINPSZ256rmk,        0 }, | 
|  | 2258 | { X86::VMINPDZ256rrk,      X86::VMINPDZ256rmk,        0 }, | 
|  | 2259 | { X86::VMAXPSZ256rrk,      X86::VMAXPSZ256rmk,        0 }, | 
|  | 2260 | { X86::VMAXPDZ256rrk,      X86::VMAXPDZ256rmk,        0 }, | 
|  | 2261 | // AVX-512{F,VL} foldable instructions 128-bit | 
|  | 2262 | { X86::VADDPSZ128rrk,      X86::VADDPSZ128rmk,        0 }, | 
|  | 2263 | { X86::VADDPDZ128rrk,      X86::VADDPDZ128rmk,        0 }, | 
|  | 2264 | { X86::VSUBPSZ128rrk,      X86::VSUBPSZ128rmk,        0 }, | 
|  | 2265 | { X86::VSUBPDZ128rrk,      X86::VSUBPDZ128rmk,        0 }, | 
|  | 2266 | { X86::VMULPSZ128rrk,      X86::VMULPSZ128rmk,        0 }, | 
|  | 2267 | { X86::VMULPDZ128rrk,      X86::VMULPDZ128rmk,        0 }, | 
|  | 2268 | { X86::VDIVPSZ128rrk,      X86::VDIVPSZ128rmk,        0 }, | 
|  | 2269 | { X86::VDIVPDZ128rrk,      X86::VDIVPDZ128rmk,        0 }, | 
|  | 2270 | { X86::VMINPSZ128rrk,      X86::VMINPSZ128rmk,        0 }, | 
|  | 2271 | { X86::VMINPDZ128rrk,      X86::VMINPDZ128rmk,        0 }, | 
|  | 2272 | { X86::VMAXPSZ128rrk,      X86::VMAXPSZ128rmk,        0 }, | 
|  | 2273 | { X86::VMAXPDZ128rrk,      X86::VMAXPDZ128rmk,        0 } | 
|  | 2274 | }; | 
|  | 2275 |  | 
| Sanjay Patel | cf0a807 | 2015-07-07 15:03:53 +0000 | [diff] [blame] | 2276 | for (X86MemoryFoldTableEntry Entry : MemoryFoldTable4) { | 
| Robert Khasanov | 79fb729 | 2014-12-18 12:28:22 +0000 | [diff] [blame] | 2277 | AddTableEntry(RegOp2MemOpTable4, MemOp2RegOpTable, | 
| Sanjay Patel | cf0a807 | 2015-07-07 15:03:53 +0000 | [diff] [blame] | 2278 | Entry.RegOp, Entry.MemOp, | 
| Robert Khasanov | 79fb729 | 2014-12-18 12:28:22 +0000 | [diff] [blame] | 2279 | // Index 4, folded load | 
| Sanjay Patel | cf0a807 | 2015-07-07 15:03:53 +0000 | [diff] [blame] | 2280 | Entry.Flags | TB_INDEX_4 | TB_FOLDED_LOAD); | 
| Robert Khasanov | 79fb729 | 2014-12-18 12:28:22 +0000 | [diff] [blame] | 2281 | } | 
| Chris Lattner | d92fb00 | 2002-10-25 22:55:53 +0000 | [diff] [blame] | 2282 | } | 
|  | 2283 |  | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 2284 | void | 
|  | 2285 | X86InstrInfo::AddTableEntry(RegOp2MemOpTableType &R2MTable, | 
|  | 2286 | MemOp2RegOpTableType &M2RTable, | 
| Craig Topper | e012ede | 2016-04-30 17:59:49 +0000 | [diff] [blame] | 2287 | uint16_t RegOp, uint16_t MemOp, uint16_t Flags) { | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 2288 | if ((Flags & TB_NO_FORWARD) == 0) { | 
|  | 2289 | assert(!R2MTable.count(RegOp) && "Duplicate entry!"); | 
|  | 2290 | R2MTable[RegOp] = std::make_pair(MemOp, Flags); | 
|  | 2291 | } | 
|  | 2292 | if ((Flags & TB_NO_REVERSE) == 0) { | 
|  | 2293 | assert(!M2RTable.count(MemOp) && | 
|  | 2294 | "Duplicated entries in unfolding maps?"); | 
|  | 2295 | M2RTable[MemOp] = std::make_pair(RegOp, Flags); | 
|  | 2296 | } | 
|  | 2297 | } | 
|  | 2298 |  | 
| Evan Cheng | 4216615 | 2010-01-12 00:09:37 +0000 | [diff] [blame] | 2299 | bool | 
| Evan Cheng | 30bebff | 2010-01-13 00:30:23 +0000 | [diff] [blame] | 2300 | X86InstrInfo::isCoalescableExtInstr(const MachineInstr &MI, | 
|  | 2301 | unsigned &SrcReg, unsigned &DstReg, | 
|  | 2302 | unsigned &SubIdx) const { | 
| Evan Cheng | 4216615 | 2010-01-12 00:09:37 +0000 | [diff] [blame] | 2303 | switch (MI.getOpcode()) { | 
|  | 2304 | default: break; | 
|  | 2305 | case X86::MOVSX16rr8: | 
|  | 2306 | case X86::MOVZX16rr8: | 
|  | 2307 | case X86::MOVSX32rr8: | 
|  | 2308 | case X86::MOVZX32rr8: | 
|  | 2309 | case X86::MOVSX64rr8: | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 2310 | if (!Subtarget.is64Bit()) | 
| Evan Cheng | ceb5a4e | 2010-01-13 08:01:32 +0000 | [diff] [blame] | 2311 | // It's not always legal to reference the low 8-bit of the larger | 
|  | 2312 | // register in 32-bit mode. | 
|  | 2313 | return false; | 
| Evan Cheng | 4216615 | 2010-01-12 00:09:37 +0000 | [diff] [blame] | 2314 | case X86::MOVSX32rr16: | 
|  | 2315 | case X86::MOVZX32rr16: | 
|  | 2316 | case X86::MOVSX64rr16: | 
| Tim Northover | 04eb423 | 2013-05-30 10:43:18 +0000 | [diff] [blame] | 2317 | case X86::MOVSX64rr32: { | 
| Evan Cheng | 4216615 | 2010-01-12 00:09:37 +0000 | [diff] [blame] | 2318 | if (MI.getOperand(0).getSubReg() || MI.getOperand(1).getSubReg()) | 
|  | 2319 | // Be conservative. | 
|  | 2320 | return false; | 
| Evan Cheng | 4216615 | 2010-01-12 00:09:37 +0000 | [diff] [blame] | 2321 | SrcReg = MI.getOperand(1).getReg(); | 
|  | 2322 | DstReg = MI.getOperand(0).getReg(); | 
| Evan Cheng | 4216615 | 2010-01-12 00:09:37 +0000 | [diff] [blame] | 2323 | switch (MI.getOpcode()) { | 
| Craig Topper | 4bc3e5a | 2012-08-21 08:16:16 +0000 | [diff] [blame] | 2324 | default: llvm_unreachable("Unreachable!"); | 
| Evan Cheng | 4216615 | 2010-01-12 00:09:37 +0000 | [diff] [blame] | 2325 | case X86::MOVSX16rr8: | 
|  | 2326 | case X86::MOVZX16rr8: | 
|  | 2327 | case X86::MOVSX32rr8: | 
|  | 2328 | case X86::MOVZX32rr8: | 
|  | 2329 | case X86::MOVSX64rr8: | 
| Jakob Stoklund Olesen | 396c880 | 2010-05-25 17:04:16 +0000 | [diff] [blame] | 2330 | SubIdx = X86::sub_8bit; | 
| Evan Cheng | 4216615 | 2010-01-12 00:09:37 +0000 | [diff] [blame] | 2331 | break; | 
|  | 2332 | case X86::MOVSX32rr16: | 
|  | 2333 | case X86::MOVZX32rr16: | 
|  | 2334 | case X86::MOVSX64rr16: | 
| Jakob Stoklund Olesen | 396c880 | 2010-05-25 17:04:16 +0000 | [diff] [blame] | 2335 | SubIdx = X86::sub_16bit; | 
| Evan Cheng | 4216615 | 2010-01-12 00:09:37 +0000 | [diff] [blame] | 2336 | break; | 
|  | 2337 | case X86::MOVSX64rr32: | 
| Jakob Stoklund Olesen | 396c880 | 2010-05-25 17:04:16 +0000 | [diff] [blame] | 2338 | SubIdx = X86::sub_32bit; | 
| Evan Cheng | 4216615 | 2010-01-12 00:09:37 +0000 | [diff] [blame] | 2339 | break; | 
|  | 2340 | } | 
| Evan Cheng | 30bebff | 2010-01-13 00:30:23 +0000 | [diff] [blame] | 2341 | return true; | 
| Evan Cheng | 4216615 | 2010-01-12 00:09:37 +0000 | [diff] [blame] | 2342 | } | 
|  | 2343 | } | 
| Evan Cheng | 30bebff | 2010-01-13 00:30:23 +0000 | [diff] [blame] | 2344 | return false; | 
| Evan Cheng | 4216615 | 2010-01-12 00:09:37 +0000 | [diff] [blame] | 2345 | } | 
|  | 2346 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2347 | int X86InstrInfo::getSPAdjust(const MachineInstr &MI) const { | 
|  | 2348 | const MachineFunction *MF = MI.getParent()->getParent(); | 
| Michael Kuperstein | 13fbd45 | 2015-02-01 16:56:04 +0000 | [diff] [blame] | 2349 | const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering(); | 
|  | 2350 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2351 | if (MI.getOpcode() == getCallFrameSetupOpcode() || | 
|  | 2352 | MI.getOpcode() == getCallFrameDestroyOpcode()) { | 
| Michael Kuperstein | 13fbd45 | 2015-02-01 16:56:04 +0000 | [diff] [blame] | 2353 | unsigned StackAlign = TFI->getStackAlignment(); | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2354 | int SPAdj = | 
|  | 2355 | (MI.getOperand(0).getImm() + StackAlign - 1) / StackAlign * StackAlign; | 
| Michael Kuperstein | 13fbd45 | 2015-02-01 16:56:04 +0000 | [diff] [blame] | 2356 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2357 | SPAdj -= MI.getOperand(1).getImm(); | 
| Michael Kuperstein | 13fbd45 | 2015-02-01 16:56:04 +0000 | [diff] [blame] | 2358 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2359 | if (MI.getOpcode() == getCallFrameSetupOpcode()) | 
| Michael Kuperstein | 13fbd45 | 2015-02-01 16:56:04 +0000 | [diff] [blame] | 2360 | return SPAdj; | 
|  | 2361 | else | 
|  | 2362 | return -SPAdj; | 
|  | 2363 | } | 
| Simon Pilgrim | cd32254 | 2015-02-10 12:57:17 +0000 | [diff] [blame] | 2364 |  | 
|  | 2365 | // To know whether a call adjusts the stack, we need information | 
| Michael Kuperstein | 13fbd45 | 2015-02-01 16:56:04 +0000 | [diff] [blame] | 2366 | // that is bound to the following ADJCALLSTACKUP pseudo. | 
|  | 2367 | // Look for the next ADJCALLSTACKUP that follows the call. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2368 | if (MI.isCall()) { | 
|  | 2369 | const MachineBasicBlock *MBB = MI.getParent(); | 
| Michael Kuperstein | 13fbd45 | 2015-02-01 16:56:04 +0000 | [diff] [blame] | 2370 | auto I = ++MachineBasicBlock::const_iterator(MI); | 
|  | 2371 | for (auto E = MBB->end(); I != E; ++I) { | 
|  | 2372 | if (I->getOpcode() == getCallFrameDestroyOpcode() || | 
|  | 2373 | I->isCall()) | 
|  | 2374 | break; | 
|  | 2375 | } | 
|  | 2376 |  | 
|  | 2377 | // If we could not find a frame destroy opcode, then it has already | 
|  | 2378 | // been simplified, so we don't care. | 
|  | 2379 | if (I->getOpcode() != getCallFrameDestroyOpcode()) | 
|  | 2380 | return 0; | 
|  | 2381 |  | 
|  | 2382 | return -(I->getOperand(1).getImm()); | 
|  | 2383 | } | 
|  | 2384 |  | 
|  | 2385 | // Currently handle only PUSHes we can reasonably expect to see | 
|  | 2386 | // in call sequences | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2387 | switch (MI.getOpcode()) { | 
| Simon Pilgrim | cd32254 | 2015-02-10 12:57:17 +0000 | [diff] [blame] | 2388 | default: | 
| Michael Kuperstein | 13fbd45 | 2015-02-01 16:56:04 +0000 | [diff] [blame] | 2389 | return 0; | 
|  | 2390 | case X86::PUSH32i8: | 
|  | 2391 | case X86::PUSH32r: | 
|  | 2392 | case X86::PUSH32rmm: | 
|  | 2393 | case X86::PUSH32rmr: | 
|  | 2394 | case X86::PUSHi32: | 
|  | 2395 | return 4; | 
| David L Kreitzer | 0fe4632 | 2016-05-02 13:45:25 +0000 | [diff] [blame] | 2396 | case X86::PUSH64i8: | 
|  | 2397 | case X86::PUSH64r: | 
|  | 2398 | case X86::PUSH64rmm: | 
|  | 2399 | case X86::PUSH64rmr: | 
|  | 2400 | case X86::PUSH64i32: | 
|  | 2401 | return 8; | 
| Michael Kuperstein | 13fbd45 | 2015-02-01 16:56:04 +0000 | [diff] [blame] | 2402 | } | 
|  | 2403 | } | 
|  | 2404 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 2405 | /// Return true and the FrameIndex if the specified | 
| David Greene | 70fdd57 | 2009-11-12 20:55:29 +0000 | [diff] [blame] | 2406 | /// operand and follow operands form a reference to the stack frame. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2407 | bool X86InstrInfo::isFrameOperand(const MachineInstr &MI, unsigned int Op, | 
| David Greene | 70fdd57 | 2009-11-12 20:55:29 +0000 | [diff] [blame] | 2408 | int &FrameIndex) const { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2409 | if (MI.getOperand(Op + X86::AddrBaseReg).isFI() && | 
|  | 2410 | MI.getOperand(Op + X86::AddrScaleAmt).isImm() && | 
|  | 2411 | MI.getOperand(Op + X86::AddrIndexReg).isReg() && | 
|  | 2412 | MI.getOperand(Op + X86::AddrDisp).isImm() && | 
|  | 2413 | MI.getOperand(Op + X86::AddrScaleAmt).getImm() == 1 && | 
|  | 2414 | MI.getOperand(Op + X86::AddrIndexReg).getReg() == 0 && | 
|  | 2415 | MI.getOperand(Op + X86::AddrDisp).getImm() == 0) { | 
|  | 2416 | FrameIndex = MI.getOperand(Op + X86::AddrBaseReg).getIndex(); | 
| David Greene | 70fdd57 | 2009-11-12 20:55:29 +0000 | [diff] [blame] | 2417 | return true; | 
|  | 2418 | } | 
|  | 2419 | return false; | 
|  | 2420 | } | 
|  | 2421 |  | 
| David Greene | 2f4c374 | 2009-11-13 00:29:53 +0000 | [diff] [blame] | 2422 | static bool isFrameLoadOpcode(int Opcode) { | 
|  | 2423 | switch (Opcode) { | 
| David Blaikie | 46a9f01 | 2012-01-20 21:51:11 +0000 | [diff] [blame] | 2424 | default: | 
|  | 2425 | return false; | 
| Chris Lattner | bb53acd | 2006-02-02 20:12:32 +0000 | [diff] [blame] | 2426 | case X86::MOV8rm: | 
|  | 2427 | case X86::MOV16rm: | 
|  | 2428 | case X86::MOV32rm: | 
| Evan Cheng | 11b0a5d | 2006-09-08 06:48:29 +0000 | [diff] [blame] | 2429 | case X86::MOV64rm: | 
| Dale Johannesen | 3d7008c | 2007-07-04 21:07:47 +0000 | [diff] [blame] | 2430 | case X86::LD_Fp64m: | 
| Chris Lattner | bb53acd | 2006-02-02 20:12:32 +0000 | [diff] [blame] | 2431 | case X86::MOVSSrm: | 
|  | 2432 | case X86::MOVSDrm: | 
| Chris Lattner | bfc2c68 | 2006-04-18 16:44:51 +0000 | [diff] [blame] | 2433 | case X86::MOVAPSrm: | 
| Craig Topper | 650a15e | 2016-07-18 06:14:39 +0000 | [diff] [blame] | 2434 | case X86::MOVUPSrm: | 
| Chris Lattner | bfc2c68 | 2006-04-18 16:44:51 +0000 | [diff] [blame] | 2435 | case X86::MOVAPDrm: | 
| Craig Topper | 650a15e | 2016-07-18 06:14:39 +0000 | [diff] [blame] | 2436 | case X86::MOVUPDrm: | 
| Dan Gohman | bdc0f8b | 2009-01-09 02:40:34 +0000 | [diff] [blame] | 2437 | case X86::MOVDQArm: | 
| Craig Topper | 650a15e | 2016-07-18 06:14:39 +0000 | [diff] [blame] | 2438 | case X86::MOVDQUrm: | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 2439 | case X86::VMOVSSrm: | 
|  | 2440 | case X86::VMOVSDrm: | 
|  | 2441 | case X86::VMOVAPSrm: | 
| Craig Topper | 650a15e | 2016-07-18 06:14:39 +0000 | [diff] [blame] | 2442 | case X86::VMOVUPSrm: | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 2443 | case X86::VMOVAPDrm: | 
| Craig Topper | 650a15e | 2016-07-18 06:14:39 +0000 | [diff] [blame] | 2444 | case X86::VMOVUPDrm: | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 2445 | case X86::VMOVDQArm: | 
| Craig Topper | 650a15e | 2016-07-18 06:14:39 +0000 | [diff] [blame] | 2446 | case X86::VMOVDQUrm: | 
| Simon Pilgrim | 9c1e412 | 2014-11-18 23:38:19 +0000 | [diff] [blame] | 2447 | case X86::VMOVUPSYrm: | 
| Bruno Cardoso Lopes | 6778597 | 2011-07-14 18:50:58 +0000 | [diff] [blame] | 2448 | case X86::VMOVAPSYrm: | 
| Simon Pilgrim | 9c1e412 | 2014-11-18 23:38:19 +0000 | [diff] [blame] | 2449 | case X86::VMOVUPDYrm: | 
| Bruno Cardoso Lopes | 6778597 | 2011-07-14 18:50:58 +0000 | [diff] [blame] | 2450 | case X86::VMOVAPDYrm: | 
| Simon Pilgrim | 9c1e412 | 2014-11-18 23:38:19 +0000 | [diff] [blame] | 2451 | case X86::VMOVDQUYrm: | 
| Bruno Cardoso Lopes | 6778597 | 2011-07-14 18:50:58 +0000 | [diff] [blame] | 2452 | case X86::VMOVDQAYrm: | 
| Bill Wendling | e7b2a86 | 2007-04-03 06:00:37 +0000 | [diff] [blame] | 2453 | case X86::MMX_MOVD64rm: | 
|  | 2454 | case X86::MMX_MOVQ64rm: | 
| Craig Topper | 650a15e | 2016-07-18 06:14:39 +0000 | [diff] [blame] | 2455 | case X86::VMOVSSZrm: | 
|  | 2456 | case X86::VMOVSDZrm: | 
| Elena Demikhovsky | a5d38a3 | 2014-01-23 14:27:26 +0000 | [diff] [blame] | 2457 | case X86::VMOVAPSZrm: | 
| Craig Topper | 650a15e | 2016-07-18 06:14:39 +0000 | [diff] [blame] | 2458 | case X86::VMOVAPSZ128rm: | 
|  | 2459 | case X86::VMOVAPSZ256rm: | 
| Elena Demikhovsky | a5d38a3 | 2014-01-23 14:27:26 +0000 | [diff] [blame] | 2460 | case X86::VMOVUPSZrm: | 
| Craig Topper | 650a15e | 2016-07-18 06:14:39 +0000 | [diff] [blame] | 2461 | case X86::VMOVUPSZ128rm: | 
|  | 2462 | case X86::VMOVUPSZ256rm: | 
|  | 2463 | case X86::VMOVAPDZrm: | 
|  | 2464 | case X86::VMOVAPDZ128rm: | 
|  | 2465 | case X86::VMOVAPDZ256rm: | 
|  | 2466 | case X86::VMOVUPDZrm: | 
|  | 2467 | case X86::VMOVUPDZ128rm: | 
|  | 2468 | case X86::VMOVUPDZ256rm: | 
|  | 2469 | case X86::VMOVDQA32Zrm: | 
|  | 2470 | case X86::VMOVDQA32Z128rm: | 
|  | 2471 | case X86::VMOVDQA32Z256rm: | 
|  | 2472 | case X86::VMOVDQU32Zrm: | 
|  | 2473 | case X86::VMOVDQU32Z128rm: | 
|  | 2474 | case X86::VMOVDQU32Z256rm: | 
|  | 2475 | case X86::VMOVDQA64Zrm: | 
|  | 2476 | case X86::VMOVDQA64Z128rm: | 
|  | 2477 | case X86::VMOVDQA64Z256rm: | 
|  | 2478 | case X86::VMOVDQU64Zrm: | 
|  | 2479 | case X86::VMOVDQU64Z128rm: | 
|  | 2480 | case X86::VMOVDQU64Z256rm: | 
|  | 2481 | case X86::VMOVDQU8Zrm: | 
|  | 2482 | case X86::VMOVDQU8Z128rm: | 
|  | 2483 | case X86::VMOVDQU8Z256rm: | 
|  | 2484 | case X86::VMOVDQU16Zrm: | 
|  | 2485 | case X86::VMOVDQU16Z128rm: | 
|  | 2486 | case X86::VMOVDQU16Z256rm: | 
|  | 2487 | case X86::KMOVBkm: | 
|  | 2488 | case X86::KMOVWkm: | 
|  | 2489 | case X86::KMOVDkm: | 
|  | 2490 | case X86::KMOVQkm: | 
| David Greene | 2f4c374 | 2009-11-13 00:29:53 +0000 | [diff] [blame] | 2491 | return true; | 
| David Greene | 2f4c374 | 2009-11-13 00:29:53 +0000 | [diff] [blame] | 2492 | } | 
| David Greene | 2f4c374 | 2009-11-13 00:29:53 +0000 | [diff] [blame] | 2493 | } | 
|  | 2494 |  | 
|  | 2495 | static bool isFrameStoreOpcode(int Opcode) { | 
|  | 2496 | switch (Opcode) { | 
|  | 2497 | default: break; | 
|  | 2498 | case X86::MOV8mr: | 
|  | 2499 | case X86::MOV16mr: | 
|  | 2500 | case X86::MOV32mr: | 
|  | 2501 | case X86::MOV64mr: | 
|  | 2502 | case X86::ST_FpP64m: | 
|  | 2503 | case X86::MOVSSmr: | 
|  | 2504 | case X86::MOVSDmr: | 
|  | 2505 | case X86::MOVAPSmr: | 
| Craig Topper | 650a15e | 2016-07-18 06:14:39 +0000 | [diff] [blame] | 2506 | case X86::MOVUPSmr: | 
| David Greene | 2f4c374 | 2009-11-13 00:29:53 +0000 | [diff] [blame] | 2507 | case X86::MOVAPDmr: | 
| Craig Topper | 650a15e | 2016-07-18 06:14:39 +0000 | [diff] [blame] | 2508 | case X86::MOVUPDmr: | 
| David Greene | 2f4c374 | 2009-11-13 00:29:53 +0000 | [diff] [blame] | 2509 | case X86::MOVDQAmr: | 
| Craig Topper | 650a15e | 2016-07-18 06:14:39 +0000 | [diff] [blame] | 2510 | case X86::MOVDQUmr: | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 2511 | case X86::VMOVSSmr: | 
|  | 2512 | case X86::VMOVSDmr: | 
|  | 2513 | case X86::VMOVAPSmr: | 
| Craig Topper | 650a15e | 2016-07-18 06:14:39 +0000 | [diff] [blame] | 2514 | case X86::VMOVUPSmr: | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 2515 | case X86::VMOVAPDmr: | 
| Craig Topper | 650a15e | 2016-07-18 06:14:39 +0000 | [diff] [blame] | 2516 | case X86::VMOVUPDmr: | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 2517 | case X86::VMOVDQAmr: | 
| Craig Topper | 650a15e | 2016-07-18 06:14:39 +0000 | [diff] [blame] | 2518 | case X86::VMOVDQUmr: | 
| Simon Pilgrim | 9c1e412 | 2014-11-18 23:38:19 +0000 | [diff] [blame] | 2519 | case X86::VMOVUPSYmr: | 
| Bruno Cardoso Lopes | 6778597 | 2011-07-14 18:50:58 +0000 | [diff] [blame] | 2520 | case X86::VMOVAPSYmr: | 
| Simon Pilgrim | 9c1e412 | 2014-11-18 23:38:19 +0000 | [diff] [blame] | 2521 | case X86::VMOVUPDYmr: | 
| Bruno Cardoso Lopes | 6778597 | 2011-07-14 18:50:58 +0000 | [diff] [blame] | 2522 | case X86::VMOVAPDYmr: | 
| Simon Pilgrim | 9c1e412 | 2014-11-18 23:38:19 +0000 | [diff] [blame] | 2523 | case X86::VMOVDQUYmr: | 
| Bruno Cardoso Lopes | 6778597 | 2011-07-14 18:50:58 +0000 | [diff] [blame] | 2524 | case X86::VMOVDQAYmr: | 
| Craig Topper | 650a15e | 2016-07-18 06:14:39 +0000 | [diff] [blame] | 2525 | case X86::VMOVSSZmr: | 
|  | 2526 | case X86::VMOVSDZmr: | 
| Elena Demikhovsky | a5d38a3 | 2014-01-23 14:27:26 +0000 | [diff] [blame] | 2527 | case X86::VMOVUPSZmr: | 
| Craig Topper | 650a15e | 2016-07-18 06:14:39 +0000 | [diff] [blame] | 2528 | case X86::VMOVUPSZ128mr: | 
|  | 2529 | case X86::VMOVUPSZ256mr: | 
| Elena Demikhovsky | a5d38a3 | 2014-01-23 14:27:26 +0000 | [diff] [blame] | 2530 | case X86::VMOVAPSZmr: | 
| Craig Topper | 650a15e | 2016-07-18 06:14:39 +0000 | [diff] [blame] | 2531 | case X86::VMOVAPSZ128mr: | 
|  | 2532 | case X86::VMOVAPSZ256mr: | 
|  | 2533 | case X86::VMOVUPDZmr: | 
|  | 2534 | case X86::VMOVUPDZ128mr: | 
|  | 2535 | case X86::VMOVUPDZ256mr: | 
|  | 2536 | case X86::VMOVAPDZmr: | 
|  | 2537 | case X86::VMOVAPDZ128mr: | 
|  | 2538 | case X86::VMOVAPDZ256mr: | 
|  | 2539 | case X86::VMOVDQA32Zmr: | 
|  | 2540 | case X86::VMOVDQA32Z128mr: | 
|  | 2541 | case X86::VMOVDQA32Z256mr: | 
|  | 2542 | case X86::VMOVDQU32Zmr: | 
|  | 2543 | case X86::VMOVDQU32Z128mr: | 
|  | 2544 | case X86::VMOVDQU32Z256mr: | 
|  | 2545 | case X86::VMOVDQA64Zmr: | 
|  | 2546 | case X86::VMOVDQA64Z128mr: | 
|  | 2547 | case X86::VMOVDQA64Z256mr: | 
|  | 2548 | case X86::VMOVDQU64Zmr: | 
|  | 2549 | case X86::VMOVDQU64Z128mr: | 
|  | 2550 | case X86::VMOVDQU64Z256mr: | 
|  | 2551 | case X86::VMOVDQU8Zmr: | 
|  | 2552 | case X86::VMOVDQU8Z128mr: | 
|  | 2553 | case X86::VMOVDQU8Z256mr: | 
|  | 2554 | case X86::VMOVDQU16Zmr: | 
|  | 2555 | case X86::VMOVDQU16Z128mr: | 
|  | 2556 | case X86::VMOVDQU16Z256mr: | 
| David Greene | 2f4c374 | 2009-11-13 00:29:53 +0000 | [diff] [blame] | 2557 | case X86::MMX_MOVD64mr: | 
|  | 2558 | case X86::MMX_MOVQ64mr: | 
|  | 2559 | case X86::MMX_MOVNTQmr: | 
| Craig Topper | 650a15e | 2016-07-18 06:14:39 +0000 | [diff] [blame] | 2560 | case X86::KMOVBmk: | 
|  | 2561 | case X86::KMOVWmk: | 
|  | 2562 | case X86::KMOVDmk: | 
|  | 2563 | case X86::KMOVQmk: | 
| David Greene | 2f4c374 | 2009-11-13 00:29:53 +0000 | [diff] [blame] | 2564 | return true; | 
|  | 2565 | } | 
|  | 2566 | return false; | 
|  | 2567 | } | 
|  | 2568 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2569 | unsigned X86InstrInfo::isLoadFromStackSlot(const MachineInstr &MI, | 
| David Greene | 2f4c374 | 2009-11-13 00:29:53 +0000 | [diff] [blame] | 2570 | int &FrameIndex) const { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2571 | if (isFrameLoadOpcode(MI.getOpcode())) | 
|  | 2572 | if (MI.getOperand(0).getSubReg() == 0 && isFrameOperand(MI, 1, FrameIndex)) | 
|  | 2573 | return MI.getOperand(0).getReg(); | 
| David Greene | 2f4c374 | 2009-11-13 00:29:53 +0000 | [diff] [blame] | 2574 | return 0; | 
|  | 2575 | } | 
|  | 2576 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2577 | unsigned X86InstrInfo::isLoadFromStackSlotPostFE(const MachineInstr &MI, | 
| David Greene | 2f4c374 | 2009-11-13 00:29:53 +0000 | [diff] [blame] | 2578 | int &FrameIndex) const { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2579 | if (isFrameLoadOpcode(MI.getOpcode())) { | 
| David Greene | 2f4c374 | 2009-11-13 00:29:53 +0000 | [diff] [blame] | 2580 | unsigned Reg; | 
|  | 2581 | if ((Reg = isLoadFromStackSlot(MI, FrameIndex))) | 
|  | 2582 | return Reg; | 
| David Greene | 70fdd57 | 2009-11-12 20:55:29 +0000 | [diff] [blame] | 2583 | // Check for post-frame index elimination operations | 
| David Greene | 0508e43 | 2009-12-04 22:38:46 +0000 | [diff] [blame] | 2584 | const MachineMemOperand *Dummy; | 
|  | 2585 | return hasLoadFromStackSlot(MI, Dummy, FrameIndex); | 
| Chris Lattner | bb53acd | 2006-02-02 20:12:32 +0000 | [diff] [blame] | 2586 | } | 
|  | 2587 | return 0; | 
|  | 2588 | } | 
|  | 2589 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2590 | unsigned X86InstrInfo::isStoreToStackSlot(const MachineInstr &MI, | 
| Chris Lattner | bb53acd | 2006-02-02 20:12:32 +0000 | [diff] [blame] | 2591 | int &FrameIndex) const { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2592 | if (isFrameStoreOpcode(MI.getOpcode())) | 
|  | 2593 | if (MI.getOperand(X86::AddrNumOperands).getSubReg() == 0 && | 
| Jakob Stoklund Olesen | 96a890a | 2010-07-27 04:17:01 +0000 | [diff] [blame] | 2594 | isFrameOperand(MI, 0, FrameIndex)) | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2595 | return MI.getOperand(X86::AddrNumOperands).getReg(); | 
| David Greene | 2f4c374 | 2009-11-13 00:29:53 +0000 | [diff] [blame] | 2596 | return 0; | 
|  | 2597 | } | 
|  | 2598 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2599 | unsigned X86InstrInfo::isStoreToStackSlotPostFE(const MachineInstr &MI, | 
| David Greene | 2f4c374 | 2009-11-13 00:29:53 +0000 | [diff] [blame] | 2600 | int &FrameIndex) const { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2601 | if (isFrameStoreOpcode(MI.getOpcode())) { | 
| David Greene | 2f4c374 | 2009-11-13 00:29:53 +0000 | [diff] [blame] | 2602 | unsigned Reg; | 
|  | 2603 | if ((Reg = isStoreToStackSlot(MI, FrameIndex))) | 
|  | 2604 | return Reg; | 
| David Greene | 70fdd57 | 2009-11-12 20:55:29 +0000 | [diff] [blame] | 2605 | // Check for post-frame index elimination operations | 
| David Greene | 0508e43 | 2009-12-04 22:38:46 +0000 | [diff] [blame] | 2606 | const MachineMemOperand *Dummy; | 
|  | 2607 | return hasStoreToStackSlot(MI, Dummy, FrameIndex); | 
| Chris Lattner | bb53acd | 2006-02-02 20:12:32 +0000 | [diff] [blame] | 2608 | } | 
|  | 2609 | return 0; | 
|  | 2610 | } | 
|  | 2611 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 2612 | /// Return true if register is PIC base; i.e.g defined by X86::MOVPC32r. | 
| Dan Gohman | 3b46030 | 2008-07-07 23:14:23 +0000 | [diff] [blame] | 2613 | static bool regIsPICBase(unsigned BaseReg, const MachineRegisterInfo &MRI) { | 
| Jakob Stoklund Olesen | 3b9a442 | 2012-08-08 00:40:47 +0000 | [diff] [blame] | 2614 | // Don't waste compile time scanning use-def chains of physregs. | 
|  | 2615 | if (!TargetRegisterInfo::isVirtualRegister(BaseReg)) | 
|  | 2616 | return false; | 
| Evan Cheng | 308e564 | 2008-03-27 01:45:11 +0000 | [diff] [blame] | 2617 | bool isPICBase = false; | 
| Owen Anderson | 16c6bf4 | 2014-03-13 23:12:04 +0000 | [diff] [blame] | 2618 | for (MachineRegisterInfo::def_instr_iterator I = MRI.def_instr_begin(BaseReg), | 
|  | 2619 | E = MRI.def_instr_end(); I != E; ++I) { | 
|  | 2620 | MachineInstr *DefMI = &*I; | 
| Evan Cheng | 308e564 | 2008-03-27 01:45:11 +0000 | [diff] [blame] | 2621 | if (DefMI->getOpcode() != X86::MOVPC32r) | 
|  | 2622 | return false; | 
|  | 2623 | assert(!isPICBase && "More than one PIC base?"); | 
|  | 2624 | isPICBase = true; | 
|  | 2625 | } | 
|  | 2626 | return isPICBase; | 
|  | 2627 | } | 
| Evan Cheng | 1973a46 | 2008-03-31 07:54:19 +0000 | [diff] [blame] | 2628 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2629 | bool X86InstrInfo::isReallyTriviallyReMaterializable(const MachineInstr &MI, | 
|  | 2630 | AliasAnalysis *AA) const { | 
|  | 2631 | switch (MI.getOpcode()) { | 
| Dan Gohman | 4a4a8eb | 2007-06-14 20:50:44 +0000 | [diff] [blame] | 2632 | default: break; | 
| Craig Topper | a0cabf1 | 2012-08-21 08:17:07 +0000 | [diff] [blame] | 2633 | case X86::MOV8rm: | 
|  | 2634 | case X86::MOV16rm: | 
|  | 2635 | case X86::MOV32rm: | 
|  | 2636 | case X86::MOV64rm: | 
|  | 2637 | case X86::LD_Fp64m: | 
|  | 2638 | case X86::MOVSSrm: | 
|  | 2639 | case X86::MOVSDrm: | 
|  | 2640 | case X86::MOVAPSrm: | 
|  | 2641 | case X86::MOVUPSrm: | 
|  | 2642 | case X86::MOVAPDrm: | 
|  | 2643 | case X86::MOVDQArm: | 
| Craig Topper | 922f10a | 2012-12-06 06:49:16 +0000 | [diff] [blame] | 2644 | case X86::MOVDQUrm: | 
| Craig Topper | a0cabf1 | 2012-08-21 08:17:07 +0000 | [diff] [blame] | 2645 | case X86::VMOVSSrm: | 
|  | 2646 | case X86::VMOVSDrm: | 
|  | 2647 | case X86::VMOVAPSrm: | 
|  | 2648 | case X86::VMOVUPSrm: | 
|  | 2649 | case X86::VMOVAPDrm: | 
|  | 2650 | case X86::VMOVDQArm: | 
| Craig Topper | 922f10a | 2012-12-06 06:49:16 +0000 | [diff] [blame] | 2651 | case X86::VMOVDQUrm: | 
| Craig Topper | a0cabf1 | 2012-08-21 08:17:07 +0000 | [diff] [blame] | 2652 | case X86::VMOVAPSYrm: | 
|  | 2653 | case X86::VMOVUPSYrm: | 
|  | 2654 | case X86::VMOVAPDYrm: | 
|  | 2655 | case X86::VMOVDQAYrm: | 
| Craig Topper | 922f10a | 2012-12-06 06:49:16 +0000 | [diff] [blame] | 2656 | case X86::VMOVDQUYrm: | 
| Craig Topper | a0cabf1 | 2012-08-21 08:17:07 +0000 | [diff] [blame] | 2657 | case X86::MMX_MOVD64rm: | 
|  | 2658 | case X86::MMX_MOVQ64rm: | 
|  | 2659 | case X86::FsVMOVAPSrm: | 
|  | 2660 | case X86::FsVMOVAPDrm: | 
|  | 2661 | case X86::FsMOVAPSrm: | 
| Igor Breger | f8e461f | 2015-10-26 08:37:12 +0000 | [diff] [blame] | 2662 | case X86::FsMOVAPDrm: | 
|  | 2663 | // AVX-512 | 
| Craig Topper | e4f868e | 2016-07-29 06:06:04 +0000 | [diff] [blame] | 2664 | case X86::VMOVSSZrm: | 
|  | 2665 | case X86::VMOVSDZrm: | 
| Igor Breger | f8e461f | 2015-10-26 08:37:12 +0000 | [diff] [blame] | 2666 | case X86::VMOVAPDZ128rm: | 
|  | 2667 | case X86::VMOVAPDZ256rm: | 
|  | 2668 | case X86::VMOVAPDZrm: | 
|  | 2669 | case X86::VMOVAPSZ128rm: | 
|  | 2670 | case X86::VMOVAPSZ256rm: | 
|  | 2671 | case X86::VMOVAPSZrm: | 
|  | 2672 | case X86::VMOVDQA32Z128rm: | 
|  | 2673 | case X86::VMOVDQA32Z256rm: | 
|  | 2674 | case X86::VMOVDQA32Zrm: | 
|  | 2675 | case X86::VMOVDQA64Z128rm: | 
|  | 2676 | case X86::VMOVDQA64Z256rm: | 
|  | 2677 | case X86::VMOVDQA64Zrm: | 
|  | 2678 | case X86::VMOVDQU16Z128rm: | 
|  | 2679 | case X86::VMOVDQU16Z256rm: | 
|  | 2680 | case X86::VMOVDQU16Zrm: | 
|  | 2681 | case X86::VMOVDQU32Z128rm: | 
|  | 2682 | case X86::VMOVDQU32Z256rm: | 
|  | 2683 | case X86::VMOVDQU32Zrm: | 
|  | 2684 | case X86::VMOVDQU64Z128rm: | 
|  | 2685 | case X86::VMOVDQU64Z256rm: | 
|  | 2686 | case X86::VMOVDQU64Zrm: | 
|  | 2687 | case X86::VMOVDQU8Z128rm: | 
|  | 2688 | case X86::VMOVDQU8Z256rm: | 
|  | 2689 | case X86::VMOVDQU8Zrm: | 
|  | 2690 | case X86::VMOVUPSZ128rm: | 
|  | 2691 | case X86::VMOVUPSZ256rm: | 
|  | 2692 | case X86::VMOVUPSZrm: { | 
| Craig Topper | a0cabf1 | 2012-08-21 08:17:07 +0000 | [diff] [blame] | 2693 | // Loads from constant pools are trivially rematerializable. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2694 | if (MI.getOperand(1 + X86::AddrBaseReg).isReg() && | 
|  | 2695 | MI.getOperand(1 + X86::AddrScaleAmt).isImm() && | 
|  | 2696 | MI.getOperand(1 + X86::AddrIndexReg).isReg() && | 
|  | 2697 | MI.getOperand(1 + X86::AddrIndexReg).getReg() == 0 && | 
|  | 2698 | MI.isInvariantLoad(AA)) { | 
|  | 2699 | unsigned BaseReg = MI.getOperand(1 + X86::AddrBaseReg).getReg(); | 
| Craig Topper | a0cabf1 | 2012-08-21 08:17:07 +0000 | [diff] [blame] | 2700 | if (BaseReg == 0 || BaseReg == X86::RIP) | 
|  | 2701 | return true; | 
|  | 2702 | // Allow re-materialization of PIC load. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2703 | if (!ReMatPICStubLoad && MI.getOperand(1 + X86::AddrDisp).isGlobal()) | 
| Craig Topper | a0cabf1 | 2012-08-21 08:17:07 +0000 | [diff] [blame] | 2704 | return false; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2705 | const MachineFunction &MF = *MI.getParent()->getParent(); | 
| Craig Topper | a0cabf1 | 2012-08-21 08:17:07 +0000 | [diff] [blame] | 2706 | const MachineRegisterInfo &MRI = MF.getRegInfo(); | 
|  | 2707 | return regIsPICBase(BaseReg, MRI); | 
| Evan Cheng | 94ba37f | 2008-02-22 09:25:47 +0000 | [diff] [blame] | 2708 | } | 
| Craig Topper | a0cabf1 | 2012-08-21 08:17:07 +0000 | [diff] [blame] | 2709 | return false; | 
|  | 2710 | } | 
| NAKAMURA Takumi | 9d29eff | 2011-01-26 02:03:37 +0000 | [diff] [blame] | 2711 |  | 
| Craig Topper | a0cabf1 | 2012-08-21 08:17:07 +0000 | [diff] [blame] | 2712 | case X86::LEA32r: | 
|  | 2713 | case X86::LEA64r: { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2714 | if (MI.getOperand(1 + X86::AddrScaleAmt).isImm() && | 
|  | 2715 | MI.getOperand(1 + X86::AddrIndexReg).isReg() && | 
|  | 2716 | MI.getOperand(1 + X86::AddrIndexReg).getReg() == 0 && | 
|  | 2717 | !MI.getOperand(1 + X86::AddrDisp).isReg()) { | 
| Craig Topper | a0cabf1 | 2012-08-21 08:17:07 +0000 | [diff] [blame] | 2718 | // lea fi#, lea GV, etc. are all rematerializable. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2719 | if (!MI.getOperand(1 + X86::AddrBaseReg).isReg()) | 
| Craig Topper | a0cabf1 | 2012-08-21 08:17:07 +0000 | [diff] [blame] | 2720 | return true; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2721 | unsigned BaseReg = MI.getOperand(1 + X86::AddrBaseReg).getReg(); | 
| Craig Topper | a0cabf1 | 2012-08-21 08:17:07 +0000 | [diff] [blame] | 2722 | if (BaseReg == 0) | 
|  | 2723 | return true; | 
|  | 2724 | // Allow re-materialization of lea PICBase + x. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2725 | const MachineFunction &MF = *MI.getParent()->getParent(); | 
| Craig Topper | a0cabf1 | 2012-08-21 08:17:07 +0000 | [diff] [blame] | 2726 | const MachineRegisterInfo &MRI = MF.getRegInfo(); | 
|  | 2727 | return regIsPICBase(BaseReg, MRI); | 
|  | 2728 | } | 
|  | 2729 | return false; | 
|  | 2730 | } | 
| Dan Gohman | 4a4a8eb | 2007-06-14 20:50:44 +0000 | [diff] [blame] | 2731 | } | 
| Evan Cheng | 29e62a5 | 2008-03-27 01:41:09 +0000 | [diff] [blame] | 2732 |  | 
| Dan Gohman | e8c1e42 | 2007-06-26 00:48:07 +0000 | [diff] [blame] | 2733 | // All other instructions marked M_REMATERIALIZABLE are always trivially | 
|  | 2734 | // rematerializable. | 
|  | 2735 | return true; | 
| Dan Gohman | 4a4a8eb | 2007-06-14 20:50:44 +0000 | [diff] [blame] | 2736 | } | 
|  | 2737 |  | 
| Alexey Volkov | 6226de6 | 2014-05-20 08:55:50 +0000 | [diff] [blame] | 2738 | bool X86InstrInfo::isSafeToClobberEFLAGS(MachineBasicBlock &MBB, | 
|  | 2739 | MachineBasicBlock::iterator I) const { | 
| Evan Cheng | b6dee6e | 2010-03-23 20:35:45 +0000 | [diff] [blame] | 2740 | MachineBasicBlock::iterator E = MBB.end(); | 
|  | 2741 |  | 
| Evan Cheng | 3f2ceac | 2008-06-24 07:10:51 +0000 | [diff] [blame] | 2742 | // For compile time consideration, if we are not able to determine the | 
| Dan Gohman | 0be8c2b | 2009-10-14 00:08:59 +0000 | [diff] [blame] | 2743 | // safety after visiting 4 instructions in each direction, we will assume | 
|  | 2744 | // it's not safe. | 
|  | 2745 | MachineBasicBlock::iterator Iter = I; | 
| Jakob Stoklund Olesen | f08354d | 2011-09-02 23:52:52 +0000 | [diff] [blame] | 2746 | for (unsigned i = 0; Iter != E && i < 4; ++i) { | 
| Evan Cheng | 3f2ceac | 2008-06-24 07:10:51 +0000 | [diff] [blame] | 2747 | bool SeenDef = false; | 
| Dan Gohman | 0be8c2b | 2009-10-14 00:08:59 +0000 | [diff] [blame] | 2748 | for (unsigned j = 0, e = Iter->getNumOperands(); j != e; ++j) { | 
|  | 2749 | MachineOperand &MO = Iter->getOperand(j); | 
| Jakob Stoklund Olesen | 4519fd0 | 2012-02-09 00:17:22 +0000 | [diff] [blame] | 2750 | if (MO.isRegMask() && MO.clobbersPhysReg(X86::EFLAGS)) | 
|  | 2751 | SeenDef = true; | 
| Dan Gohman | 0d1e9a8 | 2008-10-03 15:45:36 +0000 | [diff] [blame] | 2752 | if (!MO.isReg()) | 
| Evan Cheng | 3f2ceac | 2008-06-24 07:10:51 +0000 | [diff] [blame] | 2753 | continue; | 
|  | 2754 | if (MO.getReg() == X86::EFLAGS) { | 
|  | 2755 | if (MO.isUse()) | 
|  | 2756 | return false; | 
|  | 2757 | SeenDef = true; | 
|  | 2758 | } | 
|  | 2759 | } | 
|  | 2760 |  | 
|  | 2761 | if (SeenDef) | 
|  | 2762 | // This instruction defines EFLAGS, no need to look any further. | 
|  | 2763 | return true; | 
| Dan Gohman | 0be8c2b | 2009-10-14 00:08:59 +0000 | [diff] [blame] | 2764 | ++Iter; | 
| Evan Cheng | b6dee6e | 2010-03-23 20:35:45 +0000 | [diff] [blame] | 2765 | // Skip over DBG_VALUE. | 
|  | 2766 | while (Iter != E && Iter->isDebugValue()) | 
|  | 2767 | ++Iter; | 
| Jakob Stoklund Olesen | f08354d | 2011-09-02 23:52:52 +0000 | [diff] [blame] | 2768 | } | 
| Dan Gohman | c835458 | 2008-10-21 03:24:31 +0000 | [diff] [blame] | 2769 |  | 
| Jakob Stoklund Olesen | f08354d | 2011-09-02 23:52:52 +0000 | [diff] [blame] | 2770 | // It is safe to clobber EFLAGS at the end of a block of no successor has it | 
|  | 2771 | // live in. | 
|  | 2772 | if (Iter == E) { | 
| Craig Topper | ca66fc5 | 2015-12-20 18:41:57 +0000 | [diff] [blame] | 2773 | for (MachineBasicBlock *S : MBB.successors()) | 
|  | 2774 | if (S->isLiveIn(X86::EFLAGS)) | 
| Jakob Stoklund Olesen | f08354d | 2011-09-02 23:52:52 +0000 | [diff] [blame] | 2775 | return false; | 
|  | 2776 | return true; | 
| Dan Gohman | 0be8c2b | 2009-10-14 00:08:59 +0000 | [diff] [blame] | 2777 | } | 
|  | 2778 |  | 
| Evan Cheng | b6dee6e | 2010-03-23 20:35:45 +0000 | [diff] [blame] | 2779 | MachineBasicBlock::iterator B = MBB.begin(); | 
| Dan Gohman | 0be8c2b | 2009-10-14 00:08:59 +0000 | [diff] [blame] | 2780 | Iter = I; | 
|  | 2781 | for (unsigned i = 0; i < 4; ++i) { | 
|  | 2782 | // If we make it to the beginning of the block, it's safe to clobber | 
| Sylvestre Ledru | 91ce36c | 2012-09-27 10:14:43 +0000 | [diff] [blame] | 2783 | // EFLAGS iff EFLAGS is not live-in. | 
| Evan Cheng | b6dee6e | 2010-03-23 20:35:45 +0000 | [diff] [blame] | 2784 | if (Iter == B) | 
| Dan Gohman | 0be8c2b | 2009-10-14 00:08:59 +0000 | [diff] [blame] | 2785 | return !MBB.isLiveIn(X86::EFLAGS); | 
|  | 2786 |  | 
|  | 2787 | --Iter; | 
| Evan Cheng | b6dee6e | 2010-03-23 20:35:45 +0000 | [diff] [blame] | 2788 | // Skip over DBG_VALUE. | 
|  | 2789 | while (Iter != B && Iter->isDebugValue()) | 
|  | 2790 | --Iter; | 
|  | 2791 |  | 
| Dan Gohman | 0be8c2b | 2009-10-14 00:08:59 +0000 | [diff] [blame] | 2792 | bool SawKill = false; | 
|  | 2793 | for (unsigned j = 0, e = Iter->getNumOperands(); j != e; ++j) { | 
|  | 2794 | MachineOperand &MO = Iter->getOperand(j); | 
| Jakob Stoklund Olesen | 4519fd0 | 2012-02-09 00:17:22 +0000 | [diff] [blame] | 2795 | // A register mask may clobber EFLAGS, but we should still look for a | 
|  | 2796 | // live EFLAGS def. | 
|  | 2797 | if (MO.isRegMask() && MO.clobbersPhysReg(X86::EFLAGS)) | 
|  | 2798 | SawKill = true; | 
| Dan Gohman | 0be8c2b | 2009-10-14 00:08:59 +0000 | [diff] [blame] | 2799 | if (MO.isReg() && MO.getReg() == X86::EFLAGS) { | 
|  | 2800 | if (MO.isDef()) return MO.isDead(); | 
|  | 2801 | if (MO.isKill()) SawKill = true; | 
|  | 2802 | } | 
|  | 2803 | } | 
|  | 2804 |  | 
|  | 2805 | if (SawKill) | 
|  | 2806 | // This instruction kills EFLAGS and doesn't redefine it, so | 
|  | 2807 | // there's no need to look further. | 
| Dan Gohman | c835458 | 2008-10-21 03:24:31 +0000 | [diff] [blame] | 2808 | return true; | 
| Evan Cheng | 3f2ceac | 2008-06-24 07:10:51 +0000 | [diff] [blame] | 2809 | } | 
|  | 2810 |  | 
|  | 2811 | // Conservative answer. | 
|  | 2812 | return false; | 
|  | 2813 | } | 
|  | 2814 |  | 
| Evan Cheng | ed6e34f | 2008-03-31 20:40:39 +0000 | [diff] [blame] | 2815 | void X86InstrInfo::reMaterialize(MachineBasicBlock &MBB, | 
|  | 2816 | MachineBasicBlock::iterator I, | 
| Evan Cheng | 8451744 | 2009-07-16 09:20:10 +0000 | [diff] [blame] | 2817 | unsigned DestReg, unsigned SubIdx, | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2818 | const MachineInstr &Orig, | 
| Jakob Stoklund Olesen | a8ad977 | 2010-06-02 22:47:25 +0000 | [diff] [blame] | 2819 | const TargetRegisterInfo &TRI) const { | 
| Hans Wennborg | 08d5905 | 2015-12-15 17:10:28 +0000 | [diff] [blame] | 2820 | bool ClobbersEFLAGS = false; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2821 | for (const MachineOperand &MO : Orig.operands()) { | 
| Hans Wennborg | 08d5905 | 2015-12-15 17:10:28 +0000 | [diff] [blame] | 2822 | if (MO.isReg() && MO.isDef() && MO.getReg() == X86::EFLAGS) { | 
|  | 2823 | ClobbersEFLAGS = true; | 
|  | 2824 | break; | 
|  | 2825 | } | 
|  | 2826 | } | 
|  | 2827 |  | 
|  | 2828 | if (ClobbersEFLAGS && !isSafeToClobberEFLAGS(MBB, I)) { | 
|  | 2829 | // The instruction clobbers EFLAGS. Re-materialize as MOV32ri to avoid side | 
|  | 2830 | // effects. | 
|  | 2831 | int Value; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2832 | switch (Orig.getOpcode()) { | 
| Hans Wennborg | 08d5905 | 2015-12-15 17:10:28 +0000 | [diff] [blame] | 2833 | case X86::MOV32r0:  Value = 0; break; | 
|  | 2834 | case X86::MOV32r1:  Value = 1; break; | 
|  | 2835 | case X86::MOV32r_1: Value = -1; break; | 
|  | 2836 | default: | 
|  | 2837 | llvm_unreachable("Unexpected instruction!"); | 
|  | 2838 | } | 
|  | 2839 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2840 | const DebugLoc &DL = Orig.getDebugLoc(); | 
|  | 2841 | BuildMI(MBB, I, DL, get(X86::MOV32ri)) | 
|  | 2842 | .addOperand(Orig.getOperand(0)) | 
|  | 2843 | .addImm(Value); | 
| Tim Northover | 64ec0ff | 2013-05-30 13:19:42 +0000 | [diff] [blame] | 2844 | } else { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2845 | MachineInstr *MI = MBB.getParent()->CloneMachineInstr(&Orig); | 
| Evan Cheng | ed6e34f | 2008-03-31 20:40:39 +0000 | [diff] [blame] | 2846 | MBB.insert(I, MI); | 
| Evan Cheng | ed6e34f | 2008-03-31 20:40:39 +0000 | [diff] [blame] | 2847 | } | 
| Evan Cheng | 147cb76 | 2008-04-16 23:44:44 +0000 | [diff] [blame] | 2848 |  | 
| Duncan P. N. Exon Smith | 7b4c18e | 2016-07-12 03:18:50 +0000 | [diff] [blame] | 2849 | MachineInstr &NewMI = *std::prev(I); | 
|  | 2850 | NewMI.substituteRegister(Orig.getOperand(0).getReg(), DestReg, SubIdx, TRI); | 
| Evan Cheng | ed6e34f | 2008-03-31 20:40:39 +0000 | [diff] [blame] | 2851 | } | 
|  | 2852 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 2853 | /// True if MI has a condition code def, e.g. EFLAGS, that is not marked dead. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2854 | bool X86InstrInfo::hasLiveCondCodeDef(MachineInstr &MI) const { | 
|  | 2855 | for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { | 
|  | 2856 | MachineOperand &MO = MI.getOperand(i); | 
| Dan Gohman | 0d1e9a8 | 2008-10-03 15:45:36 +0000 | [diff] [blame] | 2857 | if (MO.isReg() && MO.isDef() && | 
| Evan Cheng | a8a9c15 | 2007-10-05 08:04:01 +0000 | [diff] [blame] | 2858 | MO.getReg() == X86::EFLAGS && !MO.isDead()) { | 
|  | 2859 | return true; | 
|  | 2860 | } | 
|  | 2861 | } | 
|  | 2862 | return false; | 
|  | 2863 | } | 
|  | 2864 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 2865 | /// Check whether the shift count for a machine operand is non-zero. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2866 | inline static unsigned getTruncatedShiftCount(MachineInstr &MI, | 
| David Majnemer | 7ea2a52 | 2013-05-22 08:13:02 +0000 | [diff] [blame] | 2867 | unsigned ShiftAmtOperandIdx) { | 
|  | 2868 | // The shift count is six bits with the REX.W prefix and five bits without. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2869 | unsigned ShiftCountMask = (MI.getDesc().TSFlags & X86II::REX_W) ? 63 : 31; | 
|  | 2870 | unsigned Imm = MI.getOperand(ShiftAmtOperandIdx).getImm(); | 
| David Majnemer | 7ea2a52 | 2013-05-22 08:13:02 +0000 | [diff] [blame] | 2871 | return Imm & ShiftCountMask; | 
|  | 2872 | } | 
|  | 2873 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 2874 | /// Check whether the given shift count is appropriate | 
| David Majnemer | 7ea2a52 | 2013-05-22 08:13:02 +0000 | [diff] [blame] | 2875 | /// can be represented by a LEA instruction. | 
|  | 2876 | inline static bool isTruncatedShiftCountForLEA(unsigned ShAmt) { | 
|  | 2877 | // Left shift instructions can be transformed into load-effective-address | 
|  | 2878 | // instructions if we can encode them appropriately. | 
| Sanjay Patel | dc87d14 | 2015-08-12 15:09:09 +0000 | [diff] [blame] | 2879 | // A LEA instruction utilizes a SIB byte to encode its scale factor. | 
| David Majnemer | 7ea2a52 | 2013-05-22 08:13:02 +0000 | [diff] [blame] | 2880 | // The SIB.scale field is two bits wide which means that we can encode any | 
|  | 2881 | // shift amount less than 4. | 
|  | 2882 | return ShAmt < 4 && ShAmt > 0; | 
|  | 2883 | } | 
|  | 2884 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2885 | bool X86InstrInfo::classifyLEAReg(MachineInstr &MI, const MachineOperand &Src, | 
|  | 2886 | unsigned Opc, bool AllowSP, unsigned &NewSrc, | 
|  | 2887 | bool &isKill, bool &isUndef, | 
| Matthias Braun | 7313ca6 | 2016-08-09 01:47:26 +0000 | [diff] [blame] | 2888 | MachineOperand &ImplicitOp, | 
|  | 2889 | LiveVariables *LV) const { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2890 | MachineFunction &MF = *MI.getParent()->getParent(); | 
| Tim Northover | 6833e3f | 2013-06-10 20:43:49 +0000 | [diff] [blame] | 2891 | const TargetRegisterClass *RC; | 
|  | 2892 | if (AllowSP) { | 
|  | 2893 | RC = Opc != X86::LEA32r ? &X86::GR64RegClass : &X86::GR32RegClass; | 
|  | 2894 | } else { | 
|  | 2895 | RC = Opc != X86::LEA32r ? | 
|  | 2896 | &X86::GR64_NOSPRegClass : &X86::GR32_NOSPRegClass; | 
|  | 2897 | } | 
|  | 2898 | unsigned SrcReg = Src.getReg(); | 
|  | 2899 |  | 
|  | 2900 | // For both LEA64 and LEA32 the register already has essentially the right | 
|  | 2901 | // type (32-bit or 64-bit) we may just need to forbid SP. | 
|  | 2902 | if (Opc != X86::LEA64_32r) { | 
|  | 2903 | NewSrc = SrcReg; | 
|  | 2904 | isKill = Src.isKill(); | 
|  | 2905 | isUndef = Src.isUndef(); | 
|  | 2906 |  | 
|  | 2907 | if (TargetRegisterInfo::isVirtualRegister(NewSrc) && | 
|  | 2908 | !MF.getRegInfo().constrainRegClass(NewSrc, RC)) | 
|  | 2909 | return false; | 
|  | 2910 |  | 
|  | 2911 | return true; | 
|  | 2912 | } | 
|  | 2913 |  | 
|  | 2914 | // This is for an LEA64_32r and incoming registers are 32-bit. One way or | 
|  | 2915 | // another we need to add 64-bit registers to the final MI. | 
|  | 2916 | if (TargetRegisterInfo::isPhysicalRegister(SrcReg)) { | 
|  | 2917 | ImplicitOp = Src; | 
|  | 2918 | ImplicitOp.setImplicit(); | 
|  | 2919 |  | 
| Craig Topper | 91dab7b | 2015-12-25 22:09:45 +0000 | [diff] [blame] | 2920 | NewSrc = getX86SubSuperRegister(Src.getReg(), 64); | 
| Matthias Braun | ca8210a | 2016-07-21 00:33:38 +0000 | [diff] [blame] | 2921 | isKill = Src.isKill(); | 
|  | 2922 | isUndef = Src.isUndef(); | 
| Tim Northover | 6833e3f | 2013-06-10 20:43:49 +0000 | [diff] [blame] | 2923 | } else { | 
|  | 2924 | // Virtual register of the wrong class, we have to create a temporary 64-bit | 
|  | 2925 | // vreg to feed into the LEA. | 
|  | 2926 | NewSrc = MF.getRegInfo().createVirtualRegister(RC); | 
| Matthias Braun | 7313ca6 | 2016-08-09 01:47:26 +0000 | [diff] [blame] | 2927 | MachineInstr *Copy = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), | 
|  | 2928 | get(TargetOpcode::COPY)) | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2929 | .addReg(NewSrc, RegState::Define | RegState::Undef, X86::sub_32bit) | 
| Tim Northover | 6833e3f | 2013-06-10 20:43:49 +0000 | [diff] [blame] | 2930 | .addOperand(Src); | 
|  | 2931 |  | 
|  | 2932 | // Which is obviously going to be dead after we're done with it. | 
|  | 2933 | isKill = true; | 
|  | 2934 | isUndef = false; | 
| Matthias Braun | 7313ca6 | 2016-08-09 01:47:26 +0000 | [diff] [blame] | 2935 |  | 
|  | 2936 | if (LV) | 
|  | 2937 | LV->replaceKillInstruction(SrcReg, MI, *Copy); | 
| Tim Northover | 6833e3f | 2013-06-10 20:43:49 +0000 | [diff] [blame] | 2938 | } | 
|  | 2939 |  | 
|  | 2940 | // We've set all the parameters without issue. | 
|  | 2941 | return true; | 
|  | 2942 | } | 
|  | 2943 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 2944 | /// Helper for convertToThreeAddress when 16-bit LEA is disabled, use 32-bit | 
|  | 2945 | /// LEA to form 3-address code by promoting to a 32-bit superregister and then | 
|  | 2946 | /// truncating back down to a 16-bit subregister. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2947 | MachineInstr *X86InstrInfo::convertToThreeAddressWithLEA( | 
|  | 2948 | unsigned MIOpc, MachineFunction::iterator &MFI, MachineInstr &MI, | 
|  | 2949 | LiveVariables *LV) const { | 
|  | 2950 | MachineBasicBlock::iterator MBBI = MI.getIterator(); | 
|  | 2951 | unsigned Dest = MI.getOperand(0).getReg(); | 
|  | 2952 | unsigned Src = MI.getOperand(1).getReg(); | 
|  | 2953 | bool isDead = MI.getOperand(0).isDead(); | 
|  | 2954 | bool isKill = MI.getOperand(1).isKill(); | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 2955 |  | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 2956 | MachineRegisterInfo &RegInfo = MFI->getParent()->getRegInfo(); | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 2957 | unsigned leaOutReg = RegInfo.createVirtualRegister(&X86::GR32RegClass); | 
| Tim Northover | 6833e3f | 2013-06-10 20:43:49 +0000 | [diff] [blame] | 2958 | unsigned Opc, leaInReg; | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 2959 | if (Subtarget.is64Bit()) { | 
| Tim Northover | 6833e3f | 2013-06-10 20:43:49 +0000 | [diff] [blame] | 2960 | Opc = X86::LEA64_32r; | 
|  | 2961 | leaInReg = RegInfo.createVirtualRegister(&X86::GR64_NOSPRegClass); | 
|  | 2962 | } else { | 
|  | 2963 | Opc = X86::LEA32r; | 
|  | 2964 | leaInReg = RegInfo.createVirtualRegister(&X86::GR32_NOSPRegClass); | 
|  | 2965 | } | 
| NAKAMURA Takumi | 9d29eff | 2011-01-26 02:03:37 +0000 | [diff] [blame] | 2966 |  | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 2967 | // Build and insert into an implicit UNDEF value. This is OK because | 
| NAKAMURA Takumi | 9d29eff | 2011-01-26 02:03:37 +0000 | [diff] [blame] | 2968 | // well be shifting and then extracting the lower 16-bits. | 
| Evan Cheng | 26fdd72 | 2009-12-12 20:03:14 +0000 | [diff] [blame] | 2969 | // This has the potential to cause partial register stall. e.g. | 
| Evan Cheng | 3974c8d | 2009-12-12 18:55:26 +0000 | [diff] [blame] | 2970 | //   movw    (%rbp,%rcx,2), %dx | 
|  | 2971 | //   leal    -65(%rdx), %esi | 
| Evan Cheng | 26fdd72 | 2009-12-12 20:03:14 +0000 | [diff] [blame] | 2972 | // But testing has shown this *does* help performance in 64-bit mode (at | 
|  | 2973 | // least on modern x86 machines). | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2974 | BuildMI(*MFI, MBBI, MI.getDebugLoc(), get(X86::IMPLICIT_DEF), leaInReg); | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 2975 | MachineInstr *InsMI = | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2976 | BuildMI(*MFI, MBBI, MI.getDebugLoc(), get(TargetOpcode::COPY)) | 
|  | 2977 | .addReg(leaInReg, RegState::Define, X86::sub_16bit) | 
|  | 2978 | .addReg(Src, getKillRegState(isKill)); | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 2979 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2980 | MachineInstrBuilder MIB = | 
|  | 2981 | BuildMI(*MFI, MBBI, MI.getDebugLoc(), get(Opc), leaOutReg); | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 2982 | switch (MIOpc) { | 
| Craig Topper | 4bc3e5a | 2012-08-21 08:16:16 +0000 | [diff] [blame] | 2983 | default: llvm_unreachable("Unreachable!"); | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 2984 | case X86::SHL16ri: { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 2985 | unsigned ShAmt = MI.getOperand(2).getImm(); | 
| Aaron Ballman | ef0fe1e | 2016-03-30 21:30:00 +0000 | [diff] [blame] | 2986 | MIB.addReg(0).addImm(1ULL << ShAmt) | 
| Chris Lattner | f469307 | 2010-07-08 23:46:44 +0000 | [diff] [blame] | 2987 | .addReg(leaInReg, RegState::Kill).addImm(0).addReg(0); | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 2988 | break; | 
|  | 2989 | } | 
|  | 2990 | case X86::INC16r: | 
| Chris Lattner | f469307 | 2010-07-08 23:46:44 +0000 | [diff] [blame] | 2991 | addRegOffset(MIB, leaInReg, true, 1); | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 2992 | break; | 
|  | 2993 | case X86::DEC16r: | 
| Chris Lattner | f469307 | 2010-07-08 23:46:44 +0000 | [diff] [blame] | 2994 | addRegOffset(MIB, leaInReg, true, -1); | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 2995 | break; | 
|  | 2996 | case X86::ADD16ri: | 
|  | 2997 | case X86::ADD16ri8: | 
| Chris Lattner | dd77477 | 2010-10-08 03:57:25 +0000 | [diff] [blame] | 2998 | case X86::ADD16ri_DB: | 
|  | 2999 | case X86::ADD16ri8_DB: | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3000 | addRegOffset(MIB, leaInReg, true, MI.getOperand(2).getImm()); | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 3001 | break; | 
| Chris Lattner | 626656a | 2010-10-08 03:54:52 +0000 | [diff] [blame] | 3002 | case X86::ADD16rr: | 
|  | 3003 | case X86::ADD16rr_DB: { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3004 | unsigned Src2 = MI.getOperand(2).getReg(); | 
|  | 3005 | bool isKill2 = MI.getOperand(2).isKill(); | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 3006 | unsigned leaInReg2 = 0; | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 3007 | MachineInstr *InsMI2 = nullptr; | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 3008 | if (Src == Src2) { | 
|  | 3009 | // ADD16rr %reg1028<kill>, %reg1028 | 
|  | 3010 | // just a single insert_subreg. | 
|  | 3011 | addRegReg(MIB, leaInReg, true, leaInReg, false); | 
|  | 3012 | } else { | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 3013 | if (Subtarget.is64Bit()) | 
| Tim Northover | 6833e3f | 2013-06-10 20:43:49 +0000 | [diff] [blame] | 3014 | leaInReg2 = RegInfo.createVirtualRegister(&X86::GR64_NOSPRegClass); | 
|  | 3015 | else | 
|  | 3016 | leaInReg2 = RegInfo.createVirtualRegister(&X86::GR32_NOSPRegClass); | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 3017 | // Build and insert into an implicit UNDEF value. This is OK because | 
| NAKAMURA Takumi | 9d29eff | 2011-01-26 02:03:37 +0000 | [diff] [blame] | 3018 | // well be shifting and then extracting the lower 16-bits. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3019 | BuildMI(*MFI, &*MIB, MI.getDebugLoc(), get(X86::IMPLICIT_DEF), leaInReg2); | 
|  | 3020 | InsMI2 = BuildMI(*MFI, &*MIB, MI.getDebugLoc(), get(TargetOpcode::COPY)) | 
|  | 3021 | .addReg(leaInReg2, RegState::Define, X86::sub_16bit) | 
|  | 3022 | .addReg(Src2, getKillRegState(isKill2)); | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 3023 | addRegReg(MIB, leaInReg, true, leaInReg2, true); | 
|  | 3024 | } | 
|  | 3025 | if (LV && isKill2 && InsMI2) | 
| Duncan P. N. Exon Smith | d26fdc8 | 2016-07-01 01:51:32 +0000 | [diff] [blame] | 3026 | LV->replaceKillInstruction(Src2, MI, *InsMI2); | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 3027 | break; | 
|  | 3028 | } | 
|  | 3029 | } | 
|  | 3030 |  | 
|  | 3031 | MachineInstr *NewMI = MIB; | 
|  | 3032 | MachineInstr *ExtMI = | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3033 | BuildMI(*MFI, MBBI, MI.getDebugLoc(), get(TargetOpcode::COPY)) | 
|  | 3034 | .addReg(Dest, RegState::Define | getDeadRegState(isDead)) | 
|  | 3035 | .addReg(leaOutReg, RegState::Kill, X86::sub_16bit); | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 3036 |  | 
|  | 3037 | if (LV) { | 
|  | 3038 | // Update live variables | 
|  | 3039 | LV->getVarInfo(leaInReg).Kills.push_back(NewMI); | 
|  | 3040 | LV->getVarInfo(leaOutReg).Kills.push_back(ExtMI); | 
|  | 3041 | if (isKill) | 
| Duncan P. N. Exon Smith | d26fdc8 | 2016-07-01 01:51:32 +0000 | [diff] [blame] | 3042 | LV->replaceKillInstruction(Src, MI, *InsMI); | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 3043 | if (isDead) | 
| Duncan P. N. Exon Smith | d26fdc8 | 2016-07-01 01:51:32 +0000 | [diff] [blame] | 3044 | LV->replaceKillInstruction(Dest, MI, *ExtMI); | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 3045 | } | 
|  | 3046 |  | 
|  | 3047 | return ExtMI; | 
|  | 3048 | } | 
|  | 3049 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 3050 | /// This method must be implemented by targets that | 
| Chris Lattner | b7782d7 | 2005-01-02 02:37:07 +0000 | [diff] [blame] | 3051 | /// set the M_CONVERTIBLE_TO_3_ADDR flag.  When this flag is set, the target | 
|  | 3052 | /// may be able to convert a two-address instruction into a true | 
|  | 3053 | /// three-address instruction on demand.  This allows the X86 target (for | 
|  | 3054 | /// example) to convert ADD and SHL instructions into LEA instructions if they | 
|  | 3055 | /// would require register copies due to two-addressness. | 
|  | 3056 | /// | 
|  | 3057 | /// This method returns a null pointer if the transformation cannot be | 
|  | 3058 | /// performed, otherwise it returns the new instruction. | 
|  | 3059 | /// | 
| Evan Cheng | 07fc107 | 2006-12-01 21:52:41 +0000 | [diff] [blame] | 3060 | MachineInstr * | 
|  | 3061 | X86InstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3062 | MachineInstr &MI, LiveVariables *LV) const { | 
| David Majnemer | 7ea2a52 | 2013-05-22 08:13:02 +0000 | [diff] [blame] | 3063 | // The following opcodes also sets the condition code register(s). Only | 
|  | 3064 | // convert them to equivalent lea if the condition code register def's | 
|  | 3065 | // are dead! | 
|  | 3066 | if (hasLiveCondCodeDef(MI)) | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 3067 | return nullptr; | 
| David Majnemer | 7ea2a52 | 2013-05-22 08:13:02 +0000 | [diff] [blame] | 3068 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3069 | MachineFunction &MF = *MI.getParent()->getParent(); | 
| Chris Lattner | b7782d7 | 2005-01-02 02:37:07 +0000 | [diff] [blame] | 3070 | // All instructions input are two-addr instructions.  Get the known operands. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3071 | const MachineOperand &Dest = MI.getOperand(0); | 
|  | 3072 | const MachineOperand &Src = MI.getOperand(1); | 
| Chris Lattner | b7782d7 | 2005-01-02 02:37:07 +0000 | [diff] [blame] | 3073 |  | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 3074 | MachineInstr *NewMI = nullptr; | 
| Evan Cheng | 07fc107 | 2006-12-01 21:52:41 +0000 | [diff] [blame] | 3075 | // FIXME: 16-bit LEA's are really slow on Athlons, but not bad on P4's.  When | 
| Chris Lattner | 3e1d917 | 2007-03-20 06:08:29 +0000 | [diff] [blame] | 3076 | // we have better subtarget support, enable the 16-bit LEA generation here. | 
| Evan Cheng | 26fdd72 | 2009-12-12 20:03:14 +0000 | [diff] [blame] | 3077 | // 16-bit LEA is also slow on Core2. | 
| Evan Cheng | 07fc107 | 2006-12-01 21:52:41 +0000 | [diff] [blame] | 3078 | bool DisableLEA16 = true; | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 3079 | bool is64Bit = Subtarget.is64Bit(); | 
| Evan Cheng | 07fc107 | 2006-12-01 21:52:41 +0000 | [diff] [blame] | 3080 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3081 | unsigned MIOpc = MI.getOpcode(); | 
| Evan Cheng | fa2c828 | 2007-10-05 20:34:26 +0000 | [diff] [blame] | 3082 | switch (MIOpc) { | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3083 | default: return nullptr; | 
| Chris Lattner | bcd3885 | 2007-03-28 18:12:31 +0000 | [diff] [blame] | 3084 | case X86::SHL64ri: { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3085 | assert(MI.getNumOperands() >= 3 && "Unknown shift instruction!"); | 
| David Majnemer | 7ea2a52 | 2013-05-22 08:13:02 +0000 | [diff] [blame] | 3086 | unsigned ShAmt = getTruncatedShiftCount(MI, 2); | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 3087 | if (!isTruncatedShiftCountForLEA(ShAmt)) return nullptr; | 
| Evan Cheng | 7d98a48 | 2008-07-03 09:09:37 +0000 | [diff] [blame] | 3088 |  | 
| Jakob Stoklund Olesen | b19bae4 | 2010-10-07 00:07:26 +0000 | [diff] [blame] | 3089 | // LEA can't handle RSP. | 
| Jakob Stoklund Olesen | 7030427 | 2012-08-23 22:36:31 +0000 | [diff] [blame] | 3090 | if (TargetRegisterInfo::isVirtualRegister(Src.getReg()) && | 
|  | 3091 | !MF.getRegInfo().constrainRegClass(Src.getReg(), | 
|  | 3092 | &X86::GR64_NOSPRegClass)) | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 3093 | return nullptr; | 
| Jakob Stoklund Olesen | b19bae4 | 2010-10-07 00:07:26 +0000 | [diff] [blame] | 3094 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3095 | NewMI = BuildMI(MF, MI.getDebugLoc(), get(X86::LEA64r)) | 
|  | 3096 | .addOperand(Dest) | 
|  | 3097 | .addReg(0) | 
|  | 3098 | .addImm(1ULL << ShAmt) | 
|  | 3099 | .addOperand(Src) | 
|  | 3100 | .addImm(0) | 
|  | 3101 | .addReg(0); | 
| Chris Lattner | bcd3885 | 2007-03-28 18:12:31 +0000 | [diff] [blame] | 3102 | break; | 
|  | 3103 | } | 
| Chris Lattner | 3e1d917 | 2007-03-20 06:08:29 +0000 | [diff] [blame] | 3104 | case X86::SHL32ri: { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3105 | assert(MI.getNumOperands() >= 3 && "Unknown shift instruction!"); | 
| David Majnemer | 7ea2a52 | 2013-05-22 08:13:02 +0000 | [diff] [blame] | 3106 | unsigned ShAmt = getTruncatedShiftCount(MI, 2); | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 3107 | if (!isTruncatedShiftCountForLEA(ShAmt)) return nullptr; | 
| Evan Cheng | 7d98a48 | 2008-07-03 09:09:37 +0000 | [diff] [blame] | 3108 |  | 
| Tim Northover | 6833e3f | 2013-06-10 20:43:49 +0000 | [diff] [blame] | 3109 | unsigned Opc = is64Bit ? X86::LEA64_32r : X86::LEA32r; | 
|  | 3110 |  | 
| Jakob Stoklund Olesen | b19bae4 | 2010-10-07 00:07:26 +0000 | [diff] [blame] | 3111 | // LEA can't handle ESP. | 
| Tim Northover | 6833e3f | 2013-06-10 20:43:49 +0000 | [diff] [blame] | 3112 | bool isKill, isUndef; | 
|  | 3113 | unsigned SrcReg; | 
|  | 3114 | MachineOperand ImplicitOp = MachineOperand::CreateReg(0, false); | 
|  | 3115 | if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/ false, | 
| Matthias Braun | 7313ca6 | 2016-08-09 01:47:26 +0000 | [diff] [blame] | 3116 | SrcReg, isKill, isUndef, ImplicitOp, LV)) | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 3117 | return nullptr; | 
| Jakob Stoklund Olesen | b19bae4 | 2010-10-07 00:07:26 +0000 | [diff] [blame] | 3118 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3119 | MachineInstrBuilder MIB = | 
|  | 3120 | BuildMI(MF, MI.getDebugLoc(), get(Opc)) | 
|  | 3121 | .addOperand(Dest) | 
|  | 3122 | .addReg(0) | 
|  | 3123 | .addImm(1ULL << ShAmt) | 
|  | 3124 | .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)) | 
|  | 3125 | .addImm(0) | 
|  | 3126 | .addReg(0); | 
| Tim Northover | 6833e3f | 2013-06-10 20:43:49 +0000 | [diff] [blame] | 3127 | if (ImplicitOp.getReg() != 0) | 
|  | 3128 | MIB.addOperand(ImplicitOp); | 
|  | 3129 | NewMI = MIB; | 
|  | 3130 |  | 
| Chris Lattner | 3e1d917 | 2007-03-20 06:08:29 +0000 | [diff] [blame] | 3131 | break; | 
|  | 3132 | } | 
|  | 3133 | case X86::SHL16ri: { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3134 | assert(MI.getNumOperands() >= 3 && "Unknown shift instruction!"); | 
| David Majnemer | 7ea2a52 | 2013-05-22 08:13:02 +0000 | [diff] [blame] | 3135 | unsigned ShAmt = getTruncatedShiftCount(MI, 2); | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 3136 | if (!isTruncatedShiftCountForLEA(ShAmt)) return nullptr; | 
| Evan Cheng | 7d98a48 | 2008-07-03 09:09:37 +0000 | [diff] [blame] | 3137 |  | 
| Evan Cheng | 766a73f | 2009-12-11 06:01:48 +0000 | [diff] [blame] | 3138 | if (DisableLEA16) | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3139 | return is64Bit ? convertToThreeAddressWithLEA(MIOpc, MFI, MI, LV) | 
|  | 3140 | : nullptr; | 
|  | 3141 | NewMI = BuildMI(MF, MI.getDebugLoc(), get(X86::LEA16r)) | 
|  | 3142 | .addOperand(Dest) | 
|  | 3143 | .addReg(0) | 
|  | 3144 | .addImm(1ULL << ShAmt) | 
|  | 3145 | .addOperand(Src) | 
|  | 3146 | .addImm(0) | 
|  | 3147 | .addReg(0); | 
| Chris Lattner | 3e1d917 | 2007-03-20 06:08:29 +0000 | [diff] [blame] | 3148 | break; | 
| Evan Cheng | 66f849b | 2006-05-30 20:26:50 +0000 | [diff] [blame] | 3149 | } | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3150 | case X86::INC64r: | 
|  | 3151 | case X86::INC32r: { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3152 | assert(MI.getNumOperands() >= 2 && "Unknown inc instruction!"); | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3153 | unsigned Opc = MIOpc == X86::INC64r ? X86::LEA64r | 
|  | 3154 | : (is64Bit ? X86::LEA64_32r : X86::LEA32r); | 
|  | 3155 | bool isKill, isUndef; | 
|  | 3156 | unsigned SrcReg; | 
|  | 3157 | MachineOperand ImplicitOp = MachineOperand::CreateReg(0, false); | 
|  | 3158 | if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/ false, | 
| Matthias Braun | 7313ca6 | 2016-08-09 01:47:26 +0000 | [diff] [blame] | 3159 | SrcReg, isKill, isUndef, ImplicitOp, LV)) | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3160 | return nullptr; | 
| Evan Cheng | 66f849b | 2006-05-30 20:26:50 +0000 | [diff] [blame] | 3161 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3162 | MachineInstrBuilder MIB = | 
|  | 3163 | BuildMI(MF, MI.getDebugLoc(), get(Opc)) | 
|  | 3164 | .addOperand(Dest) | 
|  | 3165 | .addReg(SrcReg, | 
|  | 3166 | getKillRegState(isKill) | getUndefRegState(isUndef)); | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3167 | if (ImplicitOp.getReg() != 0) | 
|  | 3168 | MIB.addOperand(ImplicitOp); | 
| Jakob Stoklund Olesen | b19bae4 | 2010-10-07 00:07:26 +0000 | [diff] [blame] | 3169 |  | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3170 | NewMI = addOffset(MIB, 1); | 
|  | 3171 | break; | 
| Evan Cheng | fa2c828 | 2007-10-05 20:34:26 +0000 | [diff] [blame] | 3172 | } | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3173 | case X86::INC16r: | 
|  | 3174 | if (DisableLEA16) | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3175 | return is64Bit ? convertToThreeAddressWithLEA(MIOpc, MFI, MI, LV) | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3176 | : nullptr; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3177 | assert(MI.getNumOperands() >= 2 && "Unknown inc instruction!"); | 
|  | 3178 | NewMI = addOffset(BuildMI(MF, MI.getDebugLoc(), get(X86::LEA16r)) | 
|  | 3179 | .addOperand(Dest) | 
|  | 3180 | .addOperand(Src), | 
|  | 3181 | 1); | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3182 | break; | 
|  | 3183 | case X86::DEC64r: | 
|  | 3184 | case X86::DEC32r: { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3185 | assert(MI.getNumOperands() >= 2 && "Unknown dec instruction!"); | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3186 | unsigned Opc = MIOpc == X86::DEC64r ? X86::LEA64r | 
|  | 3187 | : (is64Bit ? X86::LEA64_32r : X86::LEA32r); | 
|  | 3188 |  | 
|  | 3189 | bool isKill, isUndef; | 
|  | 3190 | unsigned SrcReg; | 
|  | 3191 | MachineOperand ImplicitOp = MachineOperand::CreateReg(0, false); | 
|  | 3192 | if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/ false, | 
| Matthias Braun | 7313ca6 | 2016-08-09 01:47:26 +0000 | [diff] [blame] | 3193 | SrcReg, isKill, isUndef, ImplicitOp, LV)) | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3194 | return nullptr; | 
|  | 3195 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3196 | MachineInstrBuilder MIB = BuildMI(MF, MI.getDebugLoc(), get(Opc)) | 
|  | 3197 | .addOperand(Dest) | 
|  | 3198 | .addReg(SrcReg, getUndefRegState(isUndef) | | 
|  | 3199 | getKillRegState(isKill)); | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3200 | if (ImplicitOp.getReg() != 0) | 
|  | 3201 | MIB.addOperand(ImplicitOp); | 
|  | 3202 |  | 
|  | 3203 | NewMI = addOffset(MIB, -1); | 
|  | 3204 |  | 
|  | 3205 | break; | 
|  | 3206 | } | 
|  | 3207 | case X86::DEC16r: | 
|  | 3208 | if (DisableLEA16) | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3209 | return is64Bit ? convertToThreeAddressWithLEA(MIOpc, MFI, MI, LV) | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3210 | : nullptr; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3211 | assert(MI.getNumOperands() >= 2 && "Unknown dec instruction!"); | 
|  | 3212 | NewMI = addOffset(BuildMI(MF, MI.getDebugLoc(), get(X86::LEA16r)) | 
|  | 3213 | .addOperand(Dest) | 
|  | 3214 | .addOperand(Src), | 
|  | 3215 | -1); | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3216 | break; | 
|  | 3217 | case X86::ADD64rr: | 
|  | 3218 | case X86::ADD64rr_DB: | 
|  | 3219 | case X86::ADD32rr: | 
|  | 3220 | case X86::ADD32rr_DB: { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3221 | assert(MI.getNumOperands() >= 3 && "Unknown add instruction!"); | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3222 | unsigned Opc; | 
|  | 3223 | if (MIOpc == X86::ADD64rr || MIOpc == X86::ADD64rr_DB) | 
|  | 3224 | Opc = X86::LEA64r; | 
|  | 3225 | else | 
|  | 3226 | Opc = is64Bit ? X86::LEA64_32r : X86::LEA32r; | 
|  | 3227 |  | 
|  | 3228 | bool isKill, isUndef; | 
|  | 3229 | unsigned SrcReg; | 
|  | 3230 | MachineOperand ImplicitOp = MachineOperand::CreateReg(0, false); | 
|  | 3231 | if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/ true, | 
| Matthias Braun | 7313ca6 | 2016-08-09 01:47:26 +0000 | [diff] [blame] | 3232 | SrcReg, isKill, isUndef, ImplicitOp, LV)) | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3233 | return nullptr; | 
|  | 3234 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3235 | const MachineOperand &Src2 = MI.getOperand(2); | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3236 | bool isKill2, isUndef2; | 
|  | 3237 | unsigned SrcReg2; | 
|  | 3238 | MachineOperand ImplicitOp2 = MachineOperand::CreateReg(0, false); | 
|  | 3239 | if (!classifyLEAReg(MI, Src2, Opc, /*AllowSP=*/ false, | 
| Matthias Braun | 7313ca6 | 2016-08-09 01:47:26 +0000 | [diff] [blame] | 3240 | SrcReg2, isKill2, isUndef2, ImplicitOp2, LV)) | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3241 | return nullptr; | 
|  | 3242 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3243 | MachineInstrBuilder MIB = | 
|  | 3244 | BuildMI(MF, MI.getDebugLoc(), get(Opc)).addOperand(Dest); | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3245 | if (ImplicitOp.getReg() != 0) | 
|  | 3246 | MIB.addOperand(ImplicitOp); | 
|  | 3247 | if (ImplicitOp2.getReg() != 0) | 
|  | 3248 | MIB.addOperand(ImplicitOp2); | 
|  | 3249 |  | 
|  | 3250 | NewMI = addRegReg(MIB, SrcReg, isKill, SrcReg2, isKill2); | 
|  | 3251 |  | 
|  | 3252 | // Preserve undefness of the operands. | 
|  | 3253 | NewMI->getOperand(1).setIsUndef(isUndef); | 
|  | 3254 | NewMI->getOperand(3).setIsUndef(isUndef2); | 
|  | 3255 |  | 
|  | 3256 | if (LV && Src2.isKill()) | 
| Duncan P. N. Exon Smith | d26fdc8 | 2016-07-01 01:51:32 +0000 | [diff] [blame] | 3257 | LV->replaceKillInstruction(SrcReg2, MI, *NewMI); | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3258 | break; | 
|  | 3259 | } | 
|  | 3260 | case X86::ADD16rr: | 
|  | 3261 | case X86::ADD16rr_DB: { | 
|  | 3262 | if (DisableLEA16) | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3263 | return is64Bit ? convertToThreeAddressWithLEA(MIOpc, MFI, MI, LV) | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3264 | : nullptr; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3265 | assert(MI.getNumOperands() >= 3 && "Unknown add instruction!"); | 
|  | 3266 | unsigned Src2 = MI.getOperand(2).getReg(); | 
|  | 3267 | bool isKill2 = MI.getOperand(2).isKill(); | 
|  | 3268 | NewMI = addRegReg( | 
|  | 3269 | BuildMI(MF, MI.getDebugLoc(), get(X86::LEA16r)).addOperand(Dest), | 
|  | 3270 | Src.getReg(), Src.isKill(), Src2, isKill2); | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3271 |  | 
|  | 3272 | // Preserve undefness of the operands. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3273 | bool isUndef = MI.getOperand(1).isUndef(); | 
|  | 3274 | bool isUndef2 = MI.getOperand(2).isUndef(); | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3275 | NewMI->getOperand(1).setIsUndef(isUndef); | 
|  | 3276 | NewMI->getOperand(3).setIsUndef(isUndef2); | 
|  | 3277 |  | 
|  | 3278 | if (LV && isKill2) | 
| Duncan P. N. Exon Smith | d26fdc8 | 2016-07-01 01:51:32 +0000 | [diff] [blame] | 3279 | LV->replaceKillInstruction(Src2, MI, *NewMI); | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3280 | break; | 
|  | 3281 | } | 
|  | 3282 | case X86::ADD64ri32: | 
|  | 3283 | case X86::ADD64ri8: | 
|  | 3284 | case X86::ADD64ri32_DB: | 
|  | 3285 | case X86::ADD64ri8_DB: | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3286 | assert(MI.getNumOperands() >= 3 && "Unknown add instruction!"); | 
|  | 3287 | NewMI = addOffset(BuildMI(MF, MI.getDebugLoc(), get(X86::LEA64r)) | 
|  | 3288 | .addOperand(Dest) | 
|  | 3289 | .addOperand(Src), | 
|  | 3290 | MI.getOperand(2).getImm()); | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3291 | break; | 
|  | 3292 | case X86::ADD32ri: | 
|  | 3293 | case X86::ADD32ri8: | 
|  | 3294 | case X86::ADD32ri_DB: | 
|  | 3295 | case X86::ADD32ri8_DB: { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3296 | assert(MI.getNumOperands() >= 3 && "Unknown add instruction!"); | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3297 | unsigned Opc = is64Bit ? X86::LEA64_32r : X86::LEA32r; | 
|  | 3298 |  | 
|  | 3299 | bool isKill, isUndef; | 
|  | 3300 | unsigned SrcReg; | 
|  | 3301 | MachineOperand ImplicitOp = MachineOperand::CreateReg(0, false); | 
|  | 3302 | if (!classifyLEAReg(MI, Src, Opc, /*AllowSP=*/ true, | 
| Matthias Braun | 7313ca6 | 2016-08-09 01:47:26 +0000 | [diff] [blame] | 3303 | SrcReg, isKill, isUndef, ImplicitOp, LV)) | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3304 | return nullptr; | 
|  | 3305 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3306 | MachineInstrBuilder MIB = BuildMI(MF, MI.getDebugLoc(), get(Opc)) | 
|  | 3307 | .addOperand(Dest) | 
|  | 3308 | .addReg(SrcReg, getUndefRegState(isUndef) | | 
|  | 3309 | getKillRegState(isKill)); | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3310 | if (ImplicitOp.getReg() != 0) | 
|  | 3311 | MIB.addOperand(ImplicitOp); | 
|  | 3312 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3313 | NewMI = addOffset(MIB, MI.getOperand(2).getImm()); | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3314 | break; | 
|  | 3315 | } | 
|  | 3316 | case X86::ADD16ri: | 
|  | 3317 | case X86::ADD16ri8: | 
|  | 3318 | case X86::ADD16ri_DB: | 
|  | 3319 | case X86::ADD16ri8_DB: | 
|  | 3320 | if (DisableLEA16) | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3321 | return is64Bit ? convertToThreeAddressWithLEA(MIOpc, MFI, MI, LV) | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3322 | : nullptr; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3323 | assert(MI.getNumOperands() >= 3 && "Unknown add instruction!"); | 
|  | 3324 | NewMI = addOffset(BuildMI(MF, MI.getDebugLoc(), get(X86::LEA16r)) | 
|  | 3325 | .addOperand(Dest) | 
|  | 3326 | .addOperand(Src), | 
|  | 3327 | MI.getOperand(2).getImm()); | 
| Craig Topper | 39354e1 | 2015-01-07 08:10:38 +0000 | [diff] [blame] | 3328 | break; | 
| Chris Lattner | b7782d7 | 2005-01-02 02:37:07 +0000 | [diff] [blame] | 3329 | } | 
|  | 3330 |  | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 3331 | if (!NewMI) return nullptr; | 
| Evan Cheng | 1bc1cae | 2008-02-07 08:29:53 +0000 | [diff] [blame] | 3332 |  | 
| Evan Cheng | 7d98a48 | 2008-07-03 09:09:37 +0000 | [diff] [blame] | 3333 | if (LV) {  // Update live variables | 
| Jakob Stoklund Olesen | 7030427 | 2012-08-23 22:36:31 +0000 | [diff] [blame] | 3334 | if (Src.isKill()) | 
| Duncan P. N. Exon Smith | d26fdc8 | 2016-07-01 01:51:32 +0000 | [diff] [blame] | 3335 | LV->replaceKillInstruction(Src.getReg(), MI, *NewMI); | 
| Jakob Stoklund Olesen | 7030427 | 2012-08-23 22:36:31 +0000 | [diff] [blame] | 3336 | if (Dest.isDead()) | 
| Duncan P. N. Exon Smith | d26fdc8 | 2016-07-01 01:51:32 +0000 | [diff] [blame] | 3337 | LV->replaceKillInstruction(Dest.getReg(), MI, *NewMI); | 
| Evan Cheng | 7d98a48 | 2008-07-03 09:09:37 +0000 | [diff] [blame] | 3338 | } | 
|  | 3339 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3340 | MFI->insert(MI.getIterator(), NewMI); // Insert the new inst | 
| Evan Cheng | dc2c874 | 2006-11-15 20:58:11 +0000 | [diff] [blame] | 3341 | return NewMI; | 
| Chris Lattner | b7782d7 | 2005-01-02 02:37:07 +0000 | [diff] [blame] | 3342 | } | 
|  | 3343 |  | 
| Andrew Kaylor | 4731bea | 2015-11-06 19:47:25 +0000 | [diff] [blame] | 3344 | /// Returns true if the given instruction opcode is FMA3. | 
|  | 3345 | /// Otherwise, returns false. | 
| Vyacheslav Klochkov | cbc56ba | 2015-11-13 00:07:35 +0000 | [diff] [blame] | 3346 | /// The second parameter is optional and is used as the second return from | 
|  | 3347 | /// the function. It is set to true if the given instruction has FMA3 opcode | 
|  | 3348 | /// that is used for lowering of scalar FMA intrinsics, and it is set to false | 
|  | 3349 | /// otherwise. | 
| Craig Topper | 6172b0b | 2016-07-23 07:16:53 +0000 | [diff] [blame] | 3350 | static bool isFMA3(unsigned Opcode, bool &IsIntrinsic) { | 
|  | 3351 | IsIntrinsic = false; | 
| Vyacheslav Klochkov | cbc56ba | 2015-11-13 00:07:35 +0000 | [diff] [blame] | 3352 |  | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3353 | #define FMA3_CASE(Name, Modifier) \ | 
|  | 3354 | case X86::Name##r##Modifier: case X86::Name##m##Modifier: | 
|  | 3355 |  | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 3356 | #define FMA3_SCALAR_PAIR(Name, Size, Modifier) \ | 
|  | 3357 | FMA3_CASE(Name##SD##Size, Modifier) \ | 
|  | 3358 | FMA3_CASE(Name##SS##Size, Modifier) | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3359 |  | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 3360 | #define FMA3_PACKED_PAIR(Name, Size) \ | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3361 | FMA3_CASE(Name##PD##Size, ) \ | 
|  | 3362 | FMA3_CASE(Name##PS##Size, ) | 
|  | 3363 |  | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 3364 | #define FMA3_PACKED_SET(Form, Size) \ | 
|  | 3365 | FMA3_PACKED_PAIR(VFMADD##Form, Size) \ | 
|  | 3366 | FMA3_PACKED_PAIR(VFMSUB##Form, Size) \ | 
|  | 3367 | FMA3_PACKED_PAIR(VFNMADD##Form, Size) \ | 
|  | 3368 | FMA3_PACKED_PAIR(VFNMSUB##Form, Size) \ | 
|  | 3369 | FMA3_PACKED_PAIR(VFMADDSUB##Form, Size) \ | 
|  | 3370 | FMA3_PACKED_PAIR(VFMSUBADD##Form, Size) | 
|  | 3371 |  | 
|  | 3372 | #define FMA3_CASES(Form) \ | 
|  | 3373 | FMA3_SCALAR_PAIR(VFMADD##Form, ,) \ | 
|  | 3374 | FMA3_SCALAR_PAIR(VFMSUB##Form, ,) \ | 
|  | 3375 | FMA3_SCALAR_PAIR(VFNMADD##Form, ,) \ | 
|  | 3376 | FMA3_SCALAR_PAIR(VFNMSUB##Form, ,) \ | 
|  | 3377 | FMA3_PACKED_SET(Form, ) \ | 
|  | 3378 | FMA3_PACKED_SET(Form, Y) \ | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3379 |  | 
|  | 3380 | #define FMA3_CASES_AVX512(Form) \ | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 3381 | FMA3_SCALAR_PAIR(VFMADD##Form, Z, ) \ | 
|  | 3382 | FMA3_SCALAR_PAIR(VFMSUB##Form, Z, ) \ | 
|  | 3383 | FMA3_SCALAR_PAIR(VFNMADD##Form, Z, ) \ | 
|  | 3384 | FMA3_SCALAR_PAIR(VFNMSUB##Form, Z, ) \ | 
|  | 3385 | FMA3_PACKED_SET(Form, Z128) \ | 
|  | 3386 | FMA3_PACKED_SET(Form, Z256) \ | 
|  | 3387 | FMA3_PACKED_SET(Form, Z) | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3388 |  | 
|  | 3389 | #define FMA3_CASES_SCALAR_INT(Form) \ | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 3390 | FMA3_SCALAR_PAIR(VFMADD##Form, , _Int) \ | 
|  | 3391 | FMA3_SCALAR_PAIR(VFMSUB##Form, , _Int) \ | 
|  | 3392 | FMA3_SCALAR_PAIR(VFNMADD##Form, , _Int) \ | 
|  | 3393 | FMA3_SCALAR_PAIR(VFNMSUB##Form, , _Int) | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3394 |  | 
|  | 3395 | #define FMA3_CASES_SCALAR_INT_AVX512(Form) \ | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 3396 | FMA3_SCALAR_PAIR(VFMADD##Form, Z, _Int) \ | 
|  | 3397 | FMA3_SCALAR_PAIR(VFMSUB##Form, Z, _Int) \ | 
|  | 3398 | FMA3_SCALAR_PAIR(VFNMADD##Form, Z, _Int) \ | 
|  | 3399 | FMA3_SCALAR_PAIR(VFNMSUB##Form, Z, _Int) | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3400 |  | 
| Andrew Kaylor | 4731bea | 2015-11-06 19:47:25 +0000 | [diff] [blame] | 3401 | switch (Opcode) { | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 3402 | FMA3_CASES(132) | 
|  | 3403 | FMA3_CASES(213) | 
|  | 3404 | FMA3_CASES(231) | 
| Andrew Kaylor | 4731bea | 2015-11-06 19:47:25 +0000 | [diff] [blame] | 3405 |  | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3406 | // AVX-512 instructions | 
|  | 3407 | FMA3_CASES_AVX512(132) | 
|  | 3408 | FMA3_CASES_AVX512(213) | 
|  | 3409 | FMA3_CASES_AVX512(231) | 
| Craig Topper | ca8f5f3 | 2016-07-23 07:16:50 +0000 | [diff] [blame] | 3410 | return true; | 
| Vyacheslav Klochkov | cbc56ba | 2015-11-13 00:07:35 +0000 | [diff] [blame] | 3411 |  | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 3412 | FMA3_CASES_SCALAR_INT(132) | 
|  | 3413 | FMA3_CASES_SCALAR_INT(213) | 
|  | 3414 | FMA3_CASES_SCALAR_INT(231) | 
| Vyacheslav Klochkov | cbc56ba | 2015-11-13 00:07:35 +0000 | [diff] [blame] | 3415 |  | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3416 | // AVX-512 instructions | 
|  | 3417 | FMA3_CASES_SCALAR_INT_AVX512(132) | 
|  | 3418 | FMA3_CASES_SCALAR_INT_AVX512(213) | 
|  | 3419 | FMA3_CASES_SCALAR_INT_AVX512(231) | 
| Craig Topper | 6172b0b | 2016-07-23 07:16:53 +0000 | [diff] [blame] | 3420 | IsIntrinsic = true; | 
| Craig Topper | ca8f5f3 | 2016-07-23 07:16:50 +0000 | [diff] [blame] | 3421 | return true; | 
|  | 3422 | default: | 
|  | 3423 | return false; | 
| Andrew Kaylor | 4731bea | 2015-11-06 19:47:25 +0000 | [diff] [blame] | 3424 | } | 
|  | 3425 | llvm_unreachable("Opcode not handled by the switch"); | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3426 |  | 
|  | 3427 | #undef FMA3_CASE | 
|  | 3428 | #undef FMA3_SCALAR_PAIR | 
|  | 3429 | #undef FMA3_PACKED_PAIR | 
|  | 3430 | #undef FMA3_PACKED_SET | 
|  | 3431 | #undef FMA3_CASES | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3432 | #undef FMA3_CASES_AVX512 | 
|  | 3433 | #undef FMA3_CASES_SCALAR_INT | 
|  | 3434 | #undef FMA3_CASES_SCALAR_INT_AVX512 | 
| Andrew Kaylor | 4731bea | 2015-11-06 19:47:25 +0000 | [diff] [blame] | 3435 | } | 
|  | 3436 |  | 
| Craig Topper | 6172b0b | 2016-07-23 07:16:53 +0000 | [diff] [blame] | 3437 | /// Returns an adjusted FMA opcode that must be used in FMA instruction that | 
|  | 3438 | /// performs the same computations as the given MI but which has the operands | 
|  | 3439 | /// \p SrcOpIdx1 and \p SrcOpIdx2 commuted. | 
|  | 3440 | /// It may return 0 if it is unsafe to commute the operands. | 
|  | 3441 | /// | 
|  | 3442 | /// The returned FMA opcode may differ from the opcode in the given \p MI. | 
|  | 3443 | /// For example, commuting the operands #1 and #3 in the following FMA | 
|  | 3444 | ///     FMA213 #1, #2, #3 | 
|  | 3445 | /// results into instruction with adjusted opcode: | 
|  | 3446 | ///     FMA231 #3, #2, #1 | 
|  | 3447 | static unsigned getFMA3OpcodeToCommuteOperands(unsigned Opc, | 
|  | 3448 | bool IsIntrinOpcode, | 
|  | 3449 | unsigned SrcOpIdx1, | 
|  | 3450 | unsigned SrcOpIdx2) { | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3451 | #define FMA3_ENTRY(Name, Suffix) \ | 
|  | 3452 | { X86::Name##132##Suffix, X86::Name##213##Suffix, X86::Name##231##Suffix }, | 
|  | 3453 |  | 
|  | 3454 | #define FMA3_SCALAR_PAIR(Name, Suffix) \ | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 3455 | FMA3_ENTRY(Name, SS##Suffix) \ | 
|  | 3456 | FMA3_ENTRY(Name, SD##Suffix) | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3457 |  | 
|  | 3458 | #define FMA3_PACKED_PAIR(Name, Suffix) \ | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 3459 | FMA3_ENTRY(Name, PS##Suffix) \ | 
|  | 3460 | FMA3_ENTRY(Name, PD##Suffix) | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3461 |  | 
|  | 3462 | #define FMA3_PACKED_SIZES(Name, Suffix) \ | 
|  | 3463 | FMA3_PACKED_PAIR(Name, Suffix) \ | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 3464 | FMA3_PACKED_PAIR(Name, Y##Suffix) | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3465 |  | 
|  | 3466 | #define FMA3_TABLE_ALL(Name) \ | 
|  | 3467 | FMA3_SCALAR_PAIR(Name, r) \ | 
|  | 3468 | FMA3_PACKED_SIZES(Name, r) \ | 
|  | 3469 | FMA3_SCALAR_PAIR(Name, m) \ | 
|  | 3470 | FMA3_PACKED_SIZES(Name, m) | 
|  | 3471 |  | 
|  | 3472 | #define FMA3_TABLE_PACKED(Name) \ | 
|  | 3473 | FMA3_PACKED_SIZES(Name, r) \ | 
|  | 3474 | FMA3_PACKED_SIZES(Name, m) | 
|  | 3475 |  | 
|  | 3476 | #define FMA3_TABLE_SCALAR_INT(Name) \ | 
|  | 3477 | FMA3_SCALAR_PAIR(Name, r_Int) \ | 
|  | 3478 | FMA3_SCALAR_PAIR(Name, m_Int) | 
|  | 3479 |  | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3480 | #define FMA3_PACKED_SIZES_AVX512(Name, Suffix) \ | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 3481 | FMA3_PACKED_PAIR(Name, Z128##Suffix) \ | 
|  | 3482 | FMA3_PACKED_PAIR(Name, Z256##Suffix) \ | 
|  | 3483 | FMA3_PACKED_PAIR(Name, Z##Suffix) | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3484 |  | 
|  | 3485 | #define FMA3_TABLE_ALL_AVX512(Name) \ | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 3486 | FMA3_SCALAR_PAIR(Name, Zr) \ | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3487 | FMA3_PACKED_SIZES_AVX512(Name, r) \ | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 3488 | FMA3_SCALAR_PAIR(Name, Zm) \ | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3489 | FMA3_PACKED_SIZES_AVX512(Name, m) | 
|  | 3490 |  | 
|  | 3491 | #define FMA3_TABLE_PACKED_AVX512(Name) \ | 
|  | 3492 | FMA3_PACKED_SIZES_AVX512(Name, r) \ | 
|  | 3493 | FMA3_PACKED_SIZES_AVX512(Name, m) | 
|  | 3494 |  | 
|  | 3495 | #define FMA3_TABLE_SCALAR_INT_AVX512(Name) \ | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 3496 | FMA3_SCALAR_PAIR(Name, Zr_Int) \ | 
|  | 3497 | FMA3_SCALAR_PAIR(Name, Zm_Int) | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3498 |  | 
| Craig Topper | 6172b0b | 2016-07-23 07:16:53 +0000 | [diff] [blame] | 3499 | // Define the array that holds FMA opcodes in groups | 
|  | 3500 | // of 3 opcodes(132, 213, 231) in each group. | 
|  | 3501 | static const uint16_t RegularOpcodeGroups[][3] = { | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3502 | FMA3_TABLE_ALL(VFMADD) | 
|  | 3503 | FMA3_TABLE_ALL(VFMSUB) | 
|  | 3504 | FMA3_TABLE_ALL(VFNMADD) | 
|  | 3505 | FMA3_TABLE_ALL(VFNMSUB) | 
|  | 3506 | FMA3_TABLE_PACKED(VFMADDSUB) | 
|  | 3507 | FMA3_TABLE_PACKED(VFMSUBADD) | 
| Craig Topper | 6172b0b | 2016-07-23 07:16:53 +0000 | [diff] [blame] | 3508 |  | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3509 | // AVX-512 instructions | 
|  | 3510 | FMA3_TABLE_ALL_AVX512(VFMADD) | 
|  | 3511 | FMA3_TABLE_ALL_AVX512(VFMSUB) | 
|  | 3512 | FMA3_TABLE_ALL_AVX512(VFNMADD) | 
|  | 3513 | FMA3_TABLE_ALL_AVX512(VFNMSUB) | 
|  | 3514 | FMA3_TABLE_PACKED_AVX512(VFMADDSUB) | 
|  | 3515 | FMA3_TABLE_PACKED_AVX512(VFMSUBADD) | 
| Craig Topper | 6172b0b | 2016-07-23 07:16:53 +0000 | [diff] [blame] | 3516 | }; | 
|  | 3517 |  | 
|  | 3518 | // Define the array that holds FMA*_Int opcodes in groups | 
|  | 3519 | // of 3 opcodes(132, 213, 231) in each group. | 
|  | 3520 | static const uint16_t IntrinOpcodeGroups[][3] = { | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3521 | FMA3_TABLE_SCALAR_INT(VFMADD) | 
|  | 3522 | FMA3_TABLE_SCALAR_INT(VFMSUB) | 
|  | 3523 | FMA3_TABLE_SCALAR_INT(VFNMADD) | 
|  | 3524 | FMA3_TABLE_SCALAR_INT(VFNMSUB) | 
| Craig Topper | 6172b0b | 2016-07-23 07:16:53 +0000 | [diff] [blame] | 3525 |  | 
| Craig Topper | 8152b9c | 2016-07-23 16:44:08 +0000 | [diff] [blame] | 3526 | // AVX-512 instructions | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3527 | FMA3_TABLE_SCALAR_INT_AVX512(VFMADD) | 
|  | 3528 | FMA3_TABLE_SCALAR_INT_AVX512(VFMSUB) | 
|  | 3529 | FMA3_TABLE_SCALAR_INT_AVX512(VFNMADD) | 
|  | 3530 | FMA3_TABLE_SCALAR_INT_AVX512(VFNMSUB) | 
| Craig Topper | 6172b0b | 2016-07-23 07:16:53 +0000 | [diff] [blame] | 3531 | }; | 
|  | 3532 |  | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3533 | #undef FMA3_ENTRY | 
|  | 3534 | #undef FMA3_SCALAR_PAIR | 
|  | 3535 | #undef FMA3_PACKED_PAIR | 
|  | 3536 | #undef FMA3_PACKED_SIZES | 
|  | 3537 | #undef FMA3_TABLE_ALL | 
|  | 3538 | #undef FMA3_TABLE_PACKED | 
|  | 3539 | #undef FMA3_TABLE_SCALAR_INT | 
|  | 3540 | #undef FMA3_SCALAR_PAIR_AVX512 | 
| Craig Topper | b6519db | 2016-07-23 07:16:56 +0000 | [diff] [blame] | 3541 | #undef FMA3_PACKED_SIZES_AVX512 | 
|  | 3542 | #undef FMA3_TABLE_ALL_AVX512 | 
|  | 3543 | #undef FMA3_TABLE_PACKED_AVX512 | 
|  | 3544 | #undef FMA3_TABLE_SCALAR_INT_AVX512 | 
|  | 3545 |  | 
| Craig Topper | 6172b0b | 2016-07-23 07:16:53 +0000 | [diff] [blame] | 3546 | const unsigned Form132Index = 0; | 
|  | 3547 | const unsigned Form213Index = 1; | 
|  | 3548 | const unsigned Form231Index = 2; | 
|  | 3549 | const unsigned FormsNum = 3; | 
|  | 3550 |  | 
|  | 3551 | size_t GroupsNum; | 
|  | 3552 | const uint16_t (*OpcodeGroups)[3]; | 
|  | 3553 | if (IsIntrinOpcode) { | 
|  | 3554 | GroupsNum = array_lengthof(IntrinOpcodeGroups); | 
|  | 3555 | OpcodeGroups = IntrinOpcodeGroups; | 
|  | 3556 | } else { | 
|  | 3557 | GroupsNum = array_lengthof(RegularOpcodeGroups); | 
|  | 3558 | OpcodeGroups = RegularOpcodeGroups; | 
|  | 3559 | } | 
|  | 3560 |  | 
|  | 3561 | const uint16_t *FoundOpcodesGroup = nullptr; | 
|  | 3562 | size_t FormIndex; | 
|  | 3563 |  | 
|  | 3564 | // Look for the input opcode in the corresponding opcodes table. | 
|  | 3565 | for (size_t GroupIndex = 0; GroupIndex < GroupsNum && !FoundOpcodesGroup; | 
|  | 3566 | ++GroupIndex) { | 
|  | 3567 | for (FormIndex = 0; FormIndex < FormsNum; ++FormIndex) { | 
|  | 3568 | if (OpcodeGroups[GroupIndex][FormIndex] == Opc) { | 
|  | 3569 | FoundOpcodesGroup = OpcodeGroups[GroupIndex]; | 
|  | 3570 | break; | 
|  | 3571 | } | 
|  | 3572 | } | 
|  | 3573 | } | 
|  | 3574 |  | 
|  | 3575 | // The input opcode does not match with any of the opcodes from the tables. | 
|  | 3576 | // The unsupported FMA opcode must be added to one of the two opcode groups | 
|  | 3577 | // defined above. | 
|  | 3578 | assert(FoundOpcodesGroup != nullptr && "Unexpected FMA3 opcode"); | 
|  | 3579 |  | 
|  | 3580 | // Put the lowest index to SrcOpIdx1 to simplify the checks below. | 
|  | 3581 | if (SrcOpIdx1 > SrcOpIdx2) | 
|  | 3582 | std::swap(SrcOpIdx1, SrcOpIdx2); | 
|  | 3583 |  | 
|  | 3584 | // TODO: Commuting the 1st operand of FMA*_Int requires some additional | 
|  | 3585 | // analysis. The commute optimization is legal only if all users of FMA*_Int | 
|  | 3586 | // use only the lowest element of the FMA*_Int instruction. Such analysis are | 
|  | 3587 | // not implemented yet. So, just return 0 in that case. | 
|  | 3588 | // When such analysis are available this place will be the right place for | 
|  | 3589 | // calling it. | 
|  | 3590 | if (IsIntrinOpcode && SrcOpIdx1 == 1) | 
|  | 3591 | return 0; | 
|  | 3592 |  | 
|  | 3593 | unsigned Case; | 
|  | 3594 | if (SrcOpIdx1 == 1 && SrcOpIdx2 == 2) | 
|  | 3595 | Case = 0; | 
|  | 3596 | else if (SrcOpIdx1 == 1 && SrcOpIdx2 == 3) | 
|  | 3597 | Case = 1; | 
|  | 3598 | else if (SrcOpIdx1 == 2 && SrcOpIdx2 == 3) | 
|  | 3599 | Case = 2; | 
|  | 3600 | else | 
|  | 3601 | return 0; | 
|  | 3602 |  | 
|  | 3603 | // Define the FMA forms mapping array that helps to map input FMA form | 
|  | 3604 | // to output FMA form to preserve the operation semantics after | 
|  | 3605 | // commuting the operands. | 
|  | 3606 | static const unsigned FormMapping[][3] = { | 
|  | 3607 | // 0: SrcOpIdx1 == 1 && SrcOpIdx2 == 2; | 
|  | 3608 | // FMA132 A, C, b; ==> FMA231 C, A, b; | 
|  | 3609 | // FMA213 B, A, c; ==> FMA213 A, B, c; | 
|  | 3610 | // FMA231 C, A, b; ==> FMA132 A, C, b; | 
|  | 3611 | { Form231Index, Form213Index, Form132Index }, | 
|  | 3612 | // 1: SrcOpIdx1 == 1 && SrcOpIdx2 == 3; | 
|  | 3613 | // FMA132 A, c, B; ==> FMA132 B, c, A; | 
|  | 3614 | // FMA213 B, a, C; ==> FMA231 C, a, B; | 
|  | 3615 | // FMA231 C, a, B; ==> FMA213 B, a, C; | 
|  | 3616 | { Form132Index, Form231Index, Form213Index }, | 
|  | 3617 | // 2: SrcOpIdx1 == 2 && SrcOpIdx2 == 3; | 
|  | 3618 | // FMA132 a, C, B; ==> FMA213 a, B, C; | 
|  | 3619 | // FMA213 b, A, C; ==> FMA132 b, C, A; | 
|  | 3620 | // FMA231 c, A, B; ==> FMA231 c, B, A; | 
|  | 3621 | { Form213Index, Form132Index, Form231Index } | 
|  | 3622 | }; | 
|  | 3623 |  | 
|  | 3624 | // Everything is ready, just adjust the FMA opcode and return it. | 
|  | 3625 | FormIndex = FormMapping[Case][FormIndex]; | 
|  | 3626 | return FoundOpcodesGroup[FormIndex]; | 
|  | 3627 | } | 
|  | 3628 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3629 | MachineInstr *X86InstrInfo::commuteInstructionImpl(MachineInstr &MI, bool NewMI, | 
| Andrew Kaylor | 16c4da0 | 2015-09-28 20:33:22 +0000 | [diff] [blame] | 3630 | unsigned OpIdx1, | 
|  | 3631 | unsigned OpIdx2) const { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3632 | auto cloneIfNew = [NewMI](MachineInstr &MI) -> MachineInstr & { | 
|  | 3633 | if (NewMI) | 
|  | 3634 | return *MI.getParent()->getParent()->CloneMachineInstr(&MI); | 
|  | 3635 | return MI; | 
|  | 3636 | }; | 
|  | 3637 |  | 
|  | 3638 | switch (MI.getOpcode()) { | 
| Chris Lattner | d54845f | 2005-01-19 07:31:24 +0000 | [diff] [blame] | 3639 | case X86::SHRD16rri8: // A = SHRD16rri8 B, C, I -> A = SHLD16rri8 C, B, (16-I) | 
|  | 3640 | case X86::SHLD16rri8: // A = SHLD16rri8 B, C, I -> A = SHRD16rri8 C, B, (16-I) | 
| Chris Lattner | 2947801 | 2005-01-19 07:11:01 +0000 | [diff] [blame] | 3641 | case X86::SHRD32rri8: // A = SHRD32rri8 B, C, I -> A = SHLD32rri8 C, B, (32-I) | 
| Dan Gohman | 48ea03d | 2007-09-14 23:17:45 +0000 | [diff] [blame] | 3642 | case X86::SHLD32rri8: // A = SHLD32rri8 B, C, I -> A = SHRD32rri8 C, B, (32-I) | 
|  | 3643 | case X86::SHRD64rri8: // A = SHRD64rri8 B, C, I -> A = SHLD64rri8 C, B, (64-I) | 
|  | 3644 | case X86::SHLD64rri8:{// A = SHLD64rri8 B, C, I -> A = SHRD64rri8 C, B, (64-I) | 
| Chris Lattner | d54845f | 2005-01-19 07:31:24 +0000 | [diff] [blame] | 3645 | unsigned Opc; | 
|  | 3646 | unsigned Size; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3647 | switch (MI.getOpcode()) { | 
| Torok Edwin | fbcc663 | 2009-07-14 16:55:14 +0000 | [diff] [blame] | 3648 | default: llvm_unreachable("Unreachable!"); | 
| Chris Lattner | d54845f | 2005-01-19 07:31:24 +0000 | [diff] [blame] | 3649 | case X86::SHRD16rri8: Size = 16; Opc = X86::SHLD16rri8; break; | 
|  | 3650 | case X86::SHLD16rri8: Size = 16; Opc = X86::SHRD16rri8; break; | 
|  | 3651 | case X86::SHRD32rri8: Size = 32; Opc = X86::SHLD32rri8; break; | 
|  | 3652 | case X86::SHLD32rri8: Size = 32; Opc = X86::SHRD32rri8; break; | 
| Dan Gohman | 48ea03d | 2007-09-14 23:17:45 +0000 | [diff] [blame] | 3653 | case X86::SHRD64rri8: Size = 64; Opc = X86::SHLD64rri8; break; | 
|  | 3654 | case X86::SHLD64rri8: Size = 64; Opc = X86::SHRD64rri8; break; | 
| Chris Lattner | d54845f | 2005-01-19 07:31:24 +0000 | [diff] [blame] | 3655 | } | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3656 | unsigned Amt = MI.getOperand(3).getImm(); | 
|  | 3657 | auto &WorkingMI = cloneIfNew(MI); | 
|  | 3658 | WorkingMI.setDesc(get(Opc)); | 
|  | 3659 | WorkingMI.getOperand(3).setImm(Size - Amt); | 
|  | 3660 | return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false, | 
|  | 3661 | OpIdx1, OpIdx2); | 
| Chris Lattner | 2947801 | 2005-01-19 07:11:01 +0000 | [diff] [blame] | 3662 | } | 
| Simon Pilgrim | c9a0779 | 2014-11-04 23:25:08 +0000 | [diff] [blame] | 3663 | case X86::BLENDPDrri: | 
|  | 3664 | case X86::BLENDPSrri: | 
|  | 3665 | case X86::PBLENDWrri: | 
|  | 3666 | case X86::VBLENDPDrri: | 
|  | 3667 | case X86::VBLENDPSrri: | 
|  | 3668 | case X86::VBLENDPDYrri: | 
|  | 3669 | case X86::VBLENDPSYrri: | 
|  | 3670 | case X86::VPBLENDDrri: | 
|  | 3671 | case X86::VPBLENDWrri: | 
|  | 3672 | case X86::VPBLENDDYrri: | 
|  | 3673 | case X86::VPBLENDWYrri:{ | 
|  | 3674 | unsigned Mask; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3675 | switch (MI.getOpcode()) { | 
| Simon Pilgrim | c9a0779 | 2014-11-04 23:25:08 +0000 | [diff] [blame] | 3676 | default: llvm_unreachable("Unreachable!"); | 
|  | 3677 | case X86::BLENDPDrri:    Mask = 0x03; break; | 
|  | 3678 | case X86::BLENDPSrri:    Mask = 0x0F; break; | 
|  | 3679 | case X86::PBLENDWrri:    Mask = 0xFF; break; | 
|  | 3680 | case X86::VBLENDPDrri:   Mask = 0x03; break; | 
|  | 3681 | case X86::VBLENDPSrri:   Mask = 0x0F; break; | 
|  | 3682 | case X86::VBLENDPDYrri:  Mask = 0x0F; break; | 
|  | 3683 | case X86::VBLENDPSYrri:  Mask = 0xFF; break; | 
|  | 3684 | case X86::VPBLENDDrri:   Mask = 0x0F; break; | 
|  | 3685 | case X86::VPBLENDWrri:   Mask = 0xFF; break; | 
|  | 3686 | case X86::VPBLENDDYrri:  Mask = 0xFF; break; | 
|  | 3687 | case X86::VPBLENDWYrri:  Mask = 0xFF; break; | 
|  | 3688 | } | 
| Andrea Di Biagio | 7ecd22c | 2014-11-06 14:36:45 +0000 | [diff] [blame] | 3689 | // Only the least significant bits of Imm are used. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3690 | unsigned Imm = MI.getOperand(3).getImm() & Mask; | 
|  | 3691 | auto &WorkingMI = cloneIfNew(MI); | 
|  | 3692 | WorkingMI.getOperand(3).setImm(Mask ^ Imm); | 
|  | 3693 | return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false, | 
|  | 3694 | OpIdx1, OpIdx2); | 
| Simon Pilgrim | c9a0779 | 2014-11-04 23:25:08 +0000 | [diff] [blame] | 3695 | } | 
| Simon Pilgrim | 9b7c003 | 2015-01-26 22:00:18 +0000 | [diff] [blame] | 3696 | case X86::PCLMULQDQrr: | 
|  | 3697 | case X86::VPCLMULQDQrr:{ | 
|  | 3698 | // SRC1 64bits = Imm[0] ? SRC1[127:64] : SRC1[63:0] | 
|  | 3699 | // SRC2 64bits = Imm[4] ? SRC2[127:64] : SRC2[63:0] | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3700 | unsigned Imm = MI.getOperand(3).getImm(); | 
| Simon Pilgrim | 9b7c003 | 2015-01-26 22:00:18 +0000 | [diff] [blame] | 3701 | unsigned Src1Hi = Imm & 0x01; | 
|  | 3702 | unsigned Src2Hi = Imm & 0x10; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3703 | auto &WorkingMI = cloneIfNew(MI); | 
|  | 3704 | WorkingMI.getOperand(3).setImm((Src1Hi << 4) | (Src2Hi >> 4)); | 
|  | 3705 | return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false, | 
|  | 3706 | OpIdx1, OpIdx2); | 
| Simon Pilgrim | 9b7c003 | 2015-01-26 22:00:18 +0000 | [diff] [blame] | 3707 | } | 
| Simon Pilgrim | 0629ba1 | 2015-01-26 22:29:24 +0000 | [diff] [blame] | 3708 | case X86::CMPPDrri: | 
|  | 3709 | case X86::CMPPSrri: | 
|  | 3710 | case X86::VCMPPDrri: | 
|  | 3711 | case X86::VCMPPSrri: | 
|  | 3712 | case X86::VCMPPDYrri: | 
|  | 3713 | case X86::VCMPPSYrri: { | 
|  | 3714 | // Float comparison can be safely commuted for | 
|  | 3715 | // Ordered/Unordered/Equal/NotEqual tests | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3716 | unsigned Imm = MI.getOperand(3).getImm() & 0x7; | 
| Simon Pilgrim | 0629ba1 | 2015-01-26 22:29:24 +0000 | [diff] [blame] | 3717 | switch (Imm) { | 
|  | 3718 | case 0x00: // EQUAL | 
|  | 3719 | case 0x03: // UNORDERED | 
|  | 3720 | case 0x04: // NOT EQUAL | 
|  | 3721 | case 0x07: // ORDERED | 
| Andrew Kaylor | 16c4da0 | 2015-09-28 20:33:22 +0000 | [diff] [blame] | 3722 | return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2); | 
| Simon Pilgrim | 0629ba1 | 2015-01-26 22:29:24 +0000 | [diff] [blame] | 3723 | default: | 
|  | 3724 | return nullptr; | 
|  | 3725 | } | 
|  | 3726 | } | 
| Simon Pilgrim | 31457d5 | 2015-02-14 22:40:46 +0000 | [diff] [blame] | 3727 | case X86::VPCOMBri: case X86::VPCOMUBri: | 
|  | 3728 | case X86::VPCOMDri: case X86::VPCOMUDri: | 
|  | 3729 | case X86::VPCOMQri: case X86::VPCOMUQri: | 
|  | 3730 | case X86::VPCOMWri: case X86::VPCOMUWri: { | 
|  | 3731 | // Flip comparison mode immediate (if necessary). | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3732 | unsigned Imm = MI.getOperand(3).getImm() & 0x7; | 
| Simon Pilgrim | 31457d5 | 2015-02-14 22:40:46 +0000 | [diff] [blame] | 3733 | switch (Imm) { | 
|  | 3734 | case 0x00: Imm = 0x02; break; // LT -> GT | 
|  | 3735 | case 0x01: Imm = 0x03; break; // LE -> GE | 
|  | 3736 | case 0x02: Imm = 0x00; break; // GT -> LT | 
|  | 3737 | case 0x03: Imm = 0x01; break; // GE -> LE | 
|  | 3738 | case 0x04: // EQ | 
|  | 3739 | case 0x05: // NE | 
|  | 3740 | case 0x06: // FALSE | 
|  | 3741 | case 0x07: // TRUE | 
|  | 3742 | default: | 
|  | 3743 | break; | 
|  | 3744 | } | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3745 | auto &WorkingMI = cloneIfNew(MI); | 
|  | 3746 | WorkingMI.getOperand(3).setImm(Imm); | 
|  | 3747 | return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false, | 
|  | 3748 | OpIdx1, OpIdx2); | 
| Simon Pilgrim | 31457d5 | 2015-02-14 22:40:46 +0000 | [diff] [blame] | 3749 | } | 
| Simon Pilgrim | d1d1180 | 2016-01-25 21:51:34 +0000 | [diff] [blame] | 3750 | case X86::VPERM2F128rr: | 
|  | 3751 | case X86::VPERM2I128rr: { | 
|  | 3752 | // Flip permute source immediate. | 
|  | 3753 | // Imm & 0x02: lo = if set, select Op1.lo/hi else Op0.lo/hi. | 
|  | 3754 | // Imm & 0x20: hi = if set, select Op1.lo/hi else Op0.lo/hi. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3755 | unsigned Imm = MI.getOperand(3).getImm() & 0xFF; | 
|  | 3756 | auto &WorkingMI = cloneIfNew(MI); | 
|  | 3757 | WorkingMI.getOperand(3).setImm(Imm ^ 0x22); | 
|  | 3758 | return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false, | 
|  | 3759 | OpIdx1, OpIdx2); | 
| Simon Pilgrim | d1d1180 | 2016-01-25 21:51:34 +0000 | [diff] [blame] | 3760 | } | 
| Simon Pilgrim | 7d168e1 | 2016-08-06 18:40:28 +0000 | [diff] [blame] | 3761 | case X86::MOVHLPSrr: | 
|  | 3762 | case X86::UNPCKHPDrr: { | 
|  | 3763 | if (!Subtarget.hasSSE2()) | 
|  | 3764 | return nullptr; | 
|  | 3765 |  | 
|  | 3766 | unsigned Opc = MI.getOpcode(); | 
|  | 3767 | switch (Opc) { | 
|  | 3768 | default: llvm_unreachable("Unreachable!"); | 
|  | 3769 | case X86::MOVHLPSrr: Opc = X86::UNPCKHPDrr; break; | 
|  | 3770 | case X86::UNPCKHPDrr: Opc = X86::MOVHLPSrr; break; | 
|  | 3771 | } | 
|  | 3772 | auto &WorkingMI = cloneIfNew(MI); | 
|  | 3773 | WorkingMI.setDesc(get(Opc)); | 
|  | 3774 | return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false, | 
|  | 3775 | OpIdx1, OpIdx2); | 
|  | 3776 | } | 
| Craig Topper | 653e759 | 2012-08-21 07:32:16 +0000 | [diff] [blame] | 3777 | case X86::CMOVB16rr:  case X86::CMOVB32rr:  case X86::CMOVB64rr: | 
|  | 3778 | case X86::CMOVAE16rr: case X86::CMOVAE32rr: case X86::CMOVAE64rr: | 
|  | 3779 | case X86::CMOVE16rr:  case X86::CMOVE32rr:  case X86::CMOVE64rr: | 
|  | 3780 | case X86::CMOVNE16rr: case X86::CMOVNE32rr: case X86::CMOVNE64rr: | 
|  | 3781 | case X86::CMOVBE16rr: case X86::CMOVBE32rr: case X86::CMOVBE64rr: | 
|  | 3782 | case X86::CMOVA16rr:  case X86::CMOVA32rr:  case X86::CMOVA64rr: | 
|  | 3783 | case X86::CMOVL16rr:  case X86::CMOVL32rr:  case X86::CMOVL64rr: | 
|  | 3784 | case X86::CMOVGE16rr: case X86::CMOVGE32rr: case X86::CMOVGE64rr: | 
|  | 3785 | case X86::CMOVLE16rr: case X86::CMOVLE32rr: case X86::CMOVLE64rr: | 
|  | 3786 | case X86::CMOVG16rr:  case X86::CMOVG32rr:  case X86::CMOVG64rr: | 
|  | 3787 | case X86::CMOVS16rr:  case X86::CMOVS32rr:  case X86::CMOVS64rr: | 
|  | 3788 | case X86::CMOVNS16rr: case X86::CMOVNS32rr: case X86::CMOVNS64rr: | 
|  | 3789 | case X86::CMOVP16rr:  case X86::CMOVP32rr:  case X86::CMOVP64rr: | 
|  | 3790 | case X86::CMOVNP16rr: case X86::CMOVNP32rr: case X86::CMOVNP64rr: | 
|  | 3791 | case X86::CMOVO16rr:  case X86::CMOVO32rr:  case X86::CMOVO64rr: | 
|  | 3792 | case X86::CMOVNO16rr: case X86::CMOVNO32rr: case X86::CMOVNO64rr: { | 
|  | 3793 | unsigned Opc; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3794 | switch (MI.getOpcode()) { | 
| Craig Topper | 653e759 | 2012-08-21 07:32:16 +0000 | [diff] [blame] | 3795 | default: llvm_unreachable("Unreachable!"); | 
| Evan Cheng | 1151ffd | 2007-10-05 23:13:21 +0000 | [diff] [blame] | 3796 | case X86::CMOVB16rr:  Opc = X86::CMOVAE16rr; break; | 
|  | 3797 | case X86::CMOVB32rr:  Opc = X86::CMOVAE32rr; break; | 
|  | 3798 | case X86::CMOVB64rr:  Opc = X86::CMOVAE64rr; break; | 
|  | 3799 | case X86::CMOVAE16rr: Opc = X86::CMOVB16rr; break; | 
|  | 3800 | case X86::CMOVAE32rr: Opc = X86::CMOVB32rr; break; | 
|  | 3801 | case X86::CMOVAE64rr: Opc = X86::CMOVB64rr; break; | 
|  | 3802 | case X86::CMOVE16rr:  Opc = X86::CMOVNE16rr; break; | 
|  | 3803 | case X86::CMOVE32rr:  Opc = X86::CMOVNE32rr; break; | 
|  | 3804 | case X86::CMOVE64rr:  Opc = X86::CMOVNE64rr; break; | 
|  | 3805 | case X86::CMOVNE16rr: Opc = X86::CMOVE16rr; break; | 
|  | 3806 | case X86::CMOVNE32rr: Opc = X86::CMOVE32rr; break; | 
|  | 3807 | case X86::CMOVNE64rr: Opc = X86::CMOVE64rr; break; | 
| Chris Lattner | 1a1c600 | 2010-10-05 23:00:14 +0000 | [diff] [blame] | 3808 | case X86::CMOVBE16rr: Opc = X86::CMOVA16rr; break; | 
|  | 3809 | case X86::CMOVBE32rr: Opc = X86::CMOVA32rr; break; | 
|  | 3810 | case X86::CMOVBE64rr: Opc = X86::CMOVA64rr; break; | 
|  | 3811 | case X86::CMOVA16rr:  Opc = X86::CMOVBE16rr; break; | 
|  | 3812 | case X86::CMOVA32rr:  Opc = X86::CMOVBE32rr; break; | 
|  | 3813 | case X86::CMOVA64rr:  Opc = X86::CMOVBE64rr; break; | 
| Evan Cheng | 1151ffd | 2007-10-05 23:13:21 +0000 | [diff] [blame] | 3814 | case X86::CMOVL16rr:  Opc = X86::CMOVGE16rr; break; | 
|  | 3815 | case X86::CMOVL32rr:  Opc = X86::CMOVGE32rr; break; | 
|  | 3816 | case X86::CMOVL64rr:  Opc = X86::CMOVGE64rr; break; | 
|  | 3817 | case X86::CMOVGE16rr: Opc = X86::CMOVL16rr; break; | 
|  | 3818 | case X86::CMOVGE32rr: Opc = X86::CMOVL32rr; break; | 
|  | 3819 | case X86::CMOVGE64rr: Opc = X86::CMOVL64rr; break; | 
|  | 3820 | case X86::CMOVLE16rr: Opc = X86::CMOVG16rr; break; | 
|  | 3821 | case X86::CMOVLE32rr: Opc = X86::CMOVG32rr; break; | 
|  | 3822 | case X86::CMOVLE64rr: Opc = X86::CMOVG64rr; break; | 
|  | 3823 | case X86::CMOVG16rr:  Opc = X86::CMOVLE16rr; break; | 
|  | 3824 | case X86::CMOVG32rr:  Opc = X86::CMOVLE32rr; break; | 
|  | 3825 | case X86::CMOVG64rr:  Opc = X86::CMOVLE64rr; break; | 
|  | 3826 | case X86::CMOVS16rr:  Opc = X86::CMOVNS16rr; break; | 
|  | 3827 | case X86::CMOVS32rr:  Opc = X86::CMOVNS32rr; break; | 
| Mon P Wang | 6c8bcf9 | 2009-04-18 05:16:01 +0000 | [diff] [blame] | 3828 | case X86::CMOVS64rr:  Opc = X86::CMOVNS64rr; break; | 
| Evan Cheng | 1151ffd | 2007-10-05 23:13:21 +0000 | [diff] [blame] | 3829 | case X86::CMOVNS16rr: Opc = X86::CMOVS16rr; break; | 
|  | 3830 | case X86::CMOVNS32rr: Opc = X86::CMOVS32rr; break; | 
|  | 3831 | case X86::CMOVNS64rr: Opc = X86::CMOVS64rr; break; | 
|  | 3832 | case X86::CMOVP16rr:  Opc = X86::CMOVNP16rr; break; | 
|  | 3833 | case X86::CMOVP32rr:  Opc = X86::CMOVNP32rr; break; | 
| Mon P Wang | 6c8bcf9 | 2009-04-18 05:16:01 +0000 | [diff] [blame] | 3834 | case X86::CMOVP64rr:  Opc = X86::CMOVNP64rr; break; | 
| Evan Cheng | 1151ffd | 2007-10-05 23:13:21 +0000 | [diff] [blame] | 3835 | case X86::CMOVNP16rr: Opc = X86::CMOVP16rr; break; | 
|  | 3836 | case X86::CMOVNP32rr: Opc = X86::CMOVP32rr; break; | 
|  | 3837 | case X86::CMOVNP64rr: Opc = X86::CMOVP64rr; break; | 
| Dan Gohman | 7e47cc7 | 2009-01-07 00:35:10 +0000 | [diff] [blame] | 3838 | case X86::CMOVO16rr:  Opc = X86::CMOVNO16rr; break; | 
|  | 3839 | case X86::CMOVO32rr:  Opc = X86::CMOVNO32rr; break; | 
| Mon P Wang | 6c8bcf9 | 2009-04-18 05:16:01 +0000 | [diff] [blame] | 3840 | case X86::CMOVO64rr:  Opc = X86::CMOVNO64rr; break; | 
| Dan Gohman | 7e47cc7 | 2009-01-07 00:35:10 +0000 | [diff] [blame] | 3841 | case X86::CMOVNO16rr: Opc = X86::CMOVO16rr; break; | 
|  | 3842 | case X86::CMOVNO32rr: Opc = X86::CMOVO32rr; break; | 
|  | 3843 | case X86::CMOVNO64rr: Opc = X86::CMOVO64rr; break; | 
| Evan Cheng | 1151ffd | 2007-10-05 23:13:21 +0000 | [diff] [blame] | 3844 | } | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3845 | auto &WorkingMI = cloneIfNew(MI); | 
|  | 3846 | WorkingMI.setDesc(get(Opc)); | 
|  | 3847 | return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false, | 
|  | 3848 | OpIdx1, OpIdx2); | 
| Evan Cheng | 1151ffd | 2007-10-05 23:13:21 +0000 | [diff] [blame] | 3849 | } | 
| Chris Lattner | 2947801 | 2005-01-19 07:11:01 +0000 | [diff] [blame] | 3850 | default: | 
| Craig Topper | 6172b0b | 2016-07-23 07:16:53 +0000 | [diff] [blame] | 3851 | bool IsIntrinOpcode; | 
|  | 3852 | if (isFMA3(MI.getOpcode(), IsIntrinOpcode)) { | 
|  | 3853 | unsigned Opc = getFMA3OpcodeToCommuteOperands(MI.getOpcode(), | 
|  | 3854 | IsIntrinOpcode, | 
|  | 3855 | OpIdx1, OpIdx2); | 
| Andrew Kaylor | 4731bea | 2015-11-06 19:47:25 +0000 | [diff] [blame] | 3856 | if (Opc == 0) | 
|  | 3857 | return nullptr; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3858 | auto &WorkingMI = cloneIfNew(MI); | 
|  | 3859 | WorkingMI.setDesc(get(Opc)); | 
|  | 3860 | return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false, | 
|  | 3861 | OpIdx1, OpIdx2); | 
| Andrew Kaylor | 4731bea | 2015-11-06 19:47:25 +0000 | [diff] [blame] | 3862 | } | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3863 |  | 
| Andrew Kaylor | 16c4da0 | 2015-09-28 20:33:22 +0000 | [diff] [blame] | 3864 | return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2); | 
| Chris Lattner | 2947801 | 2005-01-19 07:11:01 +0000 | [diff] [blame] | 3865 | } | 
|  | 3866 | } | 
|  | 3867 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3868 | bool X86InstrInfo::findFMA3CommutedOpIndices(MachineInstr &MI, | 
| Craig Topper | 6172b0b | 2016-07-23 07:16:53 +0000 | [diff] [blame] | 3869 | bool IsIntrinOpcode, | 
| Andrew Kaylor | 4731bea | 2015-11-06 19:47:25 +0000 | [diff] [blame] | 3870 | unsigned &SrcOpIdx1, | 
|  | 3871 | unsigned &SrcOpIdx2) const { | 
|  | 3872 |  | 
|  | 3873 | unsigned RegOpsNum = isMem(MI, 3) ? 2 : 3; | 
|  | 3874 |  | 
|  | 3875 | // Only the first RegOpsNum operands are commutable. | 
|  | 3876 | // Also, the value 'CommuteAnyOperandIndex' is valid here as it means | 
|  | 3877 | // that the operand is not specified/fixed. | 
|  | 3878 | if (SrcOpIdx1 != CommuteAnyOperandIndex && | 
|  | 3879 | (SrcOpIdx1 < 1 || SrcOpIdx1 > RegOpsNum)) | 
|  | 3880 | return false; | 
|  | 3881 | if (SrcOpIdx2 != CommuteAnyOperandIndex && | 
|  | 3882 | (SrcOpIdx2 < 1 || SrcOpIdx2 > RegOpsNum)) | 
|  | 3883 | return false; | 
|  | 3884 |  | 
|  | 3885 | // Look for two different register operands assumed to be commutable | 
|  | 3886 | // regardless of the FMA opcode. The FMA opcode is adjusted later. | 
|  | 3887 | if (SrcOpIdx1 == CommuteAnyOperandIndex || | 
|  | 3888 | SrcOpIdx2 == CommuteAnyOperandIndex) { | 
|  | 3889 | unsigned CommutableOpIdx1 = SrcOpIdx1; | 
|  | 3890 | unsigned CommutableOpIdx2 = SrcOpIdx2; | 
|  | 3891 |  | 
|  | 3892 | // At least one of operands to be commuted is not specified and | 
|  | 3893 | // this method is free to choose appropriate commutable operands. | 
|  | 3894 | if (SrcOpIdx1 == SrcOpIdx2) | 
|  | 3895 | // Both of operands are not fixed. By default set one of commutable | 
|  | 3896 | // operands to the last register operand of the instruction. | 
|  | 3897 | CommutableOpIdx2 = RegOpsNum; | 
|  | 3898 | else if (SrcOpIdx2 == CommuteAnyOperandIndex) | 
|  | 3899 | // Only one of operands is not fixed. | 
|  | 3900 | CommutableOpIdx2 = SrcOpIdx1; | 
|  | 3901 |  | 
|  | 3902 | // CommutableOpIdx2 is well defined now. Let's choose another commutable | 
|  | 3903 | // operand and assign its index to CommutableOpIdx1. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3904 | unsigned Op2Reg = MI.getOperand(CommutableOpIdx2).getReg(); | 
| Andrew Kaylor | 4731bea | 2015-11-06 19:47:25 +0000 | [diff] [blame] | 3905 | for (CommutableOpIdx1 = RegOpsNum; CommutableOpIdx1 > 0; CommutableOpIdx1--) { | 
|  | 3906 | // The commuted operands must have different registers. | 
|  | 3907 | // Otherwise, the commute transformation does not change anything and | 
|  | 3908 | // is useless then. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3909 | if (Op2Reg != MI.getOperand(CommutableOpIdx1).getReg()) | 
| Andrew Kaylor | 4731bea | 2015-11-06 19:47:25 +0000 | [diff] [blame] | 3910 | break; | 
|  | 3911 | } | 
|  | 3912 |  | 
|  | 3913 | // No appropriate commutable operands were found. | 
|  | 3914 | if (CommutableOpIdx1 == 0) | 
|  | 3915 | return false; | 
|  | 3916 |  | 
|  | 3917 | // Assign the found pair of commutable indices to SrcOpIdx1 and SrcOpidx2 | 
|  | 3918 | // to return those values. | 
|  | 3919 | if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, | 
|  | 3920 | CommutableOpIdx1, CommutableOpIdx2)) | 
|  | 3921 | return false; | 
|  | 3922 | } | 
|  | 3923 |  | 
|  | 3924 | // Check if we can adjust the opcode to preserve the semantics when | 
|  | 3925 | // commute the register operands. | 
| Craig Topper | 6172b0b | 2016-07-23 07:16:53 +0000 | [diff] [blame] | 3926 | return getFMA3OpcodeToCommuteOperands(MI.getOpcode(), IsIntrinOpcode, | 
|  | 3927 | SrcOpIdx1, SrcOpIdx2) != 0; | 
| Andrew Kaylor | 4731bea | 2015-11-06 19:47:25 +0000 | [diff] [blame] | 3928 | } | 
|  | 3929 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3930 | bool X86InstrInfo::findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1, | 
| Lang Hames | c59a2d0 | 2014-04-02 23:57:49 +0000 | [diff] [blame] | 3931 | unsigned &SrcOpIdx2) const { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3932 | switch (MI.getOpcode()) { | 
|  | 3933 | case X86::CMPPDrri: | 
|  | 3934 | case X86::CMPPSrri: | 
|  | 3935 | case X86::VCMPPDrri: | 
|  | 3936 | case X86::VCMPPSrri: | 
|  | 3937 | case X86::VCMPPDYrri: | 
|  | 3938 | case X86::VCMPPSYrri: { | 
|  | 3939 | // Float comparison can be safely commuted for | 
|  | 3940 | // Ordered/Unordered/Equal/NotEqual tests | 
|  | 3941 | unsigned Imm = MI.getOperand(3).getImm() & 0x7; | 
|  | 3942 | switch (Imm) { | 
|  | 3943 | case 0x00: // EQUAL | 
|  | 3944 | case 0x03: // UNORDERED | 
|  | 3945 | case 0x04: // NOT EQUAL | 
|  | 3946 | case 0x07: // ORDERED | 
|  | 3947 | // The indices of the commutable operands are 1 and 2. | 
|  | 3948 | // Assign them to the returned operand indices here. | 
|  | 3949 | return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2); | 
| Simon Pilgrim | 0629ba1 | 2015-01-26 22:29:24 +0000 | [diff] [blame] | 3950 | } | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3951 | return false; | 
|  | 3952 | } | 
|  | 3953 | default: | 
| Craig Topper | 6172b0b | 2016-07-23 07:16:53 +0000 | [diff] [blame] | 3954 | bool IsIntrinOpcode; | 
|  | 3955 | if (isFMA3(MI.getOpcode(), IsIntrinOpcode)) | 
|  | 3956 | return findFMA3CommutedOpIndices(MI, IsIntrinOpcode, | 
|  | 3957 | SrcOpIdx1, SrcOpIdx2); | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 3958 | return TargetInstrInfo::findCommutedOpIndices(MI, SrcOpIdx1, SrcOpIdx2); | 
| Lang Hames | c59a2d0 | 2014-04-02 23:57:49 +0000 | [diff] [blame] | 3959 | } | 
| Andrew Kaylor | 16c4da0 | 2015-09-28 20:33:22 +0000 | [diff] [blame] | 3960 | return false; | 
| Lang Hames | c59a2d0 | 2014-04-02 23:57:49 +0000 | [diff] [blame] | 3961 | } | 
|  | 3962 |  | 
| Manman Ren | 5f6fa42 | 2012-07-09 18:57:12 +0000 | [diff] [blame] | 3963 | static X86::CondCode getCondFromBranchOpc(unsigned BrOpc) { | 
| Chris Lattner | c0fb567 | 2006-10-20 17:42:20 +0000 | [diff] [blame] | 3964 | switch (BrOpc) { | 
|  | 3965 | default: return X86::COND_INVALID; | 
| Craig Topper | 49758aa | 2015-01-06 04:23:53 +0000 | [diff] [blame] | 3966 | case X86::JE_1:  return X86::COND_E; | 
|  | 3967 | case X86::JNE_1: return X86::COND_NE; | 
|  | 3968 | case X86::JL_1:  return X86::COND_L; | 
|  | 3969 | case X86::JLE_1: return X86::COND_LE; | 
|  | 3970 | case X86::JG_1:  return X86::COND_G; | 
|  | 3971 | case X86::JGE_1: return X86::COND_GE; | 
|  | 3972 | case X86::JB_1:  return X86::COND_B; | 
|  | 3973 | case X86::JBE_1: return X86::COND_BE; | 
|  | 3974 | case X86::JA_1:  return X86::COND_A; | 
|  | 3975 | case X86::JAE_1: return X86::COND_AE; | 
|  | 3976 | case X86::JS_1:  return X86::COND_S; | 
|  | 3977 | case X86::JNS_1: return X86::COND_NS; | 
|  | 3978 | case X86::JP_1:  return X86::COND_P; | 
|  | 3979 | case X86::JNP_1: return X86::COND_NP; | 
|  | 3980 | case X86::JO_1:  return X86::COND_O; | 
|  | 3981 | case X86::JNO_1: return X86::COND_NO; | 
| Chris Lattner | c0fb567 | 2006-10-20 17:42:20 +0000 | [diff] [blame] | 3982 | } | 
|  | 3983 | } | 
|  | 3984 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 3985 | /// Return condition code of a SET opcode. | 
| Manman Ren | 5f6fa42 | 2012-07-09 18:57:12 +0000 | [diff] [blame] | 3986 | static X86::CondCode getCondFromSETOpc(unsigned Opc) { | 
|  | 3987 | switch (Opc) { | 
|  | 3988 | default: return X86::COND_INVALID; | 
|  | 3989 | case X86::SETAr:  case X86::SETAm:  return X86::COND_A; | 
|  | 3990 | case X86::SETAEr: case X86::SETAEm: return X86::COND_AE; | 
|  | 3991 | case X86::SETBr:  case X86::SETBm:  return X86::COND_B; | 
|  | 3992 | case X86::SETBEr: case X86::SETBEm: return X86::COND_BE; | 
|  | 3993 | case X86::SETEr:  case X86::SETEm:  return X86::COND_E; | 
|  | 3994 | case X86::SETGr:  case X86::SETGm:  return X86::COND_G; | 
|  | 3995 | case X86::SETGEr: case X86::SETGEm: return X86::COND_GE; | 
|  | 3996 | case X86::SETLr:  case X86::SETLm:  return X86::COND_L; | 
|  | 3997 | case X86::SETLEr: case X86::SETLEm: return X86::COND_LE; | 
|  | 3998 | case X86::SETNEr: case X86::SETNEm: return X86::COND_NE; | 
|  | 3999 | case X86::SETNOr: case X86::SETNOm: return X86::COND_NO; | 
|  | 4000 | case X86::SETNPr: case X86::SETNPm: return X86::COND_NP; | 
|  | 4001 | case X86::SETNSr: case X86::SETNSm: return X86::COND_NS; | 
|  | 4002 | case X86::SETOr:  case X86::SETOm:  return X86::COND_O; | 
|  | 4003 | case X86::SETPr:  case X86::SETPm:  return X86::COND_P; | 
|  | 4004 | case X86::SETSr:  case X86::SETSm:  return X86::COND_S; | 
|  | 4005 | } | 
|  | 4006 | } | 
|  | 4007 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 4008 | /// Return condition code of a CMov opcode. | 
| Michael Liao | 3237662 | 2012-09-20 03:06:15 +0000 | [diff] [blame] | 4009 | X86::CondCode X86::getCondFromCMovOpc(unsigned Opc) { | 
| Manman Ren | 5f6fa42 | 2012-07-09 18:57:12 +0000 | [diff] [blame] | 4010 | switch (Opc) { | 
|  | 4011 | default: return X86::COND_INVALID; | 
|  | 4012 | case X86::CMOVA16rm:  case X86::CMOVA16rr:  case X86::CMOVA32rm: | 
|  | 4013 | case X86::CMOVA32rr:  case X86::CMOVA64rm:  case X86::CMOVA64rr: | 
|  | 4014 | return X86::COND_A; | 
|  | 4015 | case X86::CMOVAE16rm: case X86::CMOVAE16rr: case X86::CMOVAE32rm: | 
|  | 4016 | case X86::CMOVAE32rr: case X86::CMOVAE64rm: case X86::CMOVAE64rr: | 
|  | 4017 | return X86::COND_AE; | 
|  | 4018 | case X86::CMOVB16rm:  case X86::CMOVB16rr:  case X86::CMOVB32rm: | 
|  | 4019 | case X86::CMOVB32rr:  case X86::CMOVB64rm:  case X86::CMOVB64rr: | 
|  | 4020 | return X86::COND_B; | 
|  | 4021 | case X86::CMOVBE16rm: case X86::CMOVBE16rr: case X86::CMOVBE32rm: | 
|  | 4022 | case X86::CMOVBE32rr: case X86::CMOVBE64rm: case X86::CMOVBE64rr: | 
|  | 4023 | return X86::COND_BE; | 
|  | 4024 | case X86::CMOVE16rm:  case X86::CMOVE16rr:  case X86::CMOVE32rm: | 
|  | 4025 | case X86::CMOVE32rr:  case X86::CMOVE64rm:  case X86::CMOVE64rr: | 
|  | 4026 | return X86::COND_E; | 
|  | 4027 | case X86::CMOVG16rm:  case X86::CMOVG16rr:  case X86::CMOVG32rm: | 
|  | 4028 | case X86::CMOVG32rr:  case X86::CMOVG64rm:  case X86::CMOVG64rr: | 
|  | 4029 | return X86::COND_G; | 
|  | 4030 | case X86::CMOVGE16rm: case X86::CMOVGE16rr: case X86::CMOVGE32rm: | 
|  | 4031 | case X86::CMOVGE32rr: case X86::CMOVGE64rm: case X86::CMOVGE64rr: | 
|  | 4032 | return X86::COND_GE; | 
|  | 4033 | case X86::CMOVL16rm:  case X86::CMOVL16rr:  case X86::CMOVL32rm: | 
|  | 4034 | case X86::CMOVL32rr:  case X86::CMOVL64rm:  case X86::CMOVL64rr: | 
|  | 4035 | return X86::COND_L; | 
|  | 4036 | case X86::CMOVLE16rm: case X86::CMOVLE16rr: case X86::CMOVLE32rm: | 
|  | 4037 | case X86::CMOVLE32rr: case X86::CMOVLE64rm: case X86::CMOVLE64rr: | 
|  | 4038 | return X86::COND_LE; | 
|  | 4039 | case X86::CMOVNE16rm: case X86::CMOVNE16rr: case X86::CMOVNE32rm: | 
|  | 4040 | case X86::CMOVNE32rr: case X86::CMOVNE64rm: case X86::CMOVNE64rr: | 
|  | 4041 | return X86::COND_NE; | 
|  | 4042 | case X86::CMOVNO16rm: case X86::CMOVNO16rr: case X86::CMOVNO32rm: | 
|  | 4043 | case X86::CMOVNO32rr: case X86::CMOVNO64rm: case X86::CMOVNO64rr: | 
|  | 4044 | return X86::COND_NO; | 
|  | 4045 | case X86::CMOVNP16rm: case X86::CMOVNP16rr: case X86::CMOVNP32rm: | 
|  | 4046 | case X86::CMOVNP32rr: case X86::CMOVNP64rm: case X86::CMOVNP64rr: | 
|  | 4047 | return X86::COND_NP; | 
|  | 4048 | case X86::CMOVNS16rm: case X86::CMOVNS16rr: case X86::CMOVNS32rm: | 
|  | 4049 | case X86::CMOVNS32rr: case X86::CMOVNS64rm: case X86::CMOVNS64rr: | 
|  | 4050 | return X86::COND_NS; | 
|  | 4051 | case X86::CMOVO16rm:  case X86::CMOVO16rr:  case X86::CMOVO32rm: | 
|  | 4052 | case X86::CMOVO32rr:  case X86::CMOVO64rm:  case X86::CMOVO64rr: | 
|  | 4053 | return X86::COND_O; | 
|  | 4054 | case X86::CMOVP16rm:  case X86::CMOVP16rr:  case X86::CMOVP32rm: | 
|  | 4055 | case X86::CMOVP32rr:  case X86::CMOVP64rm:  case X86::CMOVP64rr: | 
|  | 4056 | return X86::COND_P; | 
|  | 4057 | case X86::CMOVS16rm:  case X86::CMOVS16rr:  case X86::CMOVS32rm: | 
|  | 4058 | case X86::CMOVS32rr:  case X86::CMOVS64rm:  case X86::CMOVS64rr: | 
|  | 4059 | return X86::COND_S; | 
|  | 4060 | } | 
|  | 4061 | } | 
|  | 4062 |  | 
| Chris Lattner | c0fb567 | 2006-10-20 17:42:20 +0000 | [diff] [blame] | 4063 | unsigned X86::GetCondBranchFromCond(X86::CondCode CC) { | 
|  | 4064 | switch (CC) { | 
| Torok Edwin | fbcc663 | 2009-07-14 16:55:14 +0000 | [diff] [blame] | 4065 | default: llvm_unreachable("Illegal condition code!"); | 
| Craig Topper | 49758aa | 2015-01-06 04:23:53 +0000 | [diff] [blame] | 4066 | case X86::COND_E:  return X86::JE_1; | 
|  | 4067 | case X86::COND_NE: return X86::JNE_1; | 
|  | 4068 | case X86::COND_L:  return X86::JL_1; | 
|  | 4069 | case X86::COND_LE: return X86::JLE_1; | 
|  | 4070 | case X86::COND_G:  return X86::JG_1; | 
|  | 4071 | case X86::COND_GE: return X86::JGE_1; | 
|  | 4072 | case X86::COND_B:  return X86::JB_1; | 
|  | 4073 | case X86::COND_BE: return X86::JBE_1; | 
|  | 4074 | case X86::COND_A:  return X86::JA_1; | 
|  | 4075 | case X86::COND_AE: return X86::JAE_1; | 
|  | 4076 | case X86::COND_S:  return X86::JS_1; | 
|  | 4077 | case X86::COND_NS: return X86::JNS_1; | 
|  | 4078 | case X86::COND_P:  return X86::JP_1; | 
|  | 4079 | case X86::COND_NP: return X86::JNP_1; | 
|  | 4080 | case X86::COND_O:  return X86::JO_1; | 
|  | 4081 | case X86::COND_NO: return X86::JNO_1; | 
| Chris Lattner | c0fb567 | 2006-10-20 17:42:20 +0000 | [diff] [blame] | 4082 | } | 
|  | 4083 | } | 
|  | 4084 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 4085 | /// Return the inverse of the specified condition, | 
| Chris Lattner | 3a897f3 | 2006-10-21 05:52:40 +0000 | [diff] [blame] | 4086 | /// e.g. turning COND_E to COND_NE. | 
|  | 4087 | X86::CondCode X86::GetOppositeBranchCondition(X86::CondCode CC) { | 
|  | 4088 | switch (CC) { | 
| Torok Edwin | fbcc663 | 2009-07-14 16:55:14 +0000 | [diff] [blame] | 4089 | default: llvm_unreachable("Illegal condition code!"); | 
| Chris Lattner | 3a897f3 | 2006-10-21 05:52:40 +0000 | [diff] [blame] | 4090 | case X86::COND_E:  return X86::COND_NE; | 
|  | 4091 | case X86::COND_NE: return X86::COND_E; | 
|  | 4092 | case X86::COND_L:  return X86::COND_GE; | 
|  | 4093 | case X86::COND_LE: return X86::COND_G; | 
|  | 4094 | case X86::COND_G:  return X86::COND_LE; | 
|  | 4095 | case X86::COND_GE: return X86::COND_L; | 
|  | 4096 | case X86::COND_B:  return X86::COND_AE; | 
|  | 4097 | case X86::COND_BE: return X86::COND_A; | 
|  | 4098 | case X86::COND_A:  return X86::COND_BE; | 
|  | 4099 | case X86::COND_AE: return X86::COND_B; | 
|  | 4100 | case X86::COND_S:  return X86::COND_NS; | 
|  | 4101 | case X86::COND_NS: return X86::COND_S; | 
|  | 4102 | case X86::COND_P:  return X86::COND_NP; | 
|  | 4103 | case X86::COND_NP: return X86::COND_P; | 
|  | 4104 | case X86::COND_O:  return X86::COND_NO; | 
|  | 4105 | case X86::COND_NO: return X86::COND_O; | 
| Cong Hou | 9471084 | 2016-03-23 21:45:37 +0000 | [diff] [blame] | 4106 | case X86::COND_NE_OR_P:  return X86::COND_E_AND_NP; | 
|  | 4107 | case X86::COND_E_AND_NP: return X86::COND_NE_OR_P; | 
| Chris Lattner | 3a897f3 | 2006-10-21 05:52:40 +0000 | [diff] [blame] | 4108 | } | 
|  | 4109 | } | 
|  | 4110 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 4111 | /// Assuming the flags are set by MI(a,b), return the condition code if we | 
|  | 4112 | /// modify the instructions such that flags are set by MI(b,a). | 
| Benjamin Kramer | abbfe69 | 2012-07-13 13:25:15 +0000 | [diff] [blame] | 4113 | static X86::CondCode getSwappedCondition(X86::CondCode CC) { | 
| Manman Ren | 5f6fa42 | 2012-07-09 18:57:12 +0000 | [diff] [blame] | 4114 | switch (CC) { | 
|  | 4115 | default: return X86::COND_INVALID; | 
|  | 4116 | case X86::COND_E:  return X86::COND_E; | 
|  | 4117 | case X86::COND_NE: return X86::COND_NE; | 
|  | 4118 | case X86::COND_L:  return X86::COND_G; | 
|  | 4119 | case X86::COND_LE: return X86::COND_GE; | 
|  | 4120 | case X86::COND_G:  return X86::COND_L; | 
|  | 4121 | case X86::COND_GE: return X86::COND_LE; | 
|  | 4122 | case X86::COND_B:  return X86::COND_A; | 
|  | 4123 | case X86::COND_BE: return X86::COND_AE; | 
|  | 4124 | case X86::COND_A:  return X86::COND_B; | 
|  | 4125 | case X86::COND_AE: return X86::COND_BE; | 
|  | 4126 | } | 
|  | 4127 | } | 
|  | 4128 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 4129 | /// Return a set opcode for the given condition and | 
| Manman Ren | 5f6fa42 | 2012-07-09 18:57:12 +0000 | [diff] [blame] | 4130 | /// whether it has memory operand. | 
| Juergen Ributzka | 2da1bbc | 2014-06-16 23:58:24 +0000 | [diff] [blame] | 4131 | unsigned X86::getSETFromCond(CondCode CC, bool HasMemoryOperand) { | 
| Craig Topper | bfcfdeb | 2012-08-21 08:23:21 +0000 | [diff] [blame] | 4132 | static const uint16_t Opc[16][2] = { | 
| Manman Ren | 5f6fa42 | 2012-07-09 18:57:12 +0000 | [diff] [blame] | 4133 | { X86::SETAr,  X86::SETAm  }, | 
|  | 4134 | { X86::SETAEr, X86::SETAEm }, | 
|  | 4135 | { X86::SETBr,  X86::SETBm  }, | 
|  | 4136 | { X86::SETBEr, X86::SETBEm }, | 
|  | 4137 | { X86::SETEr,  X86::SETEm  }, | 
|  | 4138 | { X86::SETGr,  X86::SETGm  }, | 
|  | 4139 | { X86::SETGEr, X86::SETGEm }, | 
|  | 4140 | { X86::SETLr,  X86::SETLm  }, | 
|  | 4141 | { X86::SETLEr, X86::SETLEm }, | 
|  | 4142 | { X86::SETNEr, X86::SETNEm }, | 
|  | 4143 | { X86::SETNOr, X86::SETNOm }, | 
|  | 4144 | { X86::SETNPr, X86::SETNPm }, | 
|  | 4145 | { X86::SETNSr, X86::SETNSm }, | 
|  | 4146 | { X86::SETOr,  X86::SETOm  }, | 
|  | 4147 | { X86::SETPr,  X86::SETPm  }, | 
|  | 4148 | { X86::SETSr,  X86::SETSm  } | 
|  | 4149 | }; | 
|  | 4150 |  | 
| Juergen Ributzka | 2da1bbc | 2014-06-16 23:58:24 +0000 | [diff] [blame] | 4151 | assert(CC <= LAST_VALID_COND && "Can only handle standard cond codes"); | 
| Manman Ren | 5f6fa42 | 2012-07-09 18:57:12 +0000 | [diff] [blame] | 4152 | return Opc[CC][HasMemoryOperand ? 1 : 0]; | 
|  | 4153 | } | 
|  | 4154 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 4155 | /// Return a cmov opcode for the given condition, | 
| Manman Ren | 5f6fa42 | 2012-07-09 18:57:12 +0000 | [diff] [blame] | 4156 | /// register size in bytes, and operand type. | 
| Juergen Ributzka | 6ef06f9 | 2014-06-23 21:55:36 +0000 | [diff] [blame] | 4157 | unsigned X86::getCMovFromCond(CondCode CC, unsigned RegBytes, | 
|  | 4158 | bool HasMemoryOperand) { | 
| Craig Topper | bfcfdeb | 2012-08-21 08:23:21 +0000 | [diff] [blame] | 4159 | static const uint16_t Opc[32][3] = { | 
| Jakob Stoklund Olesen | 49e4d4b | 2012-07-04 00:09:58 +0000 | [diff] [blame] | 4160 | { X86::CMOVA16rr,  X86::CMOVA32rr,  X86::CMOVA64rr  }, | 
|  | 4161 | { X86::CMOVAE16rr, X86::CMOVAE32rr, X86::CMOVAE64rr }, | 
|  | 4162 | { X86::CMOVB16rr,  X86::CMOVB32rr,  X86::CMOVB64rr  }, | 
|  | 4163 | { X86::CMOVBE16rr, X86::CMOVBE32rr, X86::CMOVBE64rr }, | 
|  | 4164 | { X86::CMOVE16rr,  X86::CMOVE32rr,  X86::CMOVE64rr  }, | 
|  | 4165 | { X86::CMOVG16rr,  X86::CMOVG32rr,  X86::CMOVG64rr  }, | 
|  | 4166 | { X86::CMOVGE16rr, X86::CMOVGE32rr, X86::CMOVGE64rr }, | 
|  | 4167 | { X86::CMOVL16rr,  X86::CMOVL32rr,  X86::CMOVL64rr  }, | 
|  | 4168 | { X86::CMOVLE16rr, X86::CMOVLE32rr, X86::CMOVLE64rr }, | 
|  | 4169 | { X86::CMOVNE16rr, X86::CMOVNE32rr, X86::CMOVNE64rr }, | 
|  | 4170 | { X86::CMOVNO16rr, X86::CMOVNO32rr, X86::CMOVNO64rr }, | 
|  | 4171 | { X86::CMOVNP16rr, X86::CMOVNP32rr, X86::CMOVNP64rr }, | 
|  | 4172 | { X86::CMOVNS16rr, X86::CMOVNS32rr, X86::CMOVNS64rr }, | 
|  | 4173 | { X86::CMOVO16rr,  X86::CMOVO32rr,  X86::CMOVO64rr  }, | 
|  | 4174 | { X86::CMOVP16rr,  X86::CMOVP32rr,  X86::CMOVP64rr  }, | 
| Manman Ren | 5f6fa42 | 2012-07-09 18:57:12 +0000 | [diff] [blame] | 4175 | { X86::CMOVS16rr,  X86::CMOVS32rr,  X86::CMOVS64rr  }, | 
|  | 4176 | { X86::CMOVA16rm,  X86::CMOVA32rm,  X86::CMOVA64rm  }, | 
|  | 4177 | { X86::CMOVAE16rm, X86::CMOVAE32rm, X86::CMOVAE64rm }, | 
|  | 4178 | { X86::CMOVB16rm,  X86::CMOVB32rm,  X86::CMOVB64rm  }, | 
|  | 4179 | { X86::CMOVBE16rm, X86::CMOVBE32rm, X86::CMOVBE64rm }, | 
|  | 4180 | { X86::CMOVE16rm,  X86::CMOVE32rm,  X86::CMOVE64rm  }, | 
|  | 4181 | { X86::CMOVG16rm,  X86::CMOVG32rm,  X86::CMOVG64rm  }, | 
|  | 4182 | { X86::CMOVGE16rm, X86::CMOVGE32rm, X86::CMOVGE64rm }, | 
|  | 4183 | { X86::CMOVL16rm,  X86::CMOVL32rm,  X86::CMOVL64rm  }, | 
|  | 4184 | { X86::CMOVLE16rm, X86::CMOVLE32rm, X86::CMOVLE64rm }, | 
|  | 4185 | { X86::CMOVNE16rm, X86::CMOVNE32rm, X86::CMOVNE64rm }, | 
|  | 4186 | { X86::CMOVNO16rm, X86::CMOVNO32rm, X86::CMOVNO64rm }, | 
|  | 4187 | { X86::CMOVNP16rm, X86::CMOVNP32rm, X86::CMOVNP64rm }, | 
|  | 4188 | { X86::CMOVNS16rm, X86::CMOVNS32rm, X86::CMOVNS64rm }, | 
|  | 4189 | { X86::CMOVO16rm,  X86::CMOVO32rm,  X86::CMOVO64rm  }, | 
|  | 4190 | { X86::CMOVP16rm,  X86::CMOVP32rm,  X86::CMOVP64rm  }, | 
|  | 4191 | { X86::CMOVS16rm,  X86::CMOVS32rm,  X86::CMOVS64rm  } | 
| Jakob Stoklund Olesen | 49e4d4b | 2012-07-04 00:09:58 +0000 | [diff] [blame] | 4192 | }; | 
|  | 4193 |  | 
|  | 4194 | assert(CC < 16 && "Can only handle standard cond codes"); | 
| Manman Ren | 5f6fa42 | 2012-07-09 18:57:12 +0000 | [diff] [blame] | 4195 | unsigned Idx = HasMemoryOperand ? 16+CC : CC; | 
| Jakob Stoklund Olesen | 49e4d4b | 2012-07-04 00:09:58 +0000 | [diff] [blame] | 4196 | switch(RegBytes) { | 
|  | 4197 | default: llvm_unreachable("Illegal register size!"); | 
| Manman Ren | 5f6fa42 | 2012-07-09 18:57:12 +0000 | [diff] [blame] | 4198 | case 2: return Opc[Idx][0]; | 
|  | 4199 | case 4: return Opc[Idx][1]; | 
|  | 4200 | case 8: return Opc[Idx][2]; | 
| Jakob Stoklund Olesen | 49e4d4b | 2012-07-04 00:09:58 +0000 | [diff] [blame] | 4201 | } | 
|  | 4202 | } | 
|  | 4203 |  | 
| Duncan P. N. Exon Smith | 6307eb5 | 2016-02-23 02:46:52 +0000 | [diff] [blame] | 4204 | bool X86InstrInfo::isUnpredicatedTerminator(const MachineInstr &MI) const { | 
|  | 4205 | if (!MI.isTerminator()) return false; | 
| NAKAMURA Takumi | 9d29eff | 2011-01-26 02:03:37 +0000 | [diff] [blame] | 4206 |  | 
| Chris Lattner | a98c679 | 2008-01-07 01:56:04 +0000 | [diff] [blame] | 4207 | // Conditional branch is a special case. | 
| Duncan P. N. Exon Smith | 6307eb5 | 2016-02-23 02:46:52 +0000 | [diff] [blame] | 4208 | if (MI.isBranch() && !MI.isBarrier()) | 
| Chris Lattner | a98c679 | 2008-01-07 01:56:04 +0000 | [diff] [blame] | 4209 | return true; | 
| Duncan P. N. Exon Smith | 6307eb5 | 2016-02-23 02:46:52 +0000 | [diff] [blame] | 4210 | if (!MI.isPredicable()) | 
| Chris Lattner | a98c679 | 2008-01-07 01:56:04 +0000 | [diff] [blame] | 4211 | return true; | 
|  | 4212 | return !isPredicated(MI); | 
| Dale Johannesen | 616627b | 2007-06-14 22:03:45 +0000 | [diff] [blame] | 4213 | } | 
| Chris Lattner | 3a897f3 | 2006-10-21 05:52:40 +0000 | [diff] [blame] | 4214 |  | 
| David L Kreitzer | e7c583e | 2016-05-17 12:47:46 +0000 | [diff] [blame] | 4215 | // Given a MBB and its TBB, find the FBB which was a fallthrough MBB (it may | 
|  | 4216 | // not be a fallthrough MBB now due to layout changes). Return nullptr if the | 
|  | 4217 | // fallthrough MBB cannot be identified. | 
| Cong Hou | 9471084 | 2016-03-23 21:45:37 +0000 | [diff] [blame] | 4218 | static MachineBasicBlock *getFallThroughMBB(MachineBasicBlock *MBB, | 
|  | 4219 | MachineBasicBlock *TBB) { | 
| David L Kreitzer | e7c583e | 2016-05-17 12:47:46 +0000 | [diff] [blame] | 4220 | // Look for non-EHPad successors other than TBB. If we find exactly one, it | 
|  | 4221 | // is the fallthrough MBB. If we find zero, then TBB is both the target MBB | 
|  | 4222 | // and fallthrough MBB. If we find more than one, we cannot identify the | 
|  | 4223 | // fallthrough MBB and should return nullptr. | 
| Cong Hou | 9471084 | 2016-03-23 21:45:37 +0000 | [diff] [blame] | 4224 | MachineBasicBlock *FallthroughBB = nullptr; | 
|  | 4225 | for (auto SI = MBB->succ_begin(), SE = MBB->succ_end(); SI != SE; ++SI) { | 
| David L Kreitzer | e7c583e | 2016-05-17 12:47:46 +0000 | [diff] [blame] | 4226 | if ((*SI)->isEHPad() || (*SI == TBB && FallthroughBB)) | 
| Cong Hou | 9471084 | 2016-03-23 21:45:37 +0000 | [diff] [blame] | 4227 | continue; | 
|  | 4228 | // Return a nullptr if we found more than one fallthrough successor. | 
| David L Kreitzer | e7c583e | 2016-05-17 12:47:46 +0000 | [diff] [blame] | 4229 | if (FallthroughBB && FallthroughBB != TBB) | 
| Cong Hou | 9471084 | 2016-03-23 21:45:37 +0000 | [diff] [blame] | 4230 | return nullptr; | 
|  | 4231 | FallthroughBB = *SI; | 
|  | 4232 | } | 
|  | 4233 | return FallthroughBB; | 
|  | 4234 | } | 
|  | 4235 |  | 
| Sanjoy Das | 6b34a46 | 2015-06-15 18:44:21 +0000 | [diff] [blame] | 4236 | bool X86InstrInfo::AnalyzeBranchImpl( | 
|  | 4237 | MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, | 
|  | 4238 | SmallVectorImpl<MachineOperand> &Cond, | 
|  | 4239 | SmallVectorImpl<MachineInstr *> &CondBranches, bool AllowModify) const { | 
|  | 4240 |  | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4241 | // Start from the bottom of the block and work up, examining the | 
|  | 4242 | // terminator instructions. | 
| Chris Lattner | c0fb567 | 2006-10-20 17:42:20 +0000 | [diff] [blame] | 4243 | MachineBasicBlock::iterator I = MBB.end(); | 
| Evan Cheng | 4ca4bc6 | 2010-04-13 18:50:27 +0000 | [diff] [blame] | 4244 | MachineBasicBlock::iterator UnCondBrIter = MBB.end(); | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4245 | while (I != MBB.begin()) { | 
|  | 4246 | --I; | 
| Dale Johannesen | 4244d12 | 2010-04-02 01:38:09 +0000 | [diff] [blame] | 4247 | if (I->isDebugValue()) | 
|  | 4248 | continue; | 
| Bill Wendling | 277381f | 2009-12-14 06:51:19 +0000 | [diff] [blame] | 4249 |  | 
|  | 4250 | // Working from the bottom, when we see a non-terminator instruction, we're | 
|  | 4251 | // done. | 
| Duncan P. N. Exon Smith | 6307eb5 | 2016-02-23 02:46:52 +0000 | [diff] [blame] | 4252 | if (!isUnpredicatedTerminator(*I)) | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4253 | break; | 
| Bill Wendling | 277381f | 2009-12-14 06:51:19 +0000 | [diff] [blame] | 4254 |  | 
|  | 4255 | // A terminator that isn't a branch can't easily be handled by this | 
|  | 4256 | // analysis. | 
| Evan Cheng | 7f8e563 | 2011-12-07 07:15:52 +0000 | [diff] [blame] | 4257 | if (!I->isBranch()) | 
| Chris Lattner | c0fb567 | 2006-10-20 17:42:20 +0000 | [diff] [blame] | 4258 | return true; | 
| Bill Wendling | 277381f | 2009-12-14 06:51:19 +0000 | [diff] [blame] | 4259 |  | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4260 | // Handle unconditional branches. | 
| Craig Topper | 49758aa | 2015-01-06 04:23:53 +0000 | [diff] [blame] | 4261 | if (I->getOpcode() == X86::JMP_1) { | 
| Evan Cheng | 4ca4bc6 | 2010-04-13 18:50:27 +0000 | [diff] [blame] | 4262 | UnCondBrIter = I; | 
|  | 4263 |  | 
| Evan Cheng | 64dfcac | 2009-02-09 07:14:22 +0000 | [diff] [blame] | 4264 | if (!AllowModify) { | 
|  | 4265 | TBB = I->getOperand(0).getMBB(); | 
| Evan Cheng | 2fa2811 | 2009-05-08 06:34:09 +0000 | [diff] [blame] | 4266 | continue; | 
| Evan Cheng | 64dfcac | 2009-02-09 07:14:22 +0000 | [diff] [blame] | 4267 | } | 
|  | 4268 |  | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4269 | // If the block has any instructions after a JMP, delete them. | 
| Benjamin Kramer | b6d0bd4 | 2014-03-02 12:27:27 +0000 | [diff] [blame] | 4270 | while (std::next(I) != MBB.end()) | 
|  | 4271 | std::next(I)->eraseFromParent(); | 
| Bill Wendling | 277381f | 2009-12-14 06:51:19 +0000 | [diff] [blame] | 4272 |  | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4273 | Cond.clear(); | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 4274 | FBB = nullptr; | 
| Bill Wendling | 277381f | 2009-12-14 06:51:19 +0000 | [diff] [blame] | 4275 |  | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4276 | // Delete the JMP if it's equivalent to a fall-through. | 
|  | 4277 | if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) { | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 4278 | TBB = nullptr; | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4279 | I->eraseFromParent(); | 
|  | 4280 | I = MBB.end(); | 
| Evan Cheng | 4ca4bc6 | 2010-04-13 18:50:27 +0000 | [diff] [blame] | 4281 | UnCondBrIter = MBB.end(); | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4282 | continue; | 
|  | 4283 | } | 
| Bill Wendling | 277381f | 2009-12-14 06:51:19 +0000 | [diff] [blame] | 4284 |  | 
| Evan Cheng | 4ca4bc6 | 2010-04-13 18:50:27 +0000 | [diff] [blame] | 4285 | // TBB is used to indicate the unconditional destination. | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4286 | TBB = I->getOperand(0).getMBB(); | 
|  | 4287 | continue; | 
| Chris Lattner | c0fb567 | 2006-10-20 17:42:20 +0000 | [diff] [blame] | 4288 | } | 
| Bill Wendling | 277381f | 2009-12-14 06:51:19 +0000 | [diff] [blame] | 4289 |  | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4290 | // Handle conditional branches. | 
| Manman Ren | 5f6fa42 | 2012-07-09 18:57:12 +0000 | [diff] [blame] | 4291 | X86::CondCode BranchCode = getCondFromBranchOpc(I->getOpcode()); | 
| Chris Lattner | c0fb567 | 2006-10-20 17:42:20 +0000 | [diff] [blame] | 4292 | if (BranchCode == X86::COND_INVALID) | 
|  | 4293 | return true;  // Can't handle indirect branch. | 
| Bill Wendling | 277381f | 2009-12-14 06:51:19 +0000 | [diff] [blame] | 4294 |  | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4295 | // Working from the bottom, handle the first conditional branch. | 
|  | 4296 | if (Cond.empty()) { | 
| Evan Cheng | 4ca4bc6 | 2010-04-13 18:50:27 +0000 | [diff] [blame] | 4297 | MachineBasicBlock *TargetBB = I->getOperand(0).getMBB(); | 
|  | 4298 | if (AllowModify && UnCondBrIter != MBB.end() && | 
|  | 4299 | MBB.isLayoutSuccessor(TargetBB)) { | 
|  | 4300 | // If we can modify the code and it ends in something like: | 
|  | 4301 | // | 
|  | 4302 | //     jCC L1 | 
|  | 4303 | //     jmp L2 | 
|  | 4304 | //   L1: | 
|  | 4305 | //     ... | 
|  | 4306 | //   L2: | 
|  | 4307 | // | 
|  | 4308 | // Then we can change this to: | 
|  | 4309 | // | 
|  | 4310 | //     jnCC L2 | 
|  | 4311 | //   L1: | 
|  | 4312 | //     ... | 
|  | 4313 | //   L2: | 
|  | 4314 | // | 
|  | 4315 | // Which is a bit more efficient. | 
|  | 4316 | // We conditionally jump to the fall-through block. | 
|  | 4317 | BranchCode = GetOppositeBranchCondition(BranchCode); | 
|  | 4318 | unsigned JNCC = GetCondBranchFromCond(BranchCode); | 
|  | 4319 | MachineBasicBlock::iterator OldInst = I; | 
|  | 4320 |  | 
|  | 4321 | BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(JNCC)) | 
| Benjamin Kramer | d477e9e | 2016-01-27 12:44:12 +0000 | [diff] [blame] | 4322 | .addMBB(UnCondBrIter->getOperand(0).getMBB()); | 
| Craig Topper | 49758aa | 2015-01-06 04:23:53 +0000 | [diff] [blame] | 4323 | BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(X86::JMP_1)) | 
| Benjamin Kramer | d477e9e | 2016-01-27 12:44:12 +0000 | [diff] [blame] | 4324 | .addMBB(TargetBB); | 
| Evan Cheng | 4ca4bc6 | 2010-04-13 18:50:27 +0000 | [diff] [blame] | 4325 |  | 
|  | 4326 | OldInst->eraseFromParent(); | 
|  | 4327 | UnCondBrIter->eraseFromParent(); | 
|  | 4328 |  | 
|  | 4329 | // Restart the analysis. | 
|  | 4330 | UnCondBrIter = MBB.end(); | 
|  | 4331 | I = MBB.end(); | 
|  | 4332 | continue; | 
|  | 4333 | } | 
|  | 4334 |  | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4335 | FBB = TBB; | 
|  | 4336 | TBB = I->getOperand(0).getMBB(); | 
|  | 4337 | Cond.push_back(MachineOperand::CreateImm(BranchCode)); | 
| Duncan P. N. Exon Smith | 7b4c18e | 2016-07-12 03:18:50 +0000 | [diff] [blame] | 4338 | CondBranches.push_back(&*I); | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4339 | continue; | 
|  | 4340 | } | 
| Bill Wendling | 277381f | 2009-12-14 06:51:19 +0000 | [diff] [blame] | 4341 |  | 
|  | 4342 | // Handle subsequent conditional branches. Only handle the case where all | 
|  | 4343 | // conditional branches branch to the same destination and their condition | 
|  | 4344 | // opcodes fit one of the special multi-branch idioms. | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4345 | assert(Cond.size() == 1); | 
|  | 4346 | assert(TBB); | 
| Bill Wendling | 277381f | 2009-12-14 06:51:19 +0000 | [diff] [blame] | 4347 |  | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4348 | // If the conditions are the same, we can leave them alone. | 
| Bill Wendling | 277381f | 2009-12-14 06:51:19 +0000 | [diff] [blame] | 4349 | X86::CondCode OldBranchCode = (X86::CondCode)Cond[0].getImm(); | 
| Cong Hou | 9471084 | 2016-03-23 21:45:37 +0000 | [diff] [blame] | 4350 | auto NewTBB = I->getOperand(0).getMBB(); | 
|  | 4351 | if (OldBranchCode == BranchCode && TBB == NewTBB) | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4352 | continue; | 
| Bill Wendling | 277381f | 2009-12-14 06:51:19 +0000 | [diff] [blame] | 4353 |  | 
|  | 4354 | // If they differ, see if they fit one of the known patterns. Theoretically, | 
|  | 4355 | // we could handle more patterns here, but we shouldn't expect to see them | 
|  | 4356 | // if instruction selection has done a reasonable job. | 
| Cong Hou | 9471084 | 2016-03-23 21:45:37 +0000 | [diff] [blame] | 4357 | if (TBB == NewTBB && | 
|  | 4358 | ((OldBranchCode == X86::COND_P && BranchCode == X86::COND_NE) || | 
|  | 4359 | (OldBranchCode == X86::COND_NE && BranchCode == X86::COND_P))) { | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4360 | BranchCode = X86::COND_NE_OR_P; | 
| Cong Hou | 9471084 | 2016-03-23 21:45:37 +0000 | [diff] [blame] | 4361 | } else if ((OldBranchCode == X86::COND_NP && BranchCode == X86::COND_NE) || | 
|  | 4362 | (OldBranchCode == X86::COND_E && BranchCode == X86::COND_P)) { | 
|  | 4363 | if (NewTBB != (FBB ? FBB : getFallThroughMBB(&MBB, TBB))) | 
|  | 4364 | return true; | 
|  | 4365 |  | 
|  | 4366 | // X86::COND_E_AND_NP usually has two different branch destinations. | 
|  | 4367 | // | 
|  | 4368 | // JP B1 | 
|  | 4369 | // JE B2 | 
|  | 4370 | // JMP B1 | 
|  | 4371 | // B1: | 
|  | 4372 | // B2: | 
|  | 4373 | // | 
|  | 4374 | // Here this condition branches to B2 only if NP && E. It has another | 
|  | 4375 | // equivalent form: | 
|  | 4376 | // | 
|  | 4377 | // JNE B1 | 
|  | 4378 | // JNP B2 | 
|  | 4379 | // JMP B1 | 
|  | 4380 | // B1: | 
|  | 4381 | // B2: | 
|  | 4382 | // | 
|  | 4383 | // Similarly it branches to B2 only if E && NP. That is why this condition | 
|  | 4384 | // is named with COND_E_AND_NP. | 
|  | 4385 | BranchCode = X86::COND_E_AND_NP; | 
|  | 4386 | } else | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4387 | return true; | 
| Bill Wendling | 277381f | 2009-12-14 06:51:19 +0000 | [diff] [blame] | 4388 |  | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4389 | // Update the MachineOperand. | 
|  | 4390 | Cond[0].setImm(BranchCode); | 
| Duncan P. N. Exon Smith | 7b4c18e | 2016-07-12 03:18:50 +0000 | [diff] [blame] | 4391 | CondBranches.push_back(&*I); | 
| Chris Lattner | 7443600 | 2006-10-30 22:27:23 +0000 | [diff] [blame] | 4392 | } | 
| Chris Lattner | c0fb567 | 2006-10-20 17:42:20 +0000 | [diff] [blame] | 4393 |  | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4394 | return false; | 
| Chris Lattner | c0fb567 | 2006-10-20 17:42:20 +0000 | [diff] [blame] | 4395 | } | 
|  | 4396 |  | 
| Jacques Pienaar | 71c30a1 | 2016-07-15 14:41:04 +0000 | [diff] [blame] | 4397 | bool X86InstrInfo::analyzeBranch(MachineBasicBlock &MBB, | 
| Sanjoy Das | 6b34a46 | 2015-06-15 18:44:21 +0000 | [diff] [blame] | 4398 | MachineBasicBlock *&TBB, | 
|  | 4399 | MachineBasicBlock *&FBB, | 
|  | 4400 | SmallVectorImpl<MachineOperand> &Cond, | 
|  | 4401 | bool AllowModify) const { | 
|  | 4402 | SmallVector<MachineInstr *, 4> CondBranches; | 
|  | 4403 | return AnalyzeBranchImpl(MBB, TBB, FBB, Cond, CondBranches, AllowModify); | 
|  | 4404 | } | 
|  | 4405 |  | 
| Jacques Pienaar | 71c30a1 | 2016-07-15 14:41:04 +0000 | [diff] [blame] | 4406 | bool X86InstrInfo::analyzeBranchPredicate(MachineBasicBlock &MBB, | 
| Sanjoy Das | 6b34a46 | 2015-06-15 18:44:21 +0000 | [diff] [blame] | 4407 | MachineBranchPredicate &MBP, | 
|  | 4408 | bool AllowModify) const { | 
|  | 4409 | using namespace std::placeholders; | 
|  | 4410 |  | 
|  | 4411 | SmallVector<MachineOperand, 4> Cond; | 
|  | 4412 | SmallVector<MachineInstr *, 4> CondBranches; | 
|  | 4413 | if (AnalyzeBranchImpl(MBB, MBP.TrueDest, MBP.FalseDest, Cond, CondBranches, | 
|  | 4414 | AllowModify)) | 
|  | 4415 | return true; | 
|  | 4416 |  | 
|  | 4417 | if (Cond.size() != 1) | 
|  | 4418 | return true; | 
|  | 4419 |  | 
|  | 4420 | assert(MBP.TrueDest && "expected!"); | 
|  | 4421 |  | 
|  | 4422 | if (!MBP.FalseDest) | 
|  | 4423 | MBP.FalseDest = MBB.getNextNode(); | 
|  | 4424 |  | 
|  | 4425 | const TargetRegisterInfo *TRI = &getRegisterInfo(); | 
|  | 4426 |  | 
|  | 4427 | MachineInstr *ConditionDef = nullptr; | 
|  | 4428 | bool SingleUseCondition = true; | 
|  | 4429 |  | 
|  | 4430 | for (auto I = std::next(MBB.rbegin()), E = MBB.rend(); I != E; ++I) { | 
|  | 4431 | if (I->modifiesRegister(X86::EFLAGS, TRI)) { | 
|  | 4432 | ConditionDef = &*I; | 
|  | 4433 | break; | 
|  | 4434 | } | 
|  | 4435 |  | 
|  | 4436 | if (I->readsRegister(X86::EFLAGS, TRI)) | 
|  | 4437 | SingleUseCondition = false; | 
|  | 4438 | } | 
|  | 4439 |  | 
|  | 4440 | if (!ConditionDef) | 
|  | 4441 | return true; | 
|  | 4442 |  | 
|  | 4443 | if (SingleUseCondition) { | 
|  | 4444 | for (auto *Succ : MBB.successors()) | 
|  | 4445 | if (Succ->isLiveIn(X86::EFLAGS)) | 
|  | 4446 | SingleUseCondition = false; | 
|  | 4447 | } | 
|  | 4448 |  | 
|  | 4449 | MBP.ConditionDef = ConditionDef; | 
|  | 4450 | MBP.SingleUseCondition = SingleUseCondition; | 
|  | 4451 |  | 
|  | 4452 | // Currently we only recognize the simple pattern: | 
|  | 4453 | // | 
|  | 4454 | //   test %reg, %reg | 
|  | 4455 | //   je %label | 
|  | 4456 | // | 
|  | 4457 | const unsigned TestOpcode = | 
|  | 4458 | Subtarget.is64Bit() ? X86::TEST64rr : X86::TEST32rr; | 
|  | 4459 |  | 
|  | 4460 | if (ConditionDef->getOpcode() == TestOpcode && | 
|  | 4461 | ConditionDef->getNumOperands() == 3 && | 
|  | 4462 | ConditionDef->getOperand(0).isIdenticalTo(ConditionDef->getOperand(1)) && | 
|  | 4463 | (Cond[0].getImm() == X86::COND_NE || Cond[0].getImm() == X86::COND_E)) { | 
|  | 4464 | MBP.LHS = ConditionDef->getOperand(0); | 
|  | 4465 | MBP.RHS = MachineOperand::CreateImm(0); | 
|  | 4466 | MBP.Predicate = Cond[0].getImm() == X86::COND_NE | 
|  | 4467 | ? MachineBranchPredicate::PRED_NE | 
|  | 4468 | : MachineBranchPredicate::PRED_EQ; | 
|  | 4469 | return false; | 
|  | 4470 | } | 
|  | 4471 |  | 
|  | 4472 | return true; | 
|  | 4473 | } | 
|  | 4474 |  | 
| Evan Cheng | e20dd92 | 2007-05-18 00:18:17 +0000 | [diff] [blame] | 4475 | unsigned X86InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { | 
| Chris Lattner | c0fb567 | 2006-10-20 17:42:20 +0000 | [diff] [blame] | 4476 | MachineBasicBlock::iterator I = MBB.end(); | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4477 | unsigned Count = 0; | 
|  | 4478 |  | 
|  | 4479 | while (I != MBB.begin()) { | 
|  | 4480 | --I; | 
| Dale Johannesen | 4244d12 | 2010-04-02 01:38:09 +0000 | [diff] [blame] | 4481 | if (I->isDebugValue()) | 
|  | 4482 | continue; | 
| Craig Topper | 49758aa | 2015-01-06 04:23:53 +0000 | [diff] [blame] | 4483 | if (I->getOpcode() != X86::JMP_1 && | 
| Manman Ren | 5f6fa42 | 2012-07-09 18:57:12 +0000 | [diff] [blame] | 4484 | getCondFromBranchOpc(I->getOpcode()) == X86::COND_INVALID) | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4485 | break; | 
|  | 4486 | // Remove the branch. | 
|  | 4487 | I->eraseFromParent(); | 
|  | 4488 | I = MBB.end(); | 
|  | 4489 | ++Count; | 
|  | 4490 | } | 
| NAKAMURA Takumi | 9d29eff | 2011-01-26 02:03:37 +0000 | [diff] [blame] | 4491 |  | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4492 | return Count; | 
| Chris Lattner | c0fb567 | 2006-10-20 17:42:20 +0000 | [diff] [blame] | 4493 | } | 
|  | 4494 |  | 
| Benjamin Kramer | bdc4956 | 2016-06-12 15:39:02 +0000 | [diff] [blame] | 4495 | unsigned X86InstrInfo::InsertBranch(MachineBasicBlock &MBB, | 
|  | 4496 | MachineBasicBlock *TBB, | 
|  | 4497 | MachineBasicBlock *FBB, | 
|  | 4498 | ArrayRef<MachineOperand> Cond, | 
|  | 4499 | const DebugLoc &DL) const { | 
| Chris Lattner | c0fb567 | 2006-10-20 17:42:20 +0000 | [diff] [blame] | 4500 | // Shouldn't be a fall through. | 
|  | 4501 | assert(TBB && "InsertBranch must not be told to insert a fallthrough"); | 
| Chris Lattner | 6fca75e | 2006-10-21 05:34:23 +0000 | [diff] [blame] | 4502 | assert((Cond.size() == 1 || Cond.size() == 0) && | 
|  | 4503 | "X86 branch conditions have one component!"); | 
|  | 4504 |  | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4505 | if (Cond.empty()) { | 
|  | 4506 | // Unconditional branch? | 
|  | 4507 | assert(!FBB && "Unconditional branch with multiple successors!"); | 
| Craig Topper | 49758aa | 2015-01-06 04:23:53 +0000 | [diff] [blame] | 4508 | BuildMI(&MBB, DL, get(X86::JMP_1)).addMBB(TBB); | 
| Evan Cheng | e20dd92 | 2007-05-18 00:18:17 +0000 | [diff] [blame] | 4509 | return 1; | 
| Chris Lattner | c0fb567 | 2006-10-20 17:42:20 +0000 | [diff] [blame] | 4510 | } | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4511 |  | 
| Cong Hou | 9471084 | 2016-03-23 21:45:37 +0000 | [diff] [blame] | 4512 | // If FBB is null, it is implied to be a fall-through block. | 
|  | 4513 | bool FallThru = FBB == nullptr; | 
|  | 4514 |  | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4515 | // Conditional branch. | 
|  | 4516 | unsigned Count = 0; | 
|  | 4517 | X86::CondCode CC = (X86::CondCode)Cond[0].getImm(); | 
|  | 4518 | switch (CC) { | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4519 | case X86::COND_NE_OR_P: | 
|  | 4520 | // Synthesize NE_OR_P with two branches. | 
| Craig Topper | 49758aa | 2015-01-06 04:23:53 +0000 | [diff] [blame] | 4521 | BuildMI(&MBB, DL, get(X86::JNE_1)).addMBB(TBB); | 
| Bill Wendling | 543ce1f | 2010-03-05 00:33:59 +0000 | [diff] [blame] | 4522 | ++Count; | 
| Craig Topper | 49758aa | 2015-01-06 04:23:53 +0000 | [diff] [blame] | 4523 | BuildMI(&MBB, DL, get(X86::JP_1)).addMBB(TBB); | 
| Bill Wendling | 543ce1f | 2010-03-05 00:33:59 +0000 | [diff] [blame] | 4524 | ++Count; | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4525 | break; | 
| Cong Hou | 9471084 | 2016-03-23 21:45:37 +0000 | [diff] [blame] | 4526 | case X86::COND_E_AND_NP: | 
|  | 4527 | // Use the next block of MBB as FBB if it is null. | 
|  | 4528 | if (FBB == nullptr) { | 
|  | 4529 | FBB = getFallThroughMBB(&MBB, TBB); | 
|  | 4530 | assert(FBB && "MBB cannot be the last block in function when the false " | 
|  | 4531 | "body is a fall-through."); | 
|  | 4532 | } | 
|  | 4533 | // Synthesize COND_E_AND_NP with two branches. | 
|  | 4534 | BuildMI(&MBB, DL, get(X86::JNE_1)).addMBB(FBB); | 
|  | 4535 | ++Count; | 
|  | 4536 | BuildMI(&MBB, DL, get(X86::JNP_1)).addMBB(TBB); | 
|  | 4537 | ++Count; | 
|  | 4538 | break; | 
| Bill Wendling | 543ce1f | 2010-03-05 00:33:59 +0000 | [diff] [blame] | 4539 | default: { | 
|  | 4540 | unsigned Opc = GetCondBranchFromCond(CC); | 
| Stuart Hastings | 0125b64 | 2010-06-17 22:43:56 +0000 | [diff] [blame] | 4541 | BuildMI(&MBB, DL, get(Opc)).addMBB(TBB); | 
| Bill Wendling | 543ce1f | 2010-03-05 00:33:59 +0000 | [diff] [blame] | 4542 | ++Count; | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4543 | } | 
| Bill Wendling | 543ce1f | 2010-03-05 00:33:59 +0000 | [diff] [blame] | 4544 | } | 
| Cong Hou | 9471084 | 2016-03-23 21:45:37 +0000 | [diff] [blame] | 4545 | if (!FallThru) { | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4546 | // Two-way Conditional branch. Insert the second branch. | 
| Craig Topper | 49758aa | 2015-01-06 04:23:53 +0000 | [diff] [blame] | 4547 | BuildMI(&MBB, DL, get(X86::JMP_1)).addMBB(FBB); | 
| Dan Gohman | 97d95d6 | 2008-10-21 03:29:32 +0000 | [diff] [blame] | 4548 | ++Count; | 
|  | 4549 | } | 
|  | 4550 | return Count; | 
| Chris Lattner | c0fb567 | 2006-10-20 17:42:20 +0000 | [diff] [blame] | 4551 | } | 
|  | 4552 |  | 
| Jakob Stoklund Olesen | 49e4d4b | 2012-07-04 00:09:58 +0000 | [diff] [blame] | 4553 | bool X86InstrInfo:: | 
|  | 4554 | canInsertSelect(const MachineBasicBlock &MBB, | 
| Ahmed Bougacha | c88bf54 | 2015-06-11 19:30:37 +0000 | [diff] [blame] | 4555 | ArrayRef<MachineOperand> Cond, | 
| Jakob Stoklund Olesen | 49e4d4b | 2012-07-04 00:09:58 +0000 | [diff] [blame] | 4556 | unsigned TrueReg, unsigned FalseReg, | 
|  | 4557 | int &CondCycles, int &TrueCycles, int &FalseCycles) const { | 
|  | 4558 | // Not all subtargets have cmov instructions. | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 4559 | if (!Subtarget.hasCMov()) | 
| Jakob Stoklund Olesen | 49e4d4b | 2012-07-04 00:09:58 +0000 | [diff] [blame] | 4560 | return false; | 
|  | 4561 | if (Cond.size() != 1) | 
|  | 4562 | return false; | 
|  | 4563 | // We cannot do the composite conditions, at least not in SSA form. | 
|  | 4564 | if ((X86::CondCode)Cond[0].getImm() > X86::COND_S) | 
|  | 4565 | return false; | 
|  | 4566 |  | 
|  | 4567 | // Check register classes. | 
|  | 4568 | const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); | 
|  | 4569 | const TargetRegisterClass *RC = | 
|  | 4570 | RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg)); | 
|  | 4571 | if (!RC) | 
|  | 4572 | return false; | 
|  | 4573 |  | 
|  | 4574 | // We have cmov instructions for 16, 32, and 64 bit general purpose registers. | 
|  | 4575 | if (X86::GR16RegClass.hasSubClassEq(RC) || | 
|  | 4576 | X86::GR32RegClass.hasSubClassEq(RC) || | 
|  | 4577 | X86::GR64RegClass.hasSubClassEq(RC)) { | 
|  | 4578 | // This latency applies to Pentium M, Merom, Wolfdale, Nehalem, and Sandy | 
|  | 4579 | // Bridge. Probably Ivy Bridge as well. | 
|  | 4580 | CondCycles = 2; | 
|  | 4581 | TrueCycles = 2; | 
|  | 4582 | FalseCycles = 2; | 
|  | 4583 | return true; | 
|  | 4584 | } | 
|  | 4585 |  | 
|  | 4586 | // Can't do vectors. | 
|  | 4587 | return false; | 
|  | 4588 | } | 
|  | 4589 |  | 
|  | 4590 | void X86InstrInfo::insertSelect(MachineBasicBlock &MBB, | 
| Benjamin Kramer | bdc4956 | 2016-06-12 15:39:02 +0000 | [diff] [blame] | 4591 | MachineBasicBlock::iterator I, | 
|  | 4592 | const DebugLoc &DL, unsigned DstReg, | 
|  | 4593 | ArrayRef<MachineOperand> Cond, unsigned TrueReg, | 
|  | 4594 | unsigned FalseReg) const { | 
|  | 4595 | MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); | 
|  | 4596 | assert(Cond.size() == 1 && "Invalid Cond array"); | 
|  | 4597 | unsigned Opc = getCMovFromCond((X86::CondCode)Cond[0].getImm(), | 
|  | 4598 | MRI.getRegClass(DstReg)->getSize(), | 
|  | 4599 | false /*HasMemoryOperand*/); | 
|  | 4600 | BuildMI(MBB, I, DL, get(Opc), DstReg).addReg(FalseReg).addReg(TrueReg); | 
| Jakob Stoklund Olesen | 49e4d4b | 2012-07-04 00:09:58 +0000 | [diff] [blame] | 4601 | } | 
|  | 4602 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 4603 | /// Test if the given register is a physical h register. | 
| Dan Gohman | 7913ea5 | 2009-04-15 00:04:23 +0000 | [diff] [blame] | 4604 | static bool isHReg(unsigned Reg) { | 
| Dan Gohman | 2986972 | 2009-04-27 16:41:36 +0000 | [diff] [blame] | 4605 | return X86::GR8_ABCD_HRegClass.contains(Reg); | 
| Dan Gohman | 7913ea5 | 2009-04-15 00:04:23 +0000 | [diff] [blame] | 4606 | } | 
|  | 4607 |  | 
| Anton Korobeynikov | c0b3692 | 2010-08-27 14:43:06 +0000 | [diff] [blame] | 4608 | // Try and copy between VR128/VR64 and GR64 registers. | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 4609 | static unsigned CopyToFromAsymmetricReg(unsigned DestReg, unsigned SrcReg, | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 4610 | const X86Subtarget &Subtarget) { | 
| Elena Demikhovsky | cf5b145 | 2013-08-11 07:55:09 +0000 | [diff] [blame] | 4611 |  | 
| Anton Korobeynikov | c0b3692 | 2010-08-27 14:43:06 +0000 | [diff] [blame] | 4612 | // SrcReg(VR128) -> DestReg(GR64) | 
|  | 4613 | // SrcReg(VR64)  -> DestReg(GR64) | 
|  | 4614 | // SrcReg(GR64)  -> DestReg(VR128) | 
|  | 4615 | // SrcReg(GR64)  -> DestReg(VR64) | 
|  | 4616 |  | 
| Elena Demikhovsky | cf5b145 | 2013-08-11 07:55:09 +0000 | [diff] [blame] | 4617 | bool HasAVX = Subtarget.hasAVX(); | 
| Elena Demikhovsky | 3ce8dbb | 2013-08-18 13:08:57 +0000 | [diff] [blame] | 4618 | bool HasAVX512 = Subtarget.hasAVX512(); | 
| Anton Korobeynikov | c0b3692 | 2010-08-27 14:43:06 +0000 | [diff] [blame] | 4619 | if (X86::GR64RegClass.contains(DestReg)) { | 
| Elena Demikhovsky | 3ce8dbb | 2013-08-18 13:08:57 +0000 | [diff] [blame] | 4620 | if (X86::VR128XRegClass.contains(SrcReg)) | 
| Anton Korobeynikov | c0b3692 | 2010-08-27 14:43:06 +0000 | [diff] [blame] | 4621 | // Copy from a VR128 register to a GR64 register. | 
| Craig Topper | 53f3d1b | 2016-07-18 06:14:26 +0000 | [diff] [blame] | 4622 | return HasAVX512 ? X86::VMOVPQIto64Zrr : | 
|  | 4623 | HasAVX    ? X86::VMOVPQIto64rr  : | 
|  | 4624 | X86::MOVPQIto64rr; | 
| Craig Topper | bab0c76 | 2012-08-21 08:29:51 +0000 | [diff] [blame] | 4625 | if (X86::VR64RegClass.contains(SrcReg)) | 
| Anton Korobeynikov | c0b3692 | 2010-08-27 14:43:06 +0000 | [diff] [blame] | 4626 | // Copy from a VR64 register to a GR64 register. | 
| Bruno Cardoso Lopes | 9e6dea1 | 2015-07-14 20:09:34 +0000 | [diff] [blame] | 4627 | return X86::MMX_MOVD64from64rr; | 
| Anton Korobeynikov | c0b3692 | 2010-08-27 14:43:06 +0000 | [diff] [blame] | 4628 | } else if (X86::GR64RegClass.contains(SrcReg)) { | 
|  | 4629 | // Copy from a GR64 register to a VR128 register. | 
| Elena Demikhovsky | 3ce8dbb | 2013-08-18 13:08:57 +0000 | [diff] [blame] | 4630 | if (X86::VR128XRegClass.contains(DestReg)) | 
| Craig Topper | 53f3d1b | 2016-07-18 06:14:26 +0000 | [diff] [blame] | 4631 | return HasAVX512 ? X86::VMOV64toPQIZrr : | 
|  | 4632 | HasAVX    ? X86::VMOV64toPQIrr  : | 
|  | 4633 | X86::MOV64toPQIrr; | 
| Anton Korobeynikov | c0b3692 | 2010-08-27 14:43:06 +0000 | [diff] [blame] | 4634 | // Copy from a GR64 register to a VR64 register. | 
| Craig Topper | bab0c76 | 2012-08-21 08:29:51 +0000 | [diff] [blame] | 4635 | if (X86::VR64RegClass.contains(DestReg)) | 
| Bruno Cardoso Lopes | 9e6dea1 | 2015-07-14 20:09:34 +0000 | [diff] [blame] | 4636 | return X86::MMX_MOVD64to64rr; | 
| Anton Korobeynikov | c0b3692 | 2010-08-27 14:43:06 +0000 | [diff] [blame] | 4637 | } | 
|  | 4638 |  | 
| Jakob Stoklund Olesen | f05864a | 2011-09-22 22:45:24 +0000 | [diff] [blame] | 4639 | // SrcReg(FR32) -> DestReg(GR32) | 
|  | 4640 | // SrcReg(GR32) -> DestReg(FR32) | 
|  | 4641 |  | 
| Craig Topper | 53f3d1b | 2016-07-18 06:14:26 +0000 | [diff] [blame] | 4642 | if (X86::GR32RegClass.contains(DestReg) && | 
|  | 4643 | X86::FR32XRegClass.contains(SrcReg)) | 
| Craig Topper | bab0c76 | 2012-08-21 08:29:51 +0000 | [diff] [blame] | 4644 | // Copy from a FR32 register to a GR32 register. | 
| Craig Topper | 53f3d1b | 2016-07-18 06:14:26 +0000 | [diff] [blame] | 4645 | return HasAVX512 ? X86::VMOVSS2DIZrr : | 
|  | 4646 | HasAVX    ? X86::VMOVSS2DIrr  : | 
|  | 4647 | X86::MOVSS2DIrr; | 
| Jakob Stoklund Olesen | f05864a | 2011-09-22 22:45:24 +0000 | [diff] [blame] | 4648 |  | 
| Craig Topper | 53f3d1b | 2016-07-18 06:14:26 +0000 | [diff] [blame] | 4649 | if (X86::FR32XRegClass.contains(DestReg) && | 
|  | 4650 | X86::GR32RegClass.contains(SrcReg)) | 
| Craig Topper | bab0c76 | 2012-08-21 08:29:51 +0000 | [diff] [blame] | 4651 | // Copy from a GR32 register to a FR32 register. | 
| Craig Topper | 53f3d1b | 2016-07-18 06:14:26 +0000 | [diff] [blame] | 4652 | return HasAVX512 ? X86::VMOVDI2SSZrr : | 
|  | 4653 | HasAVX    ? X86::VMOVDI2SSrr  : | 
|  | 4654 | X86::MOVDI2SSrr; | 
| Anton Korobeynikov | c0b3692 | 2010-08-27 14:43:06 +0000 | [diff] [blame] | 4655 | return 0; | 
|  | 4656 | } | 
|  | 4657 |  | 
| Elena Demikhovsky | 7c2c9fd | 2015-11-19 13:13:00 +0000 | [diff] [blame] | 4658 | static bool MaskRegClassContains(unsigned Reg) { | 
| Igor Breger | 4dc7d39 | 2016-02-15 08:25:28 +0000 | [diff] [blame] | 4659 | // All KMASK RegClasses hold the same k registers, can be tested against anyone. | 
|  | 4660 | return X86::VK16RegClass.contains(Reg); | 
| Elena Demikhovsky | 47fc44e | 2013-12-16 13:52:35 +0000 | [diff] [blame] | 4661 | } | 
| Elena Demikhovsky | 7c2c9fd | 2015-11-19 13:13:00 +0000 | [diff] [blame] | 4662 |  | 
|  | 4663 | static bool GRRegClassContains(unsigned Reg) { | 
|  | 4664 | return X86::GR64RegClass.contains(Reg) || | 
|  | 4665 | X86::GR32RegClass.contains(Reg) || | 
|  | 4666 | X86::GR16RegClass.contains(Reg) || | 
|  | 4667 | X86::GR8RegClass.contains(Reg); | 
|  | 4668 | } | 
| Elena Demikhovsky | cf5b145 | 2013-08-11 07:55:09 +0000 | [diff] [blame] | 4669 | static | 
| Elena Demikhovsky | 7c2c9fd | 2015-11-19 13:13:00 +0000 | [diff] [blame] | 4670 | unsigned copyPhysRegOpcode_AVX512_DQ(unsigned& DestReg, unsigned& SrcReg) { | 
|  | 4671 | if (MaskRegClassContains(SrcReg) && X86::GR8RegClass.contains(DestReg)) { | 
| Craig Topper | 91dab7b | 2015-12-25 22:09:45 +0000 | [diff] [blame] | 4672 | DestReg = getX86SubSuperRegister(DestReg, 32); | 
| Elena Demikhovsky | 7c2c9fd | 2015-11-19 13:13:00 +0000 | [diff] [blame] | 4673 | return X86::KMOVBrk; | 
|  | 4674 | } | 
|  | 4675 | if (MaskRegClassContains(DestReg) && X86::GR8RegClass.contains(SrcReg)) { | 
| Craig Topper | 91dab7b | 2015-12-25 22:09:45 +0000 | [diff] [blame] | 4676 | SrcReg = getX86SubSuperRegister(SrcReg, 32); | 
| Elena Demikhovsky | 7c2c9fd | 2015-11-19 13:13:00 +0000 | [diff] [blame] | 4677 | return X86::KMOVBkr; | 
|  | 4678 | } | 
|  | 4679 | return 0; | 
|  | 4680 | } | 
|  | 4681 |  | 
|  | 4682 | static | 
|  | 4683 | unsigned copyPhysRegOpcode_AVX512_BW(unsigned& DestReg, unsigned& SrcReg) { | 
|  | 4684 | if (MaskRegClassContains(SrcReg) && MaskRegClassContains(DestReg)) | 
|  | 4685 | return X86::KMOVQkk; | 
|  | 4686 | if (MaskRegClassContains(SrcReg) && X86::GR32RegClass.contains(DestReg)) | 
|  | 4687 | return X86::KMOVDrk; | 
|  | 4688 | if (MaskRegClassContains(SrcReg) && X86::GR64RegClass.contains(DestReg)) | 
|  | 4689 | return X86::KMOVQrk; | 
|  | 4690 | if (MaskRegClassContains(DestReg) && X86::GR32RegClass.contains(SrcReg)) | 
|  | 4691 | return X86::KMOVDkr; | 
|  | 4692 | if (MaskRegClassContains(DestReg) && X86::GR64RegClass.contains(SrcReg)) | 
|  | 4693 | return X86::KMOVQkr; | 
|  | 4694 | return 0; | 
|  | 4695 | } | 
|  | 4696 |  | 
|  | 4697 | static | 
|  | 4698 | unsigned copyPhysRegOpcode_AVX512(unsigned& DestReg, unsigned& SrcReg, | 
|  | 4699 | const X86Subtarget &Subtarget) | 
|  | 4700 | { | 
|  | 4701 | if (Subtarget.hasDQI()) | 
|  | 4702 | if (auto Opc = copyPhysRegOpcode_AVX512_DQ(DestReg, SrcReg)) | 
|  | 4703 | return Opc; | 
|  | 4704 | if (Subtarget.hasBWI()) | 
|  | 4705 | if (auto Opc = copyPhysRegOpcode_AVX512_BW(DestReg, SrcReg)) | 
|  | 4706 | return Opc; | 
| Craig Topper | 5c913e8 | 2016-07-18 06:14:34 +0000 | [diff] [blame] | 4707 | if (X86::VR128XRegClass.contains(DestReg, SrcReg)) { | 
|  | 4708 | if (Subtarget.hasVLX()) | 
|  | 4709 | return X86::VMOVAPSZ128rr; | 
|  | 4710 | DestReg = get512BitSuperRegister(DestReg); | 
|  | 4711 | SrcReg = get512BitSuperRegister(SrcReg); | 
|  | 4712 | return X86::VMOVAPSZrr; | 
| Elena Demikhovsky | cf5b145 | 2013-08-11 07:55:09 +0000 | [diff] [blame] | 4713 | } | 
| Craig Topper | 5c913e8 | 2016-07-18 06:14:34 +0000 | [diff] [blame] | 4714 | if (X86::VR256XRegClass.contains(DestReg, SrcReg)) { | 
|  | 4715 | if (Subtarget.hasVLX()) | 
|  | 4716 | return X86::VMOVAPSZ256rr; | 
|  | 4717 | DestReg = get512BitSuperRegister(DestReg); | 
|  | 4718 | SrcReg = get512BitSuperRegister(SrcReg); | 
|  | 4719 | return X86::VMOVAPSZrr; | 
|  | 4720 | } | 
|  | 4721 | if (X86::VR512RegClass.contains(DestReg, SrcReg)) | 
|  | 4722 | return X86::VMOVAPSZrr; | 
| Elena Demikhovsky | 7c2c9fd | 2015-11-19 13:13:00 +0000 | [diff] [blame] | 4723 | if (MaskRegClassContains(DestReg) && MaskRegClassContains(SrcReg)) | 
| Elena Demikhovsky | cf5b145 | 2013-08-11 07:55:09 +0000 | [diff] [blame] | 4724 | return X86::KMOVWkk; | 
| Elena Demikhovsky | 7c2c9fd | 2015-11-19 13:13:00 +0000 | [diff] [blame] | 4725 | if (MaskRegClassContains(DestReg) && GRRegClassContains(SrcReg)) { | 
| Craig Topper | 91dab7b | 2015-12-25 22:09:45 +0000 | [diff] [blame] | 4726 | SrcReg = getX86SubSuperRegister(SrcReg, 32); | 
| Elena Demikhovsky | 6270b38 | 2013-12-10 11:58:35 +0000 | [diff] [blame] | 4727 | return X86::KMOVWkr; | 
|  | 4728 | } | 
| Elena Demikhovsky | 7c2c9fd | 2015-11-19 13:13:00 +0000 | [diff] [blame] | 4729 | if (GRRegClassContains(DestReg) && MaskRegClassContains(SrcReg)) { | 
| Craig Topper | 91dab7b | 2015-12-25 22:09:45 +0000 | [diff] [blame] | 4730 | DestReg = getX86SubSuperRegister(DestReg, 32); | 
| Elena Demikhovsky | 6270b38 | 2013-12-10 11:58:35 +0000 | [diff] [blame] | 4731 | return X86::KMOVWrk; | 
|  | 4732 | } | 
| Elena Demikhovsky | cf5b145 | 2013-08-11 07:55:09 +0000 | [diff] [blame] | 4733 | return 0; | 
|  | 4734 | } | 
|  | 4735 |  | 
| Jakob Stoklund Olesen | 930f808 | 2010-07-08 19:46:25 +0000 | [diff] [blame] | 4736 | void X86InstrInfo::copyPhysReg(MachineBasicBlock &MBB, | 
| Benjamin Kramer | bdc4956 | 2016-06-12 15:39:02 +0000 | [diff] [blame] | 4737 | MachineBasicBlock::iterator MI, | 
|  | 4738 | const DebugLoc &DL, unsigned DestReg, | 
|  | 4739 | unsigned SrcReg, bool KillSrc) const { | 
| Jakob Stoklund Olesen | 930f808 | 2010-07-08 19:46:25 +0000 | [diff] [blame] | 4740 | // First deal with the normal symmetric copies. | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 4741 | bool HasAVX = Subtarget.hasAVX(); | 
|  | 4742 | bool HasAVX512 = Subtarget.hasAVX512(); | 
| Elena Demikhovsky | cf5b145 | 2013-08-11 07:55:09 +0000 | [diff] [blame] | 4743 | unsigned Opc = 0; | 
| Jakob Stoklund Olesen | 930f808 | 2010-07-08 19:46:25 +0000 | [diff] [blame] | 4744 | if (X86::GR64RegClass.contains(DestReg, SrcReg)) | 
|  | 4745 | Opc = X86::MOV64rr; | 
|  | 4746 | else if (X86::GR32RegClass.contains(DestReg, SrcReg)) | 
|  | 4747 | Opc = X86::MOV32rr; | 
|  | 4748 | else if (X86::GR16RegClass.contains(DestReg, SrcReg)) | 
|  | 4749 | Opc = X86::MOV16rr; | 
|  | 4750 | else if (X86::GR8RegClass.contains(DestReg, SrcReg)) { | 
|  | 4751 | // Copying to or from a physical H register on x86-64 requires a NOREX | 
|  | 4752 | // move.  Otherwise use a normal move. | 
|  | 4753 | if ((isHReg(DestReg) || isHReg(SrcReg)) && | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 4754 | Subtarget.is64Bit()) { | 
| Jakob Stoklund Olesen | 930f808 | 2010-07-08 19:46:25 +0000 | [diff] [blame] | 4755 | Opc = X86::MOV8rr_NOREX; | 
| Jakob Stoklund Olesen | 464fcc0 | 2011-10-07 20:15:54 +0000 | [diff] [blame] | 4756 | // Both operands must be encodable without an REX prefix. | 
|  | 4757 | assert(X86::GR8_NOREXRegClass.contains(SrcReg, DestReg) && | 
|  | 4758 | "8-bit H register can not be copied outside GR8_NOREX"); | 
|  | 4759 | } else | 
| Jakob Stoklund Olesen | 930f808 | 2010-07-08 19:46:25 +0000 | [diff] [blame] | 4760 | Opc = X86::MOV8rr; | 
| Elena Demikhovsky | cf5b145 | 2013-08-11 07:55:09 +0000 | [diff] [blame] | 4761 | } | 
|  | 4762 | else if (X86::VR64RegClass.contains(DestReg, SrcReg)) | 
|  | 4763 | Opc = X86::MMX_MOVQ64rr; | 
|  | 4764 | else if (HasAVX512) | 
| Elena Demikhovsky | 7c2c9fd | 2015-11-19 13:13:00 +0000 | [diff] [blame] | 4765 | Opc = copyPhysRegOpcode_AVX512(DestReg, SrcReg, Subtarget); | 
| Elena Demikhovsky | cf5b145 | 2013-08-11 07:55:09 +0000 | [diff] [blame] | 4766 | else if (X86::VR128RegClass.contains(DestReg, SrcReg)) | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 4767 | Opc = HasAVX ? X86::VMOVAPSrr : X86::MOVAPSrr; | 
| Bruno Cardoso Lopes | 6778597 | 2011-07-14 18:50:58 +0000 | [diff] [blame] | 4768 | else if (X86::VR256RegClass.contains(DestReg, SrcReg)) | 
|  | 4769 | Opc = X86::VMOVAPSYrr; | 
| Elena Demikhovsky | cf5b145 | 2013-08-11 07:55:09 +0000 | [diff] [blame] | 4770 | if (!Opc) | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 4771 | Opc = CopyToFromAsymmetricReg(DestReg, SrcReg, Subtarget); | 
| Jakob Stoklund Olesen | 930f808 | 2010-07-08 19:46:25 +0000 | [diff] [blame] | 4772 |  | 
|  | 4773 | if (Opc) { | 
|  | 4774 | BuildMI(MBB, MI, DL, get(Opc), DestReg) | 
|  | 4775 | .addReg(SrcReg, getKillRegState(KillSrc)); | 
|  | 4776 | return; | 
|  | 4777 | } | 
|  | 4778 |  | 
| JF Bastien | fa9746d | 2015-08-10 20:59:36 +0000 | [diff] [blame] | 4779 | bool FromEFLAGS = SrcReg == X86::EFLAGS; | 
|  | 4780 | bool ToEFLAGS = DestReg == X86::EFLAGS; | 
|  | 4781 | int Reg = FromEFLAGS ? DestReg : SrcReg; | 
|  | 4782 | bool is32 = X86::GR32RegClass.contains(Reg); | 
|  | 4783 | bool is64 = X86::GR64RegClass.contains(Reg); | 
| Hans Wennborg | 5000ce8 | 2015-12-04 23:00:33 +0000 | [diff] [blame] | 4784 |  | 
| JF Bastien | fa9746d | 2015-08-10 20:59:36 +0000 | [diff] [blame] | 4785 | if ((FromEFLAGS || ToEFLAGS) && (is32 || is64)) { | 
| Hans Wennborg | 5000ce8 | 2015-12-04 23:00:33 +0000 | [diff] [blame] | 4786 | int Mov = is64 ? X86::MOV64rr : X86::MOV32rr; | 
|  | 4787 | int Push = is64 ? X86::PUSH64r : X86::PUSH32r; | 
|  | 4788 | int PushF = is64 ? X86::PUSHF64 : X86::PUSHF32; | 
|  | 4789 | int Pop = is64 ? X86::POP64r : X86::POP32r; | 
|  | 4790 | int PopF = is64 ? X86::POPF64 : X86::POPF32; | 
|  | 4791 | int AX = is64 ? X86::RAX : X86::EAX; | 
|  | 4792 |  | 
|  | 4793 | if (!Subtarget.hasLAHFSAHF()) { | 
| Hans Wennborg | 7036e50 | 2015-12-15 23:21:46 +0000 | [diff] [blame] | 4794 | assert(Subtarget.is64Bit() && | 
|  | 4795 | "Not having LAHF/SAHF only happens on 64-bit."); | 
| Hans Wennborg | 5000ce8 | 2015-12-04 23:00:33 +0000 | [diff] [blame] | 4796 | // Moving EFLAGS to / from another register requires a push and a pop. | 
|  | 4797 | // Notice that we have to adjust the stack if we don't want to clobber the | 
| David Majnemer | 3346763 | 2015-12-27 06:07:26 +0000 | [diff] [blame] | 4798 | // first frame index. See X86FrameLowering.cpp - usesTheStack. | 
| Hans Wennborg | 5000ce8 | 2015-12-04 23:00:33 +0000 | [diff] [blame] | 4799 | if (FromEFLAGS) { | 
|  | 4800 | BuildMI(MBB, MI, DL, get(PushF)); | 
|  | 4801 | BuildMI(MBB, MI, DL, get(Pop), DestReg); | 
|  | 4802 | } | 
|  | 4803 | if (ToEFLAGS) { | 
|  | 4804 | BuildMI(MBB, MI, DL, get(Push)) | 
|  | 4805 | .addReg(SrcReg, getKillRegState(KillSrc)); | 
|  | 4806 | BuildMI(MBB, MI, DL, get(PopF)); | 
|  | 4807 | } | 
|  | 4808 | return; | 
|  | 4809 | } | 
|  | 4810 |  | 
| JF Bastien | fa9746d | 2015-08-10 20:59:36 +0000 | [diff] [blame] | 4811 | // The flags need to be saved, but saving EFLAGS with PUSHF/POPF is | 
|  | 4812 | // inefficient. Instead: | 
|  | 4813 | //   - Save the overflow flag OF into AL using SETO, and restore it using a | 
|  | 4814 | //     signed 8-bit addition of AL and INT8_MAX. | 
|  | 4815 | //   - Save/restore the bottom 8 EFLAGS bits (CF, PF, AF, ZF, SF) to/from AH | 
|  | 4816 | //     using LAHF/SAHF. | 
|  | 4817 | //   - When RAX/EAX is live and isn't the destination register, make sure it | 
|  | 4818 | //     isn't clobbered by PUSH/POP'ing it before and after saving/restoring | 
|  | 4819 | //     the flags. | 
|  | 4820 | // This approach is ~2.25x faster than using PUSHF/POPF. | 
|  | 4821 | // | 
|  | 4822 | // This is still somewhat inefficient because we don't know which flags are | 
|  | 4823 | // actually live inside EFLAGS. Were we able to do a single SETcc instead of | 
|  | 4824 | // SETO+LAHF / ADDB+SAHF the code could be 1.02x faster. | 
|  | 4825 | // | 
|  | 4826 | // PUSHF/POPF is also potentially incorrect because it affects other flags | 
|  | 4827 | // such as TF/IF/DF, which LLVM doesn't model. | 
|  | 4828 | // | 
|  | 4829 | // Notice that we have to adjust the stack if we don't want to clobber the | 
| David Majnemer | ca1c9f0 | 2016-01-04 04:49:41 +0000 | [diff] [blame] | 4830 | // first frame index. | 
|  | 4831 | // See X86ISelLowering.cpp - X86::hasCopyImplyingStackAdjustment. | 
| JF Bastien | fa9746d | 2015-08-10 20:59:36 +0000 | [diff] [blame] | 4832 |  | 
| Quentin Colombet | 220f7da | 2016-05-10 20:49:46 +0000 | [diff] [blame] | 4833 | const TargetRegisterInfo *TRI = &getRegisterInfo(); | 
| Quentin Colombet | 2b3a4e7 | 2016-04-26 23:14:32 +0000 | [diff] [blame] | 4834 | MachineBasicBlock::LivenessQueryResult LQR = | 
| Quentin Colombet | 220f7da | 2016-05-10 20:49:46 +0000 | [diff] [blame] | 4835 | MBB.computeRegisterLiveness(TRI, AX, MI); | 
| Quentin Colombet | 2b3a4e7 | 2016-04-26 23:14:32 +0000 | [diff] [blame] | 4836 | // We do not want to save and restore AX if we do not have to. | 
|  | 4837 | // Moreover, if we do so whereas AX is dead, we would need to set | 
|  | 4838 | // an undef flag on the use of AX, otherwise the verifier will | 
|  | 4839 | // complain that we read an undef value. | 
|  | 4840 | // We do not want to change the behavior of the machine verifier | 
|  | 4841 | // as this is usually wrong to read an undef value. | 
|  | 4842 | if (MachineBasicBlock::LQR_Unknown == LQR) { | 
| Quentin Colombet | 220f7da | 2016-05-10 20:49:46 +0000 | [diff] [blame] | 4843 | LivePhysRegs LPR(TRI); | 
| Matthias Braun | d1aabb2 | 2016-05-03 00:24:32 +0000 | [diff] [blame] | 4844 | LPR.addLiveOuts(MBB); | 
| Quentin Colombet | 2b3a4e7 | 2016-04-26 23:14:32 +0000 | [diff] [blame] | 4845 | MachineBasicBlock::iterator I = MBB.end(); | 
|  | 4846 | while (I != MI) { | 
|  | 4847 | --I; | 
|  | 4848 | LPR.stepBackward(*I); | 
|  | 4849 | } | 
| Quentin Colombet | 220f7da | 2016-05-10 20:49:46 +0000 | [diff] [blame] | 4850 | // AX contains the top most register in the aliasing hierarchy. | 
|  | 4851 | // It may not be live, but one of its aliases may be. | 
|  | 4852 | for (MCRegAliasIterator AI(AX, TRI, true); | 
|  | 4853 | AI.isValid() && LQR != MachineBasicBlock::LQR_Live; ++AI) | 
|  | 4854 | LQR = LPR.contains(*AI) ? MachineBasicBlock::LQR_Live | 
|  | 4855 | : MachineBasicBlock::LQR_Dead; | 
| Matthias Braun | 60d69e2 | 2015-12-11 19:42:09 +0000 | [diff] [blame] | 4856 | } | 
| Quentin Colombet | 2b3a4e7 | 2016-04-26 23:14:32 +0000 | [diff] [blame] | 4857 | bool AXDead = (Reg == AX) || (MachineBasicBlock::LQR_Dead == LQR); | 
|  | 4858 | if (!AXDead) | 
|  | 4859 | BuildMI(MBB, MI, DL, get(Push)).addReg(AX, getKillRegState(true)); | 
| JF Bastien | fa9746d | 2015-08-10 20:59:36 +0000 | [diff] [blame] | 4860 | if (FromEFLAGS) { | 
|  | 4861 | BuildMI(MBB, MI, DL, get(X86::SETOr), X86::AL); | 
|  | 4862 | BuildMI(MBB, MI, DL, get(X86::LAHF)); | 
|  | 4863 | BuildMI(MBB, MI, DL, get(Mov), Reg).addReg(AX); | 
| Craig Topper | bab0c76 | 2012-08-21 08:29:51 +0000 | [diff] [blame] | 4864 | } | 
| JF Bastien | fa9746d | 2015-08-10 20:59:36 +0000 | [diff] [blame] | 4865 | if (ToEFLAGS) { | 
|  | 4866 | BuildMI(MBB, MI, DL, get(Mov), AX).addReg(Reg, getKillRegState(KillSrc)); | 
|  | 4867 | BuildMI(MBB, MI, DL, get(X86::ADD8ri), X86::AL) | 
|  | 4868 | .addReg(X86::AL) | 
|  | 4869 | .addImm(INT8_MAX); | 
|  | 4870 | BuildMI(MBB, MI, DL, get(X86::SAHF)); | 
| Jakob Stoklund Olesen | 930f808 | 2010-07-08 19:46:25 +0000 | [diff] [blame] | 4871 | } | 
| JF Bastien | fa9746d | 2015-08-10 20:59:36 +0000 | [diff] [blame] | 4872 | if (!AXDead) | 
|  | 4873 | BuildMI(MBB, MI, DL, get(Pop), AX); | 
|  | 4874 | return; | 
| Jakob Stoklund Olesen | 930f808 | 2010-07-08 19:46:25 +0000 | [diff] [blame] | 4875 | } | 
|  | 4876 |  | 
|  | 4877 | DEBUG(dbgs() << "Cannot copy " << RI.getName(SrcReg) | 
|  | 4878 | << " to " << RI.getName(DestReg) << '\n'); | 
|  | 4879 | llvm_unreachable("Cannot emit physreg copy instruction"); | 
|  | 4880 | } | 
|  | 4881 |  | 
| Rafael Espindola | e302f83 | 2010-06-12 20:13:29 +0000 | [diff] [blame] | 4882 | static unsigned getLoadStoreRegOpcode(unsigned Reg, | 
|  | 4883 | const TargetRegisterClass *RC, | 
|  | 4884 | bool isStackAligned, | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 4885 | const X86Subtarget &STI, | 
| Rafael Espindola | e302f83 | 2010-06-12 20:13:29 +0000 | [diff] [blame] | 4886 | bool load) { | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 4887 | bool HasAVX = STI.hasAVX(); | 
| Craig Topper | eb1cc98 | 2016-07-31 20:19:55 +0000 | [diff] [blame] | 4888 | bool HasAVX512 = STI.hasAVX512(); | 
| Craig Topper | 7afdc0f | 2016-07-31 20:20:05 +0000 | [diff] [blame] | 4889 | bool HasVLX = STI.hasVLX(); | 
| Craig Topper | eb1cc98 | 2016-07-31 20:19:55 +0000 | [diff] [blame] | 4890 |  | 
| Jakob Stoklund Olesen | 56ce3a0 | 2011-06-01 15:32:10 +0000 | [diff] [blame] | 4891 | switch (RC->getSize()) { | 
| Rafael Espindola | 6635f98 | 2010-07-12 03:43:04 +0000 | [diff] [blame] | 4892 | default: | 
| Jakob Stoklund Olesen | 56ce3a0 | 2011-06-01 15:32:10 +0000 | [diff] [blame] | 4893 | llvm_unreachable("Unknown spill size"); | 
|  | 4894 | case 1: | 
|  | 4895 | assert(X86::GR8RegClass.hasSubClassEq(RC) && "Unknown 1-byte regclass"); | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 4896 | if (STI.is64Bit()) | 
| Jakob Stoklund Olesen | 56ce3a0 | 2011-06-01 15:32:10 +0000 | [diff] [blame] | 4897 | // Copying to or from a physical H register on x86-64 requires a NOREX | 
|  | 4898 | // move.  Otherwise use a normal move. | 
|  | 4899 | if (isHReg(Reg) || X86::GR8_ABCD_HRegClass.hasSubClassEq(RC)) | 
|  | 4900 | return load ? X86::MOV8rm_NOREX : X86::MOV8mr_NOREX; | 
|  | 4901 | return load ? X86::MOV8rm : X86::MOV8mr; | 
|  | 4902 | case 2: | 
| Craig Topper | da50eec | 2016-08-01 04:29:11 +0000 | [diff] [blame] | 4903 | if (X86::VK16RegClass.hasSubClassEq(RC)) | 
|  | 4904 | return load ? X86::KMOVWkm : X86::KMOVWmk; | 
| Jakob Stoklund Olesen | 56ce3a0 | 2011-06-01 15:32:10 +0000 | [diff] [blame] | 4905 | assert(X86::GR16RegClass.hasSubClassEq(RC) && "Unknown 2-byte regclass"); | 
|  | 4906 | return load ? X86::MOV16rm : X86::MOV16mr; | 
|  | 4907 | case 4: | 
|  | 4908 | if (X86::GR32RegClass.hasSubClassEq(RC)) | 
|  | 4909 | return load ? X86::MOV32rm : X86::MOV32mr; | 
| Craig Topper | eb1cc98 | 2016-07-31 20:19:55 +0000 | [diff] [blame] | 4910 | if (X86::FR32XRegClass.hasSubClassEq(RC)) | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 4911 | return load ? | 
| Craig Topper | eb1cc98 | 2016-07-31 20:19:55 +0000 | [diff] [blame] | 4912 | (HasAVX512 ? X86::VMOVSSZrm : HasAVX ? X86::VMOVSSrm : X86::MOVSSrm) : | 
|  | 4913 | (HasAVX512 ? X86::VMOVSSZmr : HasAVX ? X86::VMOVSSmr : X86::MOVSSmr); | 
| Jakob Stoklund Olesen | 56ce3a0 | 2011-06-01 15:32:10 +0000 | [diff] [blame] | 4914 | if (X86::RFP32RegClass.hasSubClassEq(RC)) | 
|  | 4915 | return load ? X86::LD_Fp32m : X86::ST_Fp32m; | 
| Craig Topper | da50eec | 2016-08-01 04:29:11 +0000 | [diff] [blame] | 4916 | if (X86::VK32RegClass.hasSubClassEq(RC)) | 
|  | 4917 | return load ? X86::KMOVDkm : X86::KMOVDmk; | 
| Jakob Stoklund Olesen | 56ce3a0 | 2011-06-01 15:32:10 +0000 | [diff] [blame] | 4918 | llvm_unreachable("Unknown 4-byte regclass"); | 
|  | 4919 | case 8: | 
|  | 4920 | if (X86::GR64RegClass.hasSubClassEq(RC)) | 
|  | 4921 | return load ? X86::MOV64rm : X86::MOV64mr; | 
| Craig Topper | eb1cc98 | 2016-07-31 20:19:55 +0000 | [diff] [blame] | 4922 | if (X86::FR64XRegClass.hasSubClassEq(RC)) | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 4923 | return load ? | 
| Craig Topper | eb1cc98 | 2016-07-31 20:19:55 +0000 | [diff] [blame] | 4924 | (HasAVX512 ? X86::VMOVSDZrm : HasAVX ? X86::VMOVSDrm : X86::MOVSDrm) : | 
|  | 4925 | (HasAVX512 ? X86::VMOVSDZmr : HasAVX ? X86::VMOVSDmr : X86::MOVSDmr); | 
| Jakob Stoklund Olesen | 56ce3a0 | 2011-06-01 15:32:10 +0000 | [diff] [blame] | 4926 | if (X86::VR64RegClass.hasSubClassEq(RC)) | 
|  | 4927 | return load ? X86::MMX_MOVQ64rm : X86::MMX_MOVQ64mr; | 
|  | 4928 | if (X86::RFP64RegClass.hasSubClassEq(RC)) | 
|  | 4929 | return load ? X86::LD_Fp64m : X86::ST_Fp64m; | 
| Craig Topper | da50eec | 2016-08-01 04:29:11 +0000 | [diff] [blame] | 4930 | if (X86::VK64RegClass.hasSubClassEq(RC)) | 
|  | 4931 | return load ? X86::KMOVQkm : X86::KMOVQmk; | 
| Jakob Stoklund Olesen | 56ce3a0 | 2011-06-01 15:32:10 +0000 | [diff] [blame] | 4932 | llvm_unreachable("Unknown 8-byte regclass"); | 
|  | 4933 | case 10: | 
|  | 4934 | assert(X86::RFP80RegClass.hasSubClassEq(RC) && "Unknown 10-byte regclass"); | 
| Rafael Espindola | e302f83 | 2010-06-12 20:13:29 +0000 | [diff] [blame] | 4935 | return load ? X86::LD_Fp80m : X86::ST_FpP80m; | 
| Bruno Cardoso Lopes | db520db | 2011-08-31 03:04:09 +0000 | [diff] [blame] | 4936 | case 16: { | 
| Craig Topper | 7afdc0f | 2016-07-31 20:20:05 +0000 | [diff] [blame] | 4937 | assert(X86::VR128XRegClass.hasSubClassEq(RC) && "Unknown 16-byte regclass"); | 
| Rafael Espindola | e302f83 | 2010-06-12 20:13:29 +0000 | [diff] [blame] | 4938 | // If stack is realigned we can use aligned stores. | 
|  | 4939 | if (isStackAligned) | 
| Craig Topper | 7afdc0f | 2016-07-31 20:20:05 +0000 | [diff] [blame] | 4940 | return load ? | 
|  | 4941 | (HasVLX ? X86::VMOVAPSZ128rm : HasAVX ? X86::VMOVAPSrm : X86::MOVAPSrm): | 
|  | 4942 | (HasVLX ? X86::VMOVAPSZ128mr : HasAVX ? X86::VMOVAPSmr : X86::MOVAPSmr); | 
| Rafael Espindola | e302f83 | 2010-06-12 20:13:29 +0000 | [diff] [blame] | 4943 | else | 
| Craig Topper | 7afdc0f | 2016-07-31 20:20:05 +0000 | [diff] [blame] | 4944 | return load ? | 
|  | 4945 | (HasVLX ? X86::VMOVUPSZ128rm : HasAVX ? X86::VMOVUPSrm : X86::MOVUPSrm): | 
|  | 4946 | (HasVLX ? X86::VMOVUPSZ128mr : HasAVX ? X86::VMOVUPSmr : X86::MOVUPSmr); | 
| Bruno Cardoso Lopes | db520db | 2011-08-31 03:04:09 +0000 | [diff] [blame] | 4947 | } | 
| Bruno Cardoso Lopes | 6778597 | 2011-07-14 18:50:58 +0000 | [diff] [blame] | 4948 | case 32: | 
| Craig Topper | 7afdc0f | 2016-07-31 20:20:05 +0000 | [diff] [blame] | 4949 | assert(X86::VR256XRegClass.hasSubClassEq(RC) && "Unknown 32-byte regclass"); | 
| Bruno Cardoso Lopes | 6778597 | 2011-07-14 18:50:58 +0000 | [diff] [blame] | 4950 | // If stack is realigned we can use aligned stores. | 
|  | 4951 | if (isStackAligned) | 
| Craig Topper | 7afdc0f | 2016-07-31 20:20:05 +0000 | [diff] [blame] | 4952 | return load ? | 
|  | 4953 | (HasVLX ? X86::VMOVAPSZ256rm : X86::VMOVAPSYrm) : | 
|  | 4954 | (HasVLX ? X86::VMOVAPSZ256mr : X86::VMOVAPSYmr); | 
| Bruno Cardoso Lopes | 6778597 | 2011-07-14 18:50:58 +0000 | [diff] [blame] | 4955 | else | 
| Craig Topper | 7afdc0f | 2016-07-31 20:20:05 +0000 | [diff] [blame] | 4956 | return load ? | 
|  | 4957 | (HasVLX ? X86::VMOVUPSZ256rm : X86::VMOVUPSYrm) : | 
|  | 4958 | (HasVLX ? X86::VMOVUPSZ256mr : X86::VMOVUPSYmr); | 
| Elena Demikhovsky | 3ce8dbb | 2013-08-18 13:08:57 +0000 | [diff] [blame] | 4959 | case 64: | 
|  | 4960 | assert(X86::VR512RegClass.hasSubClassEq(RC) && "Unknown 64-byte regclass"); | 
| Craig Topper | 338ec9a | 2016-07-31 20:19:53 +0000 | [diff] [blame] | 4961 | assert(STI.hasAVX512() && "Using 512-bit register requires AVX512"); | 
| Elena Demikhovsky | 3ce8dbb | 2013-08-18 13:08:57 +0000 | [diff] [blame] | 4962 | if (isStackAligned) | 
|  | 4963 | return load ? X86::VMOVAPSZrm : X86::VMOVAPSZmr; | 
|  | 4964 | else | 
|  | 4965 | return load ? X86::VMOVUPSZrm : X86::VMOVUPSZmr; | 
| Rafael Espindola | e302f83 | 2010-06-12 20:13:29 +0000 | [diff] [blame] | 4966 | } | 
|  | 4967 | } | 
|  | 4968 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 4969 | bool X86InstrInfo::getMemOpBaseRegImmOfs(MachineInstr &MemOp, unsigned &BaseReg, | 
| Chad Rosier | c27a18f | 2016-03-09 16:00:35 +0000 | [diff] [blame] | 4970 | int64_t &Offset, | 
| Sanjoy Das | b666ea3 | 2015-06-15 18:44:14 +0000 | [diff] [blame] | 4971 | const TargetRegisterInfo *TRI) const { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 4972 | const MCInstrDesc &Desc = MemOp.getDesc(); | 
| Craig Topper | 477649a | 2016-04-28 05:58:46 +0000 | [diff] [blame] | 4973 | int MemRefBegin = X86II::getMemoryOperandNo(Desc.TSFlags); | 
| Sanjoy Das | b666ea3 | 2015-06-15 18:44:14 +0000 | [diff] [blame] | 4974 | if (MemRefBegin < 0) | 
|  | 4975 | return false; | 
|  | 4976 |  | 
|  | 4977 | MemRefBegin += X86II::getOperandBias(Desc); | 
|  | 4978 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 4979 | MachineOperand &BaseMO = MemOp.getOperand(MemRefBegin + X86::AddrBaseReg); | 
| Sanjoy Das | 881de4d | 2016-02-02 02:32:43 +0000 | [diff] [blame] | 4980 | if (!BaseMO.isReg()) // Can be an MO_FrameIndex | 
|  | 4981 | return false; | 
|  | 4982 |  | 
|  | 4983 | BaseReg = BaseMO.getReg(); | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 4984 | if (MemOp.getOperand(MemRefBegin + X86::AddrScaleAmt).getImm() != 1) | 
| Sanjoy Das | b666ea3 | 2015-06-15 18:44:14 +0000 | [diff] [blame] | 4985 | return false; | 
|  | 4986 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 4987 | if (MemOp.getOperand(MemRefBegin + X86::AddrIndexReg).getReg() != | 
| Sanjoy Das | b666ea3 | 2015-06-15 18:44:14 +0000 | [diff] [blame] | 4988 | X86::NoRegister) | 
|  | 4989 | return false; | 
|  | 4990 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 4991 | const MachineOperand &DispMO = MemOp.getOperand(MemRefBegin + X86::AddrDisp); | 
| Sanjoy Das | b666ea3 | 2015-06-15 18:44:14 +0000 | [diff] [blame] | 4992 |  | 
|  | 4993 | // Displacement can be symbolic | 
|  | 4994 | if (!DispMO.isImm()) | 
|  | 4995 | return false; | 
|  | 4996 |  | 
|  | 4997 | Offset = DispMO.getImm(); | 
|  | 4998 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 4999 | return MemOp.getOperand(MemRefBegin + X86::AddrIndexReg).getReg() == | 
|  | 5000 | X86::NoRegister; | 
| Sanjoy Das | b666ea3 | 2015-06-15 18:44:14 +0000 | [diff] [blame] | 5001 | } | 
|  | 5002 |  | 
| Dan Gohman | 2986972 | 2009-04-27 16:41:36 +0000 | [diff] [blame] | 5003 | static unsigned getStoreRegOpcode(unsigned SrcReg, | 
|  | 5004 | const TargetRegisterClass *RC, | 
|  | 5005 | bool isStackAligned, | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 5006 | const X86Subtarget &STI) { | 
|  | 5007 | return getLoadStoreRegOpcode(SrcReg, RC, isStackAligned, STI, false); | 
| Rafael Espindola | e302f83 | 2010-06-12 20:13:29 +0000 | [diff] [blame] | 5008 | } | 
| Owen Anderson | eee1460 | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 5009 |  | 
| Rafael Espindola | e302f83 | 2010-06-12 20:13:29 +0000 | [diff] [blame] | 5010 |  | 
|  | 5011 | static unsigned getLoadRegOpcode(unsigned DestReg, | 
|  | 5012 | const TargetRegisterClass *RC, | 
|  | 5013 | bool isStackAligned, | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 5014 | const X86Subtarget &STI) { | 
|  | 5015 | return getLoadStoreRegOpcode(DestReg, RC, isStackAligned, STI, true); | 
| Owen Anderson | eee1460 | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 5016 | } | 
|  | 5017 |  | 
|  | 5018 | void X86InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, | 
|  | 5019 | MachineBasicBlock::iterator MI, | 
|  | 5020 | unsigned SrcReg, bool isKill, int FrameIdx, | 
| Evan Cheng | efb126a | 2010-05-06 19:06:44 +0000 | [diff] [blame] | 5021 | const TargetRegisterClass *RC, | 
|  | 5022 | const TargetRegisterInfo *TRI) const { | 
| Anton Korobeynikov | b7a4992 | 2008-07-19 06:30:51 +0000 | [diff] [blame] | 5023 | const MachineFunction &MF = *MBB.getParent(); | 
| Matthias Braun | 941a705 | 2016-07-28 18:40:00 +0000 | [diff] [blame] | 5024 | assert(MF.getFrameInfo().getObjectSize(FrameIdx) >= RC->getSize() && | 
| Jakob Stoklund Olesen | c3c05ed | 2010-07-27 04:16:58 +0000 | [diff] [blame] | 5025 | "Stack slot too small for store"); | 
| Elena Demikhovsky | 3ce8dbb | 2013-08-18 13:08:57 +0000 | [diff] [blame] | 5026 | unsigned Alignment = std::max<uint32_t>(RC->getSize(), 16); | 
| Eric Christopher | 05b8197 | 2015-02-02 17:38:43 +0000 | [diff] [blame] | 5027 | bool isAligned = | 
|  | 5028 | (Subtarget.getFrameLowering()->getStackAlignment() >= Alignment) || | 
|  | 5029 | RI.canRealignStack(MF); | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 5030 | unsigned Opc = getStoreRegOpcode(SrcReg, RC, isAligned, Subtarget); | 
| Dale Johannesen | e5a4134 | 2010-01-26 00:03:12 +0000 | [diff] [blame] | 5031 | DebugLoc DL = MBB.findDebugLoc(MI); | 
| Bill Wendling | 27b508d | 2009-02-11 21:51:19 +0000 | [diff] [blame] | 5032 | addFrameReference(BuildMI(MBB, MI, DL, get(Opc)), FrameIdx) | 
| Bill Wendling | f7b83c7 | 2009-05-13 21:33:08 +0000 | [diff] [blame] | 5033 | .addReg(SrcReg, getKillRegState(isKill)); | 
| Owen Anderson | eee1460 | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 5034 | } | 
|  | 5035 |  | 
|  | 5036 | void X86InstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, | 
|  | 5037 | bool isKill, | 
|  | 5038 | SmallVectorImpl<MachineOperand> &Addr, | 
|  | 5039 | const TargetRegisterClass *RC, | 
| Dan Gohman | dd76bb2 | 2009-10-09 18:10:05 +0000 | [diff] [blame] | 5040 | MachineInstr::mmo_iterator MMOBegin, | 
|  | 5041 | MachineInstr::mmo_iterator MMOEnd, | 
| Owen Anderson | eee1460 | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 5042 | SmallVectorImpl<MachineInstr*> &NewMIs) const { | 
| Elena Demikhovsky | 3ce8dbb | 2013-08-18 13:08:57 +0000 | [diff] [blame] | 5043 | unsigned Alignment = std::max<uint32_t>(RC->getSize(), 16); | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 5044 | bool isAligned = MMOBegin != MMOEnd && | 
|  | 5045 | (*MMOBegin)->getAlignment() >= Alignment; | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 5046 | unsigned Opc = getStoreRegOpcode(SrcReg, RC, isAligned, Subtarget); | 
| Chris Lattner | 6f306d7 | 2010-04-02 20:16:16 +0000 | [diff] [blame] | 5047 | DebugLoc DL; | 
| Dale Johannesen | 6b8c76a | 2009-02-12 23:08:38 +0000 | [diff] [blame] | 5048 | MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc)); | 
| Owen Anderson | eee1460 | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 5049 | for (unsigned i = 0, e = Addr.size(); i != e; ++i) | 
| Dan Gohman | 2af1f85 | 2009-02-18 05:45:50 +0000 | [diff] [blame] | 5050 | MIB.addOperand(Addr[i]); | 
| Bill Wendling | f7b83c7 | 2009-05-13 21:33:08 +0000 | [diff] [blame] | 5051 | MIB.addReg(SrcReg, getKillRegState(isKill)); | 
| Dan Gohman | dd76bb2 | 2009-10-09 18:10:05 +0000 | [diff] [blame] | 5052 | (*MIB).setMemRefs(MMOBegin, MMOEnd); | 
| Owen Anderson | eee1460 | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 5053 | NewMIs.push_back(MIB); | 
|  | 5054 | } | 
|  | 5055 |  | 
| Owen Anderson | eee1460 | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 5056 |  | 
|  | 5057 | void X86InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, | 
| Anton Korobeynikov | b7a4992 | 2008-07-19 06:30:51 +0000 | [diff] [blame] | 5058 | MachineBasicBlock::iterator MI, | 
|  | 5059 | unsigned DestReg, int FrameIdx, | 
| Evan Cheng | efb126a | 2010-05-06 19:06:44 +0000 | [diff] [blame] | 5060 | const TargetRegisterClass *RC, | 
|  | 5061 | const TargetRegisterInfo *TRI) const { | 
| Anton Korobeynikov | b7a4992 | 2008-07-19 06:30:51 +0000 | [diff] [blame] | 5062 | const MachineFunction &MF = *MBB.getParent(); | 
| Elena Demikhovsky | 3ce8dbb | 2013-08-18 13:08:57 +0000 | [diff] [blame] | 5063 | unsigned Alignment = std::max<uint32_t>(RC->getSize(), 16); | 
| Eric Christopher | 05b8197 | 2015-02-02 17:38:43 +0000 | [diff] [blame] | 5064 | bool isAligned = | 
|  | 5065 | (Subtarget.getFrameLowering()->getStackAlignment() >= Alignment) || | 
|  | 5066 | RI.canRealignStack(MF); | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 5067 | unsigned Opc = getLoadRegOpcode(DestReg, RC, isAligned, Subtarget); | 
| Dale Johannesen | e5a4134 | 2010-01-26 00:03:12 +0000 | [diff] [blame] | 5068 | DebugLoc DL = MBB.findDebugLoc(MI); | 
| Bill Wendling | 27b508d | 2009-02-11 21:51:19 +0000 | [diff] [blame] | 5069 | addFrameReference(BuildMI(MBB, MI, DL, get(Opc), DestReg), FrameIdx); | 
| Owen Anderson | eee1460 | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 5070 | } | 
|  | 5071 |  | 
|  | 5072 | void X86InstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, | 
| Evan Cheng | 7d98a48 | 2008-07-03 09:09:37 +0000 | [diff] [blame] | 5073 | SmallVectorImpl<MachineOperand> &Addr, | 
|  | 5074 | const TargetRegisterClass *RC, | 
| Dan Gohman | dd76bb2 | 2009-10-09 18:10:05 +0000 | [diff] [blame] | 5075 | MachineInstr::mmo_iterator MMOBegin, | 
|  | 5076 | MachineInstr::mmo_iterator MMOEnd, | 
| Owen Anderson | eee1460 | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 5077 | SmallVectorImpl<MachineInstr*> &NewMIs) const { | 
| Elena Demikhovsky | 3ce8dbb | 2013-08-18 13:08:57 +0000 | [diff] [blame] | 5078 | unsigned Alignment = std::max<uint32_t>(RC->getSize(), 16); | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 5079 | bool isAligned = MMOBegin != MMOEnd && | 
|  | 5080 | (*MMOBegin)->getAlignment() >= Alignment; | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 5081 | unsigned Opc = getLoadRegOpcode(DestReg, RC, isAligned, Subtarget); | 
| Chris Lattner | 6f306d7 | 2010-04-02 20:16:16 +0000 | [diff] [blame] | 5082 | DebugLoc DL; | 
| Dale Johannesen | 6b8c76a | 2009-02-12 23:08:38 +0000 | [diff] [blame] | 5083 | MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg); | 
| Owen Anderson | eee1460 | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 5084 | for (unsigned i = 0, e = Addr.size(); i != e; ++i) | 
| Dan Gohman | 2af1f85 | 2009-02-18 05:45:50 +0000 | [diff] [blame] | 5085 | MIB.addOperand(Addr[i]); | 
| Dan Gohman | dd76bb2 | 2009-10-09 18:10:05 +0000 | [diff] [blame] | 5086 | (*MIB).setMemRefs(MMOBegin, MMOEnd); | 
| Owen Anderson | eee1460 | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 5087 | NewMIs.push_back(MIB); | 
|  | 5088 | } | 
|  | 5089 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5090 | bool X86InstrInfo::analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, | 
|  | 5091 | unsigned &SrcReg2, int &CmpMask, | 
|  | 5092 | int &CmpValue) const { | 
|  | 5093 | switch (MI.getOpcode()) { | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5094 | default: break; | 
|  | 5095 | case X86::CMP64ri32: | 
|  | 5096 | case X86::CMP64ri8: | 
|  | 5097 | case X86::CMP32ri: | 
|  | 5098 | case X86::CMP32ri8: | 
|  | 5099 | case X86::CMP16ri: | 
|  | 5100 | case X86::CMP16ri8: | 
|  | 5101 | case X86::CMP8ri: | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5102 | SrcReg = MI.getOperand(0).getReg(); | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5103 | SrcReg2 = 0; | 
|  | 5104 | CmpMask = ~0; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5105 | CmpValue = MI.getOperand(1).getImm(); | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5106 | return true; | 
| Manman Ren | 1be131b | 2012-08-08 00:51:41 +0000 | [diff] [blame] | 5107 | // A SUB can be used to perform comparison. | 
|  | 5108 | case X86::SUB64rm: | 
|  | 5109 | case X86::SUB32rm: | 
|  | 5110 | case X86::SUB16rm: | 
|  | 5111 | case X86::SUB8rm: | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5112 | SrcReg = MI.getOperand(1).getReg(); | 
| Manman Ren | 1be131b | 2012-08-08 00:51:41 +0000 | [diff] [blame] | 5113 | SrcReg2 = 0; | 
|  | 5114 | CmpMask = ~0; | 
|  | 5115 | CmpValue = 0; | 
|  | 5116 | return true; | 
|  | 5117 | case X86::SUB64rr: | 
|  | 5118 | case X86::SUB32rr: | 
|  | 5119 | case X86::SUB16rr: | 
|  | 5120 | case X86::SUB8rr: | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5121 | SrcReg = MI.getOperand(1).getReg(); | 
|  | 5122 | SrcReg2 = MI.getOperand(2).getReg(); | 
| Manman Ren | 1be131b | 2012-08-08 00:51:41 +0000 | [diff] [blame] | 5123 | CmpMask = ~0; | 
|  | 5124 | CmpValue = 0; | 
|  | 5125 | return true; | 
|  | 5126 | case X86::SUB64ri32: | 
|  | 5127 | case X86::SUB64ri8: | 
|  | 5128 | case X86::SUB32ri: | 
|  | 5129 | case X86::SUB32ri8: | 
|  | 5130 | case X86::SUB16ri: | 
|  | 5131 | case X86::SUB16ri8: | 
|  | 5132 | case X86::SUB8ri: | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5133 | SrcReg = MI.getOperand(1).getReg(); | 
| Manman Ren | 1be131b | 2012-08-08 00:51:41 +0000 | [diff] [blame] | 5134 | SrcReg2 = 0; | 
|  | 5135 | CmpMask = ~0; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5136 | CmpValue = MI.getOperand(2).getImm(); | 
| Manman Ren | 1be131b | 2012-08-08 00:51:41 +0000 | [diff] [blame] | 5137 | return true; | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5138 | case X86::CMP64rr: | 
|  | 5139 | case X86::CMP32rr: | 
|  | 5140 | case X86::CMP16rr: | 
|  | 5141 | case X86::CMP8rr: | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5142 | SrcReg = MI.getOperand(0).getReg(); | 
|  | 5143 | SrcReg2 = MI.getOperand(1).getReg(); | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5144 | CmpMask = ~0; | 
|  | 5145 | CmpValue = 0; | 
|  | 5146 | return true; | 
| Manman Ren | d0a4ee8 | 2012-07-18 21:40:01 +0000 | [diff] [blame] | 5147 | case X86::TEST8rr: | 
|  | 5148 | case X86::TEST16rr: | 
|  | 5149 | case X86::TEST32rr: | 
|  | 5150 | case X86::TEST64rr: | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5151 | SrcReg = MI.getOperand(0).getReg(); | 
|  | 5152 | if (MI.getOperand(1).getReg() != SrcReg) | 
|  | 5153 | return false; | 
| Manman Ren | d0a4ee8 | 2012-07-18 21:40:01 +0000 | [diff] [blame] | 5154 | // Compare against zero. | 
|  | 5155 | SrcReg2 = 0; | 
|  | 5156 | CmpMask = ~0; | 
|  | 5157 | CmpValue = 0; | 
|  | 5158 | return true; | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5159 | } | 
|  | 5160 | return false; | 
|  | 5161 | } | 
|  | 5162 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 5163 | /// Check whether the first instruction, whose only | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5164 | /// purpose is to update flags, can be made redundant. | 
|  | 5165 | /// CMPrr can be made redundant by SUBrr if the operands are the same. | 
|  | 5166 | /// This function can be extended later on. | 
|  | 5167 | /// SrcReg, SrcRegs: register operands for FlagI. | 
|  | 5168 | /// ImmValue: immediate for FlagI if it takes an immediate. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5169 | inline static bool isRedundantFlagInstr(MachineInstr &FlagI, unsigned SrcReg, | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5170 | unsigned SrcReg2, int ImmValue, | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5171 | MachineInstr &OI) { | 
|  | 5172 | if (((FlagI.getOpcode() == X86::CMP64rr && OI.getOpcode() == X86::SUB64rr) || | 
|  | 5173 | (FlagI.getOpcode() == X86::CMP32rr && OI.getOpcode() == X86::SUB32rr) || | 
|  | 5174 | (FlagI.getOpcode() == X86::CMP16rr && OI.getOpcode() == X86::SUB16rr) || | 
|  | 5175 | (FlagI.getOpcode() == X86::CMP8rr && OI.getOpcode() == X86::SUB8rr)) && | 
|  | 5176 | ((OI.getOperand(1).getReg() == SrcReg && | 
|  | 5177 | OI.getOperand(2).getReg() == SrcReg2) || | 
|  | 5178 | (OI.getOperand(1).getReg() == SrcReg2 && | 
|  | 5179 | OI.getOperand(2).getReg() == SrcReg))) | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5180 | return true; | 
|  | 5181 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5182 | if (((FlagI.getOpcode() == X86::CMP64ri32 && | 
|  | 5183 | OI.getOpcode() == X86::SUB64ri32) || | 
|  | 5184 | (FlagI.getOpcode() == X86::CMP64ri8 && | 
|  | 5185 | OI.getOpcode() == X86::SUB64ri8) || | 
|  | 5186 | (FlagI.getOpcode() == X86::CMP32ri && OI.getOpcode() == X86::SUB32ri) || | 
|  | 5187 | (FlagI.getOpcode() == X86::CMP32ri8 && | 
|  | 5188 | OI.getOpcode() == X86::SUB32ri8) || | 
|  | 5189 | (FlagI.getOpcode() == X86::CMP16ri && OI.getOpcode() == X86::SUB16ri) || | 
|  | 5190 | (FlagI.getOpcode() == X86::CMP16ri8 && | 
|  | 5191 | OI.getOpcode() == X86::SUB16ri8) || | 
|  | 5192 | (FlagI.getOpcode() == X86::CMP8ri && OI.getOpcode() == X86::SUB8ri)) && | 
|  | 5193 | OI.getOperand(1).getReg() == SrcReg && | 
|  | 5194 | OI.getOperand(2).getImm() == ImmValue) | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5195 | return true; | 
|  | 5196 | return false; | 
|  | 5197 | } | 
|  | 5198 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 5199 | /// Check whether the definition can be converted | 
| Manman Ren | d0a4ee8 | 2012-07-18 21:40:01 +0000 | [diff] [blame] | 5200 | /// to remove a comparison against zero. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5201 | inline static bool isDefConvertible(MachineInstr &MI) { | 
|  | 5202 | switch (MI.getOpcode()) { | 
| Manman Ren | d0a4ee8 | 2012-07-18 21:40:01 +0000 | [diff] [blame] | 5203 | default: return false; | 
| David Majnemer | 7ea2a52 | 2013-05-22 08:13:02 +0000 | [diff] [blame] | 5204 |  | 
|  | 5205 | // The shift instructions only modify ZF if their shift count is non-zero. | 
|  | 5206 | // N.B.: The processor truncates the shift count depending on the encoding. | 
|  | 5207 | case X86::SAR8ri:    case X86::SAR16ri:  case X86::SAR32ri:case X86::SAR64ri: | 
|  | 5208 | case X86::SHR8ri:    case X86::SHR16ri:  case X86::SHR32ri:case X86::SHR64ri: | 
|  | 5209 | return getTruncatedShiftCount(MI, 2) != 0; | 
|  | 5210 |  | 
|  | 5211 | // Some left shift instructions can be turned into LEA instructions but only | 
|  | 5212 | // if their flags aren't used. Avoid transforming such instructions. | 
|  | 5213 | case X86::SHL8ri:    case X86::SHL16ri:  case X86::SHL32ri:case X86::SHL64ri:{ | 
|  | 5214 | unsigned ShAmt = getTruncatedShiftCount(MI, 2); | 
|  | 5215 | if (isTruncatedShiftCountForLEA(ShAmt)) return false; | 
|  | 5216 | return ShAmt != 0; | 
|  | 5217 | } | 
|  | 5218 |  | 
|  | 5219 | case X86::SHRD16rri8:case X86::SHRD32rri8:case X86::SHRD64rri8: | 
|  | 5220 | case X86::SHLD16rri8:case X86::SHLD32rri8:case X86::SHLD64rri8: | 
|  | 5221 | return getTruncatedShiftCount(MI, 3) != 0; | 
|  | 5222 |  | 
| Manman Ren | d0a4ee8 | 2012-07-18 21:40:01 +0000 | [diff] [blame] | 5223 | case X86::SUB64ri32: case X86::SUB64ri8: case X86::SUB32ri: | 
|  | 5224 | case X86::SUB32ri8:  case X86::SUB16ri:  case X86::SUB16ri8: | 
|  | 5225 | case X86::SUB8ri:    case X86::SUB64rr:  case X86::SUB32rr: | 
|  | 5226 | case X86::SUB16rr:   case X86::SUB8rr:   case X86::SUB64rm: | 
|  | 5227 | case X86::SUB32rm:   case X86::SUB16rm:  case X86::SUB8rm: | 
| Craig Topper | 5b08cf7 | 2012-12-17 04:55:07 +0000 | [diff] [blame] | 5228 | case X86::DEC64r:    case X86::DEC32r:   case X86::DEC16r: case X86::DEC8r: | 
| Manman Ren | d0a4ee8 | 2012-07-18 21:40:01 +0000 | [diff] [blame] | 5229 | case X86::ADD64ri32: case X86::ADD64ri8: case X86::ADD32ri: | 
|  | 5230 | case X86::ADD32ri8:  case X86::ADD16ri:  case X86::ADD16ri8: | 
|  | 5231 | case X86::ADD8ri:    case X86::ADD64rr:  case X86::ADD32rr: | 
|  | 5232 | case X86::ADD16rr:   case X86::ADD8rr:   case X86::ADD64rm: | 
|  | 5233 | case X86::ADD32rm:   case X86::ADD16rm:  case X86::ADD8rm: | 
| Craig Topper | 5b08cf7 | 2012-12-17 04:55:07 +0000 | [diff] [blame] | 5234 | case X86::INC64r:    case X86::INC32r:   case X86::INC16r: case X86::INC8r: | 
| Manman Ren | d0a4ee8 | 2012-07-18 21:40:01 +0000 | [diff] [blame] | 5235 | case X86::AND64ri32: case X86::AND64ri8: case X86::AND32ri: | 
|  | 5236 | case X86::AND32ri8:  case X86::AND16ri:  case X86::AND16ri8: | 
|  | 5237 | case X86::AND8ri:    case X86::AND64rr:  case X86::AND32rr: | 
|  | 5238 | case X86::AND16rr:   case X86::AND8rr:   case X86::AND64rm: | 
|  | 5239 | case X86::AND32rm:   case X86::AND16rm:  case X86::AND8rm: | 
|  | 5240 | case X86::XOR64ri32: case X86::XOR64ri8: case X86::XOR32ri: | 
|  | 5241 | case X86::XOR32ri8:  case X86::XOR16ri:  case X86::XOR16ri8: | 
|  | 5242 | case X86::XOR8ri:    case X86::XOR64rr:  case X86::XOR32rr: | 
|  | 5243 | case X86::XOR16rr:   case X86::XOR8rr:   case X86::XOR64rm: | 
|  | 5244 | case X86::XOR32rm:   case X86::XOR16rm:  case X86::XOR8rm: | 
|  | 5245 | case X86::OR64ri32:  case X86::OR64ri8:  case X86::OR32ri: | 
|  | 5246 | case X86::OR32ri8:   case X86::OR16ri:   case X86::OR16ri8: | 
|  | 5247 | case X86::OR8ri:     case X86::OR64rr:   case X86::OR32rr: | 
|  | 5248 | case X86::OR16rr:    case X86::OR8rr:    case X86::OR64rm: | 
|  | 5249 | case X86::OR32rm:    case X86::OR16rm:   case X86::OR8rm: | 
| David Majnemer | 8f16974 | 2013-05-15 22:03:08 +0000 | [diff] [blame] | 5250 | case X86::NEG8r:     case X86::NEG16r:   case X86::NEG32r: case X86::NEG64r: | 
|  | 5251 | case X86::SAR8r1:    case X86::SAR16r1:  case X86::SAR32r1:case X86::SAR64r1: | 
|  | 5252 | case X86::SHR8r1:    case X86::SHR16r1:  case X86::SHR32r1:case X86::SHR64r1: | 
|  | 5253 | case X86::SHL8r1:    case X86::SHL16r1:  case X86::SHL32r1:case X86::SHL64r1: | 
|  | 5254 | case X86::ADC32ri:   case X86::ADC32ri8: | 
|  | 5255 | case X86::ADC32rr:   case X86::ADC64ri32: | 
|  | 5256 | case X86::ADC64ri8:  case X86::ADC64rr: | 
|  | 5257 | case X86::SBB32ri:   case X86::SBB32ri8: | 
|  | 5258 | case X86::SBB32rr:   case X86::SBB64ri32: | 
|  | 5259 | case X86::SBB64ri8:  case X86::SBB64rr: | 
| Craig Topper | f3ff6ae | 2012-12-17 05:12:30 +0000 | [diff] [blame] | 5260 | case X86::ANDN32rr:  case X86::ANDN32rm: | 
|  | 5261 | case X86::ANDN64rr:  case X86::ANDN64rm: | 
| David Majnemer | 8f16974 | 2013-05-15 22:03:08 +0000 | [diff] [blame] | 5262 | case X86::BEXTR32rr: case X86::BEXTR64rr: | 
|  | 5263 | case X86::BEXTR32rm: case X86::BEXTR64rm: | 
|  | 5264 | case X86::BLSI32rr:  case X86::BLSI32rm: | 
|  | 5265 | case X86::BLSI64rr:  case X86::BLSI64rm: | 
|  | 5266 | case X86::BLSMSK32rr:case X86::BLSMSK32rm: | 
|  | 5267 | case X86::BLSMSK64rr:case X86::BLSMSK64rm: | 
|  | 5268 | case X86::BLSR32rr:  case X86::BLSR32rm: | 
|  | 5269 | case X86::BLSR64rr:  case X86::BLSR64rm: | 
|  | 5270 | case X86::BZHI32rr:  case X86::BZHI32rm: | 
|  | 5271 | case X86::BZHI64rr:  case X86::BZHI64rm: | 
|  | 5272 | case X86::LZCNT16rr: case X86::LZCNT16rm: | 
|  | 5273 | case X86::LZCNT32rr: case X86::LZCNT32rm: | 
|  | 5274 | case X86::LZCNT64rr: case X86::LZCNT64rm: | 
|  | 5275 | case X86::POPCNT16rr:case X86::POPCNT16rm: | 
|  | 5276 | case X86::POPCNT32rr:case X86::POPCNT32rm: | 
|  | 5277 | case X86::POPCNT64rr:case X86::POPCNT64rm: | 
|  | 5278 | case X86::TZCNT16rr: case X86::TZCNT16rm: | 
|  | 5279 | case X86::TZCNT32rr: case X86::TZCNT32rm: | 
|  | 5280 | case X86::TZCNT64rr: case X86::TZCNT64rm: | 
| Manman Ren | d0a4ee8 | 2012-07-18 21:40:01 +0000 | [diff] [blame] | 5281 | return true; | 
|  | 5282 | } | 
|  | 5283 | } | 
|  | 5284 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 5285 | /// Check whether the use can be converted to remove a comparison against zero. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5286 | static X86::CondCode isUseDefConvertible(MachineInstr &MI) { | 
|  | 5287 | switch (MI.getOpcode()) { | 
| Benjamin Kramer | 594f963 | 2014-05-14 16:14:45 +0000 | [diff] [blame] | 5288 | default: return X86::COND_INVALID; | 
|  | 5289 | case X86::LZCNT16rr: case X86::LZCNT16rm: | 
|  | 5290 | case X86::LZCNT32rr: case X86::LZCNT32rm: | 
|  | 5291 | case X86::LZCNT64rr: case X86::LZCNT64rm: | 
|  | 5292 | return X86::COND_B; | 
|  | 5293 | case X86::POPCNT16rr:case X86::POPCNT16rm: | 
|  | 5294 | case X86::POPCNT32rr:case X86::POPCNT32rm: | 
|  | 5295 | case X86::POPCNT64rr:case X86::POPCNT64rm: | 
|  | 5296 | return X86::COND_E; | 
|  | 5297 | case X86::TZCNT16rr: case X86::TZCNT16rm: | 
|  | 5298 | case X86::TZCNT32rr: case X86::TZCNT32rm: | 
|  | 5299 | case X86::TZCNT64rr: case X86::TZCNT64rm: | 
|  | 5300 | return X86::COND_B; | 
|  | 5301 | } | 
|  | 5302 | } | 
|  | 5303 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 5304 | /// Check if there exists an earlier instruction that | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5305 | /// operates on the same source operands and sets flags in the same way as | 
|  | 5306 | /// Compare; remove Compare if possible. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5307 | bool X86InstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg, | 
|  | 5308 | unsigned SrcReg2, int CmpMask, | 
|  | 5309 | int CmpValue, | 
|  | 5310 | const MachineRegisterInfo *MRI) const { | 
| Manman Ren | 1be131b | 2012-08-08 00:51:41 +0000 | [diff] [blame] | 5311 | // Check whether we can replace SUB with CMP. | 
|  | 5312 | unsigned NewOpcode = 0; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5313 | switch (CmpInstr.getOpcode()) { | 
| Manman Ren | 1be131b | 2012-08-08 00:51:41 +0000 | [diff] [blame] | 5314 | default: break; | 
|  | 5315 | case X86::SUB64ri32: | 
|  | 5316 | case X86::SUB64ri8: | 
|  | 5317 | case X86::SUB32ri: | 
|  | 5318 | case X86::SUB32ri8: | 
|  | 5319 | case X86::SUB16ri: | 
|  | 5320 | case X86::SUB16ri8: | 
|  | 5321 | case X86::SUB8ri: | 
|  | 5322 | case X86::SUB64rm: | 
|  | 5323 | case X86::SUB32rm: | 
|  | 5324 | case X86::SUB16rm: | 
|  | 5325 | case X86::SUB8rm: | 
|  | 5326 | case X86::SUB64rr: | 
|  | 5327 | case X86::SUB32rr: | 
|  | 5328 | case X86::SUB16rr: | 
|  | 5329 | case X86::SUB8rr: { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5330 | if (!MRI->use_nodbg_empty(CmpInstr.getOperand(0).getReg())) | 
| Manman Ren | 1be131b | 2012-08-08 00:51:41 +0000 | [diff] [blame] | 5331 | return false; | 
|  | 5332 | // There is no use of the destination register, we can replace SUB with CMP. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5333 | switch (CmpInstr.getOpcode()) { | 
| Craig Topper | 4bc3e5a | 2012-08-21 08:16:16 +0000 | [diff] [blame] | 5334 | default: llvm_unreachable("Unreachable!"); | 
| Manman Ren | 1be131b | 2012-08-08 00:51:41 +0000 | [diff] [blame] | 5335 | case X86::SUB64rm:   NewOpcode = X86::CMP64rm;   break; | 
|  | 5336 | case X86::SUB32rm:   NewOpcode = X86::CMP32rm;   break; | 
|  | 5337 | case X86::SUB16rm:   NewOpcode = X86::CMP16rm;   break; | 
|  | 5338 | case X86::SUB8rm:    NewOpcode = X86::CMP8rm;    break; | 
|  | 5339 | case X86::SUB64rr:   NewOpcode = X86::CMP64rr;   break; | 
|  | 5340 | case X86::SUB32rr:   NewOpcode = X86::CMP32rr;   break; | 
|  | 5341 | case X86::SUB16rr:   NewOpcode = X86::CMP16rr;   break; | 
|  | 5342 | case X86::SUB8rr:    NewOpcode = X86::CMP8rr;    break; | 
|  | 5343 | case X86::SUB64ri32: NewOpcode = X86::CMP64ri32; break; | 
|  | 5344 | case X86::SUB64ri8:  NewOpcode = X86::CMP64ri8;  break; | 
|  | 5345 | case X86::SUB32ri:   NewOpcode = X86::CMP32ri;   break; | 
|  | 5346 | case X86::SUB32ri8:  NewOpcode = X86::CMP32ri8;  break; | 
|  | 5347 | case X86::SUB16ri:   NewOpcode = X86::CMP16ri;   break; | 
|  | 5348 | case X86::SUB16ri8:  NewOpcode = X86::CMP16ri8;  break; | 
|  | 5349 | case X86::SUB8ri:    NewOpcode = X86::CMP8ri;    break; | 
|  | 5350 | } | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5351 | CmpInstr.setDesc(get(NewOpcode)); | 
|  | 5352 | CmpInstr.RemoveOperand(0); | 
| Manman Ren | 1be131b | 2012-08-08 00:51:41 +0000 | [diff] [blame] | 5353 | // Fall through to optimize Cmp if Cmp is CMPrr or CMPri. | 
|  | 5354 | if (NewOpcode == X86::CMP64rm || NewOpcode == X86::CMP32rm || | 
|  | 5355 | NewOpcode == X86::CMP16rm || NewOpcode == X86::CMP8rm) | 
|  | 5356 | return false; | 
|  | 5357 | } | 
|  | 5358 | } | 
|  | 5359 |  | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5360 | // Get the unique definition of SrcReg. | 
|  | 5361 | MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg); | 
|  | 5362 | if (!MI) return false; | 
|  | 5363 |  | 
|  | 5364 | // CmpInstr is the first instruction of the BB. | 
|  | 5365 | MachineBasicBlock::iterator I = CmpInstr, Def = MI; | 
|  | 5366 |  | 
| Manman Ren | d0a4ee8 | 2012-07-18 21:40:01 +0000 | [diff] [blame] | 5367 | // If we are comparing against zero, check whether we can use MI to update | 
|  | 5368 | // EFLAGS. If MI is not in the same BB as CmpInstr, do not optimize. | 
|  | 5369 | bool IsCmpZero = (SrcReg2 == 0 && CmpValue == 0); | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5370 | if (IsCmpZero && MI->getParent() != CmpInstr.getParent()) | 
| Manman Ren | d0a4ee8 | 2012-07-18 21:40:01 +0000 | [diff] [blame] | 5371 | return false; | 
|  | 5372 |  | 
| Benjamin Kramer | 594f963 | 2014-05-14 16:14:45 +0000 | [diff] [blame] | 5373 | // If we have a use of the source register between the def and our compare | 
|  | 5374 | // instruction we can eliminate the compare iff the use sets EFLAGS in the | 
|  | 5375 | // right way. | 
|  | 5376 | bool ShouldUpdateCC = false; | 
|  | 5377 | X86::CondCode NewCC = X86::COND_INVALID; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5378 | if (IsCmpZero && !isDefConvertible(*MI)) { | 
| Benjamin Kramer | 594f963 | 2014-05-14 16:14:45 +0000 | [diff] [blame] | 5379 | // Scan forward from the use until we hit the use we're looking for or the | 
|  | 5380 | // compare instruction. | 
|  | 5381 | for (MachineBasicBlock::iterator J = MI;; ++J) { | 
|  | 5382 | // Do we have a convertible instruction? | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5383 | NewCC = isUseDefConvertible(*J); | 
| Benjamin Kramer | 594f963 | 2014-05-14 16:14:45 +0000 | [diff] [blame] | 5384 | if (NewCC != X86::COND_INVALID && J->getOperand(1).isReg() && | 
|  | 5385 | J->getOperand(1).getReg() == SrcReg) { | 
|  | 5386 | assert(J->definesRegister(X86::EFLAGS) && "Must be an EFLAGS def!"); | 
|  | 5387 | ShouldUpdateCC = true; // Update CC later on. | 
|  | 5388 | // This is not a def of SrcReg, but still a def of EFLAGS. Keep going | 
|  | 5389 | // with the new def. | 
| Duncan P. N. Exon Smith | 7b4c18e | 2016-07-12 03:18:50 +0000 | [diff] [blame] | 5390 | Def = J; | 
|  | 5391 | MI = &*Def; | 
| Benjamin Kramer | 594f963 | 2014-05-14 16:14:45 +0000 | [diff] [blame] | 5392 | break; | 
|  | 5393 | } | 
|  | 5394 |  | 
|  | 5395 | if (J == I) | 
|  | 5396 | return false; | 
|  | 5397 | } | 
|  | 5398 | } | 
|  | 5399 |  | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5400 | // We are searching for an earlier instruction that can make CmpInstr | 
|  | 5401 | // redundant and that instruction will be saved in Sub. | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 5402 | MachineInstr *Sub = nullptr; | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5403 | const TargetRegisterInfo *TRI = &getRegisterInfo(); | 
| Manman Ren | 5f6fa42 | 2012-07-09 18:57:12 +0000 | [diff] [blame] | 5404 |  | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5405 | // We iterate backward, starting from the instruction before CmpInstr and | 
|  | 5406 | // stop when reaching the definition of a source register or done with the BB. | 
|  | 5407 | // RI points to the instruction before CmpInstr. | 
|  | 5408 | // If the definition is in this basic block, RE points to the definition; | 
|  | 5409 | // otherwise, RE is the rend of the basic block. | 
|  | 5410 | MachineBasicBlock::reverse_iterator | 
|  | 5411 | RI = MachineBasicBlock::reverse_iterator(I), | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5412 | RE = CmpInstr.getParent() == MI->getParent() | 
|  | 5413 | ? MachineBasicBlock::reverse_iterator(++Def) /* points to MI */ | 
|  | 5414 | : CmpInstr.getParent()->rend(); | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 5415 | MachineInstr *Movr0Inst = nullptr; | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5416 | for (; RI != RE; ++RI) { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5417 | MachineInstr &Instr = *RI; | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5418 | // Check whether CmpInstr can be made redundant by the current instruction. | 
| Manman Ren | d0a4ee8 | 2012-07-18 21:40:01 +0000 | [diff] [blame] | 5419 | if (!IsCmpZero && | 
|  | 5420 | isRedundantFlagInstr(CmpInstr, SrcReg, SrcReg2, CmpValue, Instr)) { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5421 | Sub = &Instr; | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5422 | break; | 
|  | 5423 | } | 
|  | 5424 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5425 | if (Instr.modifiesRegister(X86::EFLAGS, TRI) || | 
|  | 5426 | Instr.readsRegister(X86::EFLAGS, TRI)) { | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5427 | // This instruction modifies or uses EFLAGS. | 
| Manman Ren | 1553ce0 | 2012-07-11 19:35:12 +0000 | [diff] [blame] | 5428 |  | 
|  | 5429 | // MOV32r0 etc. are implemented with xor which clobbers condition code. | 
|  | 5430 | // They are safe to move up, if the definition to EFLAGS is dead and | 
|  | 5431 | // earlier instructions do not read or write EFLAGS. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5432 | if (!Movr0Inst && Instr.getOpcode() == X86::MOV32r0 && | 
|  | 5433 | Instr.registerDefIsDead(X86::EFLAGS, TRI)) { | 
|  | 5434 | Movr0Inst = &Instr; | 
| Manman Ren | 1553ce0 | 2012-07-11 19:35:12 +0000 | [diff] [blame] | 5435 | continue; | 
|  | 5436 | } | 
|  | 5437 |  | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5438 | // We can't remove CmpInstr. | 
|  | 5439 | return false; | 
| Manman Ren | 1553ce0 | 2012-07-11 19:35:12 +0000 | [diff] [blame] | 5440 | } | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5441 | } | 
|  | 5442 |  | 
|  | 5443 | // Return false if no candidates exist. | 
| Manman Ren | d0a4ee8 | 2012-07-18 21:40:01 +0000 | [diff] [blame] | 5444 | if (!IsCmpZero && !Sub) | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5445 | return false; | 
|  | 5446 |  | 
| Manman Ren | bb36074 | 2012-07-07 03:34:46 +0000 | [diff] [blame] | 5447 | bool IsSwapped = (SrcReg2 != 0 && Sub->getOperand(1).getReg() == SrcReg2 && | 
|  | 5448 | Sub->getOperand(2).getReg() == SrcReg); | 
|  | 5449 |  | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5450 | // Scan forward from the instruction after CmpInstr for uses of EFLAGS. | 
| Manman Ren | bb36074 | 2012-07-07 03:34:46 +0000 | [diff] [blame] | 5451 | // It is safe to remove CmpInstr if EFLAGS is redefined or killed. | 
|  | 5452 | // If we are done with the basic block, we need to check whether EFLAGS is | 
|  | 5453 | // live-out. | 
|  | 5454 | bool IsSafe = false; | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5455 | SmallVector<std::pair<MachineInstr*, unsigned /*NewOpc*/>, 4> OpsToUpdate; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5456 | MachineBasicBlock::iterator E = CmpInstr.getParent()->end(); | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5457 | for (++I; I != E; ++I) { | 
|  | 5458 | const MachineInstr &Instr = *I; | 
| Manman Ren | 32367c0 | 2012-07-28 03:15:46 +0000 | [diff] [blame] | 5459 | bool ModifyEFLAGS = Instr.modifiesRegister(X86::EFLAGS, TRI); | 
|  | 5460 | bool UseEFLAGS = Instr.readsRegister(X86::EFLAGS, TRI); | 
|  | 5461 | // We should check the usage if this instruction uses and updates EFLAGS. | 
|  | 5462 | if (!UseEFLAGS && ModifyEFLAGS) { | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5463 | // It is safe to remove CmpInstr if EFLAGS is updated again. | 
| Manman Ren | bb36074 | 2012-07-07 03:34:46 +0000 | [diff] [blame] | 5464 | IsSafe = true; | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5465 | break; | 
| Manman Ren | bb36074 | 2012-07-07 03:34:46 +0000 | [diff] [blame] | 5466 | } | 
| Manman Ren | 32367c0 | 2012-07-28 03:15:46 +0000 | [diff] [blame] | 5467 | if (!UseEFLAGS && !ModifyEFLAGS) | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5468 | continue; | 
|  | 5469 |  | 
|  | 5470 | // EFLAGS is used by this instruction. | 
| Nick Lewycky | 0a9a866 | 2014-06-04 07:45:54 +0000 | [diff] [blame] | 5471 | X86::CondCode OldCC = X86::COND_INVALID; | 
| Manman Ren | d0a4ee8 | 2012-07-18 21:40:01 +0000 | [diff] [blame] | 5472 | bool OpcIsSET = false; | 
|  | 5473 | if (IsCmpZero || IsSwapped) { | 
|  | 5474 | // We decode the condition code from opcode. | 
| Manman Ren | 5f6fa42 | 2012-07-09 18:57:12 +0000 | [diff] [blame] | 5475 | if (Instr.isBranch()) | 
|  | 5476 | OldCC = getCondFromBranchOpc(Instr.getOpcode()); | 
|  | 5477 | else { | 
|  | 5478 | OldCC = getCondFromSETOpc(Instr.getOpcode()); | 
|  | 5479 | if (OldCC != X86::COND_INVALID) | 
|  | 5480 | OpcIsSET = true; | 
|  | 5481 | else | 
| Michael Liao | 3237662 | 2012-09-20 03:06:15 +0000 | [diff] [blame] | 5482 | OldCC = X86::getCondFromCMovOpc(Instr.getOpcode()); | 
| Manman Ren | 5f6fa42 | 2012-07-09 18:57:12 +0000 | [diff] [blame] | 5483 | } | 
|  | 5484 | if (OldCC == X86::COND_INVALID) return false; | 
| Manman Ren | d0a4ee8 | 2012-07-18 21:40:01 +0000 | [diff] [blame] | 5485 | } | 
|  | 5486 | if (IsCmpZero) { | 
|  | 5487 | switch (OldCC) { | 
|  | 5488 | default: break; | 
|  | 5489 | case X86::COND_A: case X86::COND_AE: | 
|  | 5490 | case X86::COND_B: case X86::COND_BE: | 
|  | 5491 | case X86::COND_G: case X86::COND_GE: | 
|  | 5492 | case X86::COND_L: case X86::COND_LE: | 
|  | 5493 | case X86::COND_O: case X86::COND_NO: | 
|  | 5494 | // CF and OF are used, we can't perform this optimization. | 
|  | 5495 | return false; | 
|  | 5496 | } | 
| Benjamin Kramer | 594f963 | 2014-05-14 16:14:45 +0000 | [diff] [blame] | 5497 |  | 
|  | 5498 | // If we're updating the condition code check if we have to reverse the | 
|  | 5499 | // condition. | 
|  | 5500 | if (ShouldUpdateCC) | 
|  | 5501 | switch (OldCC) { | 
|  | 5502 | default: | 
|  | 5503 | return false; | 
|  | 5504 | case X86::COND_E: | 
|  | 5505 | break; | 
|  | 5506 | case X86::COND_NE: | 
|  | 5507 | NewCC = GetOppositeBranchCondition(NewCC); | 
|  | 5508 | break; | 
|  | 5509 | } | 
| Manman Ren | d0a4ee8 | 2012-07-18 21:40:01 +0000 | [diff] [blame] | 5510 | } else if (IsSwapped) { | 
|  | 5511 | // If we have SUB(r1, r2) and CMP(r2, r1), the condition code needs | 
|  | 5512 | // to be changed from r2 > r1 to r1 < r2, from r2 < r1 to r1 > r2, etc. | 
|  | 5513 | // We swap the condition code and synthesize the new opcode. | 
| Benjamin Kramer | 594f963 | 2014-05-14 16:14:45 +0000 | [diff] [blame] | 5514 | NewCC = getSwappedCondition(OldCC); | 
| Manman Ren | 5f6fa42 | 2012-07-09 18:57:12 +0000 | [diff] [blame] | 5515 | if (NewCC == X86::COND_INVALID) return false; | 
| Benjamin Kramer | 594f963 | 2014-05-14 16:14:45 +0000 | [diff] [blame] | 5516 | } | 
| Manman Ren | 5f6fa42 | 2012-07-09 18:57:12 +0000 | [diff] [blame] | 5517 |  | 
| Benjamin Kramer | 594f963 | 2014-05-14 16:14:45 +0000 | [diff] [blame] | 5518 | if ((ShouldUpdateCC || IsSwapped) && NewCC != OldCC) { | 
| Manman Ren | 5f6fa42 | 2012-07-09 18:57:12 +0000 | [diff] [blame] | 5519 | // Synthesize the new opcode. | 
|  | 5520 | bool HasMemoryOperand = Instr.hasOneMemOperand(); | 
|  | 5521 | unsigned NewOpc; | 
|  | 5522 | if (Instr.isBranch()) | 
|  | 5523 | NewOpc = GetCondBranchFromCond(NewCC); | 
|  | 5524 | else if(OpcIsSET) | 
|  | 5525 | NewOpc = getSETFromCond(NewCC, HasMemoryOperand); | 
|  | 5526 | else { | 
|  | 5527 | unsigned DstReg = Instr.getOperand(0).getReg(); | 
|  | 5528 | NewOpc = getCMovFromCond(NewCC, MRI->getRegClass(DstReg)->getSize(), | 
|  | 5529 | HasMemoryOperand); | 
|  | 5530 | } | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5531 |  | 
|  | 5532 | // Push the MachineInstr to OpsToUpdate. | 
|  | 5533 | // If it is safe to remove CmpInstr, the condition code of these | 
|  | 5534 | // instructions will be modified. | 
|  | 5535 | OpsToUpdate.push_back(std::make_pair(&*I, NewOpc)); | 
|  | 5536 | } | 
| Manman Ren | 32367c0 | 2012-07-28 03:15:46 +0000 | [diff] [blame] | 5537 | if (ModifyEFLAGS || Instr.killsRegister(X86::EFLAGS, TRI)) { | 
|  | 5538 | // It is safe to remove CmpInstr if EFLAGS is updated again or killed. | 
| Manman Ren | bb36074 | 2012-07-07 03:34:46 +0000 | [diff] [blame] | 5539 | IsSafe = true; | 
|  | 5540 | break; | 
|  | 5541 | } | 
|  | 5542 | } | 
|  | 5543 |  | 
|  | 5544 | // If EFLAGS is not killed nor re-defined, we should check whether it is | 
|  | 5545 | // live-out. If it is live-out, do not optimize. | 
| Manman Ren | d0a4ee8 | 2012-07-18 21:40:01 +0000 | [diff] [blame] | 5546 | if ((IsCmpZero || IsSwapped) && !IsSafe) { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5547 | MachineBasicBlock *MBB = CmpInstr.getParent(); | 
| Sanjay Patel | 4104f78 | 2015-12-29 19:14:23 +0000 | [diff] [blame] | 5548 | for (MachineBasicBlock *Successor : MBB->successors()) | 
|  | 5549 | if (Successor->isLiveIn(X86::EFLAGS)) | 
| Manman Ren | bb36074 | 2012-07-07 03:34:46 +0000 | [diff] [blame] | 5550 | return false; | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5551 | } | 
|  | 5552 |  | 
| Manman Ren | d0a4ee8 | 2012-07-18 21:40:01 +0000 | [diff] [blame] | 5553 | // The instruction to be updated is either Sub or MI. | 
|  | 5554 | Sub = IsCmpZero ? MI : Sub; | 
| David Majnemer | 5ba473a | 2013-05-18 01:02:03 +0000 | [diff] [blame] | 5555 | // Move Movr0Inst to the appropriate place before Sub. | 
| Manman Ren | 1553ce0 | 2012-07-11 19:35:12 +0000 | [diff] [blame] | 5556 | if (Movr0Inst) { | 
| David Majnemer | 5ba473a | 2013-05-18 01:02:03 +0000 | [diff] [blame] | 5557 | // Look backwards until we find a def that doesn't use the current EFLAGS. | 
|  | 5558 | Def = Sub; | 
|  | 5559 | MachineBasicBlock::reverse_iterator | 
|  | 5560 | InsertI = MachineBasicBlock::reverse_iterator(++Def), | 
|  | 5561 | InsertE = Sub->getParent()->rend(); | 
|  | 5562 | for (; InsertI != InsertE; ++InsertI) { | 
|  | 5563 | MachineInstr *Instr = &*InsertI; | 
|  | 5564 | if (!Instr->readsRegister(X86::EFLAGS, TRI) && | 
|  | 5565 | Instr->modifiesRegister(X86::EFLAGS, TRI)) { | 
|  | 5566 | Sub->getParent()->remove(Movr0Inst); | 
|  | 5567 | Instr->getParent()->insert(MachineBasicBlock::iterator(Instr), | 
|  | 5568 | Movr0Inst); | 
|  | 5569 | break; | 
|  | 5570 | } | 
|  | 5571 | } | 
|  | 5572 | if (InsertI == InsertE) | 
|  | 5573 | return false; | 
| Manman Ren | 1553ce0 | 2012-07-11 19:35:12 +0000 | [diff] [blame] | 5574 | } | 
|  | 5575 |  | 
| Jan Wen Voung | 4ce1d7b | 2012-09-17 22:04:23 +0000 | [diff] [blame] | 5576 | // Make sure Sub instruction defines EFLAGS and mark the def live. | 
| David Majnemer | 8f16974 | 2013-05-15 22:03:08 +0000 | [diff] [blame] | 5577 | unsigned i = 0, e = Sub->getNumOperands(); | 
|  | 5578 | for (; i != e; ++i) { | 
|  | 5579 | MachineOperand &MO = Sub->getOperand(i); | 
|  | 5580 | if (MO.isReg() && MO.isDef() && MO.getReg() == X86::EFLAGS) { | 
|  | 5581 | MO.setIsDead(false); | 
|  | 5582 | break; | 
|  | 5583 | } | 
|  | 5584 | } | 
|  | 5585 | assert(i != e && "Unable to locate a def EFLAGS operand"); | 
|  | 5586 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5587 | CmpInstr.eraseFromParent(); | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5588 |  | 
|  | 5589 | // Modify the condition code of instructions in OpsToUpdate. | 
| Sanjay Patel | 4104f78 | 2015-12-29 19:14:23 +0000 | [diff] [blame] | 5590 | for (auto &Op : OpsToUpdate) | 
|  | 5591 | Op.first->setDesc(get(Op.second)); | 
| Manman Ren | c965673 | 2012-07-06 17:36:20 +0000 | [diff] [blame] | 5592 | return true; | 
|  | 5593 | } | 
|  | 5594 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 5595 | /// Try to remove the load by folding it to a register | 
| Manman Ren | 5759d01 | 2012-08-02 00:56:42 +0000 | [diff] [blame] | 5596 | /// operand at the use. We fold the load instructions if load defines a virtual | 
|  | 5597 | /// register, the virtual register is used once in the same BB, and the | 
|  | 5598 | /// instructions in-between do not load or store, and have no side effects. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5599 | MachineInstr *X86InstrInfo::optimizeLoadInstr(MachineInstr &MI, | 
| Simon Pilgrim | 2f9548a | 2014-10-20 22:14:22 +0000 | [diff] [blame] | 5600 | const MachineRegisterInfo *MRI, | 
|  | 5601 | unsigned &FoldAsLoadDefReg, | 
|  | 5602 | MachineInstr *&DefMI) const { | 
| Manman Ren | 5759d01 | 2012-08-02 00:56:42 +0000 | [diff] [blame] | 5603 | if (FoldAsLoadDefReg == 0) | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 5604 | return nullptr; | 
| Manman Ren | 5759d01 | 2012-08-02 00:56:42 +0000 | [diff] [blame] | 5605 | // To be conservative, if there exists another load, clear the load candidate. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5606 | if (MI.mayLoad()) { | 
| Manman Ren | 5759d01 | 2012-08-02 00:56:42 +0000 | [diff] [blame] | 5607 | FoldAsLoadDefReg = 0; | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 5608 | return nullptr; | 
| Manman Ren | 5759d01 | 2012-08-02 00:56:42 +0000 | [diff] [blame] | 5609 | } | 
|  | 5610 |  | 
|  | 5611 | // Check whether we can move DefMI here. | 
|  | 5612 | DefMI = MRI->getVRegDef(FoldAsLoadDefReg); | 
|  | 5613 | assert(DefMI); | 
|  | 5614 | bool SawStore = false; | 
| Matthias Braun | 07066cc | 2015-05-19 21:22:20 +0000 | [diff] [blame] | 5615 | if (!DefMI->isSafeToMove(nullptr, SawStore)) | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 5616 | return nullptr; | 
| Manman Ren | 5759d01 | 2012-08-02 00:56:42 +0000 | [diff] [blame] | 5617 |  | 
| Simon Pilgrim | 2f9548a | 2014-10-20 22:14:22 +0000 | [diff] [blame] | 5618 | // Collect information about virtual register operands of MI. | 
|  | 5619 | unsigned SrcOperandId = 0; | 
|  | 5620 | bool FoundSrcOperand = false; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5621 | for (unsigned i = 0, e = MI.getDesc().getNumOperands(); i != e; ++i) { | 
|  | 5622 | MachineOperand &MO = MI.getOperand(i); | 
| Simon Pilgrim | 2f9548a | 2014-10-20 22:14:22 +0000 | [diff] [blame] | 5623 | if (!MO.isReg()) | 
|  | 5624 | continue; | 
|  | 5625 | unsigned Reg = MO.getReg(); | 
|  | 5626 | if (Reg != FoldAsLoadDefReg) | 
|  | 5627 | continue; | 
|  | 5628 | // Do not fold if we have a subreg use or a def or multiple uses. | 
|  | 5629 | if (MO.getSubReg() || MO.isDef() || FoundSrcOperand) | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 5630 | return nullptr; | 
| Manman Ren | 5759d01 | 2012-08-02 00:56:42 +0000 | [diff] [blame] | 5631 |  | 
| Simon Pilgrim | 2f9548a | 2014-10-20 22:14:22 +0000 | [diff] [blame] | 5632 | SrcOperandId = i; | 
|  | 5633 | FoundSrcOperand = true; | 
| Manman Ren | 5759d01 | 2012-08-02 00:56:42 +0000 | [diff] [blame] | 5634 | } | 
| Simon Pilgrim | 2f9548a | 2014-10-20 22:14:22 +0000 | [diff] [blame] | 5635 | if (!FoundSrcOperand) | 
|  | 5636 | return nullptr; | 
|  | 5637 |  | 
|  | 5638 | // Check whether we can fold the def into SrcOperandId. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5639 | if (MachineInstr *FoldMI = foldMemoryOperand(MI, SrcOperandId, *DefMI)) { | 
| Simon Pilgrim | 2f9548a | 2014-10-20 22:14:22 +0000 | [diff] [blame] | 5640 | FoldAsLoadDefReg = 0; | 
|  | 5641 | return FoldMI; | 
|  | 5642 | } | 
|  | 5643 |  | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 5644 | return nullptr; | 
| Manman Ren | 5759d01 | 2012-08-02 00:56:42 +0000 | [diff] [blame] | 5645 | } | 
|  | 5646 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 5647 | /// Expand a single-def pseudo instruction to a two-addr | 
|  | 5648 | /// instruction with two undef reads of the register being defined. | 
|  | 5649 | /// This is used for mapping: | 
| Jakob Stoklund Olesen | dd1904e | 2011-09-29 05:10:54 +0000 | [diff] [blame] | 5650 | ///   %xmm4 = V_SET0 | 
|  | 5651 | /// to: | 
|  | 5652 | ///   %xmm4 = PXORrr %xmm4<undef>, %xmm4<undef> | 
|  | 5653 | /// | 
| Jakob Stoklund Olesen | b159b5f | 2012-12-19 21:31:56 +0000 | [diff] [blame] | 5654 | static bool Expand2AddrUndef(MachineInstrBuilder &MIB, | 
|  | 5655 | const MCInstrDesc &Desc) { | 
| Jakob Stoklund Olesen | dd1904e | 2011-09-29 05:10:54 +0000 | [diff] [blame] | 5656 | assert(Desc.getNumOperands() == 3 && "Expected two-addr instruction."); | 
| Jakob Stoklund Olesen | b159b5f | 2012-12-19 21:31:56 +0000 | [diff] [blame] | 5657 | unsigned Reg = MIB->getOperand(0).getReg(); | 
|  | 5658 | MIB->setDesc(Desc); | 
| Jakob Stoklund Olesen | dd1904e | 2011-09-29 05:10:54 +0000 | [diff] [blame] | 5659 |  | 
|  | 5660 | // MachineInstr::addOperand() will insert explicit operands before any | 
|  | 5661 | // implicit operands. | 
| Jakob Stoklund Olesen | b159b5f | 2012-12-19 21:31:56 +0000 | [diff] [blame] | 5662 | MIB.addReg(Reg, RegState::Undef).addReg(Reg, RegState::Undef); | 
| Jakob Stoklund Olesen | dd1904e | 2011-09-29 05:10:54 +0000 | [diff] [blame] | 5663 | // But we don't trust that. | 
| Jakob Stoklund Olesen | b159b5f | 2012-12-19 21:31:56 +0000 | [diff] [blame] | 5664 | assert(MIB->getOperand(1).getReg() == Reg && | 
|  | 5665 | MIB->getOperand(2).getReg() == Reg && "Misplaced operand"); | 
| Jakob Stoklund Olesen | dd1904e | 2011-09-29 05:10:54 +0000 | [diff] [blame] | 5666 | return true; | 
|  | 5667 | } | 
|  | 5668 |  | 
| Elena Demikhovsky | 9e225a2 | 2015-12-24 08:12:22 +0000 | [diff] [blame] | 5669 | /// Expand a single-def pseudo instruction to a two-addr | 
|  | 5670 | /// instruction with two %k0 reads. | 
|  | 5671 | /// This is used for mapping: | 
|  | 5672 | ///   %k4 = K_SET1 | 
|  | 5673 | /// to: | 
|  | 5674 | ///   %k4 = KXNORrr %k0, %k0 | 
|  | 5675 | static bool Expand2AddrKreg(MachineInstrBuilder &MIB, | 
|  | 5676 | const MCInstrDesc &Desc, unsigned Reg) { | 
|  | 5677 | assert(Desc.getNumOperands() == 3 && "Expected two-addr instruction."); | 
|  | 5678 | MIB->setDesc(Desc); | 
|  | 5679 | MIB.addReg(Reg, RegState::Undef).addReg(Reg, RegState::Undef); | 
|  | 5680 | return true; | 
|  | 5681 | } | 
|  | 5682 |  | 
| Hans Wennborg | 08d5905 | 2015-12-15 17:10:28 +0000 | [diff] [blame] | 5683 | static bool expandMOV32r1(MachineInstrBuilder &MIB, const TargetInstrInfo &TII, | 
|  | 5684 | bool MinusOne) { | 
|  | 5685 | MachineBasicBlock &MBB = *MIB->getParent(); | 
|  | 5686 | DebugLoc DL = MIB->getDebugLoc(); | 
|  | 5687 | unsigned Reg = MIB->getOperand(0).getReg(); | 
|  | 5688 |  | 
|  | 5689 | // Insert the XOR. | 
|  | 5690 | BuildMI(MBB, MIB.getInstr(), DL, TII.get(X86::XOR32rr), Reg) | 
|  | 5691 | .addReg(Reg, RegState::Undef) | 
|  | 5692 | .addReg(Reg, RegState::Undef); | 
|  | 5693 |  | 
|  | 5694 | // Turn the pseudo into an INC or DEC. | 
|  | 5695 | MIB->setDesc(TII.get(MinusOne ? X86::DEC32r : X86::INC32r)); | 
|  | 5696 | MIB.addReg(Reg); | 
|  | 5697 |  | 
|  | 5698 | return true; | 
|  | 5699 | } | 
|  | 5700 |  | 
| Hans Wennborg | 4ae5119 | 2016-03-25 01:10:56 +0000 | [diff] [blame] | 5701 | bool X86InstrInfo::ExpandMOVImmSExti8(MachineInstrBuilder &MIB) const { | 
|  | 5702 | MachineBasicBlock &MBB = *MIB->getParent(); | 
|  | 5703 | DebugLoc DL = MIB->getDebugLoc(); | 
|  | 5704 | int64_t Imm = MIB->getOperand(1).getImm(); | 
|  | 5705 | assert(Imm != 0 && "Using push/pop for 0 is not efficient."); | 
|  | 5706 | MachineBasicBlock::iterator I = MIB.getInstr(); | 
|  | 5707 |  | 
|  | 5708 | int StackAdjustment; | 
|  | 5709 |  | 
|  | 5710 | if (Subtarget.is64Bit()) { | 
|  | 5711 | assert(MIB->getOpcode() == X86::MOV64ImmSExti8 || | 
|  | 5712 | MIB->getOpcode() == X86::MOV32ImmSExti8); | 
|  | 5713 |  | 
|  | 5714 | // Can't use push/pop lowering if the function might write to the red zone. | 
|  | 5715 | X86MachineFunctionInfo *X86FI = | 
|  | 5716 | MBB.getParent()->getInfo<X86MachineFunctionInfo>(); | 
|  | 5717 | if (X86FI->getUsesRedZone()) { | 
|  | 5718 | MIB->setDesc(get(MIB->getOpcode() == X86::MOV32ImmSExti8 ? X86::MOV32ri | 
|  | 5719 | : X86::MOV64ri)); | 
|  | 5720 | return true; | 
|  | 5721 | } | 
|  | 5722 |  | 
|  | 5723 | // 64-bit mode doesn't have 32-bit push/pop, so use 64-bit operations and | 
|  | 5724 | // widen the register if necessary. | 
|  | 5725 | StackAdjustment = 8; | 
|  | 5726 | BuildMI(MBB, I, DL, get(X86::PUSH64i8)).addImm(Imm); | 
|  | 5727 | MIB->setDesc(get(X86::POP64r)); | 
|  | 5728 | MIB->getOperand(0) | 
|  | 5729 | .setReg(getX86SubSuperRegister(MIB->getOperand(0).getReg(), 64)); | 
|  | 5730 | } else { | 
|  | 5731 | assert(MIB->getOpcode() == X86::MOV32ImmSExti8); | 
|  | 5732 | StackAdjustment = 4; | 
|  | 5733 | BuildMI(MBB, I, DL, get(X86::PUSH32i8)).addImm(Imm); | 
|  | 5734 | MIB->setDesc(get(X86::POP32r)); | 
|  | 5735 | } | 
|  | 5736 |  | 
|  | 5737 | // Build CFI if necessary. | 
|  | 5738 | MachineFunction &MF = *MBB.getParent(); | 
|  | 5739 | const X86FrameLowering *TFL = Subtarget.getFrameLowering(); | 
|  | 5740 | bool IsWin64Prologue = MF.getTarget().getMCAsmInfo()->usesWindowsCFI(); | 
|  | 5741 | bool NeedsDwarfCFI = | 
|  | 5742 | !IsWin64Prologue && | 
|  | 5743 | (MF.getMMI().hasDebugInfo() || MF.getFunction()->needsUnwindTableEntry()); | 
|  | 5744 | bool EmitCFI = !TFL->hasFP(MF) && NeedsDwarfCFI; | 
|  | 5745 | if (EmitCFI) { | 
|  | 5746 | TFL->BuildCFI(MBB, I, DL, | 
|  | 5747 | MCCFIInstruction::createAdjustCfaOffset(nullptr, StackAdjustment)); | 
|  | 5748 | TFL->BuildCFI(MBB, std::next(I), DL, | 
|  | 5749 | MCCFIInstruction::createAdjustCfaOffset(nullptr, -StackAdjustment)); | 
|  | 5750 | } | 
|  | 5751 |  | 
|  | 5752 | return true; | 
|  | 5753 | } | 
|  | 5754 |  | 
| Akira Hatanaka | e5b6e0d | 2014-07-25 19:31:34 +0000 | [diff] [blame] | 5755 | // LoadStackGuard has so far only been implemented for 64-bit MachO. Different | 
|  | 5756 | // code sequence is needed for other targets. | 
|  | 5757 | static void expandLoadStackGuard(MachineInstrBuilder &MIB, | 
|  | 5758 | const TargetInstrInfo &TII) { | 
|  | 5759 | MachineBasicBlock &MBB = *MIB->getParent(); | 
|  | 5760 | DebugLoc DL = MIB->getDebugLoc(); | 
|  | 5761 | unsigned Reg = MIB->getOperand(0).getReg(); | 
|  | 5762 | const GlobalValue *GV = | 
|  | 5763 | cast<GlobalValue>((*MIB->memoperands_begin())->getValue()); | 
| Justin Lebar | 0af80cd | 2016-07-15 18:26:59 +0000 | [diff] [blame] | 5764 | auto Flags = MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant; | 
| Alex Lorenz | e40c8a2 | 2015-08-11 23:09:45 +0000 | [diff] [blame] | 5765 | MachineMemOperand *MMO = MBB.getParent()->getMachineMemOperand( | 
| Justin Lebar | 0af80cd | 2016-07-15 18:26:59 +0000 | [diff] [blame] | 5766 | MachinePointerInfo::getGOT(*MBB.getParent()), Flags, 8, 8); | 
| Reid Kleckner | da00cf5 | 2014-10-31 23:19:46 +0000 | [diff] [blame] | 5767 | MachineBasicBlock::iterator I = MIB.getInstr(); | 
| Akira Hatanaka | e5b6e0d | 2014-07-25 19:31:34 +0000 | [diff] [blame] | 5768 |  | 
|  | 5769 | BuildMI(MBB, I, DL, TII.get(X86::MOV64rm), Reg).addReg(X86::RIP).addImm(1) | 
|  | 5770 | .addReg(0).addGlobalAddress(GV, 0, X86II::MO_GOTPCREL).addReg(0) | 
|  | 5771 | .addMemOperand(MMO); | 
|  | 5772 | MIB->setDebugLoc(DL); | 
|  | 5773 | MIB->setDesc(TII.get(X86::MOV64rm)); | 
|  | 5774 | MIB.addReg(Reg, RegState::Kill).addImm(1).addReg(0).addImm(0).addReg(0); | 
|  | 5775 | } | 
|  | 5776 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5777 | bool X86InstrInfo::expandPostRAPseudo(MachineInstr &MI) const { | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 5778 | bool HasAVX = Subtarget.hasAVX(); | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5779 | MachineInstrBuilder MIB(*MI.getParent()->getParent(), MI); | 
|  | 5780 | switch (MI.getOpcode()) { | 
| Craig Topper | 854f644 | 2013-12-31 03:05:38 +0000 | [diff] [blame] | 5781 | case X86::MOV32r0: | 
|  | 5782 | return Expand2AddrUndef(MIB, get(X86::XOR32rr)); | 
| Hans Wennborg | 08d5905 | 2015-12-15 17:10:28 +0000 | [diff] [blame] | 5783 | case X86::MOV32r1: | 
|  | 5784 | return expandMOV32r1(MIB, *this, /*MinusOne=*/ false); | 
|  | 5785 | case X86::MOV32r_1: | 
|  | 5786 | return expandMOV32r1(MIB, *this, /*MinusOne=*/ true); | 
| Hans Wennborg | 4ae5119 | 2016-03-25 01:10:56 +0000 | [diff] [blame] | 5787 | case X86::MOV32ImmSExti8: | 
|  | 5788 | case X86::MOV64ImmSExti8: | 
|  | 5789 | return ExpandMOVImmSExti8(MIB); | 
| Craig Topper | 9384902 | 2012-10-05 06:05:15 +0000 | [diff] [blame] | 5790 | case X86::SETB_C8r: | 
| Jakob Stoklund Olesen | b159b5f | 2012-12-19 21:31:56 +0000 | [diff] [blame] | 5791 | return Expand2AddrUndef(MIB, get(X86::SBB8rr)); | 
| Craig Topper | 9384902 | 2012-10-05 06:05:15 +0000 | [diff] [blame] | 5792 | case X86::SETB_C16r: | 
| Jakob Stoklund Olesen | b159b5f | 2012-12-19 21:31:56 +0000 | [diff] [blame] | 5793 | return Expand2AddrUndef(MIB, get(X86::SBB16rr)); | 
| Craig Topper | 9384902 | 2012-10-05 06:05:15 +0000 | [diff] [blame] | 5794 | case X86::SETB_C32r: | 
| Jakob Stoklund Olesen | b159b5f | 2012-12-19 21:31:56 +0000 | [diff] [blame] | 5795 | return Expand2AddrUndef(MIB, get(X86::SBB32rr)); | 
| Craig Topper | 9384902 | 2012-10-05 06:05:15 +0000 | [diff] [blame] | 5796 | case X86::SETB_C64r: | 
| Jakob Stoklund Olesen | b159b5f | 2012-12-19 21:31:56 +0000 | [diff] [blame] | 5797 | return Expand2AddrUndef(MIB, get(X86::SBB64rr)); | 
| Jakob Stoklund Olesen | dd1904e | 2011-09-29 05:10:54 +0000 | [diff] [blame] | 5798 | case X86::V_SET0: | 
| Jakob Stoklund Olesen | bde32d3 | 2011-11-29 22:27:25 +0000 | [diff] [blame] | 5799 | case X86::FsFLD0SS: | 
|  | 5800 | case X86::FsFLD0SD: | 
| Jakob Stoklund Olesen | b159b5f | 2012-12-19 21:31:56 +0000 | [diff] [blame] | 5801 | return Expand2AddrUndef(MIB, get(HasAVX ? X86::VXORPSrr : X86::XORPSrr)); | 
| Craig Topper | bd509ee | 2012-08-28 07:05:28 +0000 | [diff] [blame] | 5802 | case X86::AVX_SET0: | 
|  | 5803 | assert(HasAVX && "AVX not supported"); | 
| Jakob Stoklund Olesen | b159b5f | 2012-12-19 21:31:56 +0000 | [diff] [blame] | 5804 | return Expand2AddrUndef(MIB, get(X86::VXORPSYrr)); | 
| Craig Topper | e5ce84a | 2016-05-08 21:33:53 +0000 | [diff] [blame] | 5805 | case X86::AVX512_128_SET0: | 
|  | 5806 | return Expand2AddrUndef(MIB, get(X86::VPXORDZ128rr)); | 
|  | 5807 | case X86::AVX512_256_SET0: | 
|  | 5808 | return Expand2AddrUndef(MIB, get(X86::VPXORDZ256rr)); | 
| Elena Demikhovsky | f8f478b | 2013-08-25 12:54:30 +0000 | [diff] [blame] | 5809 | case X86::AVX512_512_SET0: | 
|  | 5810 | return Expand2AddrUndef(MIB, get(X86::VPXORDZrr)); | 
| Craig Topper | 72f51c3 | 2012-08-28 07:30:47 +0000 | [diff] [blame] | 5811 | case X86::V_SETALLONES: | 
| Jakob Stoklund Olesen | b159b5f | 2012-12-19 21:31:56 +0000 | [diff] [blame] | 5812 | return Expand2AddrUndef(MIB, get(HasAVX ? X86::VPCMPEQDrr : X86::PCMPEQDrr)); | 
| Craig Topper | 72f51c3 | 2012-08-28 07:30:47 +0000 | [diff] [blame] | 5813 | case X86::AVX2_SETALLONES: | 
| Jakob Stoklund Olesen | b159b5f | 2012-12-19 21:31:56 +0000 | [diff] [blame] | 5814 | return Expand2AddrUndef(MIB, get(X86::VPCMPEQDYrr)); | 
| Craig Topper | 516e14c | 2016-07-11 05:36:48 +0000 | [diff] [blame] | 5815 | case X86::AVX512_512_SETALLONES: { | 
|  | 5816 | unsigned Reg = MIB->getOperand(0).getReg(); | 
|  | 5817 | MIB->setDesc(get(X86::VPTERNLOGDZrri)); | 
|  | 5818 | // VPTERNLOGD needs 3 register inputs and an immediate. | 
|  | 5819 | // 0xff will return 1s for any input. | 
|  | 5820 | MIB.addReg(Reg, RegState::Undef).addReg(Reg, RegState::Undef) | 
|  | 5821 | .addReg(Reg, RegState::Undef).addImm(0xff); | 
|  | 5822 | return true; | 
|  | 5823 | } | 
| Jakob Stoklund Olesen | 729abd3 | 2011-10-08 18:28:28 +0000 | [diff] [blame] | 5824 | case X86::TEST8ri_NOREX: | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5825 | MI.setDesc(get(X86::TEST8ri)); | 
| Jakob Stoklund Olesen | 729abd3 | 2011-10-08 18:28:28 +0000 | [diff] [blame] | 5826 | return true; | 
| Craig Topper | e00bffb | 2016-01-05 07:44:14 +0000 | [diff] [blame] | 5827 | case X86::MOV32ri64: | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5828 | MI.setDesc(get(X86::MOV32ri)); | 
| Craig Topper | e00bffb | 2016-01-05 07:44:14 +0000 | [diff] [blame] | 5829 | return true; | 
|  | 5830 |  | 
| Elena Demikhovsky | 9e225a2 | 2015-12-24 08:12:22 +0000 | [diff] [blame] | 5831 | // KNL does not recognize dependency-breaking idioms for mask registers, | 
|  | 5832 | // so kxnor %k1, %k1, %k2 has a RAW dependence on %k1. | 
|  | 5833 | // Using %k0 as the undef input register is a performance heuristic based | 
|  | 5834 | // on the assumption that %k0 is used less frequently than the other mask | 
|  | 5835 | // registers, since it is not usable as a write mask. | 
|  | 5836 | // FIXME: A more advanced approach would be to choose the best input mask | 
|  | 5837 | // register based on context. | 
| Michael Liao | 5bf9578 | 2014-12-04 05:20:33 +0000 | [diff] [blame] | 5838 | case X86::KSET0B: | 
| Elena Demikhovsky | 9e225a2 | 2015-12-24 08:12:22 +0000 | [diff] [blame] | 5839 | case X86::KSET0W: return Expand2AddrKreg(MIB, get(X86::KXORWrr), X86::K0); | 
|  | 5840 | case X86::KSET0D: return Expand2AddrKreg(MIB, get(X86::KXORDrr), X86::K0); | 
|  | 5841 | case X86::KSET0Q: return Expand2AddrKreg(MIB, get(X86::KXORQrr), X86::K0); | 
| Elena Demikhovsky | f8f478b | 2013-08-25 12:54:30 +0000 | [diff] [blame] | 5842 | case X86::KSET1B: | 
| Elena Demikhovsky | 9e225a2 | 2015-12-24 08:12:22 +0000 | [diff] [blame] | 5843 | case X86::KSET1W: return Expand2AddrKreg(MIB, get(X86::KXNORWrr), X86::K0); | 
|  | 5844 | case X86::KSET1D: return Expand2AddrKreg(MIB, get(X86::KXNORDrr), X86::K0); | 
|  | 5845 | case X86::KSET1Q: return Expand2AddrKreg(MIB, get(X86::KXNORQrr), X86::K0); | 
| Akira Hatanaka | e5b6e0d | 2014-07-25 19:31:34 +0000 | [diff] [blame] | 5846 | case TargetOpcode::LOAD_STACK_GUARD: | 
|  | 5847 | expandLoadStackGuard(MIB, *this); | 
|  | 5848 | return true; | 
| Jakob Stoklund Olesen | dd1904e | 2011-09-29 05:10:54 +0000 | [diff] [blame] | 5849 | } | 
|  | 5850 | return false; | 
|  | 5851 | } | 
|  | 5852 |  | 
| Simon Pilgrim | 7e6606f | 2015-11-04 20:48:09 +0000 | [diff] [blame] | 5853 | static void addOperands(MachineInstrBuilder &MIB, ArrayRef<MachineOperand> MOs, | 
|  | 5854 | int PtrOffset = 0) { | 
| Keno Fischer | e70b31f | 2015-06-08 20:09:58 +0000 | [diff] [blame] | 5855 | unsigned NumAddrOps = MOs.size(); | 
| Simon Pilgrim | 7e6606f | 2015-11-04 20:48:09 +0000 | [diff] [blame] | 5856 |  | 
|  | 5857 | if (NumAddrOps < 4) { | 
|  | 5858 | // FrameIndex only - add an immediate offset (whether its zero or not). | 
|  | 5859 | for (unsigned i = 0; i != NumAddrOps; ++i) | 
|  | 5860 | MIB.addOperand(MOs[i]); | 
|  | 5861 | addOffset(MIB, PtrOffset); | 
|  | 5862 | } else { | 
|  | 5863 | // General Memory Addressing - we need to add any offset to an existing | 
|  | 5864 | // offset. | 
|  | 5865 | assert(MOs.size() == 5 && "Unexpected memory operand list length"); | 
|  | 5866 | for (unsigned i = 0; i != NumAddrOps; ++i) { | 
|  | 5867 | const MachineOperand &MO = MOs[i]; | 
|  | 5868 | if (i == 3 && PtrOffset != 0) { | 
| Simon Pilgrim | ae0140d | 2015-11-19 21:50:57 +0000 | [diff] [blame] | 5869 | MIB.addDisp(MO, PtrOffset); | 
| Simon Pilgrim | 7e6606f | 2015-11-04 20:48:09 +0000 | [diff] [blame] | 5870 | } else { | 
|  | 5871 | MIB.addOperand(MO); | 
|  | 5872 | } | 
|  | 5873 | } | 
|  | 5874 | } | 
| Keno Fischer | e70b31f | 2015-06-08 20:09:58 +0000 | [diff] [blame] | 5875 | } | 
|  | 5876 |  | 
| Dan Gohman | 3b46030 | 2008-07-07 23:14:23 +0000 | [diff] [blame] | 5877 | static MachineInstr *FuseTwoAddrInst(MachineFunction &MF, unsigned Opcode, | 
| Benjamin Kramer | f1362f6 | 2015-02-28 12:04:00 +0000 | [diff] [blame] | 5878 | ArrayRef<MachineOperand> MOs, | 
| Keno Fischer | e70b31f | 2015-06-08 20:09:58 +0000 | [diff] [blame] | 5879 | MachineBasicBlock::iterator InsertPt, | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5880 | MachineInstr &MI, | 
| Bill Wendling | e3c7836 | 2009-02-03 00:55:04 +0000 | [diff] [blame] | 5881 | const TargetInstrInfo &TII) { | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 5882 | // Create the base instruction with the memory operand as the first part. | 
| Jakob Stoklund Olesen | b159b5f | 2012-12-19 21:31:56 +0000 | [diff] [blame] | 5883 | // Omit the implicit operands, something BuildMI can't do. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5884 | MachineInstr *NewMI = | 
|  | 5885 | MF.CreateMachineInstr(TII.get(Opcode), MI.getDebugLoc(), true); | 
| Jakob Stoklund Olesen | b159b5f | 2012-12-19 21:31:56 +0000 | [diff] [blame] | 5886 | MachineInstrBuilder MIB(MF, NewMI); | 
| Keno Fischer | e70b31f | 2015-06-08 20:09:58 +0000 | [diff] [blame] | 5887 | addOperands(MIB, MOs); | 
| NAKAMURA Takumi | 9d29eff | 2011-01-26 02:03:37 +0000 | [diff] [blame] | 5888 |  | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 5889 | // Loop over the rest of the ri operands, converting them over. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5890 | unsigned NumOps = MI.getDesc().getNumOperands() - 2; | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 5891 | for (unsigned i = 0; i != NumOps; ++i) { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5892 | MachineOperand &MO = MI.getOperand(i + 2); | 
| Dan Gohman | 2af1f85 | 2009-02-18 05:45:50 +0000 | [diff] [blame] | 5893 | MIB.addOperand(MO); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 5894 | } | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5895 | for (unsigned i = NumOps + 2, e = MI.getNumOperands(); i != e; ++i) { | 
|  | 5896 | MachineOperand &MO = MI.getOperand(i); | 
| Dan Gohman | 2af1f85 | 2009-02-18 05:45:50 +0000 | [diff] [blame] | 5897 | MIB.addOperand(MO); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 5898 | } | 
| Keno Fischer | e70b31f | 2015-06-08 20:09:58 +0000 | [diff] [blame] | 5899 |  | 
|  | 5900 | MachineBasicBlock *MBB = InsertPt->getParent(); | 
|  | 5901 | MBB->insert(InsertPt, NewMI); | 
|  | 5902 |  | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 5903 | return MIB; | 
|  | 5904 | } | 
|  | 5905 |  | 
| Benjamin Kramer | f1362f6 | 2015-02-28 12:04:00 +0000 | [diff] [blame] | 5906 | static MachineInstr *FuseInst(MachineFunction &MF, unsigned Opcode, | 
|  | 5907 | unsigned OpNo, ArrayRef<MachineOperand> MOs, | 
| Keno Fischer | e70b31f | 2015-06-08 20:09:58 +0000 | [diff] [blame] | 5908 | MachineBasicBlock::iterator InsertPt, | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5909 | MachineInstr &MI, const TargetInstrInfo &TII, | 
| Simon Pilgrim | 7e6606f | 2015-11-04 20:48:09 +0000 | [diff] [blame] | 5910 | int PtrOffset = 0) { | 
| Jakob Stoklund Olesen | b159b5f | 2012-12-19 21:31:56 +0000 | [diff] [blame] | 5911 | // Omit the implicit operands, something BuildMI can't do. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5912 | MachineInstr *NewMI = | 
|  | 5913 | MF.CreateMachineInstr(TII.get(Opcode), MI.getDebugLoc(), true); | 
| Jakob Stoklund Olesen | b159b5f | 2012-12-19 21:31:56 +0000 | [diff] [blame] | 5914 | MachineInstrBuilder MIB(MF, NewMI); | 
| NAKAMURA Takumi | 9d29eff | 2011-01-26 02:03:37 +0000 | [diff] [blame] | 5915 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5916 | for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { | 
|  | 5917 | MachineOperand &MO = MI.getOperand(i); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 5918 | if (i == OpNo) { | 
| Dan Gohman | 0d1e9a8 | 2008-10-03 15:45:36 +0000 | [diff] [blame] | 5919 | assert(MO.isReg() && "Expected to fold into reg operand!"); | 
| Simon Pilgrim | 7e6606f | 2015-11-04 20:48:09 +0000 | [diff] [blame] | 5920 | addOperands(MIB, MOs, PtrOffset); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 5921 | } else { | 
| Dan Gohman | 2af1f85 | 2009-02-18 05:45:50 +0000 | [diff] [blame] | 5922 | MIB.addOperand(MO); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 5923 | } | 
|  | 5924 | } | 
| Keno Fischer | e70b31f | 2015-06-08 20:09:58 +0000 | [diff] [blame] | 5925 |  | 
|  | 5926 | MachineBasicBlock *MBB = InsertPt->getParent(); | 
|  | 5927 | MBB->insert(InsertPt, NewMI); | 
|  | 5928 |  | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 5929 | return MIB; | 
|  | 5930 | } | 
|  | 5931 |  | 
|  | 5932 | static MachineInstr *MakeM0Inst(const TargetInstrInfo &TII, unsigned Opcode, | 
| Benjamin Kramer | f1362f6 | 2015-02-28 12:04:00 +0000 | [diff] [blame] | 5933 | ArrayRef<MachineOperand> MOs, | 
| Keno Fischer | e70b31f | 2015-06-08 20:09:58 +0000 | [diff] [blame] | 5934 | MachineBasicBlock::iterator InsertPt, | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5935 | MachineInstr &MI) { | 
| Keno Fischer | e70b31f | 2015-06-08 20:09:58 +0000 | [diff] [blame] | 5936 | MachineInstrBuilder MIB = BuildMI(*InsertPt->getParent(), InsertPt, | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5937 | MI.getDebugLoc(), TII.get(Opcode)); | 
| Keno Fischer | e70b31f | 2015-06-08 20:09:58 +0000 | [diff] [blame] | 5938 | addOperands(MIB, MOs); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 5939 | return MIB.addImm(0); | 
|  | 5940 | } | 
|  | 5941 |  | 
| Simon Pilgrim | 7e6606f | 2015-11-04 20:48:09 +0000 | [diff] [blame] | 5942 | MachineInstr *X86InstrInfo::foldMemoryOperandCustom( | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5943 | MachineFunction &MF, MachineInstr &MI, unsigned OpNum, | 
| Simon Pilgrim | 7e6606f | 2015-11-04 20:48:09 +0000 | [diff] [blame] | 5944 | ArrayRef<MachineOperand> MOs, MachineBasicBlock::iterator InsertPt, | 
|  | 5945 | unsigned Size, unsigned Align) const { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5946 | switch (MI.getOpcode()) { | 
| Simon Pilgrim | 7e6606f | 2015-11-04 20:48:09 +0000 | [diff] [blame] | 5947 | case X86::INSERTPSrr: | 
|  | 5948 | case X86::VINSERTPSrr: | 
| Craig Topper | ab13b33 | 2016-07-22 05:00:35 +0000 | [diff] [blame] | 5949 | case X86::VINSERTPSZrr: | 
| Simon Pilgrim | 7e6606f | 2015-11-04 20:48:09 +0000 | [diff] [blame] | 5950 | // Attempt to convert the load of inserted vector into a fold load | 
|  | 5951 | // of a single float. | 
|  | 5952 | if (OpNum == 2) { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5953 | unsigned Imm = MI.getOperand(MI.getNumOperands() - 1).getImm(); | 
| Simon Pilgrim | 7e6606f | 2015-11-04 20:48:09 +0000 | [diff] [blame] | 5954 | unsigned ZMask = Imm & 15; | 
|  | 5955 | unsigned DstIdx = (Imm >> 4) & 3; | 
|  | 5956 | unsigned SrcIdx = (Imm >> 6) & 3; | 
|  | 5957 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5958 | unsigned RCSize = getRegClass(MI.getDesc(), OpNum, &RI, MF)->getSize(); | 
| Simon Pilgrim | 7e6606f | 2015-11-04 20:48:09 +0000 | [diff] [blame] | 5959 | if (Size <= RCSize && 4 <= Align) { | 
|  | 5960 | int PtrOffset = SrcIdx * 4; | 
|  | 5961 | unsigned NewImm = (DstIdx << 4) | ZMask; | 
|  | 5962 | unsigned NewOpCode = | 
| Craig Topper | ab13b33 | 2016-07-22 05:00:35 +0000 | [diff] [blame] | 5963 | (MI.getOpcode() == X86::VINSERTPSZrr) ? X86::VINSERTPSZrm : | 
|  | 5964 | (MI.getOpcode() == X86::VINSERTPSrr)  ? X86::VINSERTPSrm  : | 
|  | 5965 | X86::INSERTPSrm; | 
| Simon Pilgrim | 7e6606f | 2015-11-04 20:48:09 +0000 | [diff] [blame] | 5966 | MachineInstr *NewMI = | 
|  | 5967 | FuseInst(MF, NewOpCode, OpNum, MOs, InsertPt, MI, *this, PtrOffset); | 
|  | 5968 | NewMI->getOperand(NewMI->getNumOperands() - 1).setImm(NewImm); | 
|  | 5969 | return NewMI; | 
|  | 5970 | } | 
|  | 5971 | } | 
|  | 5972 | break; | 
| Simon Pilgrim | a207436 | 2016-02-08 23:03:46 +0000 | [diff] [blame] | 5973 | case X86::MOVHLPSrr: | 
|  | 5974 | case X86::VMOVHLPSrr: | 
| Craig Topper | ab13b33 | 2016-07-22 05:00:35 +0000 | [diff] [blame] | 5975 | case X86::VMOVHLPSZrr: | 
| Simon Pilgrim | a207436 | 2016-02-08 23:03:46 +0000 | [diff] [blame] | 5976 | // Move the upper 64-bits of the second operand to the lower 64-bits. | 
|  | 5977 | // To fold the load, adjust the pointer to the upper and use (V)MOVLPS. | 
|  | 5978 | // TODO: In most cases AVX doesn't have a 8-byte alignment requirement. | 
|  | 5979 | if (OpNum == 2) { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5980 | unsigned RCSize = getRegClass(MI.getDesc(), OpNum, &RI, MF)->getSize(); | 
| Simon Pilgrim | a207436 | 2016-02-08 23:03:46 +0000 | [diff] [blame] | 5981 | if (Size <= RCSize && 8 <= Align) { | 
|  | 5982 | unsigned NewOpCode = | 
| Craig Topper | ab13b33 | 2016-07-22 05:00:35 +0000 | [diff] [blame] | 5983 | (MI.getOpcode() == X86::VMOVHLPSZrr) ? X86::VMOVLPSZ128rm : | 
|  | 5984 | (MI.getOpcode() == X86::VMOVHLPSrr)  ? X86::VMOVLPSrm     : | 
|  | 5985 | X86::MOVLPSrm; | 
| Simon Pilgrim | a207436 | 2016-02-08 23:03:46 +0000 | [diff] [blame] | 5986 | MachineInstr *NewMI = | 
|  | 5987 | FuseInst(MF, NewOpCode, OpNum, MOs, InsertPt, MI, *this, 8); | 
|  | 5988 | return NewMI; | 
|  | 5989 | } | 
|  | 5990 | } | 
|  | 5991 | break; | 
| Simon Pilgrim | 7e6606f | 2015-11-04 20:48:09 +0000 | [diff] [blame] | 5992 | }; | 
|  | 5993 |  | 
|  | 5994 | return nullptr; | 
|  | 5995 | } | 
|  | 5996 |  | 
| Keno Fischer | e70b31f | 2015-06-08 20:09:58 +0000 | [diff] [blame] | 5997 | MachineInstr *X86InstrInfo::foldMemoryOperandImpl( | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 5998 | MachineFunction &MF, MachineInstr &MI, unsigned OpNum, | 
| Keno Fischer | e70b31f | 2015-06-08 20:09:58 +0000 | [diff] [blame] | 5999 | ArrayRef<MachineOperand> MOs, MachineBasicBlock::iterator InsertPt, | 
|  | 6000 | unsigned Size, unsigned Align, bool AllowCommute) const { | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6001 | const DenseMap<unsigned, | 
| Craig Topper | e012ede | 2016-04-30 17:59:49 +0000 | [diff] [blame] | 6002 | std::pair<uint16_t, uint16_t> > *OpcodeTablePtr = nullptr; | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 6003 | bool isCallRegIndirect = Subtarget.callRegIndirect(); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6004 | bool isTwoAddrFold = false; | 
| Preston Gurd | d6be4bf | 2013-03-27 23:16:18 +0000 | [diff] [blame] | 6005 |  | 
| Michael Kuperstein | 454d145 | 2015-07-23 12:23:45 +0000 | [diff] [blame] | 6006 | // For CPUs that favor the register form of a call or push, | 
|  | 6007 | // do not fold loads into calls or pushes, unless optimizing for size | 
|  | 6008 | // aggressively. | 
| Sanjay Patel | 924879a | 2015-08-04 15:49:57 +0000 | [diff] [blame] | 6009 | if (isCallRegIndirect && !MF.getFunction()->optForMinSize() && | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6010 | (MI.getOpcode() == X86::CALL32r || MI.getOpcode() == X86::CALL64r || | 
|  | 6011 | MI.getOpcode() == X86::PUSH16r || MI.getOpcode() == X86::PUSH32r || | 
|  | 6012 | MI.getOpcode() == X86::PUSH64r)) | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6013 | return nullptr; | 
| Preston Gurd | d6be4bf | 2013-03-27 23:16:18 +0000 | [diff] [blame] | 6014 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6015 | unsigned NumOps = MI.getDesc().getNumOperands(); | 
|  | 6016 | bool isTwoAddr = | 
|  | 6017 | NumOps > 1 && MI.getDesc().getOperandConstraint(1, MCOI::TIED_TO) != -1; | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6018 |  | 
| Jakob Stoklund Olesen | 2348cdd | 2011-04-30 23:00:05 +0000 | [diff] [blame] | 6019 | // FIXME: AsmPrinter doesn't know how to handle | 
|  | 6020 | // X86II::MO_GOT_ABSOLUTE_ADDRESS after folding. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6021 | if (MI.getOpcode() == X86::ADD32ri && | 
|  | 6022 | MI.getOperand(2).getTargetFlags() == X86II::MO_GOT_ABSOLUTE_ADDRESS) | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6023 | return nullptr; | 
| Jakob Stoklund Olesen | 2348cdd | 2011-04-30 23:00:05 +0000 | [diff] [blame] | 6024 |  | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6025 | MachineInstr *NewMI = nullptr; | 
| Simon Pilgrim | 7e6606f | 2015-11-04 20:48:09 +0000 | [diff] [blame] | 6026 |  | 
|  | 6027 | // Attempt to fold any custom cases we have. | 
| Simon Pilgrim | f669d38 | 2015-11-04 21:27:22 +0000 | [diff] [blame] | 6028 | if (MachineInstr *CustomMI = | 
| Simon Pilgrim | 7e6606f | 2015-11-04 20:48:09 +0000 | [diff] [blame] | 6029 | foldMemoryOperandCustom(MF, MI, OpNum, MOs, InsertPt, Size, Align)) | 
| Simon Pilgrim | f669d38 | 2015-11-04 21:27:22 +0000 | [diff] [blame] | 6030 | return CustomMI; | 
| Simon Pilgrim | 7e6606f | 2015-11-04 20:48:09 +0000 | [diff] [blame] | 6031 |  | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6032 | // Folding a memory location into the two-address part of a two-address | 
|  | 6033 | // instruction is different than folding it other places.  It requires | 
|  | 6034 | // replacing the *two* registers with the memory location. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6035 | if (isTwoAddr && NumOps >= 2 && OpNum < 2 && MI.getOperand(0).isReg() && | 
|  | 6036 | MI.getOperand(1).isReg() && | 
|  | 6037 | MI.getOperand(0).getReg() == MI.getOperand(1).getReg()) { | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6038 | OpcodeTablePtr = &RegOp2MemOpTable2Addr; | 
|  | 6039 | isTwoAddrFold = true; | 
| Sanjay Patel | a7b893d | 2015-02-09 16:30:58 +0000 | [diff] [blame] | 6040 | } else if (OpNum == 0) { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6041 | if (MI.getOpcode() == X86::MOV32r0) { | 
| Keno Fischer | e70b31f | 2015-06-08 20:09:58 +0000 | [diff] [blame] | 6042 | NewMI = MakeM0Inst(*this, X86::MOV32mi, MOs, InsertPt, MI); | 
| Tim Northover | 64ec0ff | 2013-05-30 13:19:42 +0000 | [diff] [blame] | 6043 | if (NewMI) | 
|  | 6044 | return NewMI; | 
| Craig Topper | f911597 | 2012-08-23 04:57:36 +0000 | [diff] [blame] | 6045 | } | 
| NAKAMURA Takumi | 9d29eff | 2011-01-26 02:03:37 +0000 | [diff] [blame] | 6046 |  | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6047 | OpcodeTablePtr = &RegOp2MemOpTable0; | 
| Sanjay Patel | a7b893d | 2015-02-09 16:30:58 +0000 | [diff] [blame] | 6048 | } else if (OpNum == 1) { | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6049 | OpcodeTablePtr = &RegOp2MemOpTable1; | 
| Sanjay Patel | a7b893d | 2015-02-09 16:30:58 +0000 | [diff] [blame] | 6050 | } else if (OpNum == 2) { | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6051 | OpcodeTablePtr = &RegOp2MemOpTable2; | 
| Sanjay Patel | a7b893d | 2015-02-09 16:30:58 +0000 | [diff] [blame] | 6052 | } else if (OpNum == 3) { | 
| Elena Demikhovsky | 3cb3b00 | 2012-08-01 12:06:00 +0000 | [diff] [blame] | 6053 | OpcodeTablePtr = &RegOp2MemOpTable3; | 
| Sanjay Patel | a7b893d | 2015-02-09 16:30:58 +0000 | [diff] [blame] | 6054 | } else if (OpNum == 4) { | 
| Robert Khasanov | 79fb729 | 2014-12-18 12:28:22 +0000 | [diff] [blame] | 6055 | OpcodeTablePtr = &RegOp2MemOpTable4; | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6056 | } | 
| NAKAMURA Takumi | 9d29eff | 2011-01-26 02:03:37 +0000 | [diff] [blame] | 6057 |  | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6058 | // If table selected... | 
|  | 6059 | if (OpcodeTablePtr) { | 
|  | 6060 | // Find the Opcode to fuse | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6061 | auto I = OpcodeTablePtr->find(MI.getOpcode()); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6062 | if (I != OpcodeTablePtr->end()) { | 
| Evan Cheng | 3cad628 | 2009-09-11 00:39:26 +0000 | [diff] [blame] | 6063 | unsigned Opcode = I->second.first; | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 6064 | unsigned MinAlign = (I->second.second & TB_ALIGN_MASK) >> TB_ALIGN_SHIFT; | 
| Evan Cheng | 9e0c7f2 | 2009-07-15 06:10:07 +0000 | [diff] [blame] | 6065 | if (Align < MinAlign) | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6066 | return nullptr; | 
| Evan Cheng | 74a3231 | 2009-09-11 01:01:31 +0000 | [diff] [blame] | 6067 | bool NarrowToMOV32rm = false; | 
| Evan Cheng | 3cad628 | 2009-09-11 00:39:26 +0000 | [diff] [blame] | 6068 | if (Size) { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6069 | unsigned RCSize = getRegClass(MI.getDesc(), OpNum, &RI, MF)->getSize(); | 
| Evan Cheng | 3cad628 | 2009-09-11 00:39:26 +0000 | [diff] [blame] | 6070 | if (Size < RCSize) { | 
|  | 6071 | // Check if it's safe to fold the load. If the size of the object is | 
|  | 6072 | // narrower than the load width, then it's not. | 
|  | 6073 | if (Opcode != X86::MOV64rm || RCSize != 8 || Size != 4) | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6074 | return nullptr; | 
| Evan Cheng | 3cad628 | 2009-09-11 00:39:26 +0000 | [diff] [blame] | 6075 | // If this is a 64-bit load, but the spill slot is 32, then we can do | 
| Simon Pilgrim | 2f9548a | 2014-10-20 22:14:22 +0000 | [diff] [blame] | 6076 | // a 32-bit load which is implicitly zero-extended. This likely is | 
|  | 6077 | // due to live interval analysis remat'ing a load from stack slot. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6078 | if (MI.getOperand(0).getSubReg() || MI.getOperand(1).getSubReg()) | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6079 | return nullptr; | 
| Evan Cheng | 3cad628 | 2009-09-11 00:39:26 +0000 | [diff] [blame] | 6080 | Opcode = X86::MOV32rm; | 
| Evan Cheng | 74a3231 | 2009-09-11 01:01:31 +0000 | [diff] [blame] | 6081 | NarrowToMOV32rm = true; | 
| Evan Cheng | 3cad628 | 2009-09-11 00:39:26 +0000 | [diff] [blame] | 6082 | } | 
|  | 6083 | } | 
|  | 6084 |  | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6085 | if (isTwoAddrFold) | 
| Keno Fischer | e70b31f | 2015-06-08 20:09:58 +0000 | [diff] [blame] | 6086 | NewMI = FuseTwoAddrInst(MF, Opcode, MOs, InsertPt, MI, *this); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6087 | else | 
| Keno Fischer | e70b31f | 2015-06-08 20:09:58 +0000 | [diff] [blame] | 6088 | NewMI = FuseInst(MF, Opcode, OpNum, MOs, InsertPt, MI, *this); | 
| Evan Cheng | 74a3231 | 2009-09-11 01:01:31 +0000 | [diff] [blame] | 6089 |  | 
|  | 6090 | if (NarrowToMOV32rm) { | 
|  | 6091 | // If this is the special case where we use a MOV32rm to load a 32-bit | 
|  | 6092 | // value and zero-extend the top bits. Change the destination register | 
|  | 6093 | // to a 32-bit one. | 
|  | 6094 | unsigned DstReg = NewMI->getOperand(0).getReg(); | 
|  | 6095 | if (TargetRegisterInfo::isPhysicalRegister(DstReg)) | 
| Simon Pilgrim | 2f9548a | 2014-10-20 22:14:22 +0000 | [diff] [blame] | 6096 | NewMI->getOperand(0).setReg(RI.getSubReg(DstReg, X86::sub_32bit)); | 
| Evan Cheng | 74a3231 | 2009-09-11 01:01:31 +0000 | [diff] [blame] | 6097 | else | 
| Jakob Stoklund Olesen | 9340ea5 | 2010-05-24 14:48:17 +0000 | [diff] [blame] | 6098 | NewMI->getOperand(0).setSubReg(X86::sub_32bit); | 
| Evan Cheng | 74a3231 | 2009-09-11 01:01:31 +0000 | [diff] [blame] | 6099 | } | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6100 | return NewMI; | 
|  | 6101 | } | 
|  | 6102 | } | 
| NAKAMURA Takumi | 9d29eff | 2011-01-26 02:03:37 +0000 | [diff] [blame] | 6103 |  | 
| Simon Pilgrim | 2f9548a | 2014-10-20 22:14:22 +0000 | [diff] [blame] | 6104 | // If the instruction and target operand are commutable, commute the | 
|  | 6105 | // instruction and try again. | 
|  | 6106 | if (AllowCommute) { | 
| Andrew Kaylor | 16c4da0 | 2015-09-28 20:33:22 +0000 | [diff] [blame] | 6107 | unsigned CommuteOpIdx1 = OpNum, CommuteOpIdx2 = CommuteAnyOperandIndex; | 
| Simon Pilgrim | 2f9548a | 2014-10-20 22:14:22 +0000 | [diff] [blame] | 6108 | if (findCommutedOpIndices(MI, CommuteOpIdx1, CommuteOpIdx2)) { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6109 | bool HasDef = MI.getDesc().getNumDefs(); | 
|  | 6110 | unsigned Reg0 = HasDef ? MI.getOperand(0).getReg() : 0; | 
|  | 6111 | unsigned Reg1 = MI.getOperand(CommuteOpIdx1).getReg(); | 
|  | 6112 | unsigned Reg2 = MI.getOperand(CommuteOpIdx2).getReg(); | 
| Simon Pilgrim | 2f9548a | 2014-10-20 22:14:22 +0000 | [diff] [blame] | 6113 | bool Tied1 = | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6114 | 0 == MI.getDesc().getOperandConstraint(CommuteOpIdx1, MCOI::TIED_TO); | 
| Andrew Kaylor | 16c4da0 | 2015-09-28 20:33:22 +0000 | [diff] [blame] | 6115 | bool Tied2 = | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6116 | 0 == MI.getDesc().getOperandConstraint(CommuteOpIdx2, MCOI::TIED_TO); | 
| Simon Pilgrim | 2f9548a | 2014-10-20 22:14:22 +0000 | [diff] [blame] | 6117 |  | 
|  | 6118 | // If either of the commutable operands are tied to the destination | 
|  | 6119 | // then we can not commute + fold. | 
| Andrew Kaylor | 16c4da0 | 2015-09-28 20:33:22 +0000 | [diff] [blame] | 6120 | if ((HasDef && Reg0 == Reg1 && Tied1) || | 
|  | 6121 | (HasDef && Reg0 == Reg2 && Tied2)) | 
| Simon Pilgrim | 2f9548a | 2014-10-20 22:14:22 +0000 | [diff] [blame] | 6122 | return nullptr; | 
|  | 6123 |  | 
| Andrew Kaylor | 16c4da0 | 2015-09-28 20:33:22 +0000 | [diff] [blame] | 6124 | MachineInstr *CommutedMI = | 
|  | 6125 | commuteInstruction(MI, false, CommuteOpIdx1, CommuteOpIdx2); | 
|  | 6126 | if (!CommutedMI) { | 
|  | 6127 | // Unable to commute. | 
| Simon Pilgrim | 2f9548a | 2014-10-20 22:14:22 +0000 | [diff] [blame] | 6128 | return nullptr; | 
|  | 6129 | } | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6130 | if (CommutedMI != &MI) { | 
| Andrew Kaylor | 16c4da0 | 2015-09-28 20:33:22 +0000 | [diff] [blame] | 6131 | // New instruction. We can't fold from this. | 
|  | 6132 | CommutedMI->eraseFromParent(); | 
|  | 6133 | return nullptr; | 
|  | 6134 | } | 
|  | 6135 |  | 
|  | 6136 | // Attempt to fold with the commuted version of the instruction. | 
|  | 6137 | NewMI = foldMemoryOperandImpl(MF, MI, CommuteOpIdx2, MOs, InsertPt, | 
|  | 6138 | Size, Align, /*AllowCommute=*/false); | 
|  | 6139 | if (NewMI) | 
|  | 6140 | return NewMI; | 
|  | 6141 |  | 
|  | 6142 | // Folding failed again - undo the commute before returning. | 
|  | 6143 | MachineInstr *UncommutedMI = | 
|  | 6144 | commuteInstruction(MI, false, CommuteOpIdx1, CommuteOpIdx2); | 
|  | 6145 | if (!UncommutedMI) { | 
|  | 6146 | // Unable to commute. | 
|  | 6147 | return nullptr; | 
|  | 6148 | } | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6149 | if (UncommutedMI != &MI) { | 
| Andrew Kaylor | 16c4da0 | 2015-09-28 20:33:22 +0000 | [diff] [blame] | 6150 | // New instruction. It doesn't need to be kept. | 
|  | 6151 | UncommutedMI->eraseFromParent(); | 
|  | 6152 | return nullptr; | 
|  | 6153 | } | 
|  | 6154 |  | 
|  | 6155 | // Return here to prevent duplicate fuse failure report. | 
|  | 6156 | return nullptr; | 
| Simon Pilgrim | 2f9548a | 2014-10-20 22:14:22 +0000 | [diff] [blame] | 6157 | } | 
|  | 6158 | } | 
|  | 6159 |  | 
| NAKAMURA Takumi | 9d29eff | 2011-01-26 02:03:37 +0000 | [diff] [blame] | 6160 | // No fusion | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6161 | if (PrintFailedFusing && !MI.isCopy()) | 
|  | 6162 | dbgs() << "We failed to fuse operand " << OpNum << " in " << MI; | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6163 | return nullptr; | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6164 | } | 
|  | 6165 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 6166 | /// Return true for all instructions that only update | 
| Bruno Cardoso Lopes | 6b30295 | 2011-09-15 21:42:23 +0000 | [diff] [blame] | 6167 | /// the first 32 or 64-bits of the destination register and leave the rest | 
|  | 6168 | /// unmodified. This can be used to avoid folding loads if the instructions | 
|  | 6169 | /// only update part of the destination register, and the non-updated part is | 
|  | 6170 | /// not needed. e.g. cvtss2sd, sqrtss. Unfolding the load from these | 
|  | 6171 | /// instructions breaks the partial register dependency and it can improve | 
|  | 6172 | /// performance. e.g.: | 
|  | 6173 | /// | 
|  | 6174 | ///   movss (%rdi), %xmm0 | 
|  | 6175 | ///   cvtss2sd %xmm0, %xmm0 | 
|  | 6176 | /// | 
|  | 6177 | /// Instead of | 
|  | 6178 | ///   cvtss2sd (%rdi), %xmm0 | 
|  | 6179 | /// | 
| Bruno Cardoso Lopes | 7b43568 | 2011-09-15 23:04:24 +0000 | [diff] [blame] | 6180 | /// FIXME: This should be turned into a TSFlags. | 
|  | 6181 | /// | 
| Bruno Cardoso Lopes | 6b30295 | 2011-09-15 21:42:23 +0000 | [diff] [blame] | 6182 | static bool hasPartialRegUpdate(unsigned Opcode) { | 
|  | 6183 | switch (Opcode) { | 
| Jakob Stoklund Olesen | f8ad336 | 2011-11-15 01:15:30 +0000 | [diff] [blame] | 6184 | case X86::CVTSI2SSrr: | 
| Michael Kuperstein | 47c9715 | 2014-12-15 13:18:21 +0000 | [diff] [blame] | 6185 | case X86::CVTSI2SSrm: | 
| Jakob Stoklund Olesen | f8ad336 | 2011-11-15 01:15:30 +0000 | [diff] [blame] | 6186 | case X86::CVTSI2SS64rr: | 
| Michael Kuperstein | 47c9715 | 2014-12-15 13:18:21 +0000 | [diff] [blame] | 6187 | case X86::CVTSI2SS64rm: | 
| Jakob Stoklund Olesen | f8ad336 | 2011-11-15 01:15:30 +0000 | [diff] [blame] | 6188 | case X86::CVTSI2SDrr: | 
| Michael Kuperstein | 47c9715 | 2014-12-15 13:18:21 +0000 | [diff] [blame] | 6189 | case X86::CVTSI2SDrm: | 
| Jakob Stoklund Olesen | f8ad336 | 2011-11-15 01:15:30 +0000 | [diff] [blame] | 6190 | case X86::CVTSI2SD64rr: | 
| Michael Kuperstein | 47c9715 | 2014-12-15 13:18:21 +0000 | [diff] [blame] | 6191 | case X86::CVTSI2SD64rm: | 
| Bruno Cardoso Lopes | 6b30295 | 2011-09-15 21:42:23 +0000 | [diff] [blame] | 6192 | case X86::CVTSD2SSrr: | 
| Michael Kuperstein | 47c9715 | 2014-12-15 13:18:21 +0000 | [diff] [blame] | 6193 | case X86::CVTSD2SSrm: | 
| Bruno Cardoso Lopes | 6b30295 | 2011-09-15 21:42:23 +0000 | [diff] [blame] | 6194 | case X86::Int_CVTSD2SSrr: | 
| Michael Kuperstein | 47c9715 | 2014-12-15 13:18:21 +0000 | [diff] [blame] | 6195 | case X86::Int_CVTSD2SSrm: | 
| Bruno Cardoso Lopes | 6b30295 | 2011-09-15 21:42:23 +0000 | [diff] [blame] | 6196 | case X86::CVTSS2SDrr: | 
| Michael Kuperstein | 47c9715 | 2014-12-15 13:18:21 +0000 | [diff] [blame] | 6197 | case X86::CVTSS2SDrm: | 
| Bruno Cardoso Lopes | 6b30295 | 2011-09-15 21:42:23 +0000 | [diff] [blame] | 6198 | case X86::Int_CVTSS2SDrr: | 
| Michael Kuperstein | 47c9715 | 2014-12-15 13:18:21 +0000 | [diff] [blame] | 6199 | case X86::Int_CVTSS2SDrm: | 
| Simon Pilgrim | a207436 | 2016-02-08 23:03:46 +0000 | [diff] [blame] | 6200 | case X86::MOVHPDrm: | 
|  | 6201 | case X86::MOVHPSrm: | 
|  | 6202 | case X86::MOVLPDrm: | 
|  | 6203 | case X86::MOVLPSrm: | 
| Bruno Cardoso Lopes | 6b30295 | 2011-09-15 21:42:23 +0000 | [diff] [blame] | 6204 | case X86::RCPSSr: | 
| Michael Kuperstein | 47c9715 | 2014-12-15 13:18:21 +0000 | [diff] [blame] | 6205 | case X86::RCPSSm: | 
| Bruno Cardoso Lopes | 6b30295 | 2011-09-15 21:42:23 +0000 | [diff] [blame] | 6206 | case X86::RCPSSr_Int: | 
| Michael Kuperstein | 47c9715 | 2014-12-15 13:18:21 +0000 | [diff] [blame] | 6207 | case X86::RCPSSm_Int: | 
| Bruno Cardoso Lopes | 6b30295 | 2011-09-15 21:42:23 +0000 | [diff] [blame] | 6208 | case X86::ROUNDSDr: | 
| Michael Kuperstein | 47c9715 | 2014-12-15 13:18:21 +0000 | [diff] [blame] | 6209 | case X86::ROUNDSDm: | 
| Benjamin Kramer | 2dc5dec | 2011-12-09 15:43:55 +0000 | [diff] [blame] | 6210 | case X86::ROUNDSDr_Int: | 
| Bruno Cardoso Lopes | 6b30295 | 2011-09-15 21:42:23 +0000 | [diff] [blame] | 6211 | case X86::ROUNDSSr: | 
| Michael Kuperstein | 47c9715 | 2014-12-15 13:18:21 +0000 | [diff] [blame] | 6212 | case X86::ROUNDSSm: | 
| Benjamin Kramer | 2dc5dec | 2011-12-09 15:43:55 +0000 | [diff] [blame] | 6213 | case X86::ROUNDSSr_Int: | 
| Bruno Cardoso Lopes | 6b30295 | 2011-09-15 21:42:23 +0000 | [diff] [blame] | 6214 | case X86::RSQRTSSr: | 
| Michael Kuperstein | 47c9715 | 2014-12-15 13:18:21 +0000 | [diff] [blame] | 6215 | case X86::RSQRTSSm: | 
| Bruno Cardoso Lopes | 6b30295 | 2011-09-15 21:42:23 +0000 | [diff] [blame] | 6216 | case X86::RSQRTSSr_Int: | 
| Michael Kuperstein | 47c9715 | 2014-12-15 13:18:21 +0000 | [diff] [blame] | 6217 | case X86::RSQRTSSm_Int: | 
| Bruno Cardoso Lopes | 6b30295 | 2011-09-15 21:42:23 +0000 | [diff] [blame] | 6218 | case X86::SQRTSSr: | 
| Michael Kuperstein | 47c9715 | 2014-12-15 13:18:21 +0000 | [diff] [blame] | 6219 | case X86::SQRTSSm: | 
| Bruno Cardoso Lopes | 6b30295 | 2011-09-15 21:42:23 +0000 | [diff] [blame] | 6220 | case X86::SQRTSSr_Int: | 
| Michael Kuperstein | 47c9715 | 2014-12-15 13:18:21 +0000 | [diff] [blame] | 6221 | case X86::SQRTSSm_Int: | 
|  | 6222 | case X86::SQRTSDr: | 
|  | 6223 | case X86::SQRTSDm: | 
|  | 6224 | case X86::SQRTSDr_Int: | 
|  | 6225 | case X86::SQRTSDm_Int: | 
| Bruno Cardoso Lopes | 6b30295 | 2011-09-15 21:42:23 +0000 | [diff] [blame] | 6226 | return true; | 
|  | 6227 | } | 
|  | 6228 |  | 
|  | 6229 | return false; | 
|  | 6230 | } | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6231 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 6232 | /// Inform the ExeDepsFix pass how many idle | 
| Jakob Stoklund Olesen | f8ad336 | 2011-11-15 01:15:30 +0000 | [diff] [blame] | 6233 | /// instructions we would like before a partial register update. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6234 | unsigned X86InstrInfo::getPartialRegUpdateClearance( | 
|  | 6235 | const MachineInstr &MI, unsigned OpNum, | 
|  | 6236 | const TargetRegisterInfo *TRI) const { | 
|  | 6237 | if (OpNum != 0 || !hasPartialRegUpdate(MI.getOpcode())) | 
| Jakob Stoklund Olesen | f8ad336 | 2011-11-15 01:15:30 +0000 | [diff] [blame] | 6238 | return 0; | 
|  | 6239 |  | 
|  | 6240 | // If MI is marked as reading Reg, the partial register update is wanted. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6241 | const MachineOperand &MO = MI.getOperand(0); | 
| Jakob Stoklund Olesen | f8ad336 | 2011-11-15 01:15:30 +0000 | [diff] [blame] | 6242 | unsigned Reg = MO.getReg(); | 
|  | 6243 | if (TargetRegisterInfo::isVirtualRegister(Reg)) { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6244 | if (MO.readsReg() || MI.readsVirtualRegister(Reg)) | 
| Jakob Stoklund Olesen | f8ad336 | 2011-11-15 01:15:30 +0000 | [diff] [blame] | 6245 | return 0; | 
|  | 6246 | } else { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6247 | if (MI.readsRegister(Reg, TRI)) | 
| Jakob Stoklund Olesen | f8ad336 | 2011-11-15 01:15:30 +0000 | [diff] [blame] | 6248 | return 0; | 
|  | 6249 | } | 
|  | 6250 |  | 
| Dehao Chen | 8cd84aa | 2016-06-28 21:19:34 +0000 | [diff] [blame] | 6251 | // If any instructions in the clearance range are reading Reg, insert a | 
|  | 6252 | // dependency breaking instruction, which is inexpensive and is likely to | 
|  | 6253 | // be hidden in other instruction's cycles. | 
|  | 6254 | return PartialRegUpdateClearance; | 
| Jakob Stoklund Olesen | f8ad336 | 2011-11-15 01:15:30 +0000 | [diff] [blame] | 6255 | } | 
|  | 6256 |  | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6257 | // Return true for any instruction the copies the high bits of the first source | 
|  | 6258 | // operand into the unused high bits of the destination operand. | 
|  | 6259 | static bool hasUndefRegUpdate(unsigned Opcode) { | 
|  | 6260 | switch (Opcode) { | 
|  | 6261 | case X86::VCVTSI2SSrr: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6262 | case X86::VCVTSI2SSrm: | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6263 | case X86::Int_VCVTSI2SSrr: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6264 | case X86::Int_VCVTSI2SSrm: | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6265 | case X86::VCVTSI2SS64rr: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6266 | case X86::VCVTSI2SS64rm: | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6267 | case X86::Int_VCVTSI2SS64rr: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6268 | case X86::Int_VCVTSI2SS64rm: | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6269 | case X86::VCVTSI2SDrr: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6270 | case X86::VCVTSI2SDrm: | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6271 | case X86::Int_VCVTSI2SDrr: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6272 | case X86::Int_VCVTSI2SDrm: | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6273 | case X86::VCVTSI2SD64rr: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6274 | case X86::VCVTSI2SD64rm: | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6275 | case X86::Int_VCVTSI2SD64rr: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6276 | case X86::Int_VCVTSI2SD64rm: | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6277 | case X86::VCVTSD2SSrr: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6278 | case X86::VCVTSD2SSrm: | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6279 | case X86::Int_VCVTSD2SSrr: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6280 | case X86::Int_VCVTSD2SSrm: | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6281 | case X86::VCVTSS2SDrr: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6282 | case X86::VCVTSS2SDrm: | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6283 | case X86::Int_VCVTSS2SDrr: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6284 | case X86::Int_VCVTSS2SDrm: | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6285 | case X86::VRCPSSr: | 
| Craig Topper | f5d05fb | 2016-08-06 19:31:44 +0000 | [diff] [blame] | 6286 | case X86::VRCPSSr_Int: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6287 | case X86::VRCPSSm: | 
|  | 6288 | case X86::VRCPSSm_Int: | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6289 | case X86::VROUNDSDr: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6290 | case X86::VROUNDSDm: | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6291 | case X86::VROUNDSDr_Int: | 
|  | 6292 | case X86::VROUNDSSr: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6293 | case X86::VROUNDSSm: | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6294 | case X86::VROUNDSSr_Int: | 
|  | 6295 | case X86::VRSQRTSSr: | 
| Craig Topper | f5d05fb | 2016-08-06 19:31:44 +0000 | [diff] [blame] | 6296 | case X86::VRSQRTSSr_Int: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6297 | case X86::VRSQRTSSm: | 
|  | 6298 | case X86::VRSQRTSSm_Int: | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6299 | case X86::VSQRTSSr: | 
| Craig Topper | f5d05fb | 2016-08-06 19:31:44 +0000 | [diff] [blame] | 6300 | case X86::VSQRTSSr_Int: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6301 | case X86::VSQRTSSm: | 
|  | 6302 | case X86::VSQRTSSm_Int: | 
|  | 6303 | case X86::VSQRTSDr: | 
| Craig Topper | f5d05fb | 2016-08-06 19:31:44 +0000 | [diff] [blame] | 6304 | case X86::VSQRTSDr_Int: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6305 | case X86::VSQRTSDm: | 
|  | 6306 | case X86::VSQRTSDm_Int: | 
| Craig Topper | 19505bc | 2016-08-06 19:31:50 +0000 | [diff] [blame] | 6307 | // AVX-512 | 
|  | 6308 | case X86::VCVTSI2SSZrr: | 
|  | 6309 | case X86::VCVTSI2SSZrm: | 
|  | 6310 | case X86::Int_VCVTSI2SSZrr: | 
|  | 6311 | case X86::Int_VCVTSI2SSZrm: | 
|  | 6312 | case X86::VCVTSI2SSZrr_Int: | 
|  | 6313 | case X86::VCVTSI2SSZrm_Int: | 
|  | 6314 | case X86::VCVTSI642SSZrr: | 
|  | 6315 | case X86::VCVTSI642SSZrm: | 
|  | 6316 | case X86::Int_VCVTSI2SS64Zrr: | 
|  | 6317 | case X86::Int_VCVTSI2SS64Zrm: | 
|  | 6318 | case X86::VCVTSI642SSZrr_Int: | 
|  | 6319 | case X86::VCVTSI642SSZrm_Int: | 
|  | 6320 | case X86::VCVTSI2SDZrr: | 
|  | 6321 | case X86::VCVTSI2SDZrm: | 
|  | 6322 | case X86::Int_VCVTSI2SDZrr: | 
|  | 6323 | case X86::Int_VCVTSI2SDZrm: | 
|  | 6324 | case X86::VCVTSI2SDZrr_Int: | 
|  | 6325 | case X86::VCVTSI2SDZrm_Int: | 
|  | 6326 | case X86::VCVTSI642SDZrr: | 
|  | 6327 | case X86::VCVTSI642SDZrm: | 
|  | 6328 | case X86::Int_VCVTSI2SD64Zrr: | 
|  | 6329 | case X86::Int_VCVTSI2SD64Zrm: | 
|  | 6330 | case X86::VCVTSI642SDZrr_Int: | 
|  | 6331 | case X86::VCVTSI642SDZrm_Int: | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6332 | case X86::VCVTSD2SSZrr: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6333 | case X86::VCVTSD2SSZrm: | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6334 | case X86::VCVTSS2SDZrr: | 
| Michael Kuperstein | 683c3cd | 2014-12-28 13:15:05 +0000 | [diff] [blame] | 6335 | case X86::VCVTSS2SDZrm: | 
| Craig Topper | 9d8676a | 2016-08-06 19:31:52 +0000 | [diff] [blame] | 6336 | case X86::VRNDSCALESDr: | 
|  | 6337 | case X86::VRNDSCALESDm: | 
|  | 6338 | case X86::VRNDSCALESSr: | 
|  | 6339 | case X86::VRNDSCALESSm: | 
|  | 6340 | case X86::VRCP14SSrr: | 
|  | 6341 | case X86::VRCP14SSrm: | 
|  | 6342 | case X86::VRSQRT14SSrr: | 
|  | 6343 | case X86::VRSQRT14SSrm: | 
|  | 6344 | case X86::VSQRTSSZr: | 
|  | 6345 | case X86::VSQRTSSZr_Int: | 
|  | 6346 | case X86::VSQRTSSZm: | 
|  | 6347 | case X86::VSQRTSSZm_Int: | 
|  | 6348 | case X86::VSQRTSDZr: | 
|  | 6349 | case X86::VSQRTSDZr_Int: | 
|  | 6350 | case X86::VSQRTSDZm: | 
|  | 6351 | case X86::VSQRTSDZm_Int: | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6352 | return true; | 
|  | 6353 | } | 
|  | 6354 |  | 
|  | 6355 | return false; | 
|  | 6356 | } | 
|  | 6357 |  | 
|  | 6358 | /// Inform the ExeDepsFix pass how many idle instructions we would like before | 
|  | 6359 | /// certain undef register reads. | 
|  | 6360 | /// | 
|  | 6361 | /// This catches the VCVTSI2SD family of instructions: | 
|  | 6362 | /// | 
|  | 6363 | /// vcvtsi2sdq %rax, %xmm0<undef>, %xmm14 | 
|  | 6364 | /// | 
|  | 6365 | /// We should to be careful *not* to catch VXOR idioms which are presumably | 
|  | 6366 | /// handled specially in the pipeline: | 
|  | 6367 | /// | 
|  | 6368 | /// vxorps %xmm1<undef>, %xmm1<undef>, %xmm1 | 
|  | 6369 | /// | 
|  | 6370 | /// Like getPartialRegUpdateClearance, this makes a strong assumption that the | 
|  | 6371 | /// high bits that are passed-through are not live. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6372 | unsigned | 
|  | 6373 | X86InstrInfo::getUndefRegClearance(const MachineInstr &MI, unsigned &OpNum, | 
|  | 6374 | const TargetRegisterInfo *TRI) const { | 
|  | 6375 | if (!hasUndefRegUpdate(MI.getOpcode())) | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6376 | return 0; | 
|  | 6377 |  | 
|  | 6378 | // Set the OpNum parameter to the first source operand. | 
|  | 6379 | OpNum = 1; | 
|  | 6380 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6381 | const MachineOperand &MO = MI.getOperand(OpNum); | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6382 | if (MO.isUndef() && TargetRegisterInfo::isPhysicalRegister(MO.getReg())) { | 
| Dehao Chen | 8cd84aa | 2016-06-28 21:19:34 +0000 | [diff] [blame] | 6383 | return UndefRegClearance; | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6384 | } | 
|  | 6385 | return 0; | 
|  | 6386 | } | 
|  | 6387 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6388 | void X86InstrInfo::breakPartialRegDependency( | 
|  | 6389 | MachineInstr &MI, unsigned OpNum, const TargetRegisterInfo *TRI) const { | 
|  | 6390 | unsigned Reg = MI.getOperand(OpNum).getReg(); | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6391 | // If MI kills this register, the false dependence is already broken. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6392 | if (MI.killsRegister(Reg, TRI)) | 
| Andrew Trick | b6d56be | 2013-10-14 22:19:03 +0000 | [diff] [blame] | 6393 | return; | 
| Sanjay Patel | cc4c71b | 2015-12-28 18:18:22 +0000 | [diff] [blame] | 6394 |  | 
| Jakob Stoklund Olesen | f8ad336 | 2011-11-15 01:15:30 +0000 | [diff] [blame] | 6395 | if (X86::VR128RegClass.contains(Reg)) { | 
|  | 6396 | // These instructions are all floating point domain, so xorps is the best | 
|  | 6397 | // choice. | 
| Sanjay Patel | cc4c71b | 2015-12-28 18:18:22 +0000 | [diff] [blame] | 6398 | unsigned Opc = Subtarget.hasAVX() ? X86::VXORPSrr : X86::XORPSrr; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6399 | BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), get(Opc), Reg) | 
|  | 6400 | .addReg(Reg, RegState::Undef) | 
|  | 6401 | .addReg(Reg, RegState::Undef); | 
|  | 6402 | MI.addRegisterKilled(Reg, TRI, true); | 
| Jakob Stoklund Olesen | f8ad336 | 2011-11-15 01:15:30 +0000 | [diff] [blame] | 6403 | } else if (X86::VR256RegClass.contains(Reg)) { | 
|  | 6404 | // Use vxorps to clear the full ymm register. | 
|  | 6405 | // It wants to read and write the xmm sub-register. | 
|  | 6406 | unsigned XReg = TRI->getSubReg(Reg, X86::sub_xmm); | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6407 | BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), get(X86::VXORPSrr), XReg) | 
|  | 6408 | .addReg(XReg, RegState::Undef) | 
|  | 6409 | .addReg(XReg, RegState::Undef) | 
|  | 6410 | .addReg(Reg, RegState::ImplicitDefine); | 
|  | 6411 | MI.addRegisterKilled(Reg, TRI, true); | 
| Sanjay Patel | cc4c71b | 2015-12-28 18:18:22 +0000 | [diff] [blame] | 6412 | } | 
| Jakob Stoklund Olesen | f8ad336 | 2011-11-15 01:15:30 +0000 | [diff] [blame] | 6413 | } | 
|  | 6414 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6415 | MachineInstr * | 
|  | 6416 | X86InstrInfo::foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, | 
|  | 6417 | ArrayRef<unsigned> Ops, | 
|  | 6418 | MachineBasicBlock::iterator InsertPt, | 
|  | 6419 | int FrameIndex, LiveIntervals *LIS) const { | 
| NAKAMURA Takumi | 9d29eff | 2011-01-26 02:03:37 +0000 | [diff] [blame] | 6420 | // Check switch flag | 
| Sanjay Patel | cc4c71b | 2015-12-28 18:18:22 +0000 | [diff] [blame] | 6421 | if (NoFusing) | 
|  | 6422 | return nullptr; | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6423 |  | 
| Bruno Cardoso Lopes | 6b30295 | 2011-09-15 21:42:23 +0000 | [diff] [blame] | 6424 | // Unless optimizing for size, don't fold to avoid partial | 
|  | 6425 | // register update stalls | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6426 | if (!MF.getFunction()->optForSize() && hasPartialRegUpdate(MI.getOpcode())) | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6427 | return nullptr; | 
| Evan Cheng | 4cf30b7 | 2009-12-18 07:40:29 +0000 | [diff] [blame] | 6428 |  | 
| Matthias Braun | 941a705 | 2016-07-28 18:40:00 +0000 | [diff] [blame] | 6429 | const MachineFrameInfo &MFI = MF.getFrameInfo(); | 
|  | 6430 | unsigned Size = MFI.getObjectSize(FrameIndex); | 
|  | 6431 | unsigned Alignment = MFI.getObjectAlignment(FrameIndex); | 
| Benjamin Kramer | 858a388 | 2013-10-06 13:48:22 +0000 | [diff] [blame] | 6432 | // If the function stack isn't realigned we don't want to fold instructions | 
|  | 6433 | // that need increased alignment. | 
|  | 6434 | if (!RI.needsStackRealignment(MF)) | 
| Eric Christopher | 05b8197 | 2015-02-02 17:38:43 +0000 | [diff] [blame] | 6435 | Alignment = | 
|  | 6436 | std::min(Alignment, Subtarget.getFrameLowering()->getStackAlignment()); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6437 | if (Ops.size() == 2 && Ops[0] == 0 && Ops[1] == 1) { | 
|  | 6438 | unsigned NewOpc = 0; | 
| Evan Cheng | 3cad628 | 2009-09-11 00:39:26 +0000 | [diff] [blame] | 6439 | unsigned RCSize = 0; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6440 | switch (MI.getOpcode()) { | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6441 | default: return nullptr; | 
| Evan Cheng | 3cad628 | 2009-09-11 00:39:26 +0000 | [diff] [blame] | 6442 | case X86::TEST8rr:  NewOpc = X86::CMP8ri; RCSize = 1; break; | 
| Dan Gohman | 887dd1c | 2010-05-18 21:42:03 +0000 | [diff] [blame] | 6443 | case X86::TEST16rr: NewOpc = X86::CMP16ri8; RCSize = 2; break; | 
|  | 6444 | case X86::TEST32rr: NewOpc = X86::CMP32ri8; RCSize = 4; break; | 
|  | 6445 | case X86::TEST64rr: NewOpc = X86::CMP64ri8; RCSize = 8; break; | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6446 | } | 
| Evan Cheng | 3cad628 | 2009-09-11 00:39:26 +0000 | [diff] [blame] | 6447 | // Check if it's safe to fold the load. If the size of the object is | 
|  | 6448 | // narrower than the load width, then it's not. | 
|  | 6449 | if (Size < RCSize) | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6450 | return nullptr; | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6451 | // Change to CMPXXri r, 0 first. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6452 | MI.setDesc(get(NewOpc)); | 
|  | 6453 | MI.getOperand(1).ChangeToImmediate(0); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6454 | } else if (Ops.size() != 1) | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6455 | return nullptr; | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6456 |  | 
| Benjamin Kramer | f1362f6 | 2015-02-28 12:04:00 +0000 | [diff] [blame] | 6457 | return foldMemoryOperandImpl(MF, MI, Ops[0], | 
| Keno Fischer | e70b31f | 2015-06-08 20:09:58 +0000 | [diff] [blame] | 6458 | MachineOperand::CreateFI(FrameIndex), InsertPt, | 
|  | 6459 | Size, Alignment, /*AllowCommute=*/true); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6460 | } | 
|  | 6461 |  | 
| Ahmed Bougacha | ed3c4d1 | 2015-06-22 20:51:51 +0000 | [diff] [blame] | 6462 | /// Check if \p LoadMI is a partial register load that we can't fold into \p MI | 
|  | 6463 | /// because the latter uses contents that wouldn't be defined in the folded | 
|  | 6464 | /// version.  For instance, this transformation isn't legal: | 
|  | 6465 | ///   movss (%rdi), %xmm0 | 
|  | 6466 | ///   addps %xmm0, %xmm0 | 
|  | 6467 | /// -> | 
|  | 6468 | ///   addps (%rdi), %xmm0 | 
|  | 6469 | /// | 
|  | 6470 | /// But this one is: | 
|  | 6471 | ///   movss (%rdi), %xmm0 | 
|  | 6472 | ///   addss %xmm0, %xmm0 | 
|  | 6473 | /// -> | 
|  | 6474 | ///   addss (%rdi), %xmm0 | 
|  | 6475 | /// | 
|  | 6476 | static bool isNonFoldablePartialRegisterLoad(const MachineInstr &LoadMI, | 
|  | 6477 | const MachineInstr &UserMI, | 
|  | 6478 | const MachineFunction &MF) { | 
| Akira Hatanaka | 760814a | 2014-09-15 18:23:52 +0000 | [diff] [blame] | 6479 | unsigned Opc = LoadMI.getOpcode(); | 
| Ahmed Bougacha | ed3c4d1 | 2015-06-22 20:51:51 +0000 | [diff] [blame] | 6480 | unsigned UserOpc = UserMI.getOpcode(); | 
| Akira Hatanaka | 760814a | 2014-09-15 18:23:52 +0000 | [diff] [blame] | 6481 | unsigned RegSize = | 
|  | 6482 | MF.getRegInfo().getRegClass(LoadMI.getOperand(0).getReg())->getSize(); | 
|  | 6483 |  | 
| Craig Topper | a3c55f5 | 2016-07-18 06:49:32 +0000 | [diff] [blame] | 6484 | if ((Opc == X86::MOVSSrm || Opc == X86::VMOVSSrm || Opc == X86::VMOVSSZrm) && | 
|  | 6485 | RegSize > 4) { | 
| Akira Hatanaka | 760814a | 2014-09-15 18:23:52 +0000 | [diff] [blame] | 6486 | // These instructions only load 32 bits, we can't fold them if the | 
| Ahmed Bougacha | ed3c4d1 | 2015-06-22 20:51:51 +0000 | [diff] [blame] | 6487 | // destination register is wider than 32 bits (4 bytes), and its user | 
|  | 6488 | // instruction isn't scalar (SS). | 
|  | 6489 | switch (UserOpc) { | 
| Craig Topper | a3c55f5 | 2016-07-18 06:49:32 +0000 | [diff] [blame] | 6490 | case X86::ADDSSrr_Int: case X86::VADDSSrr_Int: case X86::VADDSSZrr_Int: | 
|  | 6491 | case X86::DIVSSrr_Int: case X86::VDIVSSrr_Int: case X86::VDIVSSZrr_Int: | 
|  | 6492 | case X86::MULSSrr_Int: case X86::VMULSSrr_Int: case X86::VMULSSZrr_Int: | 
|  | 6493 | case X86::SUBSSrr_Int: case X86::VSUBSSrr_Int: case X86::VSUBSSZrr_Int: | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 6494 | case X86::VFMADD132SSr_Int: case X86::VFNMADD132SSr_Int: | 
|  | 6495 | case X86::VFMADD213SSr_Int: case X86::VFNMADD213SSr_Int: | 
|  | 6496 | case X86::VFMADD231SSr_Int: case X86::VFNMADD231SSr_Int: | 
|  | 6497 | case X86::VFMSUB132SSr_Int: case X86::VFNMSUB132SSr_Int: | 
|  | 6498 | case X86::VFMSUB213SSr_Int: case X86::VFNMSUB213SSr_Int: | 
|  | 6499 | case X86::VFMSUB231SSr_Int: case X86::VFNMSUB231SSr_Int: | 
| Ahmed Bougacha | ed3c4d1 | 2015-06-22 20:51:51 +0000 | [diff] [blame] | 6500 | return false; | 
|  | 6501 | default: | 
|  | 6502 | return true; | 
|  | 6503 | } | 
|  | 6504 | } | 
| Akira Hatanaka | 760814a | 2014-09-15 18:23:52 +0000 | [diff] [blame] | 6505 |  | 
| Craig Topper | a3c55f5 | 2016-07-18 06:49:32 +0000 | [diff] [blame] | 6506 | if ((Opc == X86::MOVSDrm || Opc == X86::VMOVSDrm || Opc == X86::VMOVSDZrm) && | 
|  | 6507 | RegSize > 8) { | 
| Akira Hatanaka | 760814a | 2014-09-15 18:23:52 +0000 | [diff] [blame] | 6508 | // These instructions only load 64 bits, we can't fold them if the | 
| Ahmed Bougacha | ed3c4d1 | 2015-06-22 20:51:51 +0000 | [diff] [blame] | 6509 | // destination register is wider than 64 bits (8 bytes), and its user | 
|  | 6510 | // instruction isn't scalar (SD). | 
|  | 6511 | switch (UserOpc) { | 
| Craig Topper | a3c55f5 | 2016-07-18 06:49:32 +0000 | [diff] [blame] | 6512 | case X86::ADDSDrr_Int: case X86::VADDSDrr_Int: case X86::VADDSDZrr_Int: | 
|  | 6513 | case X86::DIVSDrr_Int: case X86::VDIVSDrr_Int: case X86::VDIVSDZrr_Int: | 
|  | 6514 | case X86::MULSDrr_Int: case X86::VMULSDrr_Int: case X86::VMULSDZrr_Int: | 
|  | 6515 | case X86::SUBSDrr_Int: case X86::VSUBSDrr_Int: case X86::VSUBSDZrr_Int: | 
| Craig Topper | 2dca3b2 | 2016-07-24 08:26:38 +0000 | [diff] [blame] | 6516 | case X86::VFMADD132SDr_Int: case X86::VFNMADD132SDr_Int: | 
|  | 6517 | case X86::VFMADD213SDr_Int: case X86::VFNMADD213SDr_Int: | 
|  | 6518 | case X86::VFMADD231SDr_Int: case X86::VFNMADD231SDr_Int: | 
|  | 6519 | case X86::VFMSUB132SDr_Int: case X86::VFNMSUB132SDr_Int: | 
|  | 6520 | case X86::VFMSUB213SDr_Int: case X86::VFNMSUB213SDr_Int: | 
|  | 6521 | case X86::VFMSUB231SDr_Int: case X86::VFNMSUB231SDr_Int: | 
| Ahmed Bougacha | ed3c4d1 | 2015-06-22 20:51:51 +0000 | [diff] [blame] | 6522 | return false; | 
|  | 6523 | default: | 
|  | 6524 | return true; | 
|  | 6525 | } | 
|  | 6526 | } | 
| Akira Hatanaka | 760814a | 2014-09-15 18:23:52 +0000 | [diff] [blame] | 6527 |  | 
|  | 6528 | return false; | 
|  | 6529 | } | 
|  | 6530 |  | 
| Keno Fischer | e70b31f | 2015-06-08 20:09:58 +0000 | [diff] [blame] | 6531 | MachineInstr *X86InstrInfo::foldMemoryOperandImpl( | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6532 | MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned> Ops, | 
|  | 6533 | MachineBasicBlock::iterator InsertPt, MachineInstr &LoadMI, | 
| Jonas Paulsson | 8e5b0c6 | 2016-05-10 08:09:37 +0000 | [diff] [blame] | 6534 | LiveIntervals *LIS) const { | 
| Andrew Trick | 3112a5e | 2013-11-12 18:06:12 +0000 | [diff] [blame] | 6535 | // If loading from a FrameIndex, fold directly from the FrameIndex. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6536 | unsigned NumOps = LoadMI.getDesc().getNumOperands(); | 
| Andrew Trick | 3112a5e | 2013-11-12 18:06:12 +0000 | [diff] [blame] | 6537 | int FrameIndex; | 
| Akira Hatanaka | 760814a | 2014-09-15 18:23:52 +0000 | [diff] [blame] | 6538 | if (isLoadFromStackSlot(LoadMI, FrameIndex)) { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6539 | if (isNonFoldablePartialRegisterLoad(LoadMI, MI, MF)) | 
| Akira Hatanaka | 760814a | 2014-09-15 18:23:52 +0000 | [diff] [blame] | 6540 | return nullptr; | 
| Jonas Paulsson | 8e5b0c6 | 2016-05-10 08:09:37 +0000 | [diff] [blame] | 6541 | return foldMemoryOperandImpl(MF, MI, Ops, InsertPt, FrameIndex, LIS); | 
| Akira Hatanaka | 760814a | 2014-09-15 18:23:52 +0000 | [diff] [blame] | 6542 | } | 
| Andrew Trick | 3112a5e | 2013-11-12 18:06:12 +0000 | [diff] [blame] | 6543 |  | 
| NAKAMURA Takumi | 9d29eff | 2011-01-26 02:03:37 +0000 | [diff] [blame] | 6544 | // Check switch flag | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6545 | if (NoFusing) return nullptr; | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6546 |  | 
| Sanjay Patel | d09391c | 2015-08-10 20:45:44 +0000 | [diff] [blame] | 6547 | // Avoid partial register update stalls unless optimizing for size. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6548 | if (!MF.getFunction()->optForSize() && hasPartialRegUpdate(MI.getOpcode())) | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6549 | return nullptr; | 
| Evan Cheng | 4cf30b7 | 2009-12-18 07:40:29 +0000 | [diff] [blame] | 6550 |  | 
| Dan Gohman | 9a542a4 | 2008-07-12 00:10:52 +0000 | [diff] [blame] | 6551 | // Determine the alignment of the load. | 
| Evan Cheng | 3b3286d | 2008-02-08 21:20:40 +0000 | [diff] [blame] | 6552 | unsigned Alignment = 0; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6553 | if (LoadMI.hasOneMemOperand()) | 
|  | 6554 | Alignment = (*LoadMI.memoperands_begin())->getAlignment(); | 
| Dan Gohman | 69499b13 | 2009-09-21 18:30:38 +0000 | [diff] [blame] | 6555 | else | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6556 | switch (LoadMI.getOpcode()) { | 
| Craig Topper | 8674849 | 2016-07-11 05:36:41 +0000 | [diff] [blame] | 6557 | case X86::AVX512_512_SET0: | 
| Craig Topper | 516e14c | 2016-07-11 05:36:48 +0000 | [diff] [blame] | 6558 | case X86::AVX512_512_SETALLONES: | 
| Craig Topper | 8674849 | 2016-07-11 05:36:41 +0000 | [diff] [blame] | 6559 | Alignment = 64; | 
|  | 6560 | break; | 
| Craig Topper | a3a6583 | 2011-11-19 22:34:59 +0000 | [diff] [blame] | 6561 | case X86::AVX2_SETALLONES: | 
| Craig Topper | bd509ee | 2012-08-28 07:05:28 +0000 | [diff] [blame] | 6562 | case X86::AVX_SET0: | 
| Craig Topper | 8674849 | 2016-07-11 05:36:41 +0000 | [diff] [blame] | 6563 | case X86::AVX512_256_SET0: | 
| Bruno Cardoso Lopes | 7f704b3 | 2010-08-12 20:20:53 +0000 | [diff] [blame] | 6564 | Alignment = 32; | 
|  | 6565 | break; | 
| Jakob Stoklund Olesen | dd1904e | 2011-09-29 05:10:54 +0000 | [diff] [blame] | 6566 | case X86::V_SET0: | 
| Dan Gohman | 69499b13 | 2009-09-21 18:30:38 +0000 | [diff] [blame] | 6567 | case X86::V_SETALLONES: | 
| Craig Topper | 8674849 | 2016-07-11 05:36:41 +0000 | [diff] [blame] | 6568 | case X86::AVX512_128_SET0: | 
| Dan Gohman | 69499b13 | 2009-09-21 18:30:38 +0000 | [diff] [blame] | 6569 | Alignment = 16; | 
|  | 6570 | break; | 
|  | 6571 | case X86::FsFLD0SD: | 
|  | 6572 | Alignment = 8; | 
|  | 6573 | break; | 
|  | 6574 | case X86::FsFLD0SS: | 
|  | 6575 | Alignment = 4; | 
|  | 6576 | break; | 
|  | 6577 | default: | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6578 | return nullptr; | 
| Dan Gohman | 69499b13 | 2009-09-21 18:30:38 +0000 | [diff] [blame] | 6579 | } | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6580 | if (Ops.size() == 2 && Ops[0] == 0 && Ops[1] == 1) { | 
|  | 6581 | unsigned NewOpc = 0; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6582 | switch (MI.getOpcode()) { | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6583 | default: return nullptr; | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6584 | case X86::TEST8rr:  NewOpc = X86::CMP8ri; break; | 
| Dan Gohman | f8bf663 | 2010-05-18 21:54:15 +0000 | [diff] [blame] | 6585 | case X86::TEST16rr: NewOpc = X86::CMP16ri8; break; | 
|  | 6586 | case X86::TEST32rr: NewOpc = X86::CMP32ri8; break; | 
|  | 6587 | case X86::TEST64rr: NewOpc = X86::CMP64ri8; break; | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6588 | } | 
|  | 6589 | // Change to CMPXXri r, 0 first. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6590 | MI.setDesc(get(NewOpc)); | 
|  | 6591 | MI.getOperand(1).ChangeToImmediate(0); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6592 | } else if (Ops.size() != 1) | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6593 | return nullptr; | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6594 |  | 
| Jakob Stoklund Olesen | 9c473e4 | 2010-08-11 23:08:22 +0000 | [diff] [blame] | 6595 | // Make sure the subregisters match. | 
|  | 6596 | // Otherwise we risk changing the size of the load. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6597 | if (LoadMI.getOperand(0).getSubReg() != MI.getOperand(Ops[0]).getSubReg()) | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6598 | return nullptr; | 
| Jakob Stoklund Olesen | 9c473e4 | 2010-08-11 23:08:22 +0000 | [diff] [blame] | 6599 |  | 
| Chris Lattner | ec53627 | 2010-07-08 22:41:28 +0000 | [diff] [blame] | 6600 | SmallVector<MachineOperand,X86::AddrNumOperands> MOs; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6601 | switch (LoadMI.getOpcode()) { | 
| Jakob Stoklund Olesen | dd1904e | 2011-09-29 05:10:54 +0000 | [diff] [blame] | 6602 | case X86::V_SET0: | 
| Dan Gohman | 69499b13 | 2009-09-21 18:30:38 +0000 | [diff] [blame] | 6603 | case X86::V_SETALLONES: | 
| Craig Topper | a3a6583 | 2011-11-19 22:34:59 +0000 | [diff] [blame] | 6604 | case X86::AVX2_SETALLONES: | 
| Craig Topper | bd509ee | 2012-08-28 07:05:28 +0000 | [diff] [blame] | 6605 | case X86::AVX_SET0: | 
| Craig Topper | 8674849 | 2016-07-11 05:36:41 +0000 | [diff] [blame] | 6606 | case X86::AVX512_128_SET0: | 
|  | 6607 | case X86::AVX512_256_SET0: | 
|  | 6608 | case X86::AVX512_512_SET0: | 
| Craig Topper | 516e14c | 2016-07-11 05:36:48 +0000 | [diff] [blame] | 6609 | case X86::AVX512_512_SETALLONES: | 
| Dan Gohman | 69499b13 | 2009-09-21 18:30:38 +0000 | [diff] [blame] | 6610 | case X86::FsFLD0SD: | 
| Jakob Stoklund Olesen | bde32d3 | 2011-11-29 22:27:25 +0000 | [diff] [blame] | 6611 | case X86::FsFLD0SS: { | 
| Jakob Stoklund Olesen | dd1904e | 2011-09-29 05:10:54 +0000 | [diff] [blame] | 6612 | // Folding a V_SET0 or V_SETALLONES as a load, to ease register pressure. | 
| Dan Gohman | cc78cdf | 2008-12-03 05:21:24 +0000 | [diff] [blame] | 6613 | // Create a constant-pool entry and operands to load from it. | 
|  | 6614 |  | 
| Dan Gohman | 772952f | 2010-03-09 03:01:40 +0000 | [diff] [blame] | 6615 | // Medium and large mode can't fold loads this way. | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 6616 | if (MF.getTarget().getCodeModel() != CodeModel::Small && | 
|  | 6617 | MF.getTarget().getCodeModel() != CodeModel::Kernel) | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6618 | return nullptr; | 
| Dan Gohman | 772952f | 2010-03-09 03:01:40 +0000 | [diff] [blame] | 6619 |  | 
| Dan Gohman | cc78cdf | 2008-12-03 05:21:24 +0000 | [diff] [blame] | 6620 | // x86-32 PIC requires a PIC base register for constant pools. | 
|  | 6621 | unsigned PICBase = 0; | 
| Rafael Espindola | f9e348b | 2016-06-27 21:33:08 +0000 | [diff] [blame] | 6622 | if (MF.getTarget().isPositionIndependent()) { | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 6623 | if (Subtarget.is64Bit()) | 
| Evan Cheng | fdd0eb4 | 2009-07-16 18:44:05 +0000 | [diff] [blame] | 6624 | PICBase = X86::RIP; | 
| Jakob Stoklund Olesen | c7895d3 | 2009-07-16 21:24:13 +0000 | [diff] [blame] | 6625 | else | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 6626 | // FIXME: PICBase = getGlobalBaseReg(&MF); | 
| Evan Cheng | fdd0eb4 | 2009-07-16 18:44:05 +0000 | [diff] [blame] | 6627 | // This doesn't work for several reasons. | 
|  | 6628 | // 1. GlobalBaseReg may have been spilled. | 
|  | 6629 | // 2. It may not be live at MI. | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6630 | return nullptr; | 
| Jakob Stoklund Olesen | c7895d3 | 2009-07-16 21:24:13 +0000 | [diff] [blame] | 6631 | } | 
| Dan Gohman | cc78cdf | 2008-12-03 05:21:24 +0000 | [diff] [blame] | 6632 |  | 
| Dan Gohman | 69499b13 | 2009-09-21 18:30:38 +0000 | [diff] [blame] | 6633 | // Create a constant-pool entry. | 
| Dan Gohman | cc78cdf | 2008-12-03 05:21:24 +0000 | [diff] [blame] | 6634 | MachineConstantPool &MCP = *MF.getConstantPool(); | 
| Chris Lattner | 229907c | 2011-07-18 04:54:35 +0000 | [diff] [blame] | 6635 | Type *Ty; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6636 | unsigned Opc = LoadMI.getOpcode(); | 
| Jakob Stoklund Olesen | bde32d3 | 2011-11-29 22:27:25 +0000 | [diff] [blame] | 6637 | if (Opc == X86::FsFLD0SS) | 
| Dan Gohman | 69499b13 | 2009-09-21 18:30:38 +0000 | [diff] [blame] | 6638 | Ty = Type::getFloatTy(MF.getFunction()->getContext()); | 
| Jakob Stoklund Olesen | bde32d3 | 2011-11-29 22:27:25 +0000 | [diff] [blame] | 6639 | else if (Opc == X86::FsFLD0SD) | 
| Dan Gohman | 69499b13 | 2009-09-21 18:30:38 +0000 | [diff] [blame] | 6640 | Ty = Type::getDoubleTy(MF.getFunction()->getContext()); | 
| Craig Topper | 516e14c | 2016-07-11 05:36:48 +0000 | [diff] [blame] | 6641 | else if (Opc == X86::AVX512_512_SET0 || Opc == X86::AVX512_512_SETALLONES) | 
| Craig Topper | 8674849 | 2016-07-11 05:36:41 +0000 | [diff] [blame] | 6642 | Ty = VectorType::get(Type::getInt32Ty(MF.getFunction()->getContext()),16); | 
|  | 6643 | else if (Opc == X86::AVX2_SETALLONES || Opc == X86::AVX_SET0 || | 
|  | 6644 | Opc == X86::AVX512_256_SET0) | 
| Craig Topper | a4c5a47 | 2012-01-13 06:12:41 +0000 | [diff] [blame] | 6645 | Ty = VectorType::get(Type::getInt32Ty(MF.getFunction()->getContext()), 8); | 
| Dan Gohman | 69499b13 | 2009-09-21 18:30:38 +0000 | [diff] [blame] | 6646 | else | 
|  | 6647 | Ty = VectorType::get(Type::getInt32Ty(MF.getFunction()->getContext()), 4); | 
| Bruno Cardoso Lopes | 9212bf2 | 2011-07-25 23:05:32 +0000 | [diff] [blame] | 6648 |  | 
| Craig Topper | 516e14c | 2016-07-11 05:36:48 +0000 | [diff] [blame] | 6649 | bool IsAllOnes = (Opc == X86::V_SETALLONES || Opc == X86::AVX2_SETALLONES || | 
|  | 6650 | Opc == X86::AVX512_512_SETALLONES); | 
| Bruno Cardoso Lopes | 9212bf2 | 2011-07-25 23:05:32 +0000 | [diff] [blame] | 6651 | const Constant *C = IsAllOnes ? Constant::getAllOnesValue(Ty) : | 
|  | 6652 | Constant::getNullValue(Ty); | 
| Dan Gohman | 69499b13 | 2009-09-21 18:30:38 +0000 | [diff] [blame] | 6653 | unsigned CPI = MCP.getConstantPoolIndex(C, Alignment); | 
| Dan Gohman | cc78cdf | 2008-12-03 05:21:24 +0000 | [diff] [blame] | 6654 |  | 
|  | 6655 | // Create operands to load from the constant pool entry. | 
|  | 6656 | MOs.push_back(MachineOperand::CreateReg(PICBase, false)); | 
|  | 6657 | MOs.push_back(MachineOperand::CreateImm(1)); | 
|  | 6658 | MOs.push_back(MachineOperand::CreateReg(0, false)); | 
|  | 6659 | MOs.push_back(MachineOperand::CreateCPI(CPI, 0)); | 
| Rafael Espindola | 3b2df10 | 2009-04-08 21:14:34 +0000 | [diff] [blame] | 6660 | MOs.push_back(MachineOperand::CreateReg(0, false)); | 
| Dan Gohman | 69499b13 | 2009-09-21 18:30:38 +0000 | [diff] [blame] | 6661 | break; | 
|  | 6662 | } | 
|  | 6663 | default: { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6664 | if (isNonFoldablePartialRegisterLoad(LoadMI, MI, MF)) | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6665 | return nullptr; | 
| Manman Ren | 5b46282 | 2012-11-27 18:09:26 +0000 | [diff] [blame] | 6666 |  | 
| Dan Gohman | cc78cdf | 2008-12-03 05:21:24 +0000 | [diff] [blame] | 6667 | // Folding a normal load. Just copy the load's address operands. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6668 | MOs.append(LoadMI.operands_begin() + NumOps - X86::AddrNumOperands, | 
|  | 6669 | LoadMI.operands_begin() + NumOps); | 
| Dan Gohman | 69499b13 | 2009-09-21 18:30:38 +0000 | [diff] [blame] | 6670 | break; | 
|  | 6671 | } | 
| Dan Gohman | cc78cdf | 2008-12-03 05:21:24 +0000 | [diff] [blame] | 6672 | } | 
| Keno Fischer | e70b31f | 2015-06-08 20:09:58 +0000 | [diff] [blame] | 6673 | return foldMemoryOperandImpl(MF, MI, Ops[0], MOs, InsertPt, | 
| Simon Pilgrim | 2f9548a | 2014-10-20 22:14:22 +0000 | [diff] [blame] | 6674 | /*Size=*/0, Alignment, /*AllowCommute=*/true); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6675 | } | 
|  | 6676 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6677 | bool X86InstrInfo::unfoldMemoryOperand( | 
|  | 6678 | MachineFunction &MF, MachineInstr &MI, unsigned Reg, bool UnfoldLoad, | 
|  | 6679 | bool UnfoldStore, SmallVectorImpl<MachineInstr *> &NewMIs) const { | 
|  | 6680 | auto I = MemOp2RegOpTable.find(MI.getOpcode()); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6681 | if (I == MemOp2RegOpTable.end()) | 
|  | 6682 | return false; | 
|  | 6683 | unsigned Opc = I->second.first; | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 6684 | unsigned Index = I->second.second & TB_INDEX_MASK; | 
|  | 6685 | bool FoldedLoad = I->second.second & TB_FOLDED_LOAD; | 
|  | 6686 | bool FoldedStore = I->second.second & TB_FOLDED_STORE; | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6687 | if (UnfoldLoad && !FoldedLoad) | 
|  | 6688 | return false; | 
|  | 6689 | UnfoldLoad &= FoldedLoad; | 
|  | 6690 | if (UnfoldStore && !FoldedStore) | 
|  | 6691 | return false; | 
|  | 6692 | UnfoldStore &= FoldedStore; | 
|  | 6693 |  | 
| Evan Cheng | 6cc775f | 2011-06-28 19:10:37 +0000 | [diff] [blame] | 6694 | const MCInstrDesc &MCID = get(Opc); | 
| Jakob Stoklund Olesen | 3c52f02 | 2012-05-07 22:10:26 +0000 | [diff] [blame] | 6695 | const TargetRegisterClass *RC = getRegClass(MCID, Index, &RI, MF); | 
| Sanjay Patel | 9e916dc | 2015-08-21 20:17:26 +0000 | [diff] [blame] | 6696 | // TODO: Check if 32-byte or greater accesses are slow too? | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6697 | if (!MI.hasOneMemOperand() && RC == &X86::VR128RegClass && | 
| Sanjay Patel | 3014567 | 2015-09-01 20:51:51 +0000 | [diff] [blame] | 6698 | Subtarget.isUnalignedMem16Slow()) | 
| Evan Cheng | 0ce8448 | 2010-07-02 20:36:18 +0000 | [diff] [blame] | 6699 | // Without memoperands, loadRegFromAddr and storeRegToStackSlot will | 
|  | 6700 | // conservatively assume the address is unaligned. That's bad for | 
|  | 6701 | // performance. | 
|  | 6702 | return false; | 
| Chris Lattner | ec53627 | 2010-07-08 22:41:28 +0000 | [diff] [blame] | 6703 | SmallVector<MachineOperand, X86::AddrNumOperands> AddrOps; | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6704 | SmallVector<MachineOperand,2> BeforeOps; | 
|  | 6705 | SmallVector<MachineOperand,2> AfterOps; | 
|  | 6706 | SmallVector<MachineOperand,4> ImpOps; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6707 | for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { | 
|  | 6708 | MachineOperand &Op = MI.getOperand(i); | 
| Chris Lattner | ec53627 | 2010-07-08 22:41:28 +0000 | [diff] [blame] | 6709 | if (i >= Index && i < Index + X86::AddrNumOperands) | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6710 | AddrOps.push_back(Op); | 
| Dan Gohman | 0d1e9a8 | 2008-10-03 15:45:36 +0000 | [diff] [blame] | 6711 | else if (Op.isReg() && Op.isImplicit()) | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6712 | ImpOps.push_back(Op); | 
|  | 6713 | else if (i < Index) | 
|  | 6714 | BeforeOps.push_back(Op); | 
|  | 6715 | else if (i > Index) | 
|  | 6716 | AfterOps.push_back(Op); | 
|  | 6717 | } | 
|  | 6718 |  | 
|  | 6719 | // Emit the load instruction. | 
|  | 6720 | if (UnfoldLoad) { | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6721 | std::pair<MachineInstr::mmo_iterator, MachineInstr::mmo_iterator> MMOs = | 
|  | 6722 | MF.extractLoadMemRefs(MI.memoperands_begin(), MI.memoperands_end()); | 
| Dan Gohman | dd76bb2 | 2009-10-09 18:10:05 +0000 | [diff] [blame] | 6723 | loadRegFromAddr(MF, Reg, AddrOps, RC, MMOs.first, MMOs.second, NewMIs); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6724 | if (UnfoldStore) { | 
|  | 6725 | // Address operands cannot be marked isKill. | 
| Chris Lattner | ec53627 | 2010-07-08 22:41:28 +0000 | [diff] [blame] | 6726 | for (unsigned i = 1; i != 1 + X86::AddrNumOperands; ++i) { | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6727 | MachineOperand &MO = NewMIs[0]->getOperand(i); | 
| Dan Gohman | 0d1e9a8 | 2008-10-03 15:45:36 +0000 | [diff] [blame] | 6728 | if (MO.isReg()) | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6729 | MO.setIsKill(false); | 
|  | 6730 | } | 
|  | 6731 | } | 
|  | 6732 | } | 
|  | 6733 |  | 
|  | 6734 | // Emit the data processing instruction. | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6735 | MachineInstr *DataMI = MF.CreateMachineInstr(MCID, MI.getDebugLoc(), true); | 
| Jakob Stoklund Olesen | b159b5f | 2012-12-19 21:31:56 +0000 | [diff] [blame] | 6736 | MachineInstrBuilder MIB(MF, DataMI); | 
| NAKAMURA Takumi | 9d29eff | 2011-01-26 02:03:37 +0000 | [diff] [blame] | 6737 |  | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6738 | if (FoldedStore) | 
| Bill Wendling | f7b83c7 | 2009-05-13 21:33:08 +0000 | [diff] [blame] | 6739 | MIB.addReg(Reg, RegState::Define); | 
| Sanjay Patel | 4104f78 | 2015-12-29 19:14:23 +0000 | [diff] [blame] | 6740 | for (MachineOperand &BeforeOp : BeforeOps) | 
|  | 6741 | MIB.addOperand(BeforeOp); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6742 | if (FoldedLoad) | 
|  | 6743 | MIB.addReg(Reg); | 
| Sanjay Patel | 4104f78 | 2015-12-29 19:14:23 +0000 | [diff] [blame] | 6744 | for (MachineOperand &AfterOp : AfterOps) | 
|  | 6745 | MIB.addOperand(AfterOp); | 
|  | 6746 | for (MachineOperand &ImpOp : ImpOps) { | 
|  | 6747 | MIB.addReg(ImpOp.getReg(), | 
|  | 6748 | getDefRegState(ImpOp.isDef()) | | 
| Bill Wendling | f7b83c7 | 2009-05-13 21:33:08 +0000 | [diff] [blame] | 6749 | RegState::Implicit | | 
| Sanjay Patel | 4104f78 | 2015-12-29 19:14:23 +0000 | [diff] [blame] | 6750 | getKillRegState(ImpOp.isKill()) | | 
|  | 6751 | getDeadRegState(ImpOp.isDead()) | | 
|  | 6752 | getUndefRegState(ImpOp.isUndef())); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6753 | } | 
|  | 6754 | // Change CMP32ri r, 0 back to TEST32rr r, r, etc. | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6755 | switch (DataMI->getOpcode()) { | 
|  | 6756 | default: break; | 
|  | 6757 | case X86::CMP64ri32: | 
| Dan Gohman | f8bf663 | 2010-05-18 21:54:15 +0000 | [diff] [blame] | 6758 | case X86::CMP64ri8: | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6759 | case X86::CMP32ri: | 
| Dan Gohman | f8bf663 | 2010-05-18 21:54:15 +0000 | [diff] [blame] | 6760 | case X86::CMP32ri8: | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6761 | case X86::CMP16ri: | 
| Dan Gohman | f8bf663 | 2010-05-18 21:54:15 +0000 | [diff] [blame] | 6762 | case X86::CMP16ri8: | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6763 | case X86::CMP8ri: { | 
|  | 6764 | MachineOperand &MO0 = DataMI->getOperand(0); | 
|  | 6765 | MachineOperand &MO1 = DataMI->getOperand(1); | 
|  | 6766 | if (MO1.getImm() == 0) { | 
| Craig Topper | 4bc3e5a | 2012-08-21 08:16:16 +0000 | [diff] [blame] | 6767 | unsigned NewOpc; | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6768 | switch (DataMI->getOpcode()) { | 
| Craig Topper | 4bc3e5a | 2012-08-21 08:16:16 +0000 | [diff] [blame] | 6769 | default: llvm_unreachable("Unreachable!"); | 
| Dan Gohman | f8bf663 | 2010-05-18 21:54:15 +0000 | [diff] [blame] | 6770 | case X86::CMP64ri8: | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6771 | case X86::CMP64ri32: NewOpc = X86::TEST64rr; break; | 
| Dan Gohman | f8bf663 | 2010-05-18 21:54:15 +0000 | [diff] [blame] | 6772 | case X86::CMP32ri8: | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6773 | case X86::CMP32ri:   NewOpc = X86::TEST32rr; break; | 
| Dan Gohman | f8bf663 | 2010-05-18 21:54:15 +0000 | [diff] [blame] | 6774 | case X86::CMP16ri8: | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6775 | case X86::CMP16ri:   NewOpc = X86::TEST16rr; break; | 
|  | 6776 | case X86::CMP8ri:    NewOpc = X86::TEST8rr; break; | 
|  | 6777 | } | 
| Chris Lattner | 5968751 | 2008-01-11 18:10:50 +0000 | [diff] [blame] | 6778 | DataMI->setDesc(get(NewOpc)); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6779 | MO1.ChangeToRegister(MO0.getReg(), false); | 
|  | 6780 | } | 
|  | 6781 | } | 
|  | 6782 | } | 
|  | 6783 | NewMIs.push_back(DataMI); | 
|  | 6784 |  | 
|  | 6785 | // Emit the store instruction. | 
|  | 6786 | if (UnfoldStore) { | 
| Jakob Stoklund Olesen | 3c52f02 | 2012-05-07 22:10:26 +0000 | [diff] [blame] | 6787 | const TargetRegisterClass *DstRC = getRegClass(MCID, 0, &RI, MF); | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 6788 | std::pair<MachineInstr::mmo_iterator, MachineInstr::mmo_iterator> MMOs = | 
|  | 6789 | MF.extractStoreMemRefs(MI.memoperands_begin(), MI.memoperands_end()); | 
| Dan Gohman | dd76bb2 | 2009-10-09 18:10:05 +0000 | [diff] [blame] | 6790 | storeRegToAddr(MF, Reg, true, AddrOps, DstRC, MMOs.first, MMOs.second, NewMIs); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6791 | } | 
|  | 6792 |  | 
|  | 6793 | return true; | 
|  | 6794 | } | 
|  | 6795 |  | 
|  | 6796 | bool | 
|  | 6797 | X86InstrInfo::unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N, | 
| Bill Wendling | 27b508d | 2009-02-11 21:51:19 +0000 | [diff] [blame] | 6798 | SmallVectorImpl<SDNode*> &NewNodes) const { | 
| Dan Gohman | 1705968 | 2008-07-17 19:10:17 +0000 | [diff] [blame] | 6799 | if (!N->isMachineOpcode()) | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6800 | return false; | 
|  | 6801 |  | 
| Craig Topper | e012ede | 2016-04-30 17:59:49 +0000 | [diff] [blame] | 6802 | auto I = MemOp2RegOpTable.find(N->getMachineOpcode()); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6803 | if (I == MemOp2RegOpTable.end()) | 
|  | 6804 | return false; | 
|  | 6805 | unsigned Opc = I->second.first; | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 6806 | unsigned Index = I->second.second & TB_INDEX_MASK; | 
|  | 6807 | bool FoldedLoad = I->second.second & TB_FOLDED_LOAD; | 
|  | 6808 | bool FoldedStore = I->second.second & TB_FOLDED_STORE; | 
| Evan Cheng | 6cc775f | 2011-06-28 19:10:37 +0000 | [diff] [blame] | 6809 | const MCInstrDesc &MCID = get(Opc); | 
| Jakob Stoklund Olesen | 3c52f02 | 2012-05-07 22:10:26 +0000 | [diff] [blame] | 6810 | MachineFunction &MF = DAG.getMachineFunction(); | 
|  | 6811 | const TargetRegisterClass *RC = getRegClass(MCID, Index, &RI, MF); | 
| Evan Cheng | 6cc775f | 2011-06-28 19:10:37 +0000 | [diff] [blame] | 6812 | unsigned NumDefs = MCID.NumDefs; | 
| Dan Gohman | 2ce6f2a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 6813 | std::vector<SDValue> AddrOps; | 
|  | 6814 | std::vector<SDValue> BeforeOps; | 
|  | 6815 | std::vector<SDValue> AfterOps; | 
| Andrew Trick | ef9de2a | 2013-05-25 02:42:55 +0000 | [diff] [blame] | 6816 | SDLoc dl(N); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6817 | unsigned NumOps = N->getNumOperands(); | 
| Dan Gohman | 48b185d | 2009-09-25 20:36:54 +0000 | [diff] [blame] | 6818 | for (unsigned i = 0; i != NumOps-1; ++i) { | 
| Dan Gohman | 2ce6f2a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 6819 | SDValue Op = N->getOperand(i); | 
| Chris Lattner | ec53627 | 2010-07-08 22:41:28 +0000 | [diff] [blame] | 6820 | if (i >= Index-NumDefs && i < Index-NumDefs + X86::AddrNumOperands) | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6821 | AddrOps.push_back(Op); | 
| Dan Gohman | cc329b5 | 2009-03-04 19:23:38 +0000 | [diff] [blame] | 6822 | else if (i < Index-NumDefs) | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6823 | BeforeOps.push_back(Op); | 
| Dan Gohman | cc329b5 | 2009-03-04 19:23:38 +0000 | [diff] [blame] | 6824 | else if (i > Index-NumDefs) | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6825 | AfterOps.push_back(Op); | 
|  | 6826 | } | 
| Dan Gohman | 2ce6f2a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 6827 | SDValue Chain = N->getOperand(NumOps-1); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6828 | AddrOps.push_back(Chain); | 
|  | 6829 |  | 
|  | 6830 | // Emit the load instruction. | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6831 | SDNode *Load = nullptr; | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6832 | if (FoldedLoad) { | 
| Owen Anderson | 53aa7a9 | 2009-08-10 22:56:29 +0000 | [diff] [blame] | 6833 | EVT VT = *RC->vt_begin(); | 
| Evan Cheng | f25ef4f | 2009-11-16 21:56:03 +0000 | [diff] [blame] | 6834 | std::pair<MachineInstr::mmo_iterator, | 
|  | 6835 | MachineInstr::mmo_iterator> MMOs = | 
|  | 6836 | MF.extractLoadMemRefs(cast<MachineSDNode>(N)->memoperands_begin(), | 
|  | 6837 | cast<MachineSDNode>(N)->memoperands_end()); | 
| Evan Cheng | 0ce8448 | 2010-07-02 20:36:18 +0000 | [diff] [blame] | 6838 | if (!(*MMOs.first) && | 
|  | 6839 | RC == &X86::VR128RegClass && | 
| Sanjay Patel | 3014567 | 2015-09-01 20:51:51 +0000 | [diff] [blame] | 6840 | Subtarget.isUnalignedMem16Slow()) | 
| Evan Cheng | 0ce8448 | 2010-07-02 20:36:18 +0000 | [diff] [blame] | 6841 | // Do not introduce a slow unaligned load. | 
|  | 6842 | return false; | 
| Sanjay Patel | 9e916dc | 2015-08-21 20:17:26 +0000 | [diff] [blame] | 6843 | // FIXME: If a VR128 can have size 32, we should be checking if a 32-byte | 
|  | 6844 | // memory access is slow above. | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 6845 | unsigned Alignment = RC->getSize() == 32 ? 32 : 16; | 
|  | 6846 | bool isAligned = (*MMOs.first) && | 
|  | 6847 | (*MMOs.first)->getAlignment() >= Alignment; | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 6848 | Load = DAG.getMachineNode(getLoadRegOpcode(0, RC, isAligned, Subtarget), dl, | 
| Michael Liao | b53d896 | 2013-04-19 22:22:57 +0000 | [diff] [blame] | 6849 | VT, MVT::Other, AddrOps); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6850 | NewNodes.push_back(Load); | 
| Dan Gohman | dd76bb2 | 2009-10-09 18:10:05 +0000 | [diff] [blame] | 6851 |  | 
|  | 6852 | // Preserve memory reference information. | 
| Dan Gohman | dd76bb2 | 2009-10-09 18:10:05 +0000 | [diff] [blame] | 6853 | cast<MachineSDNode>(Load)->setMemRefs(MMOs.first, MMOs.second); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6854 | } | 
|  | 6855 |  | 
|  | 6856 | // Emit the data processing instruction. | 
| Owen Anderson | 53aa7a9 | 2009-08-10 22:56:29 +0000 | [diff] [blame] | 6857 | std::vector<EVT> VTs; | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 6858 | const TargetRegisterClass *DstRC = nullptr; | 
| Evan Cheng | 6cc775f | 2011-06-28 19:10:37 +0000 | [diff] [blame] | 6859 | if (MCID.getNumDefs() > 0) { | 
| Jakob Stoklund Olesen | 3c52f02 | 2012-05-07 22:10:26 +0000 | [diff] [blame] | 6860 | DstRC = getRegClass(MCID, 0, &RI, MF); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6861 | VTs.push_back(*DstRC->vt_begin()); | 
|  | 6862 | } | 
|  | 6863 | for (unsigned i = 0, e = N->getNumValues(); i != e; ++i) { | 
| Owen Anderson | 53aa7a9 | 2009-08-10 22:56:29 +0000 | [diff] [blame] | 6864 | EVT VT = N->getValueType(i); | 
| Evan Cheng | 6cc775f | 2011-06-28 19:10:37 +0000 | [diff] [blame] | 6865 | if (VT != MVT::Other && i >= (unsigned)MCID.getNumDefs()) | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6866 | VTs.push_back(VT); | 
|  | 6867 | } | 
|  | 6868 | if (Load) | 
| Dan Gohman | 2ce6f2a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 6869 | BeforeOps.push_back(SDValue(Load, 0)); | 
| Benjamin Kramer | 4f6ac16 | 2015-02-28 10:11:12 +0000 | [diff] [blame] | 6870 | BeforeOps.insert(BeforeOps.end(), AfterOps.begin(), AfterOps.end()); | 
| Michael Liao | b53d896 | 2013-04-19 22:22:57 +0000 | [diff] [blame] | 6871 | SDNode *NewNode= DAG.getMachineNode(Opc, dl, VTs, BeforeOps); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6872 | NewNodes.push_back(NewNode); | 
|  | 6873 |  | 
|  | 6874 | // Emit the store instruction. | 
|  | 6875 | if (FoldedStore) { | 
|  | 6876 | AddrOps.pop_back(); | 
| Dan Gohman | 2ce6f2a | 2008-07-27 21:46:04 +0000 | [diff] [blame] | 6877 | AddrOps.push_back(SDValue(NewNode, 0)); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6878 | AddrOps.push_back(Chain); | 
| Evan Cheng | f25ef4f | 2009-11-16 21:56:03 +0000 | [diff] [blame] | 6879 | std::pair<MachineInstr::mmo_iterator, | 
|  | 6880 | MachineInstr::mmo_iterator> MMOs = | 
|  | 6881 | MF.extractStoreMemRefs(cast<MachineSDNode>(N)->memoperands_begin(), | 
|  | 6882 | cast<MachineSDNode>(N)->memoperands_end()); | 
| Evan Cheng | 0ce8448 | 2010-07-02 20:36:18 +0000 | [diff] [blame] | 6883 | if (!(*MMOs.first) && | 
|  | 6884 | RC == &X86::VR128RegClass && | 
| Sanjay Patel | 3014567 | 2015-09-01 20:51:51 +0000 | [diff] [blame] | 6885 | Subtarget.isUnalignedMem16Slow()) | 
| Evan Cheng | 0ce8448 | 2010-07-02 20:36:18 +0000 | [diff] [blame] | 6886 | // Do not introduce a slow unaligned store. | 
|  | 6887 | return false; | 
| Sanjay Patel | 9e916dc | 2015-08-21 20:17:26 +0000 | [diff] [blame] | 6888 | // FIXME: If a VR128 can have size 32, we should be checking if a 32-byte | 
|  | 6889 | // memory access is slow above. | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 6890 | unsigned Alignment = RC->getSize() == 32 ? 32 : 16; | 
|  | 6891 | bool isAligned = (*MMOs.first) && | 
|  | 6892 | (*MMOs.first)->getAlignment() >= Alignment; | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 6893 | SDNode *Store = | 
|  | 6894 | DAG.getMachineNode(getStoreRegOpcode(0, DstRC, isAligned, Subtarget), | 
|  | 6895 | dl, MVT::Other, AddrOps); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6896 | NewNodes.push_back(Store); | 
| Dan Gohman | dd76bb2 | 2009-10-09 18:10:05 +0000 | [diff] [blame] | 6897 |  | 
|  | 6898 | // Preserve memory reference information. | 
| Craig Topper | 9e71b82 | 2015-02-10 06:29:28 +0000 | [diff] [blame] | 6899 | cast<MachineSDNode>(Store)->setMemRefs(MMOs.first, MMOs.second); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6900 | } | 
|  | 6901 |  | 
|  | 6902 | return true; | 
|  | 6903 | } | 
|  | 6904 |  | 
|  | 6905 | unsigned X86InstrInfo::getOpcodeAfterMemoryUnfold(unsigned Opc, | 
| Dan Gohman | 49fa51d | 2009-10-30 22:18:41 +0000 | [diff] [blame] | 6906 | bool UnfoldLoad, bool UnfoldStore, | 
|  | 6907 | unsigned *LoadRegIndex) const { | 
| Craig Topper | e012ede | 2016-04-30 17:59:49 +0000 | [diff] [blame] | 6908 | auto I = MemOp2RegOpTable.find(Opc); | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6909 | if (I == MemOp2RegOpTable.end()) | 
|  | 6910 | return 0; | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 6911 | bool FoldedLoad = I->second.second & TB_FOLDED_LOAD; | 
|  | 6912 | bool FoldedStore = I->second.second & TB_FOLDED_STORE; | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6913 | if (UnfoldLoad && !FoldedLoad) | 
|  | 6914 | return 0; | 
|  | 6915 | if (UnfoldStore && !FoldedStore) | 
|  | 6916 | return 0; | 
| Dan Gohman | 49fa51d | 2009-10-30 22:18:41 +0000 | [diff] [blame] | 6917 | if (LoadRegIndex) | 
| Bruno Cardoso Lopes | 23eb526 | 2011-09-08 18:35:57 +0000 | [diff] [blame] | 6918 | *LoadRegIndex = I->second.second & TB_INDEX_MASK; | 
| Owen Anderson | 2a3be7b | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 6919 | return I->second.first; | 
|  | 6920 | } | 
|  | 6921 |  | 
| Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 6922 | bool | 
|  | 6923 | X86InstrInfo::areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, | 
|  | 6924 | int64_t &Offset1, int64_t &Offset2) const { | 
|  | 6925 | if (!Load1->isMachineOpcode() || !Load2->isMachineOpcode()) | 
|  | 6926 | return false; | 
|  | 6927 | unsigned Opc1 = Load1->getMachineOpcode(); | 
|  | 6928 | unsigned Opc2 = Load2->getMachineOpcode(); | 
|  | 6929 | switch (Opc1) { | 
|  | 6930 | default: return false; | 
|  | 6931 | case X86::MOV8rm: | 
|  | 6932 | case X86::MOV16rm: | 
|  | 6933 | case X86::MOV32rm: | 
|  | 6934 | case X86::MOV64rm: | 
|  | 6935 | case X86::LD_Fp32m: | 
|  | 6936 | case X86::LD_Fp64m: | 
|  | 6937 | case X86::LD_Fp80m: | 
|  | 6938 | case X86::MOVSSrm: | 
|  | 6939 | case X86::MOVSDrm: | 
|  | 6940 | case X86::MMX_MOVD64rm: | 
|  | 6941 | case X86::MMX_MOVQ64rm: | 
|  | 6942 | case X86::FsMOVAPSrm: | 
|  | 6943 | case X86::FsMOVAPDrm: | 
|  | 6944 | case X86::MOVAPSrm: | 
|  | 6945 | case X86::MOVUPSrm: | 
| Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 6946 | case X86::MOVAPDrm: | 
| Craig Topper | f7a06c2 | 2016-07-18 06:14:43 +0000 | [diff] [blame] | 6947 | case X86::MOVUPDrm: | 
| Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 6948 | case X86::MOVDQArm: | 
|  | 6949 | case X86::MOVDQUrm: | 
| Bruno Cardoso Lopes | c69d68a | 2011-09-15 22:15:52 +0000 | [diff] [blame] | 6950 | // AVX load instructions | 
|  | 6951 | case X86::VMOVSSrm: | 
|  | 6952 | case X86::VMOVSDrm: | 
|  | 6953 | case X86::FsVMOVAPSrm: | 
|  | 6954 | case X86::FsVMOVAPDrm: | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 6955 | case X86::VMOVAPSrm: | 
|  | 6956 | case X86::VMOVUPSrm: | 
|  | 6957 | case X86::VMOVAPDrm: | 
| Craig Topper | f7a06c2 | 2016-07-18 06:14:43 +0000 | [diff] [blame] | 6958 | case X86::VMOVUPDrm: | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 6959 | case X86::VMOVDQArm: | 
|  | 6960 | case X86::VMOVDQUrm: | 
| Bruno Cardoso Lopes | 6778597 | 2011-07-14 18:50:58 +0000 | [diff] [blame] | 6961 | case X86::VMOVAPSYrm: | 
|  | 6962 | case X86::VMOVUPSYrm: | 
|  | 6963 | case X86::VMOVAPDYrm: | 
| Craig Topper | f7a06c2 | 2016-07-18 06:14:43 +0000 | [diff] [blame] | 6964 | case X86::VMOVUPDYrm: | 
| Bruno Cardoso Lopes | 6778597 | 2011-07-14 18:50:58 +0000 | [diff] [blame] | 6965 | case X86::VMOVDQAYrm: | 
|  | 6966 | case X86::VMOVDQUYrm: | 
| Craig Topper | f7a06c2 | 2016-07-18 06:14:43 +0000 | [diff] [blame] | 6967 | // AVX512 load instructions | 
|  | 6968 | case X86::VMOVSSZrm: | 
|  | 6969 | case X86::VMOVSDZrm: | 
|  | 6970 | case X86::VMOVAPSZ128rm: | 
|  | 6971 | case X86::VMOVUPSZ128rm: | 
|  | 6972 | case X86::VMOVAPDZ128rm: | 
|  | 6973 | case X86::VMOVUPDZ128rm: | 
|  | 6974 | case X86::VMOVDQU8Z128rm: | 
|  | 6975 | case X86::VMOVDQU16Z128rm: | 
|  | 6976 | case X86::VMOVDQA32Z128rm: | 
|  | 6977 | case X86::VMOVDQU32Z128rm: | 
|  | 6978 | case X86::VMOVDQA64Z128rm: | 
|  | 6979 | case X86::VMOVDQU64Z128rm: | 
|  | 6980 | case X86::VMOVAPSZ256rm: | 
|  | 6981 | case X86::VMOVUPSZ256rm: | 
|  | 6982 | case X86::VMOVAPDZ256rm: | 
|  | 6983 | case X86::VMOVUPDZ256rm: | 
|  | 6984 | case X86::VMOVDQU8Z256rm: | 
|  | 6985 | case X86::VMOVDQU16Z256rm: | 
|  | 6986 | case X86::VMOVDQA32Z256rm: | 
|  | 6987 | case X86::VMOVDQU32Z256rm: | 
|  | 6988 | case X86::VMOVDQA64Z256rm: | 
|  | 6989 | case X86::VMOVDQU64Z256rm: | 
|  | 6990 | case X86::VMOVAPSZrm: | 
|  | 6991 | case X86::VMOVUPSZrm: | 
|  | 6992 | case X86::VMOVAPDZrm: | 
|  | 6993 | case X86::VMOVUPDZrm: | 
|  | 6994 | case X86::VMOVDQU8Zrm: | 
|  | 6995 | case X86::VMOVDQU16Zrm: | 
|  | 6996 | case X86::VMOVDQA32Zrm: | 
|  | 6997 | case X86::VMOVDQU32Zrm: | 
|  | 6998 | case X86::VMOVDQA64Zrm: | 
|  | 6999 | case X86::VMOVDQU64Zrm: | 
|  | 7000 | case X86::KMOVBkm: | 
|  | 7001 | case X86::KMOVWkm: | 
|  | 7002 | case X86::KMOVDkm: | 
|  | 7003 | case X86::KMOVQkm: | 
| Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 7004 | break; | 
|  | 7005 | } | 
|  | 7006 | switch (Opc2) { | 
|  | 7007 | default: return false; | 
|  | 7008 | case X86::MOV8rm: | 
|  | 7009 | case X86::MOV16rm: | 
|  | 7010 | case X86::MOV32rm: | 
|  | 7011 | case X86::MOV64rm: | 
|  | 7012 | case X86::LD_Fp32m: | 
|  | 7013 | case X86::LD_Fp64m: | 
|  | 7014 | case X86::LD_Fp80m: | 
|  | 7015 | case X86::MOVSSrm: | 
|  | 7016 | case X86::MOVSDrm: | 
|  | 7017 | case X86::MMX_MOVD64rm: | 
|  | 7018 | case X86::MMX_MOVQ64rm: | 
|  | 7019 | case X86::FsMOVAPSrm: | 
|  | 7020 | case X86::FsMOVAPDrm: | 
|  | 7021 | case X86::MOVAPSrm: | 
|  | 7022 | case X86::MOVUPSrm: | 
| Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 7023 | case X86::MOVAPDrm: | 
| Craig Topper | f7a06c2 | 2016-07-18 06:14:43 +0000 | [diff] [blame] | 7024 | case X86::MOVUPDrm: | 
| Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 7025 | case X86::MOVDQArm: | 
|  | 7026 | case X86::MOVDQUrm: | 
| Bruno Cardoso Lopes | c69d68a | 2011-09-15 22:15:52 +0000 | [diff] [blame] | 7027 | // AVX load instructions | 
|  | 7028 | case X86::VMOVSSrm: | 
|  | 7029 | case X86::VMOVSDrm: | 
|  | 7030 | case X86::FsVMOVAPSrm: | 
|  | 7031 | case X86::FsVMOVAPDrm: | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 7032 | case X86::VMOVAPSrm: | 
|  | 7033 | case X86::VMOVUPSrm: | 
|  | 7034 | case X86::VMOVAPDrm: | 
| Craig Topper | f7a06c2 | 2016-07-18 06:14:43 +0000 | [diff] [blame] | 7035 | case X86::VMOVUPDrm: | 
| Bruno Cardoso Lopes | d560b8c | 2011-09-14 02:36:58 +0000 | [diff] [blame] | 7036 | case X86::VMOVDQArm: | 
|  | 7037 | case X86::VMOVDQUrm: | 
| Bruno Cardoso Lopes | 6778597 | 2011-07-14 18:50:58 +0000 | [diff] [blame] | 7038 | case X86::VMOVAPSYrm: | 
|  | 7039 | case X86::VMOVUPSYrm: | 
|  | 7040 | case X86::VMOVAPDYrm: | 
| Craig Topper | f7a06c2 | 2016-07-18 06:14:43 +0000 | [diff] [blame] | 7041 | case X86::VMOVUPDYrm: | 
| Bruno Cardoso Lopes | 6778597 | 2011-07-14 18:50:58 +0000 | [diff] [blame] | 7042 | case X86::VMOVDQAYrm: | 
|  | 7043 | case X86::VMOVDQUYrm: | 
| Craig Topper | f7a06c2 | 2016-07-18 06:14:43 +0000 | [diff] [blame] | 7044 | // AVX512 load instructions | 
|  | 7045 | case X86::VMOVSSZrm: | 
|  | 7046 | case X86::VMOVSDZrm: | 
|  | 7047 | case X86::VMOVAPSZ128rm: | 
|  | 7048 | case X86::VMOVUPSZ128rm: | 
|  | 7049 | case X86::VMOVAPDZ128rm: | 
|  | 7050 | case X86::VMOVUPDZ128rm: | 
|  | 7051 | case X86::VMOVDQU8Z128rm: | 
|  | 7052 | case X86::VMOVDQU16Z128rm: | 
|  | 7053 | case X86::VMOVDQA32Z128rm: | 
|  | 7054 | case X86::VMOVDQU32Z128rm: | 
|  | 7055 | case X86::VMOVDQA64Z128rm: | 
|  | 7056 | case X86::VMOVDQU64Z128rm: | 
|  | 7057 | case X86::VMOVAPSZ256rm: | 
|  | 7058 | case X86::VMOVUPSZ256rm: | 
|  | 7059 | case X86::VMOVAPDZ256rm: | 
|  | 7060 | case X86::VMOVUPDZ256rm: | 
|  | 7061 | case X86::VMOVDQU8Z256rm: | 
|  | 7062 | case X86::VMOVDQU16Z256rm: | 
|  | 7063 | case X86::VMOVDQA32Z256rm: | 
|  | 7064 | case X86::VMOVDQU32Z256rm: | 
|  | 7065 | case X86::VMOVDQA64Z256rm: | 
|  | 7066 | case X86::VMOVDQU64Z256rm: | 
|  | 7067 | case X86::VMOVAPSZrm: | 
|  | 7068 | case X86::VMOVUPSZrm: | 
|  | 7069 | case X86::VMOVAPDZrm: | 
|  | 7070 | case X86::VMOVUPDZrm: | 
|  | 7071 | case X86::VMOVDQU8Zrm: | 
|  | 7072 | case X86::VMOVDQU16Zrm: | 
|  | 7073 | case X86::VMOVDQA32Zrm: | 
|  | 7074 | case X86::VMOVDQU32Zrm: | 
|  | 7075 | case X86::VMOVDQA64Zrm: | 
|  | 7076 | case X86::VMOVDQU64Zrm: | 
|  | 7077 | case X86::KMOVBkm: | 
|  | 7078 | case X86::KMOVWkm: | 
|  | 7079 | case X86::KMOVDkm: | 
|  | 7080 | case X86::KMOVQkm: | 
| Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 7081 | break; | 
|  | 7082 | } | 
|  | 7083 |  | 
|  | 7084 | // Check if chain operands and base addresses match. | 
|  | 7085 | if (Load1->getOperand(0) != Load2->getOperand(0) || | 
|  | 7086 | Load1->getOperand(5) != Load2->getOperand(5)) | 
|  | 7087 | return false; | 
|  | 7088 | // Segment operands should match as well. | 
|  | 7089 | if (Load1->getOperand(4) != Load2->getOperand(4)) | 
|  | 7090 | return false; | 
|  | 7091 | // Scale should be 1, Index should be Reg0. | 
|  | 7092 | if (Load1->getOperand(1) == Load2->getOperand(1) && | 
|  | 7093 | Load1->getOperand(2) == Load2->getOperand(2)) { | 
|  | 7094 | if (cast<ConstantSDNode>(Load1->getOperand(1))->getZExtValue() != 1) | 
|  | 7095 | return false; | 
| Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 7096 |  | 
|  | 7097 | // Now let's examine the displacements. | 
|  | 7098 | if (isa<ConstantSDNode>(Load1->getOperand(3)) && | 
|  | 7099 | isa<ConstantSDNode>(Load2->getOperand(3))) { | 
|  | 7100 | Offset1 = cast<ConstantSDNode>(Load1->getOperand(3))->getSExtValue(); | 
|  | 7101 | Offset2 = cast<ConstantSDNode>(Load2->getOperand(3))->getSExtValue(); | 
|  | 7102 | return true; | 
|  | 7103 | } | 
|  | 7104 | } | 
|  | 7105 | return false; | 
|  | 7106 | } | 
|  | 7107 |  | 
|  | 7108 | bool X86InstrInfo::shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2, | 
|  | 7109 | int64_t Offset1, int64_t Offset2, | 
|  | 7110 | unsigned NumLoads) const { | 
|  | 7111 | assert(Offset2 > Offset1); | 
|  | 7112 | if ((Offset2 - Offset1) / 8 > 64) | 
|  | 7113 | return false; | 
|  | 7114 |  | 
|  | 7115 | unsigned Opc1 = Load1->getMachineOpcode(); | 
|  | 7116 | unsigned Opc2 = Load2->getMachineOpcode(); | 
|  | 7117 | if (Opc1 != Opc2) | 
|  | 7118 | return false;  // FIXME: overly conservative? | 
|  | 7119 |  | 
|  | 7120 | switch (Opc1) { | 
|  | 7121 | default: break; | 
|  | 7122 | case X86::LD_Fp32m: | 
|  | 7123 | case X86::LD_Fp64m: | 
|  | 7124 | case X86::LD_Fp80m: | 
|  | 7125 | case X86::MMX_MOVD64rm: | 
|  | 7126 | case X86::MMX_MOVQ64rm: | 
|  | 7127 | return false; | 
|  | 7128 | } | 
|  | 7129 |  | 
|  | 7130 | EVT VT = Load1->getValueType(0); | 
|  | 7131 | switch (VT.getSimpleVT().SimpleTy) { | 
| Bill Wendling | 8ce69cd | 2010-06-22 22:16:17 +0000 | [diff] [blame] | 7132 | default: | 
| Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 7133 | // XMM registers. In 64-bit mode we can be a bit more aggressive since we | 
|  | 7134 | // have 16 of them to play with. | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 7135 | if (Subtarget.is64Bit()) { | 
| Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 7136 | if (NumLoads >= 3) | 
|  | 7137 | return false; | 
| Bill Wendling | 8ce69cd | 2010-06-22 22:16:17 +0000 | [diff] [blame] | 7138 | } else if (NumLoads) { | 
| Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 7139 | return false; | 
| Bill Wendling | 8ce69cd | 2010-06-22 22:16:17 +0000 | [diff] [blame] | 7140 | } | 
| Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 7141 | break; | 
| Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 7142 | case MVT::i8: | 
|  | 7143 | case MVT::i16: | 
|  | 7144 | case MVT::i32: | 
|  | 7145 | case MVT::i64: | 
| Evan Cheng | 16cf934 | 2010-01-22 23:49:11 +0000 | [diff] [blame] | 7146 | case MVT::f32: | 
|  | 7147 | case MVT::f64: | 
| Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 7148 | if (NumLoads) | 
|  | 7149 | return false; | 
| Bill Wendling | 8ce69cd | 2010-06-22 22:16:17 +0000 | [diff] [blame] | 7150 | break; | 
| Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 7151 | } | 
|  | 7152 |  | 
|  | 7153 | return true; | 
|  | 7154 | } | 
|  | 7155 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 7156 | bool X86InstrInfo::shouldScheduleAdjacent(MachineInstr &First, | 
|  | 7157 | MachineInstr &Second) const { | 
| Andrew Trick | 47740de | 2013-06-23 09:00:28 +0000 | [diff] [blame] | 7158 | // Check if this processor supports macro-fusion. Since this is a minor | 
|  | 7159 | // heuristic, we haven't specifically reserved a feature. hasAVX is a decent | 
|  | 7160 | // proxy for SandyBridge+. | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 7161 | if (!Subtarget.hasAVX()) | 
| Andrew Trick | 47740de | 2013-06-23 09:00:28 +0000 | [diff] [blame] | 7162 | return false; | 
|  | 7163 |  | 
|  | 7164 | enum { | 
|  | 7165 | FuseTest, | 
|  | 7166 | FuseCmp, | 
|  | 7167 | FuseInc | 
|  | 7168 | } FuseKind; | 
|  | 7169 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 7170 | switch (Second.getOpcode()) { | 
| Andrew Trick | 47740de | 2013-06-23 09:00:28 +0000 | [diff] [blame] | 7171 | default: | 
|  | 7172 | return false; | 
| Craig Topper | 49758aa | 2015-01-06 04:23:53 +0000 | [diff] [blame] | 7173 | case X86::JE_1: | 
|  | 7174 | case X86::JNE_1: | 
|  | 7175 | case X86::JL_1: | 
|  | 7176 | case X86::JLE_1: | 
|  | 7177 | case X86::JG_1: | 
|  | 7178 | case X86::JGE_1: | 
| Andrew Trick | 47740de | 2013-06-23 09:00:28 +0000 | [diff] [blame] | 7179 | FuseKind = FuseInc; | 
|  | 7180 | break; | 
| Craig Topper | 49758aa | 2015-01-06 04:23:53 +0000 | [diff] [blame] | 7181 | case X86::JB_1: | 
|  | 7182 | case X86::JBE_1: | 
|  | 7183 | case X86::JA_1: | 
|  | 7184 | case X86::JAE_1: | 
| Andrew Trick | 47740de | 2013-06-23 09:00:28 +0000 | [diff] [blame] | 7185 | FuseKind = FuseCmp; | 
|  | 7186 | break; | 
| Craig Topper | 49758aa | 2015-01-06 04:23:53 +0000 | [diff] [blame] | 7187 | case X86::JS_1: | 
|  | 7188 | case X86::JNS_1: | 
|  | 7189 | case X86::JP_1: | 
|  | 7190 | case X86::JNP_1: | 
|  | 7191 | case X86::JO_1: | 
|  | 7192 | case X86::JNO_1: | 
| Andrew Trick | 47740de | 2013-06-23 09:00:28 +0000 | [diff] [blame] | 7193 | FuseKind = FuseTest; | 
|  | 7194 | break; | 
|  | 7195 | } | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 7196 | switch (First.getOpcode()) { | 
| Andrew Trick | 47740de | 2013-06-23 09:00:28 +0000 | [diff] [blame] | 7197 | default: | 
|  | 7198 | return false; | 
|  | 7199 | case X86::TEST8rr: | 
|  | 7200 | case X86::TEST16rr: | 
|  | 7201 | case X86::TEST32rr: | 
|  | 7202 | case X86::TEST64rr: | 
|  | 7203 | case X86::TEST8ri: | 
|  | 7204 | case X86::TEST16ri: | 
|  | 7205 | case X86::TEST32ri: | 
|  | 7206 | case X86::TEST32i32: | 
|  | 7207 | case X86::TEST64i32: | 
|  | 7208 | case X86::TEST64ri32: | 
|  | 7209 | case X86::TEST8rm: | 
|  | 7210 | case X86::TEST16rm: | 
|  | 7211 | case X86::TEST32rm: | 
|  | 7212 | case X86::TEST64rm: | 
| Akira Hatanaka | 7cc2764 | 2014-07-10 18:00:53 +0000 | [diff] [blame] | 7213 | case X86::TEST8ri_NOREX: | 
| Andrew Trick | 47740de | 2013-06-23 09:00:28 +0000 | [diff] [blame] | 7214 | case X86::AND16i16: | 
|  | 7215 | case X86::AND16ri: | 
|  | 7216 | case X86::AND16ri8: | 
|  | 7217 | case X86::AND16rm: | 
|  | 7218 | case X86::AND16rr: | 
|  | 7219 | case X86::AND32i32: | 
|  | 7220 | case X86::AND32ri: | 
|  | 7221 | case X86::AND32ri8: | 
|  | 7222 | case X86::AND32rm: | 
|  | 7223 | case X86::AND32rr: | 
|  | 7224 | case X86::AND64i32: | 
|  | 7225 | case X86::AND64ri32: | 
|  | 7226 | case X86::AND64ri8: | 
|  | 7227 | case X86::AND64rm: | 
|  | 7228 | case X86::AND64rr: | 
|  | 7229 | case X86::AND8i8: | 
|  | 7230 | case X86::AND8ri: | 
|  | 7231 | case X86::AND8rm: | 
|  | 7232 | case X86::AND8rr: | 
|  | 7233 | return true; | 
|  | 7234 | case X86::CMP16i16: | 
|  | 7235 | case X86::CMP16ri: | 
|  | 7236 | case X86::CMP16ri8: | 
|  | 7237 | case X86::CMP16rm: | 
|  | 7238 | case X86::CMP16rr: | 
|  | 7239 | case X86::CMP32i32: | 
|  | 7240 | case X86::CMP32ri: | 
|  | 7241 | case X86::CMP32ri8: | 
|  | 7242 | case X86::CMP32rm: | 
|  | 7243 | case X86::CMP32rr: | 
|  | 7244 | case X86::CMP64i32: | 
|  | 7245 | case X86::CMP64ri32: | 
|  | 7246 | case X86::CMP64ri8: | 
|  | 7247 | case X86::CMP64rm: | 
|  | 7248 | case X86::CMP64rr: | 
|  | 7249 | case X86::CMP8i8: | 
|  | 7250 | case X86::CMP8ri: | 
|  | 7251 | case X86::CMP8rm: | 
|  | 7252 | case X86::CMP8rr: | 
|  | 7253 | case X86::ADD16i16: | 
|  | 7254 | case X86::ADD16ri: | 
|  | 7255 | case X86::ADD16ri8: | 
|  | 7256 | case X86::ADD16ri8_DB: | 
|  | 7257 | case X86::ADD16ri_DB: | 
|  | 7258 | case X86::ADD16rm: | 
|  | 7259 | case X86::ADD16rr: | 
|  | 7260 | case X86::ADD16rr_DB: | 
|  | 7261 | case X86::ADD32i32: | 
|  | 7262 | case X86::ADD32ri: | 
|  | 7263 | case X86::ADD32ri8: | 
|  | 7264 | case X86::ADD32ri8_DB: | 
|  | 7265 | case X86::ADD32ri_DB: | 
|  | 7266 | case X86::ADD32rm: | 
|  | 7267 | case X86::ADD32rr: | 
|  | 7268 | case X86::ADD32rr_DB: | 
|  | 7269 | case X86::ADD64i32: | 
|  | 7270 | case X86::ADD64ri32: | 
|  | 7271 | case X86::ADD64ri32_DB: | 
|  | 7272 | case X86::ADD64ri8: | 
|  | 7273 | case X86::ADD64ri8_DB: | 
|  | 7274 | case X86::ADD64rm: | 
|  | 7275 | case X86::ADD64rr: | 
|  | 7276 | case X86::ADD64rr_DB: | 
|  | 7277 | case X86::ADD8i8: | 
|  | 7278 | case X86::ADD8mi: | 
|  | 7279 | case X86::ADD8mr: | 
|  | 7280 | case X86::ADD8ri: | 
|  | 7281 | case X86::ADD8rm: | 
|  | 7282 | case X86::ADD8rr: | 
|  | 7283 | case X86::SUB16i16: | 
|  | 7284 | case X86::SUB16ri: | 
|  | 7285 | case X86::SUB16ri8: | 
|  | 7286 | case X86::SUB16rm: | 
|  | 7287 | case X86::SUB16rr: | 
|  | 7288 | case X86::SUB32i32: | 
|  | 7289 | case X86::SUB32ri: | 
|  | 7290 | case X86::SUB32ri8: | 
|  | 7291 | case X86::SUB32rm: | 
|  | 7292 | case X86::SUB32rr: | 
|  | 7293 | case X86::SUB64i32: | 
|  | 7294 | case X86::SUB64ri32: | 
|  | 7295 | case X86::SUB64ri8: | 
|  | 7296 | case X86::SUB64rm: | 
|  | 7297 | case X86::SUB64rr: | 
|  | 7298 | case X86::SUB8i8: | 
|  | 7299 | case X86::SUB8ri: | 
|  | 7300 | case X86::SUB8rm: | 
|  | 7301 | case X86::SUB8rr: | 
|  | 7302 | return FuseKind == FuseCmp || FuseKind == FuseInc; | 
|  | 7303 | case X86::INC16r: | 
|  | 7304 | case X86::INC32r: | 
| Andrew Trick | 47740de | 2013-06-23 09:00:28 +0000 | [diff] [blame] | 7305 | case X86::INC64r: | 
|  | 7306 | case X86::INC8r: | 
|  | 7307 | case X86::DEC16r: | 
|  | 7308 | case X86::DEC32r: | 
| Andrew Trick | 47740de | 2013-06-23 09:00:28 +0000 | [diff] [blame] | 7309 | case X86::DEC64r: | 
|  | 7310 | case X86::DEC8r: | 
|  | 7311 | return FuseKind == FuseInc; | 
|  | 7312 | } | 
|  | 7313 | } | 
| Evan Cheng | 4f026f3 | 2010-01-22 03:34:51 +0000 | [diff] [blame] | 7314 |  | 
| Chris Lattner | c0fb567 | 2006-10-20 17:42:20 +0000 | [diff] [blame] | 7315 | bool X86InstrInfo:: | 
| Owen Anderson | 4f6bf04 | 2008-08-14 22:49:33 +0000 | [diff] [blame] | 7316 | ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { | 
| Chris Lattner | 3a897f3 | 2006-10-21 05:52:40 +0000 | [diff] [blame] | 7317 | assert(Cond.size() == 1 && "Invalid X86 branch condition!"); | 
| Evan Cheng | f93bc7f | 2008-08-29 23:21:31 +0000 | [diff] [blame] | 7318 | X86::CondCode CC = static_cast<X86::CondCode>(Cond[0].getImm()); | 
|  | 7319 | Cond[0].setImm(GetOppositeBranchCondition(CC)); | 
| Chris Lattner | 3a897f3 | 2006-10-21 05:52:40 +0000 | [diff] [blame] | 7320 | return false; | 
| Chris Lattner | c0fb567 | 2006-10-20 17:42:20 +0000 | [diff] [blame] | 7321 | } | 
|  | 7322 |  | 
| Evan Cheng | f713722 | 2008-10-27 07:14:50 +0000 | [diff] [blame] | 7323 | bool X86InstrInfo:: | 
| Evan Cheng | b5f0ec3 | 2009-02-06 17:17:30 +0000 | [diff] [blame] | 7324 | isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const { | 
|  | 7325 | // FIXME: Return false for x87 stack register classes for now. We can't | 
| Evan Cheng | f713722 | 2008-10-27 07:14:50 +0000 | [diff] [blame] | 7326 | // allow any loads of these registers before FpGet_ST0_80. | 
| Evan Cheng | b5f0ec3 | 2009-02-06 17:17:30 +0000 | [diff] [blame] | 7327 | return !(RC == &X86::CCRRegClass || RC == &X86::RFP32RegClass || | 
|  | 7328 | RC == &X86::RFP64RegClass || RC == &X86::RFP80RegClass); | 
| Evan Cheng | f713722 | 2008-10-27 07:14:50 +0000 | [diff] [blame] | 7329 | } | 
|  | 7330 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 7331 | /// Return a virtual register initialized with the | 
| Dan Gohman | 6ebe734 | 2008-09-30 00:58:23 +0000 | [diff] [blame] | 7332 | /// the global base register value. Output instructions required to | 
|  | 7333 | /// initialize the register in the function entry block, if necessary. | 
| Dan Gohman | 2430073 | 2008-09-23 18:22:58 +0000 | [diff] [blame] | 7334 | /// | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 7335 | /// TODO: Eliminate this and move the code to X86MachineFunctionInfo. | 
|  | 7336 | /// | 
| Dan Gohman | 6ebe734 | 2008-09-30 00:58:23 +0000 | [diff] [blame] | 7337 | unsigned X86InstrInfo::getGlobalBaseReg(MachineFunction *MF) const { | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 7338 | assert(!Subtarget.is64Bit() && | 
| Dan Gohman | 6ebe734 | 2008-09-30 00:58:23 +0000 | [diff] [blame] | 7339 | "X86-64 PIC uses RIP relative addressing"); | 
|  | 7340 |  | 
|  | 7341 | X86MachineFunctionInfo *X86FI = MF->getInfo<X86MachineFunctionInfo>(); | 
|  | 7342 | unsigned GlobalBaseReg = X86FI->getGlobalBaseReg(); | 
|  | 7343 | if (GlobalBaseReg != 0) | 
|  | 7344 | return GlobalBaseReg; | 
|  | 7345 |  | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 7346 | // Create the register. The code to initialize it is inserted | 
|  | 7347 | // later, by the CGBR pass (below). | 
| Dan Gohman | 2430073 | 2008-09-23 18:22:58 +0000 | [diff] [blame] | 7348 | MachineRegisterInfo &RegInfo = MF->getRegInfo(); | 
| Jakob Stoklund Olesen | 38dcd59 | 2012-05-20 18:43:00 +0000 | [diff] [blame] | 7349 | GlobalBaseReg = RegInfo.createVirtualRegister(&X86::GR32_NOSPRegClass); | 
| Dan Gohman | 6ebe734 | 2008-09-30 00:58:23 +0000 | [diff] [blame] | 7350 | X86FI->setGlobalBaseReg(GlobalBaseReg); | 
|  | 7351 | return GlobalBaseReg; | 
| Dan Gohman | 2430073 | 2008-09-23 18:22:58 +0000 | [diff] [blame] | 7352 | } | 
| Jakob Stoklund Olesen | 49e121d | 2010-03-25 17:25:00 +0000 | [diff] [blame] | 7353 |  | 
| Jakob Stoklund Olesen | b551aa4 | 2010-03-29 23:24:21 +0000 | [diff] [blame] | 7354 | // These are the replaceable SSE instructions. Some of these have Int variants | 
|  | 7355 | // that we don't include here. We don't want to replace instructions selected | 
|  | 7356 | // by intrinsics. | 
| Craig Topper | 2dac962 | 2012-03-09 07:45:21 +0000 | [diff] [blame] | 7357 | static const uint16_t ReplaceableInstrs[][3] = { | 
| Bruno Cardoso Lopes | 1401e04 | 2010-08-12 02:08:52 +0000 | [diff] [blame] | 7358 | //PackedSingle     PackedDouble    PackedInt | 
| Jakob Stoklund Olesen | dbff4e8 | 2010-03-30 22:46:53 +0000 | [diff] [blame] | 7359 | { X86::MOVAPSmr,   X86::MOVAPDmr,  X86::MOVDQAmr  }, | 
|  | 7360 | { X86::MOVAPSrm,   X86::MOVAPDrm,  X86::MOVDQArm  }, | 
|  | 7361 | { X86::MOVAPSrr,   X86::MOVAPDrr,  X86::MOVDQArr  }, | 
|  | 7362 | { X86::MOVUPSmr,   X86::MOVUPDmr,  X86::MOVDQUmr  }, | 
|  | 7363 | { X86::MOVUPSrm,   X86::MOVUPDrm,  X86::MOVDQUrm  }, | 
| Sanjay Patel | c03d93b | 2015-04-15 15:47:51 +0000 | [diff] [blame] | 7364 | { X86::MOVLPSmr,   X86::MOVLPDmr,  X86::MOVPQI2QImr  }, | 
| Jakob Stoklund Olesen | dbff4e8 | 2010-03-30 22:46:53 +0000 | [diff] [blame] | 7365 | { X86::MOVNTPSmr,  X86::MOVNTPDmr, X86::MOVNTDQmr }, | 
|  | 7366 | { X86::ANDNPSrm,   X86::ANDNPDrm,  X86::PANDNrm   }, | 
|  | 7367 | { X86::ANDNPSrr,   X86::ANDNPDrr,  X86::PANDNrr   }, | 
|  | 7368 | { X86::ANDPSrm,    X86::ANDPDrm,   X86::PANDrm    }, | 
|  | 7369 | { X86::ANDPSrr,    X86::ANDPDrr,   X86::PANDrr    }, | 
|  | 7370 | { X86::ORPSrm,     X86::ORPDrm,    X86::PORrm     }, | 
|  | 7371 | { X86::ORPSrr,     X86::ORPDrr,    X86::PORrr     }, | 
|  | 7372 | { X86::XORPSrm,    X86::XORPDrm,   X86::PXORrm    }, | 
|  | 7373 | { X86::XORPSrr,    X86::XORPDrr,   X86::PXORrr    }, | 
| Bruno Cardoso Lopes | 7f704b3 | 2010-08-12 20:20:53 +0000 | [diff] [blame] | 7374 | // AVX 128-bit support | 
|  | 7375 | { X86::VMOVAPSmr,  X86::VMOVAPDmr,  X86::VMOVDQAmr  }, | 
|  | 7376 | { X86::VMOVAPSrm,  X86::VMOVAPDrm,  X86::VMOVDQArm  }, | 
|  | 7377 | { X86::VMOVAPSrr,  X86::VMOVAPDrr,  X86::VMOVDQArr  }, | 
|  | 7378 | { X86::VMOVUPSmr,  X86::VMOVUPDmr,  X86::VMOVDQUmr  }, | 
|  | 7379 | { X86::VMOVUPSrm,  X86::VMOVUPDrm,  X86::VMOVDQUrm  }, | 
| Sanjay Patel | 2161c49 | 2015-04-17 17:02:37 +0000 | [diff] [blame] | 7380 | { X86::VMOVLPSmr,  X86::VMOVLPDmr,  X86::VMOVPQI2QImr  }, | 
| Bruno Cardoso Lopes | 7f704b3 | 2010-08-12 20:20:53 +0000 | [diff] [blame] | 7381 | { X86::VMOVNTPSmr, X86::VMOVNTPDmr, X86::VMOVNTDQmr }, | 
|  | 7382 | { X86::VANDNPSrm,  X86::VANDNPDrm,  X86::VPANDNrm   }, | 
|  | 7383 | { X86::VANDNPSrr,  X86::VANDNPDrr,  X86::VPANDNrr   }, | 
|  | 7384 | { X86::VANDPSrm,   X86::VANDPDrm,   X86::VPANDrm    }, | 
|  | 7385 | { X86::VANDPSrr,   X86::VANDPDrr,   X86::VPANDrr    }, | 
|  | 7386 | { X86::VORPSrm,    X86::VORPDrm,    X86::VPORrm     }, | 
|  | 7387 | { X86::VORPSrr,    X86::VORPDrr,    X86::VPORrr     }, | 
| Bruno Cardoso Lopes | 7f704b3 | 2010-08-12 20:20:53 +0000 | [diff] [blame] | 7388 | { X86::VXORPSrm,   X86::VXORPDrm,   X86::VPXORrm    }, | 
|  | 7389 | { X86::VXORPSrr,   X86::VXORPDrr,   X86::VPXORrr    }, | 
| Bruno Cardoso Lopes | 6778597 | 2011-07-14 18:50:58 +0000 | [diff] [blame] | 7390 | // AVX 256-bit support | 
|  | 7391 | { X86::VMOVAPSYmr,   X86::VMOVAPDYmr,   X86::VMOVDQAYmr  }, | 
|  | 7392 | { X86::VMOVAPSYrm,   X86::VMOVAPDYrm,   X86::VMOVDQAYrm  }, | 
|  | 7393 | { X86::VMOVAPSYrr,   X86::VMOVAPDYrr,   X86::VMOVDQAYrr  }, | 
|  | 7394 | { X86::VMOVUPSYmr,   X86::VMOVUPDYmr,   X86::VMOVDQUYmr  }, | 
|  | 7395 | { X86::VMOVUPSYrm,   X86::VMOVUPDYrm,   X86::VMOVDQUYrm  }, | 
| Craig Topper | f4151be | 2016-07-22 05:00:52 +0000 | [diff] [blame] | 7396 | { X86::VMOVNTPSYmr,  X86::VMOVNTPDYmr,  X86::VMOVNTDQYmr }, | 
|  | 7397 | // AVX512 support | 
|  | 7398 | { X86::VMOVLPSZ128mr,  X86::VMOVLPDZ128mr,  X86::VMOVPQI2QIZmr  }, | 
|  | 7399 | { X86::VMOVNTPSZ128mr, X86::VMOVNTPDZ128mr, X86::VMOVNTDQZ128mr }, | 
|  | 7400 | { X86::VMOVNTPSZ128mr, X86::VMOVNTPDZ128mr, X86::VMOVNTDQZ128mr }, | 
|  | 7401 | { X86::VMOVNTPSZmr,    X86::VMOVNTPDZmr,    X86::VMOVNTDQZmr    }, | 
| Craig Topper | 05baa85 | 2011-11-15 05:55:35 +0000 | [diff] [blame] | 7402 | }; | 
|  | 7403 |  | 
| Craig Topper | 2dac962 | 2012-03-09 07:45:21 +0000 | [diff] [blame] | 7404 | static const uint16_t ReplaceableInstrsAVX2[][3] = { | 
| Craig Topper | 05baa85 | 2011-11-15 05:55:35 +0000 | [diff] [blame] | 7405 | //PackedSingle       PackedDouble       PackedInt | 
| Craig Topper | f87a2be | 2011-11-09 09:37:21 +0000 | [diff] [blame] | 7406 | { X86::VANDNPSYrm,   X86::VANDNPDYrm,   X86::VPANDNYrm   }, | 
|  | 7407 | { X86::VANDNPSYrr,   X86::VANDNPDYrr,   X86::VPANDNYrr   }, | 
|  | 7408 | { X86::VANDPSYrm,    X86::VANDPDYrm,    X86::VPANDYrm    }, | 
|  | 7409 | { X86::VANDPSYrr,    X86::VANDPDYrr,    X86::VPANDYrr    }, | 
|  | 7410 | { X86::VORPSYrm,     X86::VORPDYrm,     X86::VPORYrm     }, | 
|  | 7411 | { X86::VORPSYrr,     X86::VORPDYrr,     X86::VPORYrr     }, | 
|  | 7412 | { X86::VXORPSYrm,    X86::VXORPDYrm,    X86::VPXORYrm    }, | 
| Craig Topper | 12b72de | 2011-11-29 05:37:58 +0000 | [diff] [blame] | 7413 | { X86::VXORPSYrr,    X86::VXORPDYrr,    X86::VPXORYrr    }, | 
|  | 7414 | { X86::VEXTRACTF128mr, X86::VEXTRACTF128mr, X86::VEXTRACTI128mr }, | 
|  | 7415 | { X86::VEXTRACTF128rr, X86::VEXTRACTF128rr, X86::VEXTRACTI128rr }, | 
|  | 7416 | { X86::VINSERTF128rm,  X86::VINSERTF128rm,  X86::VINSERTI128rm }, | 
|  | 7417 | { X86::VINSERTF128rr,  X86::VINSERTF128rr,  X86::VINSERTI128rr }, | 
|  | 7418 | { X86::VPERM2F128rm,   X86::VPERM2F128rm,   X86::VPERM2I128rm }, | 
| Quentin Colombet | 6f12ae0 | 2014-03-26 00:10:22 +0000 | [diff] [blame] | 7419 | { X86::VPERM2F128rr,   X86::VPERM2F128rr,   X86::VPERM2I128rr }, | 
|  | 7420 | { X86::VBROADCASTSSrm, X86::VBROADCASTSSrm, X86::VPBROADCASTDrm}, | 
|  | 7421 | { X86::VBROADCASTSSrr, X86::VBROADCASTSSrr, X86::VPBROADCASTDrr}, | 
|  | 7422 | { X86::VBROADCASTSSYrr, X86::VBROADCASTSSYrr, X86::VPBROADCASTDYrr}, | 
|  | 7423 | { X86::VBROADCASTSSYrm, X86::VBROADCASTSSYrm, X86::VPBROADCASTDYrm}, | 
|  | 7424 | { X86::VBROADCASTSDYrr, X86::VBROADCASTSDYrr, X86::VPBROADCASTQYrr}, | 
|  | 7425 | { X86::VBROADCASTSDYrm, X86::VBROADCASTSDYrm, X86::VPBROADCASTQYrm} | 
| Jakob Stoklund Olesen | b551aa4 | 2010-03-29 23:24:21 +0000 | [diff] [blame] | 7426 | }; | 
| Jakob Stoklund Olesen | 49e121d | 2010-03-25 17:25:00 +0000 | [diff] [blame] | 7427 |  | 
| Craig Topper | f4151be | 2016-07-22 05:00:52 +0000 | [diff] [blame] | 7428 | static const uint16_t ReplaceableInstrsAVX512[][4] = { | 
|  | 7429 | // Two integer columns for 64-bit and 32-bit elements. | 
| Craig Topper | c48c029 | 2016-08-01 07:55:33 +0000 | [diff] [blame] | 7430 | //PackedSingle        PackedDouble        PackedInt             PackedInt | 
|  | 7431 | { X86::VMOVAPSZ128mr, X86::VMOVAPDZ128mr, X86::VMOVDQA64Z128mr, X86::VMOVDQA32Z128mr  }, | 
|  | 7432 | { X86::VMOVAPSZ128rm, X86::VMOVAPDZ128rm, X86::VMOVDQA64Z128rm, X86::VMOVDQA32Z128rm  }, | 
|  | 7433 | { X86::VMOVAPSZ128rr, X86::VMOVAPDZ128rr, X86::VMOVDQA64Z128rr, X86::VMOVDQA32Z128rr  }, | 
|  | 7434 | { X86::VMOVUPSZ128mr, X86::VMOVUPDZ128mr, X86::VMOVDQU64Z128mr, X86::VMOVDQU32Z128mr  }, | 
|  | 7435 | { X86::VMOVUPSZ128rm, X86::VMOVUPDZ128rm, X86::VMOVDQU64Z128rm, X86::VMOVDQU32Z128rm  }, | 
|  | 7436 | { X86::VMOVAPSZ256mr, X86::VMOVAPDZ256mr, X86::VMOVDQA64Z256mr, X86::VMOVDQA32Z256mr  }, | 
|  | 7437 | { X86::VMOVAPSZ256rm, X86::VMOVAPDZ256rm, X86::VMOVDQA64Z256rm, X86::VMOVDQA32Z256rm  }, | 
|  | 7438 | { X86::VMOVAPSZ256rr, X86::VMOVAPDZ256rr, X86::VMOVDQA64Z256rr, X86::VMOVDQA32Z256rr  }, | 
|  | 7439 | { X86::VMOVUPSZ256mr, X86::VMOVUPDZ256mr, X86::VMOVDQU64Z256mr, X86::VMOVDQU32Z256mr  }, | 
|  | 7440 | { X86::VMOVUPSZ256rm, X86::VMOVUPDZ256rm, X86::VMOVDQU64Z256rm, X86::VMOVDQU32Z256rm  }, | 
|  | 7441 | { X86::VMOVAPSZmr,    X86::VMOVAPDZmr,    X86::VMOVDQA64Zmr,    X86::VMOVDQA32Zmr     }, | 
|  | 7442 | { X86::VMOVAPSZrm,    X86::VMOVAPDZrm,    X86::VMOVDQA64Zrm,    X86::VMOVDQA32Zrm     }, | 
|  | 7443 | { X86::VMOVAPSZrr,    X86::VMOVAPDZrr,    X86::VMOVDQA64Zrr,    X86::VMOVDQA32Zrr     }, | 
|  | 7444 | { X86::VMOVUPSZmr,    X86::VMOVUPDZmr,    X86::VMOVDQU64Zmr,    X86::VMOVDQU32Zmr     }, | 
|  | 7445 | { X86::VMOVUPSZrm,    X86::VMOVUPDZrm,    X86::VMOVDQU64Zrm,    X86::VMOVDQU32Zrm     }, | 
| Craig Topper | 00d34ed | 2016-07-31 17:15:07 +0000 | [diff] [blame] | 7446 | }; | 
|  | 7447 |  | 
|  | 7448 | static const uint16_t ReplaceableInstrsAVX512DQ[][4] = { | 
|  | 7449 | // Two integer columns for 64-bit and 32-bit elements. | 
|  | 7450 | //PackedSingle        PackedDouble        PackedInt           PackedInt | 
| Craig Topper | f4151be | 2016-07-22 05:00:52 +0000 | [diff] [blame] | 7451 | { X86::VANDNPSZ128rm, X86::VANDNPDZ128rm, X86::VPANDNQZ128rm, X86::VPANDNDZ128rm }, | 
|  | 7452 | { X86::VANDNPSZ128rr, X86::VANDNPDZ128rr, X86::VPANDNQZ128rr, X86::VPANDNDZ128rr }, | 
|  | 7453 | { X86::VANDPSZ128rm,  X86::VANDPDZ128rm,  X86::VPANDQZ128rm,  X86::VPANDDZ128rm  }, | 
|  | 7454 | { X86::VANDPSZ128rr,  X86::VANDPDZ128rr,  X86::VPANDQZ128rr,  X86::VPANDDZ128rr  }, | 
|  | 7455 | { X86::VORPSZ128rm,   X86::VORPDZ128rm,   X86::VPORQZ128rm,   X86::VPORDZ128rm   }, | 
|  | 7456 | { X86::VORPSZ128rr,   X86::VORPDZ128rr,   X86::VPORQZ128rr,   X86::VPORDZ128rr   }, | 
|  | 7457 | { X86::VXORPSZ128rm,  X86::VXORPDZ128rm,  X86::VPXORQZ128rm,  X86::VPXORDZ128rm  }, | 
|  | 7458 | { X86::VXORPSZ128rr,  X86::VXORPDZ128rr,  X86::VPXORQZ128rr,  X86::VPXORDZ128rr  }, | 
|  | 7459 | { X86::VANDNPSZ256rm, X86::VANDNPDZ256rm, X86::VPANDNQZ256rm, X86::VPANDNDZ256rm }, | 
|  | 7460 | { X86::VANDNPSZ256rr, X86::VANDNPDZ256rr, X86::VPANDNQZ256rr, X86::VPANDNDZ256rr }, | 
|  | 7461 | { X86::VANDPSZ256rm,  X86::VANDPDZ256rm,  X86::VPANDQZ256rm,  X86::VPANDDZ256rm  }, | 
|  | 7462 | { X86::VANDPSZ256rr,  X86::VANDPDZ256rr,  X86::VPANDQZ256rr,  X86::VPANDDZ256rr  }, | 
|  | 7463 | { X86::VORPSZ256rm,   X86::VORPDZ256rm,   X86::VPORQZ256rm,   X86::VPORDZ256rm   }, | 
|  | 7464 | { X86::VORPSZ256rr,   X86::VORPDZ256rr,   X86::VPORQZ256rr,   X86::VPORDZ256rr   }, | 
|  | 7465 | { X86::VXORPSZ256rm,  X86::VXORPDZ256rm,  X86::VPXORQZ256rm,  X86::VPXORDZ256rm  }, | 
|  | 7466 | { X86::VXORPSZ256rr,  X86::VXORPDZ256rr,  X86::VPXORQZ256rr,  X86::VPXORDZ256rr  }, | 
|  | 7467 | { X86::VANDNPSZrm,    X86::VANDNPDZrm,    X86::VPANDNQZrm,    X86::VPANDNDZrm    }, | 
|  | 7468 | { X86::VANDNPSZrr,    X86::VANDNPDZrr,    X86::VPANDNQZrr,    X86::VPANDNDZrr    }, | 
|  | 7469 | { X86::VANDPSZrm,     X86::VANDPDZrm,     X86::VPANDQZrm,     X86::VPANDDZrm     }, | 
|  | 7470 | { X86::VANDPSZrr,     X86::VANDPDZrr,     X86::VPANDQZrr,     X86::VPANDDZrr     }, | 
|  | 7471 | { X86::VORPSZrm,      X86::VORPDZrm,      X86::VPORQZrm,      X86::VPORDZrm      }, | 
|  | 7472 | { X86::VORPSZrr,      X86::VORPDZrr,      X86::VPORQZrr,      X86::VPORDZrr      }, | 
|  | 7473 | { X86::VXORPSZrm,     X86::VXORPDZrm,     X86::VPXORQZrm,     X86::VPXORDZrm     }, | 
|  | 7474 | { X86::VXORPSZrr,     X86::VXORPDZrr,     X86::VPXORQZrr,     X86::VPXORDZrr     }, | 
| Craig Topper | f4151be | 2016-07-22 05:00:52 +0000 | [diff] [blame] | 7475 | }; | 
|  | 7476 |  | 
| Jakob Stoklund Olesen | b551aa4 | 2010-03-29 23:24:21 +0000 | [diff] [blame] | 7477 | // FIXME: Some shuffle and unpack instructions have equivalents in different | 
|  | 7478 | // domains, but they require a bit more work than just switching opcodes. | 
| Jakob Stoklund Olesen | 49e121d | 2010-03-25 17:25:00 +0000 | [diff] [blame] | 7479 |  | 
| Craig Topper | 2dac962 | 2012-03-09 07:45:21 +0000 | [diff] [blame] | 7480 | static const uint16_t *lookup(unsigned opcode, unsigned domain) { | 
| Craig Topper | 271f9de | 2015-12-01 06:13:15 +0000 | [diff] [blame] | 7481 | for (const uint16_t (&Row)[3] : ReplaceableInstrs) | 
|  | 7482 | if (Row[domain-1] == opcode) | 
|  | 7483 | return Row; | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 7484 | return nullptr; | 
| Craig Topper | 649d1c5 | 2011-11-15 06:39:01 +0000 | [diff] [blame] | 7485 | } | 
|  | 7486 |  | 
| Craig Topper | 2dac962 | 2012-03-09 07:45:21 +0000 | [diff] [blame] | 7487 | static const uint16_t *lookupAVX2(unsigned opcode, unsigned domain) { | 
| Craig Topper | 271f9de | 2015-12-01 06:13:15 +0000 | [diff] [blame] | 7488 | for (const uint16_t (&Row)[3] : ReplaceableInstrsAVX2) | 
|  | 7489 | if (Row[domain-1] == opcode) | 
|  | 7490 | return Row; | 
| Craig Topper | 062a2ba | 2014-04-25 05:30:21 +0000 | [diff] [blame] | 7491 | return nullptr; | 
| Jakob Stoklund Olesen | b551aa4 | 2010-03-29 23:24:21 +0000 | [diff] [blame] | 7492 | } | 
|  | 7493 |  | 
| Craig Topper | f4151be | 2016-07-22 05:00:52 +0000 | [diff] [blame] | 7494 | static const uint16_t *lookupAVX512(unsigned opcode, unsigned domain) { | 
|  | 7495 | // If this is the integer domain make sure to check both integer columns. | 
|  | 7496 | for (const uint16_t (&Row)[4] : ReplaceableInstrsAVX512) | 
|  | 7497 | if (Row[domain-1] == opcode || (domain == 3 && Row[3] == opcode)) | 
|  | 7498 | return Row; | 
|  | 7499 | return nullptr; | 
|  | 7500 | } | 
|  | 7501 |  | 
| Craig Topper | 00d34ed | 2016-07-31 17:15:07 +0000 | [diff] [blame] | 7502 | static const uint16_t *lookupAVX512DQ(unsigned opcode, unsigned domain) { | 
|  | 7503 | // If this is the integer domain make sure to check both integer columns. | 
|  | 7504 | for (const uint16_t (&Row)[4] : ReplaceableInstrsAVX512DQ) | 
|  | 7505 | if (Row[domain-1] == opcode || (domain == 3 && Row[3] == opcode)) | 
|  | 7506 | return Row; | 
|  | 7507 | return nullptr; | 
|  | 7508 | } | 
|  | 7509 |  | 
| Jakob Stoklund Olesen | b551aa4 | 2010-03-29 23:24:21 +0000 | [diff] [blame] | 7510 | std::pair<uint16_t, uint16_t> | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 7511 | X86InstrInfo::getExecutionDomain(const MachineInstr &MI) const { | 
|  | 7512 | uint16_t domain = (MI.getDesc().TSFlags >> X86II::SSEDomainShift) & 3; | 
| Craig Topper | 649d1c5 | 2011-11-15 06:39:01 +0000 | [diff] [blame] | 7513 | uint16_t validDomains = 0; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 7514 | if (domain && lookup(MI.getOpcode(), domain)) | 
| Craig Topper | 649d1c5 | 2011-11-15 06:39:01 +0000 | [diff] [blame] | 7515 | validDomains = 0xe; | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 7516 | else if (domain && lookupAVX2(MI.getOpcode(), domain)) | 
| Craig Topper | 00d34ed | 2016-07-31 17:15:07 +0000 | [diff] [blame] | 7517 | validDomains = Subtarget.hasAVX2() ? 0xe : 0x6; | 
| Craig Topper | f4151be | 2016-07-22 05:00:52 +0000 | [diff] [blame] | 7518 | else if (domain && lookupAVX512(MI.getOpcode(), domain)) | 
|  | 7519 | validDomains = 0xe; | 
| Craig Topper | 00d34ed | 2016-07-31 17:15:07 +0000 | [diff] [blame] | 7520 | else if (domain && lookupAVX512DQ(MI.getOpcode(), domain)) | 
|  | 7521 | validDomains = Subtarget.hasDQI() ? 0xe : 0x8; | 
| Craig Topper | 649d1c5 | 2011-11-15 06:39:01 +0000 | [diff] [blame] | 7522 | return std::make_pair(domain, validDomains); | 
| Jakob Stoklund Olesen | b551aa4 | 2010-03-29 23:24:21 +0000 | [diff] [blame] | 7523 | } | 
|  | 7524 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 7525 | void X86InstrInfo::setExecutionDomain(MachineInstr &MI, unsigned Domain) const { | 
| Jakob Stoklund Olesen | b551aa4 | 2010-03-29 23:24:21 +0000 | [diff] [blame] | 7526 | assert(Domain>0 && Domain<4 && "Invalid execution domain"); | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 7527 | uint16_t dom = (MI.getDesc().TSFlags >> X86II::SSEDomainShift) & 3; | 
| Jakob Stoklund Olesen | b551aa4 | 2010-03-29 23:24:21 +0000 | [diff] [blame] | 7528 | assert(dom && "Not an SSE instruction"); | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 7529 | const uint16_t *table = lookup(MI.getOpcode(), dom); | 
| Jakob Stoklund Olesen | 0284541 | 2011-11-23 04:03:08 +0000 | [diff] [blame] | 7530 | if (!table) { // try the other table | 
| Eric Christopher | 6c786a1 | 2014-06-10 22:34:31 +0000 | [diff] [blame] | 7531 | assert((Subtarget.hasAVX2() || Domain < 3) && | 
| Jakob Stoklund Olesen | 0284541 | 2011-11-23 04:03:08 +0000 | [diff] [blame] | 7532 | "256-bit vector operations only available in AVX2"); | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 7533 | table = lookupAVX2(MI.getOpcode(), dom); | 
| Jakob Stoklund Olesen | 0284541 | 2011-11-23 04:03:08 +0000 | [diff] [blame] | 7534 | } | 
| Craig Topper | f4151be | 2016-07-22 05:00:52 +0000 | [diff] [blame] | 7535 | if (!table) { // try the AVX512 table | 
| Craig Topper | 00d34ed | 2016-07-31 17:15:07 +0000 | [diff] [blame] | 7536 | assert(Subtarget.hasAVX512() && "Requires AVX-512"); | 
| Craig Topper | f4151be | 2016-07-22 05:00:52 +0000 | [diff] [blame] | 7537 | table = lookupAVX512(MI.getOpcode(), dom); | 
|  | 7538 | // Don't change integer Q instructions to D instructions. | 
| Craig Topper | c48c029 | 2016-08-01 07:55:33 +0000 | [diff] [blame] | 7539 | if (table && Domain == 3 && table[3] == MI.getOpcode()) | 
| Craig Topper | 00d34ed | 2016-07-31 17:15:07 +0000 | [diff] [blame] | 7540 | Domain = 4; | 
|  | 7541 | } | 
|  | 7542 | if (!table) { // try the AVX512DQ table | 
|  | 7543 | assert((Subtarget.hasDQI() || Domain >=3) && "Requires AVX-512DQ"); | 
|  | 7544 | table = lookupAVX512DQ(MI.getOpcode(), dom); | 
|  | 7545 | // Don't change integer Q instructions to D instructions. | 
| Craig Topper | c48c029 | 2016-08-01 07:55:33 +0000 | [diff] [blame] | 7546 | if (table && Domain == 3 && table[3] == MI.getOpcode()) | 
| Craig Topper | f4151be | 2016-07-22 05:00:52 +0000 | [diff] [blame] | 7547 | Domain = 4; | 
|  | 7548 | } | 
| Jakob Stoklund Olesen | b551aa4 | 2010-03-29 23:24:21 +0000 | [diff] [blame] | 7549 | assert(table && "Cannot change domain"); | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 7550 | MI.setDesc(get(table[Domain - 1])); | 
| Jakob Stoklund Olesen | 49e121d | 2010-03-25 17:25:00 +0000 | [diff] [blame] | 7551 | } | 
| Chris Lattner | 6a5e706 | 2010-04-26 23:37:21 +0000 | [diff] [blame] | 7552 |  | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 7553 | /// Return the noop instruction to use for a noop. | 
| Chris Lattner | 6a5e706 | 2010-04-26 23:37:21 +0000 | [diff] [blame] | 7554 | void X86InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const { | 
|  | 7555 | NopInst.setOpcode(X86::NOOP); | 
|  | 7556 | } | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 7557 |  | 
| Tom Roeder | eb7a303 | 2014-11-11 21:08:02 +0000 | [diff] [blame] | 7558 | // This code must remain in sync with getJumpInstrTableEntryBound in this class! | 
|  | 7559 | // In particular, getJumpInstrTableEntryBound must always return an upper bound | 
|  | 7560 | // on the encoding lengths of the instructions generated by | 
|  | 7561 | // getUnconditionalBranch and getTrap. | 
| Tom Roeder | 44cb65f | 2014-06-05 19:29:43 +0000 | [diff] [blame] | 7562 | void X86InstrInfo::getUnconditionalBranch( | 
|  | 7563 | MCInst &Branch, const MCSymbolRefExpr *BranchTarget) const { | 
| Craig Topper | 49758aa | 2015-01-06 04:23:53 +0000 | [diff] [blame] | 7564 | Branch.setOpcode(X86::JMP_1); | 
| Jim Grosbach | e9119e4 | 2015-05-13 18:37:00 +0000 | [diff] [blame] | 7565 | Branch.addOperand(MCOperand::createExpr(BranchTarget)); | 
| Tom Roeder | 44cb65f | 2014-06-05 19:29:43 +0000 | [diff] [blame] | 7566 | } | 
|  | 7567 |  | 
| Tom Roeder | eb7a303 | 2014-11-11 21:08:02 +0000 | [diff] [blame] | 7568 | // This code must remain in sync with getJumpInstrTableEntryBound in this class! | 
|  | 7569 | // In particular, getJumpInstrTableEntryBound must always return an upper bound | 
|  | 7570 | // on the encoding lengths of the instructions generated by | 
|  | 7571 | // getUnconditionalBranch and getTrap. | 
| Tom Roeder | 44cb65f | 2014-06-05 19:29:43 +0000 | [diff] [blame] | 7572 | void X86InstrInfo::getTrap(MCInst &MI) const { | 
|  | 7573 | MI.setOpcode(X86::TRAP); | 
|  | 7574 | } | 
|  | 7575 |  | 
| Tom Roeder | eb7a303 | 2014-11-11 21:08:02 +0000 | [diff] [blame] | 7576 | // See getTrap and getUnconditionalBranch for conditions on the value returned | 
|  | 7577 | // by this function. | 
|  | 7578 | unsigned X86InstrInfo::getJumpInstrTableEntryBound() const { | 
|  | 7579 | // 5 bytes suffice: JMP_4 Symbol@PLT is uses 1 byte (E9) for the JMP_4 and 4 | 
|  | 7580 | // bytes for the symbol offset. And TRAP is ud2, which is two bytes (0F 0B). | 
|  | 7581 | return 5; | 
|  | 7582 | } | 
|  | 7583 |  | 
| Andrew Trick | 641e2d4 | 2011-03-05 08:00:22 +0000 | [diff] [blame] | 7584 | bool X86InstrInfo::isHighLatencyDef(int opc) const { | 
|  | 7585 | switch (opc) { | 
| Evan Cheng | 63c7608 | 2010-10-19 18:58:51 +0000 | [diff] [blame] | 7586 | default: return false; | 
| Craig Topper | fe5a6dc | 2016-07-18 06:14:45 +0000 | [diff] [blame] | 7587 | case X86::DIVPDrm: | 
|  | 7588 | case X86::DIVPDrr: | 
|  | 7589 | case X86::DIVPSrm: | 
|  | 7590 | case X86::DIVPSrr: | 
| Evan Cheng | 63c7608 | 2010-10-19 18:58:51 +0000 | [diff] [blame] | 7591 | case X86::DIVSDrm: | 
|  | 7592 | case X86::DIVSDrm_Int: | 
|  | 7593 | case X86::DIVSDrr: | 
|  | 7594 | case X86::DIVSDrr_Int: | 
|  | 7595 | case X86::DIVSSrm: | 
|  | 7596 | case X86::DIVSSrm_Int: | 
|  | 7597 | case X86::DIVSSrr: | 
|  | 7598 | case X86::DIVSSrr_Int: | 
|  | 7599 | case X86::SQRTPDm: | 
| Evan Cheng | 63c7608 | 2010-10-19 18:58:51 +0000 | [diff] [blame] | 7600 | case X86::SQRTPDr: | 
| Evan Cheng | 63c7608 | 2010-10-19 18:58:51 +0000 | [diff] [blame] | 7601 | case X86::SQRTPSm: | 
| Evan Cheng | 63c7608 | 2010-10-19 18:58:51 +0000 | [diff] [blame] | 7602 | case X86::SQRTPSr: | 
| Evan Cheng | 63c7608 | 2010-10-19 18:58:51 +0000 | [diff] [blame] | 7603 | case X86::SQRTSDm: | 
|  | 7604 | case X86::SQRTSDm_Int: | 
|  | 7605 | case X86::SQRTSDr: | 
|  | 7606 | case X86::SQRTSDr_Int: | 
|  | 7607 | case X86::SQRTSSm: | 
|  | 7608 | case X86::SQRTSSm_Int: | 
|  | 7609 | case X86::SQRTSSr: | 
|  | 7610 | case X86::SQRTSSr_Int: | 
| Bruno Cardoso Lopes | c69d68a | 2011-09-15 22:15:52 +0000 | [diff] [blame] | 7611 | // AVX instructions with high latency | 
| Craig Topper | fe5a6dc | 2016-07-18 06:14:45 +0000 | [diff] [blame] | 7612 | case X86::VDIVPDrm: | 
|  | 7613 | case X86::VDIVPDrr: | 
|  | 7614 | case X86::VDIVPDYrm: | 
|  | 7615 | case X86::VDIVPDYrr: | 
|  | 7616 | case X86::VDIVPSrm: | 
|  | 7617 | case X86::VDIVPSrr: | 
|  | 7618 | case X86::VDIVPSYrm: | 
|  | 7619 | case X86::VDIVPSYrr: | 
| Bruno Cardoso Lopes | c69d68a | 2011-09-15 22:15:52 +0000 | [diff] [blame] | 7620 | case X86::VDIVSDrm: | 
|  | 7621 | case X86::VDIVSDrm_Int: | 
|  | 7622 | case X86::VDIVSDrr: | 
|  | 7623 | case X86::VDIVSDrr_Int: | 
|  | 7624 | case X86::VDIVSSrm: | 
|  | 7625 | case X86::VDIVSSrm_Int: | 
|  | 7626 | case X86::VDIVSSrr: | 
|  | 7627 | case X86::VDIVSSrr_Int: | 
|  | 7628 | case X86::VSQRTPDm: | 
| Bruno Cardoso Lopes | c69d68a | 2011-09-15 22:15:52 +0000 | [diff] [blame] | 7629 | case X86::VSQRTPDr: | 
| Craig Topper | fe5a6dc | 2016-07-18 06:14:45 +0000 | [diff] [blame] | 7630 | case X86::VSQRTPDYm: | 
|  | 7631 | case X86::VSQRTPDYr: | 
| Bruno Cardoso Lopes | c69d68a | 2011-09-15 22:15:52 +0000 | [diff] [blame] | 7632 | case X86::VSQRTPSm: | 
| Bruno Cardoso Lopes | c69d68a | 2011-09-15 22:15:52 +0000 | [diff] [blame] | 7633 | case X86::VSQRTPSr: | 
| Craig Topper | fe5a6dc | 2016-07-18 06:14:45 +0000 | [diff] [blame] | 7634 | case X86::VSQRTPSYm: | 
|  | 7635 | case X86::VSQRTPSYr: | 
| Bruno Cardoso Lopes | c69d68a | 2011-09-15 22:15:52 +0000 | [diff] [blame] | 7636 | case X86::VSQRTSDm: | 
|  | 7637 | case X86::VSQRTSDm_Int: | 
|  | 7638 | case X86::VSQRTSDr: | 
| Craig Topper | fe5a6dc | 2016-07-18 06:14:45 +0000 | [diff] [blame] | 7639 | case X86::VSQRTSDr_Int: | 
| Bruno Cardoso Lopes | c69d68a | 2011-09-15 22:15:52 +0000 | [diff] [blame] | 7640 | case X86::VSQRTSSm: | 
|  | 7641 | case X86::VSQRTSSm_Int: | 
|  | 7642 | case X86::VSQRTSSr: | 
| Craig Topper | fe5a6dc | 2016-07-18 06:14:45 +0000 | [diff] [blame] | 7643 | case X86::VSQRTSSr_Int: | 
|  | 7644 | // AVX512 instructions with high latency | 
|  | 7645 | case X86::VDIVPDZ128rm: | 
|  | 7646 | case X86::VDIVPDZ128rmb: | 
|  | 7647 | case X86::VDIVPDZ128rmbk: | 
|  | 7648 | case X86::VDIVPDZ128rmbkz: | 
|  | 7649 | case X86::VDIVPDZ128rmk: | 
|  | 7650 | case X86::VDIVPDZ128rmkz: | 
|  | 7651 | case X86::VDIVPDZ128rr: | 
|  | 7652 | case X86::VDIVPDZ128rrk: | 
|  | 7653 | case X86::VDIVPDZ128rrkz: | 
|  | 7654 | case X86::VDIVPDZ256rm: | 
|  | 7655 | case X86::VDIVPDZ256rmb: | 
|  | 7656 | case X86::VDIVPDZ256rmbk: | 
|  | 7657 | case X86::VDIVPDZ256rmbkz: | 
|  | 7658 | case X86::VDIVPDZ256rmk: | 
|  | 7659 | case X86::VDIVPDZ256rmkz: | 
|  | 7660 | case X86::VDIVPDZ256rr: | 
|  | 7661 | case X86::VDIVPDZ256rrk: | 
|  | 7662 | case X86::VDIVPDZ256rrkz: | 
|  | 7663 | case X86::VDIVPDZrb: | 
|  | 7664 | case X86::VDIVPDZrbk: | 
|  | 7665 | case X86::VDIVPDZrbkz: | 
|  | 7666 | case X86::VDIVPDZrm: | 
|  | 7667 | case X86::VDIVPDZrmb: | 
|  | 7668 | case X86::VDIVPDZrmbk: | 
|  | 7669 | case X86::VDIVPDZrmbkz: | 
|  | 7670 | case X86::VDIVPDZrmk: | 
|  | 7671 | case X86::VDIVPDZrmkz: | 
|  | 7672 | case X86::VDIVPDZrr: | 
|  | 7673 | case X86::VDIVPDZrrk: | 
|  | 7674 | case X86::VDIVPDZrrkz: | 
|  | 7675 | case X86::VDIVPSZ128rm: | 
|  | 7676 | case X86::VDIVPSZ128rmb: | 
|  | 7677 | case X86::VDIVPSZ128rmbk: | 
|  | 7678 | case X86::VDIVPSZ128rmbkz: | 
|  | 7679 | case X86::VDIVPSZ128rmk: | 
|  | 7680 | case X86::VDIVPSZ128rmkz: | 
|  | 7681 | case X86::VDIVPSZ128rr: | 
|  | 7682 | case X86::VDIVPSZ128rrk: | 
|  | 7683 | case X86::VDIVPSZ128rrkz: | 
|  | 7684 | case X86::VDIVPSZ256rm: | 
|  | 7685 | case X86::VDIVPSZ256rmb: | 
|  | 7686 | case X86::VDIVPSZ256rmbk: | 
|  | 7687 | case X86::VDIVPSZ256rmbkz: | 
|  | 7688 | case X86::VDIVPSZ256rmk: | 
|  | 7689 | case X86::VDIVPSZ256rmkz: | 
|  | 7690 | case X86::VDIVPSZ256rr: | 
|  | 7691 | case X86::VDIVPSZ256rrk: | 
|  | 7692 | case X86::VDIVPSZ256rrkz: | 
|  | 7693 | case X86::VDIVPSZrb: | 
|  | 7694 | case X86::VDIVPSZrbk: | 
|  | 7695 | case X86::VDIVPSZrbkz: | 
|  | 7696 | case X86::VDIVPSZrm: | 
|  | 7697 | case X86::VDIVPSZrmb: | 
|  | 7698 | case X86::VDIVPSZrmbk: | 
|  | 7699 | case X86::VDIVPSZrmbkz: | 
|  | 7700 | case X86::VDIVPSZrmk: | 
|  | 7701 | case X86::VDIVPSZrmkz: | 
|  | 7702 | case X86::VDIVPSZrr: | 
|  | 7703 | case X86::VDIVPSZrrk: | 
|  | 7704 | case X86::VDIVPSZrrkz: | 
| Elena Demikhovsky | 402ee64 | 2013-09-02 07:41:01 +0000 | [diff] [blame] | 7705 | case X86::VDIVSDZrm: | 
|  | 7706 | case X86::VDIVSDZrr: | 
| Craig Topper | fe5a6dc | 2016-07-18 06:14:45 +0000 | [diff] [blame] | 7707 | case X86::VDIVSDZrm_Int: | 
|  | 7708 | case X86::VDIVSDZrm_Intk: | 
|  | 7709 | case X86::VDIVSDZrm_Intkz: | 
|  | 7710 | case X86::VDIVSDZrr_Int: | 
|  | 7711 | case X86::VDIVSDZrr_Intk: | 
|  | 7712 | case X86::VDIVSDZrr_Intkz: | 
|  | 7713 | case X86::VDIVSDZrrb: | 
|  | 7714 | case X86::VDIVSDZrrbk: | 
|  | 7715 | case X86::VDIVSDZrrbkz: | 
| Elena Demikhovsky | 402ee64 | 2013-09-02 07:41:01 +0000 | [diff] [blame] | 7716 | case X86::VDIVSSZrm: | 
|  | 7717 | case X86::VDIVSSZrr: | 
| Craig Topper | fe5a6dc | 2016-07-18 06:14:45 +0000 | [diff] [blame] | 7718 | case X86::VDIVSSZrm_Int: | 
|  | 7719 | case X86::VDIVSSZrm_Intk: | 
|  | 7720 | case X86::VDIVSSZrm_Intkz: | 
|  | 7721 | case X86::VDIVSSZrr_Int: | 
|  | 7722 | case X86::VDIVSSZrr_Intk: | 
|  | 7723 | case X86::VDIVSSZrr_Intkz: | 
|  | 7724 | case X86::VDIVSSZrrb: | 
|  | 7725 | case X86::VDIVSSZrrbk: | 
|  | 7726 | case X86::VDIVSSZrrbkz: | 
|  | 7727 | case X86::VSQRTPDZ128m: | 
|  | 7728 | case X86::VSQRTPDZ128mb: | 
|  | 7729 | case X86::VSQRTPDZ128mbk: | 
|  | 7730 | case X86::VSQRTPDZ128mbkz: | 
|  | 7731 | case X86::VSQRTPDZ128mk: | 
|  | 7732 | case X86::VSQRTPDZ128mkz: | 
|  | 7733 | case X86::VSQRTPDZ128r: | 
|  | 7734 | case X86::VSQRTPDZ128rk: | 
|  | 7735 | case X86::VSQRTPDZ128rkz: | 
|  | 7736 | case X86::VSQRTPDZ256m: | 
|  | 7737 | case X86::VSQRTPDZ256mb: | 
|  | 7738 | case X86::VSQRTPDZ256mbk: | 
|  | 7739 | case X86::VSQRTPDZ256mbkz: | 
|  | 7740 | case X86::VSQRTPDZ256mk: | 
|  | 7741 | case X86::VSQRTPDZ256mkz: | 
|  | 7742 | case X86::VSQRTPDZ256r: | 
|  | 7743 | case X86::VSQRTPDZ256rk: | 
|  | 7744 | case X86::VSQRTPDZ256rkz: | 
|  | 7745 | case X86::VSQRTPDZm: | 
|  | 7746 | case X86::VSQRTPDZmb: | 
|  | 7747 | case X86::VSQRTPDZmbk: | 
|  | 7748 | case X86::VSQRTPDZmbkz: | 
|  | 7749 | case X86::VSQRTPDZmk: | 
|  | 7750 | case X86::VSQRTPDZmkz: | 
|  | 7751 | case X86::VSQRTPDZr: | 
|  | 7752 | case X86::VSQRTPDZrb: | 
|  | 7753 | case X86::VSQRTPDZrbk: | 
|  | 7754 | case X86::VSQRTPDZrbkz: | 
|  | 7755 | case X86::VSQRTPDZrk: | 
|  | 7756 | case X86::VSQRTPDZrkz: | 
|  | 7757 | case X86::VSQRTPSZ128m: | 
|  | 7758 | case X86::VSQRTPSZ128mb: | 
|  | 7759 | case X86::VSQRTPSZ128mbk: | 
|  | 7760 | case X86::VSQRTPSZ128mbkz: | 
|  | 7761 | case X86::VSQRTPSZ128mk: | 
|  | 7762 | case X86::VSQRTPSZ128mkz: | 
|  | 7763 | case X86::VSQRTPSZ128r: | 
|  | 7764 | case X86::VSQRTPSZ128rk: | 
|  | 7765 | case X86::VSQRTPSZ128rkz: | 
|  | 7766 | case X86::VSQRTPSZ256m: | 
|  | 7767 | case X86::VSQRTPSZ256mb: | 
|  | 7768 | case X86::VSQRTPSZ256mbk: | 
|  | 7769 | case X86::VSQRTPSZ256mbkz: | 
|  | 7770 | case X86::VSQRTPSZ256mk: | 
|  | 7771 | case X86::VSQRTPSZ256mkz: | 
|  | 7772 | case X86::VSQRTPSZ256r: | 
|  | 7773 | case X86::VSQRTPSZ256rk: | 
|  | 7774 | case X86::VSQRTPSZ256rkz: | 
|  | 7775 | case X86::VSQRTPSZm: | 
|  | 7776 | case X86::VSQRTPSZmb: | 
|  | 7777 | case X86::VSQRTPSZmbk: | 
|  | 7778 | case X86::VSQRTPSZmbkz: | 
|  | 7779 | case X86::VSQRTPSZmk: | 
|  | 7780 | case X86::VSQRTPSZmkz: | 
|  | 7781 | case X86::VSQRTPSZr: | 
|  | 7782 | case X86::VSQRTPSZrb: | 
|  | 7783 | case X86::VSQRTPSZrbk: | 
|  | 7784 | case X86::VSQRTPSZrbkz: | 
|  | 7785 | case X86::VSQRTPSZrk: | 
|  | 7786 | case X86::VSQRTPSZrkz: | 
|  | 7787 | case X86::VSQRTSDZm: | 
|  | 7788 | case X86::VSQRTSDZm_Int: | 
|  | 7789 | case X86::VSQRTSDZm_Intk: | 
|  | 7790 | case X86::VSQRTSDZm_Intkz: | 
|  | 7791 | case X86::VSQRTSDZr: | 
|  | 7792 | case X86::VSQRTSDZr_Int: | 
|  | 7793 | case X86::VSQRTSDZr_Intk: | 
|  | 7794 | case X86::VSQRTSDZr_Intkz: | 
|  | 7795 | case X86::VSQRTSDZrb_Int: | 
|  | 7796 | case X86::VSQRTSDZrb_Intk: | 
|  | 7797 | case X86::VSQRTSDZrb_Intkz: | 
|  | 7798 | case X86::VSQRTSSZm: | 
|  | 7799 | case X86::VSQRTSSZm_Int: | 
|  | 7800 | case X86::VSQRTSSZm_Intk: | 
|  | 7801 | case X86::VSQRTSSZm_Intkz: | 
|  | 7802 | case X86::VSQRTSSZr: | 
|  | 7803 | case X86::VSQRTSSZr_Int: | 
|  | 7804 | case X86::VSQRTSSZr_Intk: | 
|  | 7805 | case X86::VSQRTSSZr_Intkz: | 
|  | 7806 | case X86::VSQRTSSZrb_Int: | 
|  | 7807 | case X86::VSQRTSSZrb_Intk: | 
|  | 7808 | case X86::VSQRTSSZrb_Intkz: | 
| Elena Demikhovsky | 534015e | 2013-09-02 07:12:29 +0000 | [diff] [blame] | 7809 |  | 
| Craig Topper | fe5a6dc | 2016-07-18 06:14:45 +0000 | [diff] [blame] | 7810 | case X86::VGATHERDPDYrm: | 
|  | 7811 | case X86::VGATHERDPDZ128rm: | 
|  | 7812 | case X86::VGATHERDPDZ256rm: | 
| Elena Demikhovsky | 534015e | 2013-09-02 07:12:29 +0000 | [diff] [blame] | 7813 | case X86::VGATHERDPDZrm: | 
| Craig Topper | fe5a6dc | 2016-07-18 06:14:45 +0000 | [diff] [blame] | 7814 | case X86::VGATHERDPDrm: | 
|  | 7815 | case X86::VGATHERDPSYrm: | 
|  | 7816 | case X86::VGATHERDPSZ128rm: | 
|  | 7817 | case X86::VGATHERDPSZ256rm: | 
| Elena Demikhovsky | 534015e | 2013-09-02 07:12:29 +0000 | [diff] [blame] | 7818 | case X86::VGATHERDPSZrm: | 
| Craig Topper | fe5a6dc | 2016-07-18 06:14:45 +0000 | [diff] [blame] | 7819 | case X86::VGATHERDPSrm: | 
|  | 7820 | case X86::VGATHERPF0DPDm: | 
|  | 7821 | case X86::VGATHERPF0DPSm: | 
|  | 7822 | case X86::VGATHERPF0QPDm: | 
|  | 7823 | case X86::VGATHERPF0QPSm: | 
|  | 7824 | case X86::VGATHERPF1DPDm: | 
|  | 7825 | case X86::VGATHERPF1DPSm: | 
|  | 7826 | case X86::VGATHERPF1QPDm: | 
|  | 7827 | case X86::VGATHERPF1QPSm: | 
|  | 7828 | case X86::VGATHERQPDYrm: | 
|  | 7829 | case X86::VGATHERQPDZ128rm: | 
|  | 7830 | case X86::VGATHERQPDZ256rm: | 
|  | 7831 | case X86::VGATHERQPDZrm: | 
|  | 7832 | case X86::VGATHERQPDrm: | 
|  | 7833 | case X86::VGATHERQPSYrm: | 
|  | 7834 | case X86::VGATHERQPSZ128rm: | 
|  | 7835 | case X86::VGATHERQPSZ256rm: | 
|  | 7836 | case X86::VGATHERQPSZrm: | 
|  | 7837 | case X86::VGATHERQPSrm: | 
|  | 7838 | case X86::VPGATHERDDYrm: | 
|  | 7839 | case X86::VPGATHERDDZ128rm: | 
|  | 7840 | case X86::VPGATHERDDZ256rm: | 
| Elena Demikhovsky | 534015e | 2013-09-02 07:12:29 +0000 | [diff] [blame] | 7841 | case X86::VPGATHERDDZrm: | 
| Craig Topper | fe5a6dc | 2016-07-18 06:14:45 +0000 | [diff] [blame] | 7842 | case X86::VPGATHERDDrm: | 
|  | 7843 | case X86::VPGATHERDQYrm: | 
|  | 7844 | case X86::VPGATHERDQZ128rm: | 
|  | 7845 | case X86::VPGATHERDQZ256rm: | 
| Elena Demikhovsky | 402ee64 | 2013-09-02 07:41:01 +0000 | [diff] [blame] | 7846 | case X86::VPGATHERDQZrm: | 
| Craig Topper | fe5a6dc | 2016-07-18 06:14:45 +0000 | [diff] [blame] | 7847 | case X86::VPGATHERDQrm: | 
|  | 7848 | case X86::VPGATHERQDYrm: | 
|  | 7849 | case X86::VPGATHERQDZ128rm: | 
|  | 7850 | case X86::VPGATHERQDZ256rm: | 
|  | 7851 | case X86::VPGATHERQDZrm: | 
|  | 7852 | case X86::VPGATHERQDrm: | 
|  | 7853 | case X86::VPGATHERQQYrm: | 
|  | 7854 | case X86::VPGATHERQQZ128rm: | 
|  | 7855 | case X86::VPGATHERQQZ256rm: | 
|  | 7856 | case X86::VPGATHERQQZrm: | 
|  | 7857 | case X86::VPGATHERQQrm: | 
|  | 7858 | case X86::VSCATTERDPDZ128mr: | 
|  | 7859 | case X86::VSCATTERDPDZ256mr: | 
| Elena Demikhovsky | 402ee64 | 2013-09-02 07:41:01 +0000 | [diff] [blame] | 7860 | case X86::VSCATTERDPDZmr: | 
| Craig Topper | fe5a6dc | 2016-07-18 06:14:45 +0000 | [diff] [blame] | 7861 | case X86::VSCATTERDPSZ128mr: | 
|  | 7862 | case X86::VSCATTERDPSZ256mr: | 
| Elena Demikhovsky | 402ee64 | 2013-09-02 07:41:01 +0000 | [diff] [blame] | 7863 | case X86::VSCATTERDPSZmr: | 
| Craig Topper | fe5a6dc | 2016-07-18 06:14:45 +0000 | [diff] [blame] | 7864 | case X86::VSCATTERPF0DPDm: | 
|  | 7865 | case X86::VSCATTERPF0DPSm: | 
|  | 7866 | case X86::VSCATTERPF0QPDm: | 
|  | 7867 | case X86::VSCATTERPF0QPSm: | 
|  | 7868 | case X86::VSCATTERPF1DPDm: | 
|  | 7869 | case X86::VSCATTERPF1DPSm: | 
|  | 7870 | case X86::VSCATTERPF1QPDm: | 
|  | 7871 | case X86::VSCATTERPF1QPSm: | 
|  | 7872 | case X86::VSCATTERQPDZ128mr: | 
|  | 7873 | case X86::VSCATTERQPDZ256mr: | 
|  | 7874 | case X86::VSCATTERQPDZmr: | 
|  | 7875 | case X86::VSCATTERQPSZ128mr: | 
|  | 7876 | case X86::VSCATTERQPSZ256mr: | 
|  | 7877 | case X86::VSCATTERQPSZmr: | 
|  | 7878 | case X86::VPSCATTERDDZ128mr: | 
|  | 7879 | case X86::VPSCATTERDDZ256mr: | 
| Elena Demikhovsky | 402ee64 | 2013-09-02 07:41:01 +0000 | [diff] [blame] | 7880 | case X86::VPSCATTERDDZmr: | 
| Craig Topper | fe5a6dc | 2016-07-18 06:14:45 +0000 | [diff] [blame] | 7881 | case X86::VPSCATTERDQZ128mr: | 
|  | 7882 | case X86::VPSCATTERDQZ256mr: | 
| Elena Demikhovsky | 402ee64 | 2013-09-02 07:41:01 +0000 | [diff] [blame] | 7883 | case X86::VPSCATTERDQZmr: | 
| Craig Topper | fe5a6dc | 2016-07-18 06:14:45 +0000 | [diff] [blame] | 7884 | case X86::VPSCATTERQDZ128mr: | 
|  | 7885 | case X86::VPSCATTERQDZ256mr: | 
|  | 7886 | case X86::VPSCATTERQDZmr: | 
|  | 7887 | case X86::VPSCATTERQQZ128mr: | 
|  | 7888 | case X86::VPSCATTERQQZ256mr: | 
|  | 7889 | case X86::VPSCATTERQQZmr: | 
| Evan Cheng | 63c7608 | 2010-10-19 18:58:51 +0000 | [diff] [blame] | 7890 | return true; | 
|  | 7891 | } | 
|  | 7892 | } | 
|  | 7893 |  | 
| Duncan P. N. Exon Smith | 9cfc75c | 2016-06-30 00:01:54 +0000 | [diff] [blame] | 7894 | bool X86InstrInfo::hasHighOperandLatency(const TargetSchedModel &SchedModel, | 
|  | 7895 | const MachineRegisterInfo *MRI, | 
|  | 7896 | const MachineInstr &DefMI, | 
|  | 7897 | unsigned DefIdx, | 
|  | 7898 | const MachineInstr &UseMI, | 
|  | 7899 | unsigned UseIdx) const { | 
|  | 7900 | return isHighLatencyDef(DefMI.getOpcode()); | 
| Andrew Trick | 641e2d4 | 2011-03-05 08:00:22 +0000 | [diff] [blame] | 7901 | } | 
|  | 7902 |  | 
| Chad Rosier | 03a4730 | 2015-09-21 15:09:11 +0000 | [diff] [blame] | 7903 | bool X86InstrInfo::hasReassociableOperands(const MachineInstr &Inst, | 
|  | 7904 | const MachineBasicBlock *MBB) const { | 
| Sanjay Patel | 9ff4626 | 2015-07-31 16:21:55 +0000 | [diff] [blame] | 7905 | assert((Inst.getNumOperands() == 3 || Inst.getNumOperands() == 4) && | 
|  | 7906 | "Reassociation needs binary operators"); | 
| Sanjay Patel | 08829ba | 2015-06-10 20:32:21 +0000 | [diff] [blame] | 7907 |  | 
| Sanjay Patel | 9ff4626 | 2015-07-31 16:21:55 +0000 | [diff] [blame] | 7908 | // Integer binary math/logic instructions have a third source operand: | 
|  | 7909 | // the EFLAGS register. That operand must be both defined here and never | 
|  | 7910 | // used; ie, it must be dead. If the EFLAGS operand is live, then we can | 
|  | 7911 | // not change anything because rearranging the operands could affect other | 
|  | 7912 | // instructions that depend on the exact status flags (zero, sign, etc.) | 
|  | 7913 | // that are set by using these particular operands with this operation. | 
|  | 7914 | if (Inst.getNumOperands() == 4) { | 
|  | 7915 | assert(Inst.getOperand(3).isReg() && | 
|  | 7916 | Inst.getOperand(3).getReg() == X86::EFLAGS && | 
|  | 7917 | "Unexpected operand in reassociable instruction"); | 
|  | 7918 | if (!Inst.getOperand(3).isDead()) | 
|  | 7919 | return false; | 
|  | 7920 | } | 
| Sanjay Patel | e79b43a | 2015-06-23 00:39:40 +0000 | [diff] [blame] | 7921 |  | 
| Chad Rosier | 03a4730 | 2015-09-21 15:09:11 +0000 | [diff] [blame] | 7922 | return TargetInstrInfo::hasReassociableOperands(Inst, MBB); | 
| Sanjay Patel | 08829ba | 2015-06-10 20:32:21 +0000 | [diff] [blame] | 7923 | } | 
|  | 7924 |  | 
| Sanjay Patel | 681a56a | 2015-07-06 22:35:29 +0000 | [diff] [blame] | 7925 | // TODO: There are many more machine instruction opcodes to match: | 
| Sanjay Patel | 81beefc | 2015-07-09 22:58:39 +0000 | [diff] [blame] | 7926 | //       1. Other data types (integer, vectors) | 
| Sanjay Patel | 7c91289 | 2015-08-28 14:09:48 +0000 | [diff] [blame] | 7927 | //       2. Other math / logic operations (xor, or) | 
| Sanjay Patel | 40d4eb4 | 2015-08-15 17:01:54 +0000 | [diff] [blame] | 7928 | //       3. Other forms of the same operation (intrinsics and other variants) | 
| Chad Rosier | 03a4730 | 2015-09-21 15:09:11 +0000 | [diff] [blame] | 7929 | bool X86InstrInfo::isAssociativeAndCommutative(const MachineInstr &Inst) const { | 
| Sanjay Patel | 5bfbb36 | 2015-07-30 00:04:21 +0000 | [diff] [blame] | 7930 | switch (Inst.getOpcode()) { | 
| Sanjay Patel | 7c91289 | 2015-08-28 14:09:48 +0000 | [diff] [blame] | 7931 | case X86::AND8rr: | 
|  | 7932 | case X86::AND16rr: | 
|  | 7933 | case X86::AND32rr: | 
|  | 7934 | case X86::AND64rr: | 
| Sanjay Patel | d9a5c22 | 2015-08-31 20:27:03 +0000 | [diff] [blame] | 7935 | case X86::OR8rr: | 
|  | 7936 | case X86::OR16rr: | 
|  | 7937 | case X86::OR32rr: | 
|  | 7938 | case X86::OR64rr: | 
| Sanjay Patel | c9ae9d7 | 2015-09-03 16:36:16 +0000 | [diff] [blame] | 7939 | case X86::XOR8rr: | 
|  | 7940 | case X86::XOR16rr: | 
|  | 7941 | case X86::XOR32rr: | 
|  | 7942 | case X86::XOR64rr: | 
| Sanjay Patel | 9ff4626 | 2015-07-31 16:21:55 +0000 | [diff] [blame] | 7943 | case X86::IMUL16rr: | 
|  | 7944 | case X86::IMUL32rr: | 
|  | 7945 | case X86::IMUL64rr: | 
| Sanjay Patel | 8b960d2 | 2015-09-12 19:47:50 +0000 | [diff] [blame] | 7946 | case X86::PANDrr: | 
|  | 7947 | case X86::PORrr: | 
|  | 7948 | case X86::PXORrr: | 
| Craig Topper | ba9b93d | 2016-07-18 06:14:50 +0000 | [diff] [blame] | 7949 | case X86::ANDPDrr: | 
|  | 7950 | case X86::ANDPSrr: | 
|  | 7951 | case X86::ORPDrr: | 
|  | 7952 | case X86::ORPSrr: | 
|  | 7953 | case X86::XORPDrr: | 
|  | 7954 | case X86::XORPSrr: | 
| Craig Topper | 1af6cc0 | 2016-07-18 06:14:54 +0000 | [diff] [blame] | 7955 | case X86::PADDBrr: | 
|  | 7956 | case X86::PADDWrr: | 
|  | 7957 | case X86::PADDDrr: | 
|  | 7958 | case X86::PADDQrr: | 
| Sanjay Patel | 8b960d2 | 2015-09-12 19:47:50 +0000 | [diff] [blame] | 7959 | case X86::VPANDrr: | 
| Sanjay Patel | a114a10 | 2015-09-30 22:25:55 +0000 | [diff] [blame] | 7960 | case X86::VPANDYrr: | 
| Craig Topper | 3a99de4 | 2016-07-18 06:14:47 +0000 | [diff] [blame] | 7961 | case X86::VPANDDZ128rr: | 
|  | 7962 | case X86::VPANDDZ256rr: | 
|  | 7963 | case X86::VPANDDZrr: | 
|  | 7964 | case X86::VPANDQZ128rr: | 
|  | 7965 | case X86::VPANDQZ256rr: | 
|  | 7966 | case X86::VPANDQZrr: | 
| Sanjay Patel | 8b960d2 | 2015-09-12 19:47:50 +0000 | [diff] [blame] | 7967 | case X86::VPORrr: | 
| Sanjay Patel | a114a10 | 2015-09-30 22:25:55 +0000 | [diff] [blame] | 7968 | case X86::VPORYrr: | 
| Craig Topper | 3a99de4 | 2016-07-18 06:14:47 +0000 | [diff] [blame] | 7969 | case X86::VPORDZ128rr: | 
|  | 7970 | case X86::VPORDZ256rr: | 
|  | 7971 | case X86::VPORDZrr: | 
|  | 7972 | case X86::VPORQZ128rr: | 
|  | 7973 | case X86::VPORQZ256rr: | 
|  | 7974 | case X86::VPORQZrr: | 
| Sanjay Patel | 8b960d2 | 2015-09-12 19:47:50 +0000 | [diff] [blame] | 7975 | case X86::VPXORrr: | 
| Sanjay Patel | a114a10 | 2015-09-30 22:25:55 +0000 | [diff] [blame] | 7976 | case X86::VPXORYrr: | 
| Craig Topper | 3a99de4 | 2016-07-18 06:14:47 +0000 | [diff] [blame] | 7977 | case X86::VPXORDZ128rr: | 
|  | 7978 | case X86::VPXORDZ256rr: | 
|  | 7979 | case X86::VPXORDZrr: | 
|  | 7980 | case X86::VPXORQZ128rr: | 
|  | 7981 | case X86::VPXORQZ256rr: | 
|  | 7982 | case X86::VPXORQZrr: | 
| Craig Topper | ba9b93d | 2016-07-18 06:14:50 +0000 | [diff] [blame] | 7983 | case X86::VANDPDrr: | 
|  | 7984 | case X86::VANDPSrr: | 
|  | 7985 | case X86::VANDPDYrr: | 
|  | 7986 | case X86::VANDPSYrr: | 
|  | 7987 | case X86::VANDPDZ128rr: | 
|  | 7988 | case X86::VANDPSZ128rr: | 
|  | 7989 | case X86::VANDPDZ256rr: | 
|  | 7990 | case X86::VANDPSZ256rr: | 
|  | 7991 | case X86::VANDPDZrr: | 
|  | 7992 | case X86::VANDPSZrr: | 
|  | 7993 | case X86::VORPDrr: | 
|  | 7994 | case X86::VORPSrr: | 
|  | 7995 | case X86::VORPDYrr: | 
|  | 7996 | case X86::VORPSYrr: | 
|  | 7997 | case X86::VORPDZ128rr: | 
|  | 7998 | case X86::VORPSZ128rr: | 
|  | 7999 | case X86::VORPDZ256rr: | 
|  | 8000 | case X86::VORPSZ256rr: | 
|  | 8001 | case X86::VORPDZrr: | 
|  | 8002 | case X86::VORPSZrr: | 
|  | 8003 | case X86::VXORPDrr: | 
|  | 8004 | case X86::VXORPSrr: | 
|  | 8005 | case X86::VXORPDYrr: | 
|  | 8006 | case X86::VXORPSYrr: | 
|  | 8007 | case X86::VXORPDZ128rr: | 
|  | 8008 | case X86::VXORPSZ128rr: | 
|  | 8009 | case X86::VXORPDZ256rr: | 
|  | 8010 | case X86::VXORPSZ256rr: | 
|  | 8011 | case X86::VXORPDZrr: | 
|  | 8012 | case X86::VXORPSZrr: | 
| Craig Topper | 16a0744 | 2016-07-18 06:14:59 +0000 | [diff] [blame] | 8013 | case X86::KADDBrr: | 
|  | 8014 | case X86::KADDWrr: | 
|  | 8015 | case X86::KADDDrr: | 
|  | 8016 | case X86::KADDQrr: | 
|  | 8017 | case X86::KANDBrr: | 
|  | 8018 | case X86::KANDWrr: | 
|  | 8019 | case X86::KANDDrr: | 
|  | 8020 | case X86::KANDQrr: | 
|  | 8021 | case X86::KORBrr: | 
|  | 8022 | case X86::KORWrr: | 
|  | 8023 | case X86::KORDrr: | 
|  | 8024 | case X86::KORQrr: | 
|  | 8025 | case X86::KXORBrr: | 
|  | 8026 | case X86::KXORWrr: | 
|  | 8027 | case X86::KXORDrr: | 
|  | 8028 | case X86::KXORQrr: | 
| Craig Topper | 1af6cc0 | 2016-07-18 06:14:54 +0000 | [diff] [blame] | 8029 | case X86::VPADDBrr: | 
|  | 8030 | case X86::VPADDWrr: | 
|  | 8031 | case X86::VPADDDrr: | 
|  | 8032 | case X86::VPADDQrr: | 
|  | 8033 | case X86::VPADDBYrr: | 
|  | 8034 | case X86::VPADDWYrr: | 
|  | 8035 | case X86::VPADDDYrr: | 
|  | 8036 | case X86::VPADDQYrr: | 
|  | 8037 | case X86::VPADDBZ128rr: | 
|  | 8038 | case X86::VPADDWZ128rr: | 
|  | 8039 | case X86::VPADDDZ128rr: | 
|  | 8040 | case X86::VPADDQZ128rr: | 
|  | 8041 | case X86::VPADDBZ256rr: | 
|  | 8042 | case X86::VPADDWZ256rr: | 
|  | 8043 | case X86::VPADDDZ256rr: | 
|  | 8044 | case X86::VPADDQZ256rr: | 
|  | 8045 | case X86::VPADDBZrr: | 
|  | 8046 | case X86::VPADDWZrr: | 
|  | 8047 | case X86::VPADDDZrr: | 
|  | 8048 | case X86::VPADDQZrr: | 
| Craig Topper | 463f949 | 2016-07-18 06:14:57 +0000 | [diff] [blame] | 8049 | case X86::VPMULLWrr: | 
|  | 8050 | case X86::VPMULLWYrr: | 
|  | 8051 | case X86::VPMULLWZ128rr: | 
|  | 8052 | case X86::VPMULLWZ256rr: | 
|  | 8053 | case X86::VPMULLWZrr: | 
|  | 8054 | case X86::VPMULLDrr: | 
|  | 8055 | case X86::VPMULLDYrr: | 
|  | 8056 | case X86::VPMULLDZ128rr: | 
|  | 8057 | case X86::VPMULLDZ256rr: | 
|  | 8058 | case X86::VPMULLDZrr: | 
|  | 8059 | case X86::VPMULLQZ128rr: | 
|  | 8060 | case X86::VPMULLQZ256rr: | 
|  | 8061 | case X86::VPMULLQZrr: | 
| Sanjay Patel | 40d4eb4 | 2015-08-15 17:01:54 +0000 | [diff] [blame] | 8062 | // Normal min/max instructions are not commutative because of NaN and signed | 
|  | 8063 | // zero semantics, but these are. Thus, there's no need to check for global | 
|  | 8064 | // relaxed math; the instructions themselves have the properties we need. | 
| Sanjay Patel | cf942fa | 2015-08-21 18:06:49 +0000 | [diff] [blame] | 8065 | case X86::MAXCPDrr: | 
|  | 8066 | case X86::MAXCPSrr: | 
| Sanjay Patel | 9e5927f | 2015-08-19 21:27:27 +0000 | [diff] [blame] | 8067 | case X86::MAXCSDrr: | 
| Sanjay Patel | 4e3ee1e | 2015-08-19 21:18:46 +0000 | [diff] [blame] | 8068 | case X86::MAXCSSrr: | 
| Sanjay Patel | cf942fa | 2015-08-21 18:06:49 +0000 | [diff] [blame] | 8069 | case X86::MINCPDrr: | 
|  | 8070 | case X86::MINCPSrr: | 
| Sanjay Patel | 9e5927f | 2015-08-19 21:27:27 +0000 | [diff] [blame] | 8071 | case X86::MINCSDrr: | 
| Sanjay Patel | 40d4eb4 | 2015-08-15 17:01:54 +0000 | [diff] [blame] | 8072 | case X86::MINCSSrr: | 
| Sanjay Patel | cf942fa | 2015-08-21 18:06:49 +0000 | [diff] [blame] | 8073 | case X86::VMAXCPDrr: | 
|  | 8074 | case X86::VMAXCPSrr: | 
| Sanjay Patel | f0bc07f | 2015-08-21 21:04:21 +0000 | [diff] [blame] | 8075 | case X86::VMAXCPDYrr: | 
|  | 8076 | case X86::VMAXCPSYrr: | 
| Craig Topper | 3a99de4 | 2016-07-18 06:14:47 +0000 | [diff] [blame] | 8077 | case X86::VMAXCPDZ128rr: | 
|  | 8078 | case X86::VMAXCPSZ128rr: | 
|  | 8079 | case X86::VMAXCPDZ256rr: | 
|  | 8080 | case X86::VMAXCPSZ256rr: | 
|  | 8081 | case X86::VMAXCPDZrr: | 
|  | 8082 | case X86::VMAXCPSZrr: | 
| Sanjay Patel | 9e5927f | 2015-08-19 21:27:27 +0000 | [diff] [blame] | 8083 | case X86::VMAXCSDrr: | 
| Sanjay Patel | 4e3ee1e | 2015-08-19 21:18:46 +0000 | [diff] [blame] | 8084 | case X86::VMAXCSSrr: | 
| Craig Topper | 3a99de4 | 2016-07-18 06:14:47 +0000 | [diff] [blame] | 8085 | case X86::VMAXCSDZrr: | 
|  | 8086 | case X86::VMAXCSSZrr: | 
| Sanjay Patel | cf942fa | 2015-08-21 18:06:49 +0000 | [diff] [blame] | 8087 | case X86::VMINCPDrr: | 
|  | 8088 | case X86::VMINCPSrr: | 
| Sanjay Patel | f0bc07f | 2015-08-21 21:04:21 +0000 | [diff] [blame] | 8089 | case X86::VMINCPDYrr: | 
|  | 8090 | case X86::VMINCPSYrr: | 
| Craig Topper | 3a99de4 | 2016-07-18 06:14:47 +0000 | [diff] [blame] | 8091 | case X86::VMINCPDZ128rr: | 
|  | 8092 | case X86::VMINCPSZ128rr: | 
|  | 8093 | case X86::VMINCPDZ256rr: | 
|  | 8094 | case X86::VMINCPSZ256rr: | 
|  | 8095 | case X86::VMINCPDZrr: | 
|  | 8096 | case X86::VMINCPSZrr: | 
| Sanjay Patel | 9e5927f | 2015-08-19 21:27:27 +0000 | [diff] [blame] | 8097 | case X86::VMINCSDrr: | 
| Sanjay Patel | 40d4eb4 | 2015-08-15 17:01:54 +0000 | [diff] [blame] | 8098 | case X86::VMINCSSrr: | 
| Craig Topper | 3a99de4 | 2016-07-18 06:14:47 +0000 | [diff] [blame] | 8099 | case X86::VMINCSDZrr: | 
|  | 8100 | case X86::VMINCSSZrr: | 
| Sanjay Patel | 9ff4626 | 2015-07-31 16:21:55 +0000 | [diff] [blame] | 8101 | return true; | 
| Sanjay Patel | e017826 | 2015-08-08 19:08:20 +0000 | [diff] [blame] | 8102 | case X86::ADDPDrr: | 
|  | 8103 | case X86::ADDPSrr: | 
| Sanjay Patel | ea81edf | 2015-07-09 22:48:54 +0000 | [diff] [blame] | 8104 | case X86::ADDSDrr: | 
| Sanjay Patel | 681a56a | 2015-07-06 22:35:29 +0000 | [diff] [blame] | 8105 | case X86::ADDSSrr: | 
| Sanjay Patel | 2c6a015 | 2015-08-11 20:19:23 +0000 | [diff] [blame] | 8106 | case X86::MULPDrr: | 
|  | 8107 | case X86::MULPSrr: | 
|  | 8108 | case X86::MULSDrr: | 
|  | 8109 | case X86::MULSSrr: | 
| Sanjay Patel | e017826 | 2015-08-08 19:08:20 +0000 | [diff] [blame] | 8110 | case X86::VADDPDrr: | 
|  | 8111 | case X86::VADDPSrr: | 
| Sanjay Patel | 260b6d3 | 2015-08-12 00:29:10 +0000 | [diff] [blame] | 8112 | case X86::VADDPDYrr: | 
|  | 8113 | case X86::VADDPSYrr: | 
| Craig Topper | 3a99de4 | 2016-07-18 06:14:47 +0000 | [diff] [blame] | 8114 | case X86::VADDPDZ128rr: | 
|  | 8115 | case X86::VADDPSZ128rr: | 
|  | 8116 | case X86::VADDPDZ256rr: | 
|  | 8117 | case X86::VADDPSZ256rr: | 
|  | 8118 | case X86::VADDPDZrr: | 
|  | 8119 | case X86::VADDPSZrr: | 
| Sanjay Patel | ea81edf | 2015-07-09 22:48:54 +0000 | [diff] [blame] | 8120 | case X86::VADDSDrr: | 
| Sanjay Patel | 093fb17 | 2015-07-08 22:35:20 +0000 | [diff] [blame] | 8121 | case X86::VADDSSrr: | 
| Craig Topper | 3a99de4 | 2016-07-18 06:14:47 +0000 | [diff] [blame] | 8122 | case X86::VADDSDZrr: | 
|  | 8123 | case X86::VADDSSZrr: | 
| Sanjay Patel | 2c6a015 | 2015-08-11 20:19:23 +0000 | [diff] [blame] | 8124 | case X86::VMULPDrr: | 
|  | 8125 | case X86::VMULPSrr: | 
| Sanjay Patel | 260b6d3 | 2015-08-12 00:29:10 +0000 | [diff] [blame] | 8126 | case X86::VMULPDYrr: | 
|  | 8127 | case X86::VMULPSYrr: | 
| Craig Topper | 3a99de4 | 2016-07-18 06:14:47 +0000 | [diff] [blame] | 8128 | case X86::VMULPDZ128rr: | 
|  | 8129 | case X86::VMULPSZ128rr: | 
|  | 8130 | case X86::VMULPDZ256rr: | 
|  | 8131 | case X86::VMULPSZ256rr: | 
|  | 8132 | case X86::VMULPDZrr: | 
|  | 8133 | case X86::VMULPSZrr: | 
| Sanjay Patel | 81beefc | 2015-07-09 22:58:39 +0000 | [diff] [blame] | 8134 | case X86::VMULSDrr: | 
| Sanjay Patel | 093fb17 | 2015-07-08 22:35:20 +0000 | [diff] [blame] | 8135 | case X86::VMULSSrr: | 
| Craig Topper | 3a99de4 | 2016-07-18 06:14:47 +0000 | [diff] [blame] | 8136 | case X86::VMULSDZrr: | 
|  | 8137 | case X86::VMULSSZrr: | 
| Sanjay Patel | 5bfbb36 | 2015-07-30 00:04:21 +0000 | [diff] [blame] | 8138 | return Inst.getParent()->getParent()->getTarget().Options.UnsafeFPMath; | 
| Sanjay Patel | 681a56a | 2015-07-06 22:35:29 +0000 | [diff] [blame] | 8139 | default: | 
|  | 8140 | return false; | 
|  | 8141 | } | 
|  | 8142 | } | 
|  | 8143 |  | 
| Sanjay Patel | 75ced27 | 2015-08-04 15:21:56 +0000 | [diff] [blame] | 8144 | /// This is an architecture-specific helper function of reassociateOps. | 
|  | 8145 | /// Set special operand attributes for new instructions after reassociation. | 
| Chad Rosier | 03a4730 | 2015-09-21 15:09:11 +0000 | [diff] [blame] | 8146 | void X86InstrInfo::setSpecialOperandAttr(MachineInstr &OldMI1, | 
|  | 8147 | MachineInstr &OldMI2, | 
|  | 8148 | MachineInstr &NewMI1, | 
|  | 8149 | MachineInstr &NewMI2) const { | 
| Sanjay Patel | 75ced27 | 2015-08-04 15:21:56 +0000 | [diff] [blame] | 8150 | // Integer instructions define an implicit EFLAGS source register operand as | 
|  | 8151 | // the third source (fourth total) operand. | 
|  | 8152 | if (OldMI1.getNumOperands() != 4 || OldMI2.getNumOperands() != 4) | 
|  | 8153 | return; | 
|  | 8154 |  | 
|  | 8155 | assert(NewMI1.getNumOperands() == 4 && NewMI2.getNumOperands() == 4 && | 
|  | 8156 | "Unexpected instruction type for reassociation"); | 
| Chad Rosier | 03a4730 | 2015-09-21 15:09:11 +0000 | [diff] [blame] | 8157 |  | 
| Sanjay Patel | 75ced27 | 2015-08-04 15:21:56 +0000 | [diff] [blame] | 8158 | MachineOperand &OldOp1 = OldMI1.getOperand(3); | 
|  | 8159 | MachineOperand &OldOp2 = OldMI2.getOperand(3); | 
|  | 8160 | MachineOperand &NewOp1 = NewMI1.getOperand(3); | 
|  | 8161 | MachineOperand &NewOp2 = NewMI2.getOperand(3); | 
|  | 8162 |  | 
|  | 8163 | assert(OldOp1.isReg() && OldOp1.getReg() == X86::EFLAGS && OldOp1.isDead() && | 
|  | 8164 | "Must have dead EFLAGS operand in reassociable instruction"); | 
|  | 8165 | assert(OldOp2.isReg() && OldOp2.getReg() == X86::EFLAGS && OldOp2.isDead() && | 
|  | 8166 | "Must have dead EFLAGS operand in reassociable instruction"); | 
|  | 8167 |  | 
|  | 8168 | (void)OldOp1; | 
|  | 8169 | (void)OldOp2; | 
|  | 8170 |  | 
|  | 8171 | assert(NewOp1.isReg() && NewOp1.getReg() == X86::EFLAGS && | 
|  | 8172 | "Unexpected operand in reassociable instruction"); | 
|  | 8173 | assert(NewOp2.isReg() && NewOp2.getReg() == X86::EFLAGS && | 
|  | 8174 | "Unexpected operand in reassociable instruction"); | 
|  | 8175 |  | 
|  | 8176 | // Mark the new EFLAGS operands as dead to be helpful to subsequent iterations | 
|  | 8177 | // of this pass or other passes. The EFLAGS operands must be dead in these new | 
|  | 8178 | // instructions because the EFLAGS operands in the original instructions must | 
|  | 8179 | // be dead in order for reassociation to occur. | 
|  | 8180 | NewOp1.setIsDead(); | 
|  | 8181 | NewOp2.setIsDead(); | 
|  | 8182 | } | 
|  | 8183 |  | 
| Alex Lorenz | 49873a8 | 2015-08-06 00:44:07 +0000 | [diff] [blame] | 8184 | std::pair<unsigned, unsigned> | 
|  | 8185 | X86InstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const { | 
|  | 8186 | return std::make_pair(TF, 0u); | 
|  | 8187 | } | 
|  | 8188 |  | 
|  | 8189 | ArrayRef<std::pair<unsigned, const char *>> | 
|  | 8190 | X86InstrInfo::getSerializableDirectMachineOperandTargetFlags() const { | 
|  | 8191 | using namespace X86II; | 
| Hal Finkel | 982e8d4 | 2015-08-30 08:07:29 +0000 | [diff] [blame] | 8192 | static const std::pair<unsigned, const char *> TargetFlags[] = { | 
| Alex Lorenz | 49873a8 | 2015-08-06 00:44:07 +0000 | [diff] [blame] | 8193 | {MO_GOT_ABSOLUTE_ADDRESS, "x86-got-absolute-address"}, | 
|  | 8194 | {MO_PIC_BASE_OFFSET, "x86-pic-base-offset"}, | 
|  | 8195 | {MO_GOT, "x86-got"}, | 
|  | 8196 | {MO_GOTOFF, "x86-gotoff"}, | 
|  | 8197 | {MO_GOTPCREL, "x86-gotpcrel"}, | 
|  | 8198 | {MO_PLT, "x86-plt"}, | 
|  | 8199 | {MO_TLSGD, "x86-tlsgd"}, | 
|  | 8200 | {MO_TLSLD, "x86-tlsld"}, | 
|  | 8201 | {MO_TLSLDM, "x86-tlsldm"}, | 
|  | 8202 | {MO_GOTTPOFF, "x86-gottpoff"}, | 
|  | 8203 | {MO_INDNTPOFF, "x86-indntpoff"}, | 
|  | 8204 | {MO_TPOFF, "x86-tpoff"}, | 
|  | 8205 | {MO_DTPOFF, "x86-dtpoff"}, | 
|  | 8206 | {MO_NTPOFF, "x86-ntpoff"}, | 
|  | 8207 | {MO_GOTNTPOFF, "x86-gotntpoff"}, | 
|  | 8208 | {MO_DLLIMPORT, "x86-dllimport"}, | 
| Alex Lorenz | 49873a8 | 2015-08-06 00:44:07 +0000 | [diff] [blame] | 8209 | {MO_DARWIN_NONLAZY, "x86-darwin-nonlazy"}, | 
|  | 8210 | {MO_DARWIN_NONLAZY_PIC_BASE, "x86-darwin-nonlazy-pic-base"}, | 
| Alex Lorenz | 49873a8 | 2015-08-06 00:44:07 +0000 | [diff] [blame] | 8211 | {MO_TLVP, "x86-tlvp"}, | 
|  | 8212 | {MO_TLVP_PIC_BASE, "x86-tlvp-pic-base"}, | 
|  | 8213 | {MO_SECREL, "x86-secrel"}}; | 
|  | 8214 | return makeArrayRef(TargetFlags); | 
|  | 8215 | } | 
|  | 8216 |  | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 8217 | namespace { | 
| Sanjay Patel | 203ee50 | 2015-02-17 21:55:20 +0000 | [diff] [blame] | 8218 | /// Create Global Base Reg pass. This initializes the PIC | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 8219 | /// global base register for x86-32. | 
|  | 8220 | struct CGBR : public MachineFunctionPass { | 
|  | 8221 | static char ID; | 
| Owen Anderson | a7aed18 | 2010-08-06 18:33:48 +0000 | [diff] [blame] | 8222 | CGBR() : MachineFunctionPass(ID) {} | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 8223 |  | 
| Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 8224 | bool runOnMachineFunction(MachineFunction &MF) override { | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 8225 | const X86TargetMachine *TM = | 
|  | 8226 | static_cast<const X86TargetMachine *>(&MF.getTarget()); | 
| Eric Christopher | 05b8197 | 2015-02-02 17:38:43 +0000 | [diff] [blame] | 8227 | const X86Subtarget &STI = MF.getSubtarget<X86Subtarget>(); | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 8228 |  | 
| Eric Christopher | 0d5c99e | 2014-05-22 01:46:02 +0000 | [diff] [blame] | 8229 | // Don't do anything if this is 64-bit as 64-bit PIC | 
|  | 8230 | // uses RIP relative addressing. | 
| Eric Christopher | 05b8197 | 2015-02-02 17:38:43 +0000 | [diff] [blame] | 8231 | if (STI.is64Bit()) | 
| Eric Christopher | 0d5c99e | 2014-05-22 01:46:02 +0000 | [diff] [blame] | 8232 | return false; | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 8233 |  | 
|  | 8234 | // Only emit a global base reg in PIC mode. | 
| Rafael Espindola | f9e348b | 2016-06-27 21:33:08 +0000 | [diff] [blame] | 8235 | if (!TM->isPositionIndependent()) | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 8236 | return false; | 
|  | 8237 |  | 
| Dan Gohman | 534db8a | 2010-09-17 20:24:24 +0000 | [diff] [blame] | 8238 | X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>(); | 
|  | 8239 | unsigned GlobalBaseReg = X86FI->getGlobalBaseReg(); | 
|  | 8240 |  | 
|  | 8241 | // If we didn't need a GlobalBaseReg, don't insert code. | 
|  | 8242 | if (GlobalBaseReg == 0) | 
|  | 8243 | return false; | 
|  | 8244 |  | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 8245 | // Insert the set of GlobalBaseReg into the first MBB of the function | 
|  | 8246 | MachineBasicBlock &FirstMBB = MF.front(); | 
|  | 8247 | MachineBasicBlock::iterator MBBI = FirstMBB.begin(); | 
|  | 8248 | DebugLoc DL = FirstMBB.findDebugLoc(MBBI); | 
|  | 8249 | MachineRegisterInfo &RegInfo = MF.getRegInfo(); | 
| Eric Christopher | 05b8197 | 2015-02-02 17:38:43 +0000 | [diff] [blame] | 8250 | const X86InstrInfo *TII = STI.getInstrInfo(); | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 8251 |  | 
|  | 8252 | unsigned PC; | 
| Eric Christopher | 05b8197 | 2015-02-02 17:38:43 +0000 | [diff] [blame] | 8253 | if (STI.isPICStyleGOT()) | 
| Craig Topper | abadc66 | 2012-04-20 06:31:50 +0000 | [diff] [blame] | 8254 | PC = RegInfo.createVirtualRegister(&X86::GR32RegClass); | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 8255 | else | 
| Dan Gohman | 534db8a | 2010-09-17 20:24:24 +0000 | [diff] [blame] | 8256 | PC = GlobalBaseReg; | 
| NAKAMURA Takumi | 9d29eff | 2011-01-26 02:03:37 +0000 | [diff] [blame] | 8257 |  | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 8258 | // Operand of MovePCtoStack is completely ignored by asm printer. It's | 
|  | 8259 | // only used in JIT code emission as displacement to pc. | 
|  | 8260 | BuildMI(FirstMBB, MBBI, DL, TII->get(X86::MOVPC32r), PC).addImm(0); | 
| NAKAMURA Takumi | 9d29eff | 2011-01-26 02:03:37 +0000 | [diff] [blame] | 8261 |  | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 8262 | // If we're using vanilla 'GOT' PIC style, we should use relative addressing | 
|  | 8263 | // not to pc, but to _GLOBAL_OFFSET_TABLE_ external. | 
| Eric Christopher | 05b8197 | 2015-02-02 17:38:43 +0000 | [diff] [blame] | 8264 | if (STI.isPICStyleGOT()) { | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 8265 | // Generate addl $__GLOBAL_OFFSET_TABLE_ + [.-piclabel], %some_register | 
|  | 8266 | BuildMI(FirstMBB, MBBI, DL, TII->get(X86::ADD32ri), GlobalBaseReg) | 
|  | 8267 | .addReg(PC).addExternalSymbol("_GLOBAL_OFFSET_TABLE_", | 
|  | 8268 | X86II::MO_GOT_ABSOLUTE_ADDRESS); | 
|  | 8269 | } | 
|  | 8270 |  | 
|  | 8271 | return true; | 
|  | 8272 | } | 
|  | 8273 |  | 
| Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 8274 | const char *getPassName() const override { | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 8275 | return "X86 PIC Global Base Reg Initialization"; | 
|  | 8276 | } | 
|  | 8277 |  | 
| Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 8278 | void getAnalysisUsage(AnalysisUsage &AU) const override { | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 8279 | AU.setPreservesCFG(); | 
|  | 8280 | MachineFunctionPass::getAnalysisUsage(AU); | 
|  | 8281 | } | 
|  | 8282 | }; | 
| Alexander Kornienko | f00654e | 2015-06-23 09:49:53 +0000 | [diff] [blame] | 8283 | } | 
| Dan Gohman | d7b5ce3 | 2010-07-10 09:00:22 +0000 | [diff] [blame] | 8284 |  | 
|  | 8285 | char CGBR::ID = 0; | 
|  | 8286 | FunctionPass* | 
| Eric Christopher | 463b84b | 2014-05-22 01:45:57 +0000 | [diff] [blame] | 8287 | llvm::createX86GlobalBaseRegPass() { return new CGBR(); } | 
| Hans Wennborg | 789acfb | 2012-06-01 16:27:21 +0000 | [diff] [blame] | 8288 |  | 
|  | 8289 | namespace { | 
|  | 8290 | struct LDTLSCleanup : public MachineFunctionPass { | 
|  | 8291 | static char ID; | 
|  | 8292 | LDTLSCleanup() : MachineFunctionPass(ID) {} | 
|  | 8293 |  | 
| Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 8294 | bool runOnMachineFunction(MachineFunction &MF) override { | 
| Andrew Kaylor | 2bee5ef | 2016-04-26 21:44:24 +0000 | [diff] [blame] | 8295 | if (skipFunction(*MF.getFunction())) | 
|  | 8296 | return false; | 
|  | 8297 |  | 
|  | 8298 | X86MachineFunctionInfo *MFI = MF.getInfo<X86MachineFunctionInfo>(); | 
| Hans Wennborg | 789acfb | 2012-06-01 16:27:21 +0000 | [diff] [blame] | 8299 | if (MFI->getNumLocalDynamicTLSAccesses() < 2) { | 
|  | 8300 | // No point folding accesses if there isn't at least two. | 
|  | 8301 | return false; | 
|  | 8302 | } | 
|  | 8303 |  | 
|  | 8304 | MachineDominatorTree *DT = &getAnalysis<MachineDominatorTree>(); | 
|  | 8305 | return VisitNode(DT->getRootNode(), 0); | 
|  | 8306 | } | 
|  | 8307 |  | 
|  | 8308 | // Visit the dominator subtree rooted at Node in pre-order. | 
|  | 8309 | // If TLSBaseAddrReg is non-null, then use that to replace any | 
|  | 8310 | // TLS_base_addr instructions. Otherwise, create the register | 
|  | 8311 | // when the first such instruction is seen, and then use it | 
|  | 8312 | // as we encounter more instructions. | 
|  | 8313 | bool VisitNode(MachineDomTreeNode *Node, unsigned TLSBaseAddrReg) { | 
|  | 8314 | MachineBasicBlock *BB = Node->getBlock(); | 
|  | 8315 | bool Changed = false; | 
|  | 8316 |  | 
|  | 8317 | // Traverse the current block. | 
|  | 8318 | for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; | 
|  | 8319 | ++I) { | 
|  | 8320 | switch (I->getOpcode()) { | 
|  | 8321 | case X86::TLS_base_addr32: | 
|  | 8322 | case X86::TLS_base_addr64: | 
|  | 8323 | if (TLSBaseAddrReg) | 
| Duncan P. N. Exon Smith | 7b4c18e | 2016-07-12 03:18:50 +0000 | [diff] [blame] | 8324 | I = ReplaceTLSBaseAddrCall(*I, TLSBaseAddrReg); | 
| Hans Wennborg | 789acfb | 2012-06-01 16:27:21 +0000 | [diff] [blame] | 8325 | else | 
| Duncan P. N. Exon Smith | 7b4c18e | 2016-07-12 03:18:50 +0000 | [diff] [blame] | 8326 | I = SetRegister(*I, &TLSBaseAddrReg); | 
| Hans Wennborg | 789acfb | 2012-06-01 16:27:21 +0000 | [diff] [blame] | 8327 | Changed = true; | 
|  | 8328 | break; | 
|  | 8329 | default: | 
|  | 8330 | break; | 
|  | 8331 | } | 
|  | 8332 | } | 
|  | 8333 |  | 
|  | 8334 | // Visit the children of this block in the dominator tree. | 
|  | 8335 | for (MachineDomTreeNode::iterator I = Node->begin(), E = Node->end(); | 
|  | 8336 | I != E; ++I) { | 
|  | 8337 | Changed |= VisitNode(*I, TLSBaseAddrReg); | 
|  | 8338 | } | 
|  | 8339 |  | 
|  | 8340 | return Changed; | 
|  | 8341 | } | 
|  | 8342 |  | 
|  | 8343 | // Replace the TLS_base_addr instruction I with a copy from | 
|  | 8344 | // TLSBaseAddrReg, returning the new instruction. | 
| Duncan P. N. Exon Smith | 7b4c18e | 2016-07-12 03:18:50 +0000 | [diff] [blame] | 8345 | MachineInstr *ReplaceTLSBaseAddrCall(MachineInstr &I, | 
| Hans Wennborg | 789acfb | 2012-06-01 16:27:21 +0000 | [diff] [blame] | 8346 | unsigned TLSBaseAddrReg) { | 
| Duncan P. N. Exon Smith | 7b4c18e | 2016-07-12 03:18:50 +0000 | [diff] [blame] | 8347 | MachineFunction *MF = I.getParent()->getParent(); | 
| Eric Christopher | 05b8197 | 2015-02-02 17:38:43 +0000 | [diff] [blame] | 8348 | const X86Subtarget &STI = MF->getSubtarget<X86Subtarget>(); | 
|  | 8349 | const bool is64Bit = STI.is64Bit(); | 
|  | 8350 | const X86InstrInfo *TII = STI.getInstrInfo(); | 
| Hans Wennborg | 789acfb | 2012-06-01 16:27:21 +0000 | [diff] [blame] | 8351 |  | 
|  | 8352 | // Insert a Copy from TLSBaseAddrReg to RAX/EAX. | 
| Duncan P. N. Exon Smith | 7b4c18e | 2016-07-12 03:18:50 +0000 | [diff] [blame] | 8353 | MachineInstr *Copy = | 
|  | 8354 | BuildMI(*I.getParent(), I, I.getDebugLoc(), | 
|  | 8355 | TII->get(TargetOpcode::COPY), is64Bit ? X86::RAX : X86::EAX) | 
|  | 8356 | .addReg(TLSBaseAddrReg); | 
| Hans Wennborg | 789acfb | 2012-06-01 16:27:21 +0000 | [diff] [blame] | 8357 |  | 
|  | 8358 | // Erase the TLS_base_addr instruction. | 
| Duncan P. N. Exon Smith | 7b4c18e | 2016-07-12 03:18:50 +0000 | [diff] [blame] | 8359 | I.eraseFromParent(); | 
| Hans Wennborg | 789acfb | 2012-06-01 16:27:21 +0000 | [diff] [blame] | 8360 |  | 
|  | 8361 | return Copy; | 
|  | 8362 | } | 
|  | 8363 |  | 
|  | 8364 | // Create a virtal register in *TLSBaseAddrReg, and populate it by | 
|  | 8365 | // inserting a copy instruction after I. Returns the new instruction. | 
| Duncan P. N. Exon Smith | 7b4c18e | 2016-07-12 03:18:50 +0000 | [diff] [blame] | 8366 | MachineInstr *SetRegister(MachineInstr &I, unsigned *TLSBaseAddrReg) { | 
|  | 8367 | MachineFunction *MF = I.getParent()->getParent(); | 
| Eric Christopher | 05b8197 | 2015-02-02 17:38:43 +0000 | [diff] [blame] | 8368 | const X86Subtarget &STI = MF->getSubtarget<X86Subtarget>(); | 
|  | 8369 | const bool is64Bit = STI.is64Bit(); | 
|  | 8370 | const X86InstrInfo *TII = STI.getInstrInfo(); | 
| Hans Wennborg | 789acfb | 2012-06-01 16:27:21 +0000 | [diff] [blame] | 8371 |  | 
|  | 8372 | // Create a virtual register for the TLS base address. | 
|  | 8373 | MachineRegisterInfo &RegInfo = MF->getRegInfo(); | 
|  | 8374 | *TLSBaseAddrReg = RegInfo.createVirtualRegister(is64Bit | 
|  | 8375 | ? &X86::GR64RegClass | 
|  | 8376 | : &X86::GR32RegClass); | 
|  | 8377 |  | 
|  | 8378 | // Insert a copy from RAX/EAX to TLSBaseAddrReg. | 
| Duncan P. N. Exon Smith | 7b4c18e | 2016-07-12 03:18:50 +0000 | [diff] [blame] | 8379 | MachineInstr *Next = I.getNextNode(); | 
|  | 8380 | MachineInstr *Copy = | 
|  | 8381 | BuildMI(*I.getParent(), Next, I.getDebugLoc(), | 
|  | 8382 | TII->get(TargetOpcode::COPY), *TLSBaseAddrReg) | 
|  | 8383 | .addReg(is64Bit ? X86::RAX : X86::EAX); | 
| Hans Wennborg | 789acfb | 2012-06-01 16:27:21 +0000 | [diff] [blame] | 8384 |  | 
|  | 8385 | return Copy; | 
|  | 8386 | } | 
|  | 8387 |  | 
| Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 8388 | const char *getPassName() const override { | 
| Hans Wennborg | 789acfb | 2012-06-01 16:27:21 +0000 | [diff] [blame] | 8389 | return "Local Dynamic TLS Access Clean-up"; | 
|  | 8390 | } | 
|  | 8391 |  | 
| Craig Topper | 2d9361e | 2014-03-09 07:44:38 +0000 | [diff] [blame] | 8392 | void getAnalysisUsage(AnalysisUsage &AU) const override { | 
| Hans Wennborg | 789acfb | 2012-06-01 16:27:21 +0000 | [diff] [blame] | 8393 | AU.setPreservesCFG(); | 
|  | 8394 | AU.addRequired<MachineDominatorTree>(); | 
|  | 8395 | MachineFunctionPass::getAnalysisUsage(AU); | 
|  | 8396 | } | 
|  | 8397 | }; | 
| Alexander Kornienko | f00654e | 2015-06-23 09:49:53 +0000 | [diff] [blame] | 8398 | } | 
| Hans Wennborg | 789acfb | 2012-06-01 16:27:21 +0000 | [diff] [blame] | 8399 |  | 
|  | 8400 | char LDTLSCleanup::ID = 0; | 
|  | 8401 | FunctionPass* | 
|  | 8402 | llvm::createCleanupLocalDynamicTLSPass() { return new LDTLSCleanup(); } |