[llvm-exegesis][NFC] Pass Instruction instead of bare Opcode
[llvm-core.git] / lib / Target / X86 / X86ScheduleBtVer2.td
blob2c1a4b6c7f56f78754eeacb95d0e52c4b505187b
1 //=- X86ScheduleBtVer2.td - X86 BtVer2 (Jaguar) Scheduling ---*- tablegen -*-=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the machine model for AMD btver2 (Jaguar) to support
11 // instruction scheduling and other instruction cost heuristics. Based off AMD Software
12 // Optimization Guide for AMD Family 16h Processors & Instruction Latency appendix.
14 //===----------------------------------------------------------------------===//
16 def BtVer2Model : SchedMachineModel {
17   // All x86 instructions are modeled as a single micro-op, and btver2 can
18   // decode 2 instructions per cycle.
19   let IssueWidth = 2;
20   let MicroOpBufferSize = 64; // Retire Control Unit
21   let LoadLatency = 5; // FPU latency (worse case cf Integer 3 cycle latency)
22   let HighLatency = 25;
23   let MispredictPenalty = 14; // Minimum branch misdirection penalty
24   let PostRAScheduler = 1;
26   // FIXME: SSE4/AVX is unimplemented. This flag is set to allow
27   // the scheduler to assign a default model to unrecognized opcodes.
28   let CompleteModel = 0;
31 let SchedModel = BtVer2Model in {
33 // Jaguar can issue up to 6 micro-ops in one cycle
34 def JALU0 : ProcResource<1>; // Integer Pipe0: integer ALU0 (also handle FP->INT jam)
35 def JALU1 : ProcResource<1>; // Integer Pipe1: integer ALU1/MUL/DIV
36 def JLAGU : ProcResource<1>; // Integer Pipe2: LAGU
37 def JSAGU : ProcResource<1>; // Integer Pipe3: SAGU (also handles 3-operand LEA)
38 def JFPU0 : ProcResource<1>; // Vector/FPU Pipe0: VALU0/VIMUL/FPA
39 def JFPU1 : ProcResource<1>; // Vector/FPU Pipe1: VALU1/STC/FPM
41 // The Integer PRF for Jaguar is 64 entries, and it holds the architectural and
42 // speculative version of the 64-bit integer registers.
43 // Reference: www.realworldtech.com/jaguar/4/
45 // The processor always keeps the different parts of an integer register
46 // together. An instruction that writes to a part of a register will therefore
47 // have a false dependence on any previous write to the same register or any
48 // part of it.
49 // Reference: Section 21.10 "AMD Bobcat and Jaguar pipeline: Partial register
50 // access" - Agner Fog's "microarchitecture.pdf".
51 def JIntegerPRF : RegisterFile<64, [GR64, CCR]>;
53 // The Jaguar FP Retire Queue renames SIMD and FP uOps onto a pool of 72 SSE
54 // registers. Operations on 256-bit data types are cracked into two COPs.
55 // Reference: www.realworldtech.com/jaguar/4/
56 def JFpuPRF: RegisterFile<72, [VR64, VR128, VR256], [1, 1, 2]>;
58 // The retire control unit (RCU) can track up to 64 macro-ops in-flight. It can
59 // retire up to two macro-ops per cycle.
60 // Reference: "Software Optimization Guide for AMD Family 16h Processors"
61 def JRCU : RetireControlUnit<64, 2>;
63 // Integer Pipe Scheduler
64 def JALU01 : ProcResGroup<[JALU0, JALU1]> {
65   let BufferSize=20;
68 // AGU Pipe Scheduler
69 def JLSAGU : ProcResGroup<[JLAGU, JSAGU]> {
70   let BufferSize=12;
73 // Fpu Pipe Scheduler
74 def JFPU01 : ProcResGroup<[JFPU0, JFPU1]> {
75   let BufferSize=18;
78 // Functional units
79 def JDiv    : ProcResource<1>; // integer division
80 def JMul    : ProcResource<1>; // integer multiplication
81 def JVALU0  : ProcResource<1>; // vector integer
82 def JVALU1  : ProcResource<1>; // vector integer
83 def JVIMUL  : ProcResource<1>; // vector integer multiplication
84 def JSTC    : ProcResource<1>; // vector store/convert
85 def JFPM    : ProcResource<1>; // FP multiplication
86 def JFPA    : ProcResource<1>; // FP addition
88 // Functional unit groups
89 def JFPX  : ProcResGroup<[JFPA, JFPM]>;
90 def JVALU : ProcResGroup<[JVALU0, JVALU1]>;
92 // Integer loads are 3 cycles, so ReadAfterLd registers needn't be available until 3
93 // cycles after the memory operand.
94 def : ReadAdvance<ReadAfterLd, 3>;
96 // Vector loads are 5 cycles, so ReadAfterVec*Ld registers needn't be available until 5
97 // cycles after the memory operand.
98 def : ReadAdvance<ReadAfterVecLd, 5>;
99 def : ReadAdvance<ReadAfterVecXLd, 5>;
100 def : ReadAdvance<ReadAfterVecYLd, 5>;
102 // Many SchedWrites are defined in pairs with and without a folded load.
103 // Instructions with folded loads are usually micro-fused, so they only appear
104 // as two micro-ops when dispatched by the schedulers.
105 // This multiclass defines the resource usage for variants with and without
106 // folded loads.
107 multiclass JWriteResIntPair<X86FoldableSchedWrite SchedRW,
108                             list<ProcResourceKind> ExePorts,
109                             int Lat, list<int> Res = [], int UOps = 1,
110                             int LoadUOps = 0> {
111   // Register variant is using a single cycle on ExePort.
112   def : WriteRes<SchedRW, ExePorts> {
113     let Latency = Lat;
114     let ResourceCycles = Res;
115     let NumMicroOps = UOps;
116   }
118   // Memory variant also uses a cycle on JLAGU and adds 3 cycles to the
119   // latency.
120   def : WriteRes<SchedRW.Folded, !listconcat([JLAGU], ExePorts)> {
121     let Latency = !add(Lat, 3);
122     let ResourceCycles = !if(!empty(Res), [], !listconcat([1], Res));
123     let NumMicroOps = !add(UOps, LoadUOps);
124   }
127 multiclass JWriteResFpuPair<X86FoldableSchedWrite SchedRW,
128                             list<ProcResourceKind> ExePorts,
129                             int Lat, list<int> Res = [], int UOps = 1,
130                             int LoadUOps = 0> {
131   // Register variant is using a single cycle on ExePort.
132   def : WriteRes<SchedRW, ExePorts> {
133     let Latency = Lat;
134     let ResourceCycles = Res;
135     let NumMicroOps = UOps;
136   }
138   // Memory variant also uses a cycle on JLAGU and adds 5 cycles to the
139   // latency.
140   def : WriteRes<SchedRW.Folded, !listconcat([JLAGU], ExePorts)> {
141     let Latency = !add(Lat, 5);
142     let ResourceCycles = !if(!empty(Res), [], !listconcat([1], Res));
143     let NumMicroOps = !add(UOps, LoadUOps);
144   }
147 multiclass JWriteResYMMPair<X86FoldableSchedWrite SchedRW,
148                             list<ProcResourceKind> ExePorts,
149                             int Lat, list<int> Res = [2], int UOps = 2,
150                             int LoadUOps = 0> {
151   // Register variant is using a single cycle on ExePort.
152   def : WriteRes<SchedRW, ExePorts> {
153     let Latency = Lat;
154     let ResourceCycles = Res;
155     let NumMicroOps = UOps;
156   }
158   // Memory variant also uses 2 cycles on JLAGU and adds 5 cycles to the
159   // latency.
160   def : WriteRes<SchedRW.Folded, !listconcat([JLAGU], ExePorts)> {
161     let Latency = !add(Lat, 5);
162     let ResourceCycles = !listconcat([2], Res);
163     let NumMicroOps = !add(UOps, LoadUOps);
164   }
167 // A folded store needs a cycle on the SAGU for the store data,
168 // most RMW instructions don't need an extra uop.
169 defm : X86WriteRes<WriteRMW, [JSAGU], 1, [1], 0>;
171 ////////////////////////////////////////////////////////////////////////////////
172 // Arithmetic.
173 ////////////////////////////////////////////////////////////////////////////////
175 defm : JWriteResIntPair<WriteALU,    [JALU01], 1>;
176 defm : JWriteResIntPair<WriteADC,    [JALU01], 1, [2]>;
178 defm : X86WriteRes<WriteBSWAP32, [JALU01], 1, [1], 1>;
179 defm : X86WriteRes<WriteBSWAP64, [JALU01], 1, [1], 1>;
180 defm : X86WriteRes<WriteCMPXCHG,[JALU01], 1, [1], 1>;
181 defm : X86WriteRes<WriteCMPXCHGRMW,[JALU01, JSAGU, JLAGU], 4, [1, 1, 1], 2>;
182 defm : X86WriteRes<WriteXCHG,        [JALU01], 1, [1], 1>;
184 defm : JWriteResIntPair<WriteIMul8,     [JALU1, JMul], 3, [1, 1], 2>;
185 defm : JWriteResIntPair<WriteIMul16,    [JALU1, JMul], 3, [1, 1], 2>;
186 defm : JWriteResIntPair<WriteIMul16Imm, [JALU1, JMul], 3, [1, 1], 2>;
187 defm : JWriteResIntPair<WriteIMul16Reg, [JALU1, JMul], 3, [1, 1], 2>;
188 defm : JWriteResIntPair<WriteIMul32,    [JALU1, JMul], 3, [1, 1], 2>;
189 defm : JWriteResIntPair<WriteIMul32Imm, [JALU1, JMul], 3, [1, 1], 2>;
190 defm : JWriteResIntPair<WriteIMul32Reg, [JALU1, JMul], 3, [1, 1], 2>;
191 defm : JWriteResIntPair<WriteIMul64,    [JALU1, JMul], 6, [1, 4], 2>;
192 defm : JWriteResIntPair<WriteIMul64Imm, [JALU1, JMul], 6, [1, 4], 2>;
193 defm : JWriteResIntPair<WriteIMul64Reg, [JALU1, JMul], 6, [1, 4], 2>;
194 defm : X86WriteRes<WriteIMulH,          [JALU1], 6, [4], 1>;
196 defm : JWriteResIntPair<WriteDiv8,   [JALU1, JDiv], 12, [1, 12], 1>;
197 defm : JWriteResIntPair<WriteDiv16,  [JALU1, JDiv], 17, [1, 17], 2>;
198 defm : JWriteResIntPair<WriteDiv32,  [JALU1, JDiv], 25, [1, 25], 2>;
199 defm : JWriteResIntPair<WriteDiv64,  [JALU1, JDiv], 41, [1, 41], 2>;
200 defm : JWriteResIntPair<WriteIDiv8,  [JALU1, JDiv], 12, [1, 12], 1>;
201 defm : JWriteResIntPair<WriteIDiv16, [JALU1, JDiv], 17, [1, 17], 2>;
202 defm : JWriteResIntPair<WriteIDiv32, [JALU1, JDiv], 25, [1, 25], 2>;
203 defm : JWriteResIntPair<WriteIDiv64, [JALU1, JDiv], 41, [1, 41], 2>;
205 defm : JWriteResIntPair<WriteCRC32,  [JALU01], 3, [4], 3>;
207 defm : JWriteResIntPair<WriteCMOV,  [JALU01], 1>; // Conditional move.
208 defm : JWriteResIntPair<WriteCMOV2, [JALU01], 1>; // Conditional (CF + ZF flag) move.
209 defm : X86WriteRes<WriteFCMOV, [JFPU0, JFPA], 3, [1,1], 1>; // x87 conditional move.
210 def  : WriteRes<WriteSETCC, [JALU01]>; // Setcc.
211 def  : WriteRes<WriteSETCCStore, [JALU01,JSAGU]>;
212 def  : WriteRes<WriteLAHFSAHF, [JALU01]>;
214 defm : X86WriteRes<WriteBitTest,         [JALU01], 1, [1], 1>;
215 defm : X86WriteRes<WriteBitTestImmLd,    [JALU01,JLAGU], 4, [1,1], 1>;
216 defm : X86WriteRes<WriteBitTestRegLd,    [JALU01,JLAGU], 4, [1,1], 5>;
217 defm : X86WriteRes<WriteBitTestSet,      [JALU01], 1, [1], 2>;
218 defm : X86WriteRes<WriteBitTestSetImmLd, [JALU01,JLAGU], 4, [1,1], 4>;
219 defm : X86WriteRes<WriteBitTestSetRegLd, [JALU01,JLAGU], 4, [1,1], 8>;
221 // This is for simple LEAs with one or two input operands.
222 def : WriteRes<WriteLEA, [JALU01]>;
224 // Bit counts.
225 defm : JWriteResIntPair<WriteBSF, [JALU01], 4, [8], 7>;
226 defm : JWriteResIntPair<WriteBSR, [JALU01], 5, [8], 8>;
227 defm : JWriteResIntPair<WritePOPCNT,         [JALU01], 1>;
228 defm : JWriteResIntPair<WriteLZCNT,          [JALU01], 1>;
229 defm : JWriteResIntPair<WriteTZCNT,          [JALU01], 2, [2], 2>;
231 // BMI1 BEXTR/BLS, BMI2 BZHI
232 defm : JWriteResIntPair<WriteBEXTR, [JALU01], 1>;
233 defm : JWriteResIntPair<WriteBLS,   [JALU01], 2, [2], 2>;
234 defm : X86WriteResPairUnsupported<WriteBZHI>;
236 ////////////////////////////////////////////////////////////////////////////////
237 // Integer shifts and rotates.
238 ////////////////////////////////////////////////////////////////////////////////
240 defm : JWriteResIntPair<WriteShift,    [JALU01], 1>;
241 defm : JWriteResIntPair<WriteShiftCL,  [JALU01], 1>;
242 defm : JWriteResIntPair<WriteRotate,   [JALU01], 1>;
243 defm : JWriteResIntPair<WriteRotateCL, [JALU01], 1>;
245 // SHLD/SHRD.
246 defm : X86WriteRes<WriteSHDrri, [JALU01], 3, [6], 6>;
247 defm : X86WriteRes<WriteSHDrrcl,[JALU01], 4, [8], 7>;
248 defm : X86WriteRes<WriteSHDmri, [JLAGU, JALU01], 9, [1, 22], 8>;
249 defm : X86WriteRes<WriteSHDmrcl,[JLAGU, JALU01], 9, [1, 22], 8>;
251 ////////////////////////////////////////////////////////////////////////////////
252 // Loads, stores, and moves, not folded with other operations.
253 ////////////////////////////////////////////////////////////////////////////////
255 def : WriteRes<WriteLoad,    [JLAGU]> { let Latency = 5; }
256 def : WriteRes<WriteStore,   [JSAGU]>;
257 def : WriteRes<WriteStoreNT, [JSAGU]>;
258 def : WriteRes<WriteMove,    [JALU01]>;
260 // Load/store MXCSR.
261 // FIXME: These are copy and pasted from WriteLoad/Store.
262 def : WriteRes<WriteLDMXCSR, [JLAGU]> { let Latency = 5; }
263 def : WriteRes<WriteSTMXCSR, [JSAGU]>;
265 // Treat misc copies as a move.
266 def : InstRW<[WriteMove], (instrs COPY)>;
268 ////////////////////////////////////////////////////////////////////////////////
269 // Idioms that clear a register, like xorps %xmm0, %xmm0.
270 // These can often bypass execution ports completely.
271 ////////////////////////////////////////////////////////////////////////////////
273 def : WriteRes<WriteZero,  []>;
275 ////////////////////////////////////////////////////////////////////////////////
276 // Branches don't produce values, so they have no latency, but they still
277 // consume resources. Indirect branches can fold loads.
278 ////////////////////////////////////////////////////////////////////////////////
280 defm : JWriteResIntPair<WriteJump,  [JALU01], 1>;
282 ////////////////////////////////////////////////////////////////////////////////
283 // Special case scheduling classes.
284 ////////////////////////////////////////////////////////////////////////////////
286 def : WriteRes<WriteSystem,     [JALU01]> { let Latency = 100; }
287 def : WriteRes<WriteMicrocoded, [JALU01]> { let Latency = 100; }
288 def : WriteRes<WriteFence,  [JSAGU]>;
290 // Nops don't have dependencies, so there's no actual latency, but we set this
291 // to '1' to tell the scheduler that the nop uses an ALU slot for a cycle.
292 def : WriteRes<WriteNop, [JALU01]> { let Latency = 1; }
294 ////////////////////////////////////////////////////////////////////////////////
295 // Floating point. This covers both scalar and vector operations.
296 ////////////////////////////////////////////////////////////////////////////////
298 defm : X86WriteRes<WriteFLD0,          [JFPU1, JSTC], 3, [1,1], 1>;
299 defm : X86WriteRes<WriteFLD1,          [JFPU1, JSTC], 3, [1,1], 1>;
300 defm : X86WriteRes<WriteFLDC,          [JFPU1, JSTC], 3, [1,1], 1>;
301 defm : X86WriteRes<WriteFLoad,         [JLAGU, JFPU01, JFPX], 5, [1, 1, 1], 1>;
302 defm : X86WriteRes<WriteFLoadX,        [JLAGU, JFPU01, JFPX], 5, [1, 1, 1], 1>;
303 defm : X86WriteRes<WriteFLoadY,        [JLAGU, JFPU01, JFPX], 5, [1, 1, 1], 1>;
304 defm : X86WriteRes<WriteFMaskedLoad,   [JLAGU, JFPU01, JFPX], 6, [1, 2, 2], 1>;
305 defm : X86WriteRes<WriteFMaskedLoadY,  [JLAGU, JFPU01, JFPX], 6, [2, 4, 4], 2>;
307 defm : X86WriteRes<WriteFStore,        [JSAGU, JFPU1,  JSTC], 2, [1, 1, 1], 1>;
308 defm : X86WriteRes<WriteFStoreX,       [JSAGU, JFPU1,  JSTC], 1, [1, 1, 1], 1>;
309 defm : X86WriteRes<WriteFStoreY,       [JSAGU, JFPU1,  JSTC], 1, [1, 1, 1], 1>;
310 defm : X86WriteRes<WriteFStoreNT,      [JSAGU, JFPU1,  JSTC], 3, [1, 1, 1], 1>;
311 defm : X86WriteRes<WriteFStoreNTX,     [JSAGU, JFPU1,  JSTC], 3, [1, 1, 1], 1>;
312 defm : X86WriteRes<WriteFStoreNTY,     [JSAGU, JFPU1,  JSTC], 3, [2, 2, 2], 1>;
313 defm : X86WriteRes<WriteFMaskedStore,  [JSAGU, JFPU01, JFPX], 6, [1, 1, 4], 1>;
314 defm : X86WriteRes<WriteFMaskedStoreY, [JSAGU, JFPU01, JFPX], 6, [2, 2, 4], 2>;
316 defm : X86WriteRes<WriteFMove,         [JFPU01, JFPX], 1, [1, 1], 1>;
317 defm : X86WriteRes<WriteFMoveX,        [JFPU01, JFPX], 1, [1, 1], 1>;
318 defm : X86WriteRes<WriteFMoveY,        [JFPU01, JFPX], 1, [2, 2], 2>;
320 defm : X86WriteRes<WriteEMMS,          [JFPU01, JFPX], 2, [1, 1], 1>;
322 defm : JWriteResFpuPair<WriteFAdd,         [JFPU0, JFPA],  3>;
323 defm : JWriteResFpuPair<WriteFAddX,        [JFPU0, JFPA],  3>;
324 defm : JWriteResYMMPair<WriteFAddY,        [JFPU0, JFPA],  3, [2,2], 2>;
325 defm : X86WriteResPairUnsupported<WriteFAddZ>;
326 defm : JWriteResFpuPair<WriteFAdd64,       [JFPU0, JFPA],  3>;
327 defm : JWriteResFpuPair<WriteFAdd64X,      [JFPU0, JFPA],  3>;
328 defm : JWriteResYMMPair<WriteFAdd64Y,      [JFPU0, JFPA],  3, [2,2], 2>;
329 defm : X86WriteResPairUnsupported<WriteFAdd64Z>;
330 defm : JWriteResFpuPair<WriteFCmp,         [JFPU0, JFPA],  2>;
331 defm : JWriteResFpuPair<WriteFCmpX,        [JFPU0, JFPA],  2>;
332 defm : JWriteResYMMPair<WriteFCmpY,        [JFPU0, JFPA],  2, [2,2], 2>;
333 defm : X86WriteResPairUnsupported<WriteFCmpZ>;
334 defm : JWriteResFpuPair<WriteFCmp64,       [JFPU0, JFPA],  2>;
335 defm : JWriteResFpuPair<WriteFCmp64X,      [JFPU0, JFPA],  2>;
336 defm : JWriteResYMMPair<WriteFCmp64Y,      [JFPU0, JFPA],  2, [2,2], 2>;
337 defm : X86WriteResPairUnsupported<WriteFCmp64Z>;
338 defm : JWriteResFpuPair<WriteFCom,  [JFPU0, JFPA, JALU0],  3>;
339 defm : JWriteResFpuPair<WriteFMul,         [JFPU1, JFPM],  2>;
340 defm : JWriteResFpuPair<WriteFMulX,        [JFPU1, JFPM],  2>;
341 defm : JWriteResYMMPair<WriteFMulY,        [JFPU1, JFPM],  2, [2,2], 2>;
342 defm : X86WriteResPairUnsupported<WriteFMulZ>;
343 defm : JWriteResFpuPair<WriteFMul64,       [JFPU1, JFPM],  4, [1,2]>;
344 defm : JWriteResFpuPair<WriteFMul64X,      [JFPU1, JFPM],  4, [1,2]>;
345 defm : JWriteResYMMPair<WriteFMul64Y,      [JFPU1, JFPM],  4, [2,4], 2>;
346 defm : X86WriteResPairUnsupported<WriteFMul64Z>;
347 defm : X86WriteResPairUnsupported<WriteFMA>;
348 defm : X86WriteResPairUnsupported<WriteFMAX>;
349 defm : X86WriteResPairUnsupported<WriteFMAY>;
350 defm : X86WriteResPairUnsupported<WriteFMAZ>;
351 defm : JWriteResFpuPair<WriteDPPD,   [JFPU1, JFPM, JFPA],  9, [1, 3, 3],  3>;
352 defm : JWriteResFpuPair<WriteDPPS,   [JFPU1, JFPM, JFPA], 11, [1, 3, 3],  5>;
353 defm : JWriteResYMMPair<WriteDPPSY,  [JFPU1, JFPM, JFPA], 12, [2, 6, 6], 10>;
354 defm : X86WriteResPairUnsupported<WriteDPPSZ>;
355 defm : JWriteResFpuPair<WriteFRcp,         [JFPU1, JFPM],  2>;
356 defm : JWriteResFpuPair<WriteFRcpX,        [JFPU1, JFPM],  2>;
357 defm : JWriteResYMMPair<WriteFRcpY,        [JFPU1, JFPM],  2, [2,2], 2>;
358 defm : X86WriteResPairUnsupported<WriteFRcpZ>;
359 defm : JWriteResFpuPair<WriteFRsqrt,       [JFPU1, JFPM],  2>;
360 defm : JWriteResFpuPair<WriteFRsqrtX,      [JFPU1, JFPM],  2>;
361 defm : JWriteResYMMPair<WriteFRsqrtY,      [JFPU1, JFPM],  2, [2,2], 2>;
362 defm : X86WriteResPairUnsupported<WriteFRsqrtZ>;
363 defm : JWriteResFpuPair<WriteFDiv,         [JFPU1, JFPM], 19, [1, 19]>;
364 defm : JWriteResFpuPair<WriteFDivX,        [JFPU1, JFPM], 19, [1, 19]>;
365 defm : JWriteResYMMPair<WriteFDivY,        [JFPU1, JFPM], 38, [2, 38], 2>;
366 defm : X86WriteResPairUnsupported<WriteFDivZ>;
367 defm : JWriteResFpuPair<WriteFDiv64,       [JFPU1, JFPM], 19, [1, 19]>;
368 defm : JWriteResFpuPair<WriteFDiv64X,      [JFPU1, JFPM], 19, [1, 19]>;
369 defm : JWriteResYMMPair<WriteFDiv64Y,      [JFPU1, JFPM], 38, [2, 38], 2>;
370 defm : X86WriteResPairUnsupported<WriteFDiv64Z>;
371 defm : JWriteResFpuPair<WriteFSqrt,        [JFPU1, JFPM], 21, [1, 21]>;
372 defm : JWriteResFpuPair<WriteFSqrtX,       [JFPU1, JFPM], 21, [1, 21]>;
373 defm : JWriteResYMMPair<WriteFSqrtY,       [JFPU1, JFPM], 42, [2, 42], 2>;
374 defm : X86WriteResPairUnsupported<WriteFSqrtZ>;
375 defm : JWriteResFpuPair<WriteFSqrt64,      [JFPU1, JFPM], 27, [1, 27]>;
376 defm : JWriteResFpuPair<WriteFSqrt64X,     [JFPU1, JFPM], 27, [1, 27]>;
377 defm : JWriteResYMMPair<WriteFSqrt64Y,     [JFPU1, JFPM], 54, [2, 54], 2>;
378 defm : X86WriteResPairUnsupported<WriteFSqrt64Z>;
379 defm : JWriteResFpuPair<WriteFSqrt80,      [JFPU1, JFPM], 35, [1, 35]>;
380 defm : JWriteResFpuPair<WriteFSign,        [JFPU1, JFPM],  2>;
381 defm : JWriteResFpuPair<WriteFRnd,         [JFPU1, JSTC],  3>;
382 defm : JWriteResYMMPair<WriteFRndY,        [JFPU1, JSTC],  3, [2,2], 2>;
383 defm : X86WriteResPairUnsupported<WriteFRndZ>;
384 defm : JWriteResFpuPair<WriteFLogic,      [JFPU01, JFPX],  1>;
385 defm : JWriteResYMMPair<WriteFLogicY,     [JFPU01, JFPX],  1, [2, 2], 2>;
386 defm : X86WriteResPairUnsupported<WriteFLogicZ>;
387 defm : JWriteResFpuPair<WriteFTest,       [JFPU0, JFPA, JALU0], 3>;
388 defm : JWriteResYMMPair<WriteFTestY ,     [JFPU01, JFPX, JFPA, JALU0], 4, [2, 2, 2, 1], 3>;
389 defm : X86WriteResPairUnsupported<WriteFTestZ>;
390 defm : JWriteResFpuPair<WriteFShuffle,    [JFPU01, JFPX],  1>;
391 defm : JWriteResYMMPair<WriteFShuffleY,   [JFPU01, JFPX],  1, [2, 2], 2>;
392 defm : X86WriteResPairUnsupported<WriteFShuffleZ>;
393 defm : JWriteResFpuPair<WriteFVarShuffle, [JFPU01, JFPX],  2, [1, 4], 3>;
394 defm : JWriteResYMMPair<WriteFVarShuffleY,[JFPU01, JFPX],  3, [2, 6], 6>;
395 defm : X86WriteResPairUnsupported<WriteFVarShuffleZ>;
396 defm : JWriteResFpuPair<WriteFBlend,      [JFPU01, JFPX],  1>;
397 defm : JWriteResYMMPair<WriteFBlendY,     [JFPU01, JFPX],  1, [2, 2], 2>;
398 defm : X86WriteResPairUnsupported<WriteFBlendZ>;
399 defm : JWriteResFpuPair<WriteFVarBlend,   [JFPU01, JFPX],  2, [4, 4], 3>;
400 defm : JWriteResYMMPair<WriteFVarBlendY,  [JFPU01, JFPX],  3, [6, 6], 6>;
401 defm : X86WriteResPairUnsupported<WriteFVarBlendZ>;
402 defm : JWriteResFpuPair<WriteFShuffle256, [JFPU01, JFPX],  1, [2, 2], 2>;
403 defm : X86WriteResPairUnsupported<WriteFVarShuffle256>;
405 ////////////////////////////////////////////////////////////////////////////////
406 // Conversions.
407 ////////////////////////////////////////////////////////////////////////////////
409 defm : JWriteResFpuPair<WriteCvtSS2I,      [JFPU1, JSTC, JFPU0, JFPA, JALU0], 7, [1,1,1,1,1], 2>;
410 defm : JWriteResFpuPair<WriteCvtPS2I,      [JFPU1, JSTC], 3, [1,1], 1>;
411 defm : JWriteResYMMPair<WriteCvtPS2IY,     [JFPU1, JSTC], 3, [2,2], 2>;
412 defm : X86WriteResPairUnsupported<WriteCvtPS2IZ>;
413 defm : JWriteResFpuPair<WriteCvtSD2I,      [JFPU1, JSTC, JFPU0, JFPA, JALU0], 7, [1,1,1,1,1], 2>;
414 defm : JWriteResFpuPair<WriteCvtPD2I,      [JFPU1, JSTC], 3, [1,1], 1>;
415 defm : JWriteResYMMPair<WriteCvtPD2IY,     [JFPU1, JSTC, JFPX], 6, [2,2,4], 3>;
416 defm : X86WriteResPairUnsupported<WriteCvtPD2IZ>;
418 // FIXME: f+3 ST, LD+STC latency
419 defm : JWriteResFpuPair<WriteCvtI2SS,      [JFPU1, JSTC], 9, [1,1], 2>;
420 defm : JWriteResFpuPair<WriteCvtI2PS,      [JFPU1, JSTC], 3, [1,1], 1>;
421 defm : JWriteResYMMPair<WriteCvtI2PSY,     [JFPU1, JSTC], 3, [2,2], 2>;
422 defm : X86WriteResPairUnsupported<WriteCvtI2PSZ>;
423 defm : JWriteResFpuPair<WriteCvtI2SD,      [JFPU1, JSTC], 9, [1,1], 2>;
424 defm : JWriteResFpuPair<WriteCvtI2PD,      [JFPU1, JSTC], 3, [1,1], 1>;
425 defm : JWriteResYMMPair<WriteCvtI2PDY,     [JFPU1, JSTC], 3, [2,2], 2>;
426 defm : X86WriteResPairUnsupported<WriteCvtI2PDZ>;
428 defm : JWriteResFpuPair<WriteCvtSS2SD,      [JFPU1, JSTC], 7, [1,2], 2>;
429 defm : JWriteResFpuPair<WriteCvtPS2PD,      [JFPU1, JSTC], 2, [1,1], 1>;
430 defm : JWriteResYMMPair<WriteCvtPS2PDY,     [JFPU1, JSTC], 2, [2,2], 2>;
431 defm : X86WriteResPairUnsupported<WriteCvtPS2PDZ>;
433 defm : JWriteResFpuPair<WriteCvtSD2SS,    [JFPU1, JSTC], 7, [1,2], 2>;
434 defm : JWriteResFpuPair<WriteCvtPD2PS,    [JFPU1, JSTC], 3, [1,1], 1>;
435 defm : JWriteResYMMPair<WriteCvtPD2PSY,   [JFPU1, JSTC, JFPX], 6, [2,2,4], 3>;
436 defm : X86WriteResPairUnsupported<WriteCvtPD2PSZ>;
438 defm : JWriteResFpuPair<WriteCvtPH2PS,     [JFPU1, JSTC], 3, [1,1], 1>;
439 defm : JWriteResYMMPair<WriteCvtPH2PSY,    [JFPU1, JSTC], 3, [2,2], 2>;
440 defm : X86WriteResPairUnsupported<WriteCvtPH2PSZ>;
442 defm : X86WriteRes<WriteCvtPS2PH,                 [JFPU1, JSTC], 3, [1,1], 1>;
443 defm : X86WriteRes<WriteCvtPS2PHY,          [JFPU1, JSTC, JFPX], 6, [2,2,2], 3>;
444 defm : X86WriteResUnsupported<WriteCvtPS2PHZ>;
445 defm : X86WriteRes<WriteCvtPS2PHSt,        [JFPU1, JSTC, JSAGU], 4, [1,1,1], 1>;
446 defm : X86WriteRes<WriteCvtPS2PHYSt, [JFPU1, JSTC, JFPX, JSAGU], 7, [2,2,2,1], 3>;
447 defm : X86WriteResUnsupported<WriteCvtPS2PHZSt>;
449 ////////////////////////////////////////////////////////////////////////////////
450 // Vector integer operations.
451 ////////////////////////////////////////////////////////////////////////////////
453 defm : X86WriteRes<WriteVecLoad,          [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
454 defm : X86WriteRes<WriteVecLoadX,         [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
455 defm : X86WriteRes<WriteVecLoadY,         [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
456 defm : X86WriteRes<WriteVecLoadNT,        [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
457 defm : X86WriteRes<WriteVecLoadNTY,       [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
458 defm : X86WriteRes<WriteVecMaskedLoad,    [JLAGU, JFPU01, JVALU], 6, [1, 2, 2], 1>;
459 defm : X86WriteRes<WriteVecMaskedLoadY,   [JLAGU, JFPU01, JVALU], 6, [2, 4, 4], 2>;
461 defm : X86WriteRes<WriteVecStore,         [JSAGU, JFPU1,   JSTC], 2, [1, 1, 1], 1>;
462 defm : X86WriteRes<WriteVecStoreX,        [JSAGU, JFPU1,   JSTC], 1, [1, 1, 1], 1>;
463 defm : X86WriteRes<WriteVecStoreY,        [JSAGU, JFPU1,   JSTC], 1, [1, 1, 1], 1>;
464 defm : X86WriteRes<WriteVecStoreNT,       [JSAGU, JFPU1,   JSTC], 2, [1, 1, 1], 1>;
465 defm : X86WriteRes<WriteVecStoreNTY,      [JSAGU, JFPU1,   JSTC], 2, [2, 2, 2], 1>;
466 defm : X86WriteRes<WriteVecMaskedStore,   [JSAGU, JFPU01, JVALU], 6, [1, 1, 4], 1>;
467 defm : X86WriteRes<WriteVecMaskedStoreY,  [JSAGU, JFPU01, JVALU], 6, [2, 2, 4], 2>;
469 defm : X86WriteRes<WriteVecMove,          [JFPU01, JVALU], 1, [1, 1], 1>;
470 defm : X86WriteRes<WriteVecMoveX,         [JFPU01, JVALU], 1, [1, 1], 1>;
471 defm : X86WriteRes<WriteVecMoveY,         [JFPU01, JVALU], 1, [2, 2], 2>;
472 defm : X86WriteRes<WriteVecMoveToGpr,     [JFPU0, JFPA, JALU0], 4, [1, 1, 1], 1>;
473 defm : X86WriteRes<WriteVecMoveFromGpr,   [JFPU01, JFPX], 8, [1, 1], 2>;
475 defm : JWriteResFpuPair<WriteVecALU,      [JFPU01, JVALU], 1>;
476 defm : JWriteResFpuPair<WriteVecALUX,     [JFPU01, JVALU], 1>;
477 defm : X86WriteResPairUnsupported<WriteVecALUY>;
478 defm : X86WriteResPairUnsupported<WriteVecALUZ>;
479 defm : JWriteResFpuPair<WriteVecShift,    [JFPU01, JVALU], 1>;
480 defm : JWriteResFpuPair<WriteVecShiftX,   [JFPU01, JVALU], 1>;
481 defm : X86WriteResPairUnsupported<WriteVecShiftY>;
482 defm : X86WriteResPairUnsupported<WriteVecShiftZ>;
483 defm : JWriteResFpuPair<WriteVecShiftImm, [JFPU01, JVALU], 1>;
484 defm : JWriteResFpuPair<WriteVecShiftImmX,[JFPU01, JVALU], 1>;
485 defm : X86WriteResPairUnsupported<WriteVecShiftImmY>;
486 defm : X86WriteResPairUnsupported<WriteVecShiftImmZ>;
487 defm : X86WriteResPairUnsupported<WriteVarVecShift>;
488 defm : X86WriteResPairUnsupported<WriteVarVecShiftY>;
489 defm : X86WriteResPairUnsupported<WriteVarVecShiftZ>;
490 defm : JWriteResFpuPair<WriteVecIMul,     [JFPU0, JVIMUL], 2>;
491 defm : JWriteResFpuPair<WriteVecIMulX,    [JFPU0, JVIMUL], 2>;
492 defm : X86WriteResPairUnsupported<WriteVecIMulY>;
493 defm : X86WriteResPairUnsupported<WriteVecIMulZ>;
494 defm : JWriteResFpuPair<WritePMULLD,      [JFPU0, JFPU01, JVIMUL, JVALU], 4, [2, 1, 2, 1], 3>;
495 defm : X86WriteResPairUnsupported<WritePMULLDY>;
496 defm : X86WriteResPairUnsupported<WritePMULLDZ>;
497 defm : JWriteResFpuPair<WriteMPSAD,       [JFPU0, JVIMUL], 3, [1, 2], 3>;
498 defm : X86WriteResPairUnsupported<WriteMPSADY>;
499 defm : X86WriteResPairUnsupported<WriteMPSADZ>;
500 defm : JWriteResFpuPair<WritePSADBW,      [JFPU01, JVALU], 2>;
501 defm : JWriteResFpuPair<WritePSADBWX,     [JFPU01, JVALU], 2>;
502 defm : X86WriteResPairUnsupported<WritePSADBWY>;
503 defm : X86WriteResPairUnsupported<WritePSADBWZ>;
504 defm : JWriteResFpuPair<WritePHMINPOS,    [JFPU01, JVALU], 2>;
505 defm : JWriteResFpuPair<WriteShuffle,     [JFPU01, JVALU], 1>;
506 defm : JWriteResFpuPair<WriteShuffleX,    [JFPU01, JVALU], 1>;
507 defm : X86WriteResPairUnsupported<WriteShuffleY>;
508 defm : X86WriteResPairUnsupported<WriteShuffleZ>;
509 defm : JWriteResFpuPair<WriteVarShuffle,  [JFPU01, JVALU], 2, [1, 1], 1>;
510 defm : JWriteResFpuPair<WriteVarShuffleX, [JFPU01, JVALU], 2, [1, 4], 3>;
511 defm : X86WriteResPairUnsupported<WriteVarShuffleY>;
512 defm : X86WriteResPairUnsupported<WriteVarShuffleZ>;
513 defm : JWriteResFpuPair<WriteBlend,       [JFPU01, JVALU], 1>;
514 defm : X86WriteResPairUnsupported<WriteBlendY>;
515 defm : X86WriteResPairUnsupported<WriteBlendZ>;
516 defm : JWriteResFpuPair<WriteVarBlend,    [JFPU01, JVALU], 2, [4, 4], 3>;
517 defm : X86WriteResPairUnsupported<WriteVarBlendY>;
518 defm : X86WriteResPairUnsupported<WriteVarBlendZ>;
519 defm : JWriteResFpuPair<WriteVecLogic,    [JFPU01, JVALU], 1>;
520 defm : JWriteResFpuPair<WriteVecLogicX,   [JFPU01, JVALU], 1>;
521 defm : X86WriteResPairUnsupported<WriteVecLogicY>;
522 defm : X86WriteResPairUnsupported<WriteVecLogicZ>;
523 defm : JWriteResFpuPair<WriteVecTest,     [JFPU0, JFPA, JALU0], 3>;
524 defm : JWriteResYMMPair<WriteVecTestY,    [JFPU01, JFPX, JFPA, JALU0], 4, [2, 2, 2, 1], 3>;
525 defm : X86WriteResPairUnsupported<WriteVecTestZ>;
526 defm : X86WriteResPairUnsupported<WriteShuffle256>;
527 defm : X86WriteResPairUnsupported<WriteVarShuffle256>;
529 ////////////////////////////////////////////////////////////////////////////////
530 // Vector insert/extract operations.
531 ////////////////////////////////////////////////////////////////////////////////
533 defm : X86WriteRes<WriteVecInsert,      [JFPU01, JVALU], 7, [1,1], 2>;
534 defm : X86WriteRes<WriteVecInsertLd,    [JFPU01, JVALU, JLAGU], 4, [1,1,1], 1>;
535 defm : X86WriteRes<WriteVecExtract,     [JFPU0, JFPA, JALU0], 3, [1,1,1], 1>;
536 defm : X86WriteRes<WriteVecExtractSt,   [JFPU1, JSTC, JSAGU], 3, [1,1,1], 1>;
538 ////////////////////////////////////////////////////////////////////////////////
539 // SSE42 String instructions.
540 ////////////////////////////////////////////////////////////////////////////////
542 defm : JWriteResFpuPair<WritePCmpIStrI, [JFPU1, JVALU1, JFPU0, JFPA, JALU0], 7, [2, 2, 1, 1, 1], 3>;
543 defm : JWriteResFpuPair<WritePCmpIStrM, [JFPU1, JVALU1, JFPU0, JFPA, JALU0], 8, [2, 2, 1, 1, 1], 3>;
544 defm : JWriteResFpuPair<WritePCmpEStrI, [JFPU1, JSAGU, JLAGU, JVALU, JVALU1, JFPA, JALU0], 14, [1, 2, 2, 6, 4, 1, 1], 9>;
545 defm : JWriteResFpuPair<WritePCmpEStrM, [JFPU1, JSAGU, JLAGU, JVALU, JVALU1, JFPA, JALU0], 14, [1, 2, 2, 6, 4, 1, 1], 9>;
547 ////////////////////////////////////////////////////////////////////////////////
548 // MOVMSK Instructions.
549 ////////////////////////////////////////////////////////////////////////////////
551 def  : WriteRes<WriteFMOVMSK,    [JFPU0, JFPA, JALU0]> { let Latency = 3; }
552 def  : WriteRes<WriteVecMOVMSK,  [JFPU0, JFPA, JALU0]> { let Latency = 3; }
553 defm : X86WriteResUnsupported<WriteVecMOVMSKY>;
554 def  : WriteRes<WriteMMXMOVMSK,  [JFPU0, JFPA, JALU0]> { let Latency = 3; }
556 ////////////////////////////////////////////////////////////////////////////////
557 // AES Instructions.
558 ////////////////////////////////////////////////////////////////////////////////
560 defm : JWriteResFpuPair<WriteAESIMC,      [JFPU0, JVIMUL], 2>;
561 defm : JWriteResFpuPair<WriteAESKeyGen,   [JFPU0, JVIMUL], 2>;
562 defm : JWriteResFpuPair<WriteAESDecEnc,   [JFPU01, JVALU, JFPU0, JVIMUL], 3, [1,1,1,1], 2>;
564 ////////////////////////////////////////////////////////////////////////////////
565 // Horizontal add/sub  instructions.
566 ////////////////////////////////////////////////////////////////////////////////
568 defm : JWriteResFpuPair<WriteFHAdd,         [JFPU0, JFPA], 3>;
569 defm : JWriteResYMMPair<WriteFHAddY,        [JFPU0, JFPA], 3, [2,2], 2>;
570 defm : JWriteResFpuPair<WritePHAdd,       [JFPU01, JVALU], 1>;
571 defm : JWriteResFpuPair<WritePHAddX,      [JFPU01, JVALU], 1>;
572 defm : X86WriteResPairUnsupported<WritePHAddY>;
574 ////////////////////////////////////////////////////////////////////////////////
575 // Carry-less multiplication instructions.
576 ////////////////////////////////////////////////////////////////////////////////
578 defm : JWriteResFpuPair<WriteCLMul,       [JFPU0, JVIMUL], 2>;
580 ////////////////////////////////////////////////////////////////////////////////
581 // SSE4A instructions.
582 ////////////////////////////////////////////////////////////////////////////////
584 def JWriteINSERTQ: SchedWriteRes<[JFPU01, JVALU]> {
585   let Latency = 2;
586   let ResourceCycles = [1, 4];
588 def : InstRW<[JWriteINSERTQ], (instrs INSERTQ, INSERTQI)>;
590 ////////////////////////////////////////////////////////////////////////////////
591 // AVX instructions.
592 ////////////////////////////////////////////////////////////////////////////////
594 def JWriteVecExtractF128: SchedWriteRes<[JFPU01, JFPX]>;
595 def : InstRW<[JWriteVecExtractF128], (instrs VEXTRACTF128rr)>;
597 def JWriteVBROADCASTYLd: SchedWriteRes<[JLAGU, JFPU01, JFPX]> {
598   let Latency = 6;
599   let ResourceCycles = [1, 2, 4];
600   let NumMicroOps = 2;
602 def : InstRW<[JWriteVBROADCASTYLd], (instrs VBROADCASTSDYrm,
603                                             VBROADCASTSSYrm,
604                                             VBROADCASTF128)>;
606 def JWriteJVZEROALL: SchedWriteRes<[]> {
607   let Latency = 90;
608   let NumMicroOps = 73;
610 def : InstRW<[JWriteJVZEROALL], (instrs VZEROALL)>;
612 def JWriteJVZEROUPPER: SchedWriteRes<[]> {
613   let Latency = 46;
614   let NumMicroOps = 37;
616 def : InstRW<[JWriteJVZEROUPPER], (instrs VZEROUPPER)>;
618 ///////////////////////////////////////////////////////////////////////////////
619 //  SchedWriteVariant definitions.
620 ///////////////////////////////////////////////////////////////////////////////
622 def JWriteZeroLatency : SchedWriteRes<[]> {
623   let Latency = 0;
626 def JWriteZeroIdiomYmm : SchedWriteRes<[JFPU01, JFPX]> {
627   let NumMicroOps = 2;
630 // Certain instructions that use the same register for both source
631 // operands do not have a real dependency on the previous contents of the
632 // register, and thus, do not have to wait before completing. They can be
633 // optimized out at register renaming stage.
634 // Reference: Section 10.8 of the "Software Optimization Guide for AMD Family
635 // 15h Processors".
636 // Reference: Agner's Fog "The microarchitecture of Intel, AMD and VIA CPUs",
637 // Section 21.8 [Dependency-breaking instructions].
639 def JWriteZeroIdiom : SchedWriteVariant<[
640     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
641     SchedVar<NoSchedPred,                          [WriteALU]>
643 def : InstRW<[JWriteZeroIdiom], (instrs SUB32rr, SUB64rr,
644                                         XOR32rr, XOR64rr)>;
646 def JWriteFZeroIdiom : SchedWriteVariant<[
647     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
648     SchedVar<NoSchedPred,                          [WriteFLogic]>
650 def : InstRW<[JWriteFZeroIdiom], (instrs XORPSrr, VXORPSrr, XORPDrr, VXORPDrr,
651                                          ANDNPSrr, VANDNPSrr,
652                                          ANDNPDrr, VANDNPDrr)>;
654 def JWriteFZeroIdiomY : SchedWriteVariant<[
655     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroIdiomYmm]>,
656     SchedVar<NoSchedPred,                          [WriteFLogicY]>
658 def : InstRW<[JWriteFZeroIdiomY], (instrs VXORPSYrr, VXORPDYrr,
659                                           VANDNPSYrr, VANDNPDYrr)>;
661 def JWriteVZeroIdiomLogic : SchedWriteVariant<[
662     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
663     SchedVar<NoSchedPred,                          [WriteVecLogic]>
665 def : InstRW<[JWriteVZeroIdiomLogic], (instrs MMX_PXORirr, MMX_PANDNirr)>;
667 def JWriteVZeroIdiomLogicX : SchedWriteVariant<[
668     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
669     SchedVar<NoSchedPred,                          [WriteVecLogicX]>
671 def : InstRW<[JWriteVZeroIdiomLogicX], (instrs PXORrr, VPXORrr,
672                                                PANDNrr, VPANDNrr)>;
674 def JWriteVZeroIdiomALU : SchedWriteVariant<[
675     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
676     SchedVar<NoSchedPred,                          [WriteVecALU]>
678 def : InstRW<[JWriteVZeroIdiomALU], (instrs MMX_PSUBBirr, MMX_PSUBDirr,
679                                             MMX_PSUBQirr, MMX_PSUBWirr,
680                                             MMX_PSUBSBirr, MMX_PSUBSWirr,
681                                             MMX_PSUBUSBirr, MMX_PSUBUSWirr,
682                                             MMX_PCMPGTBirr, MMX_PCMPGTDirr,
683                                             MMX_PCMPGTWirr)>;
685 def JWriteVZeroIdiomALUX : SchedWriteVariant<[
686     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
687     SchedVar<NoSchedPred,                          [WriteVecALUX]>
689 def : InstRW<[JWriteVZeroIdiomALUX], (instrs PSUBBrr, VPSUBBrr,
690                                              PSUBDrr, VPSUBDrr,
691                                              PSUBQrr, VPSUBQrr,
692                                              PSUBWrr, VPSUBWrr,
693                                              PSUBSBrr, VPSUBSBrr,
694                                              PSUBSWrr, VPSUBSWrr,
695                                              PSUBUSBrr, VPSUBUSBrr,
696                                              PSUBUSWrr, VPSUBUSWrr,
697                                              PCMPGTBrr, VPCMPGTBrr,
698                                              PCMPGTDrr, VPCMPGTDrr,
699                                              PCMPGTQrr, VPCMPGTQrr,
700                                              PCMPGTWrr, VPCMPGTWrr)>;
702 def JWriteVPERM2F128 : SchedWriteVariant<[
703   SchedVar<MCSchedPredicate<ZeroIdiomVPERMPredicate>, [JWriteZeroIdiomYmm]>,
704   SchedVar<NoSchedPred,                               [WriteFShuffle256]>
706 def : InstRW<[JWriteVPERM2F128], (instrs VPERM2F128rr)>;
708 // This write is used for slow LEA instructions.
709 def JWrite3OpsLEA : SchedWriteRes<[JALU1, JSAGU]> {
710   let Latency = 2;
713 // On Jaguar, a slow LEA is either a 3Ops LEA (base, index, offset), or an LEA
714 // with a `Scale` value different than 1.
715 def JSlowLEAPredicate : MCSchedPredicate<
716   CheckAny<[
717     // A 3-operand LEA (base, index, offset).
718     IsThreeOperandsLEAFn,
719     // An LEA with a "Scale" different than 1.
720     CheckAll<[
721       CheckIsImmOperand<2>,
722       CheckNot<CheckImmOperand<2, 1>>
723     ]>
724   ]>
727 def JWriteLEA : SchedWriteVariant<[
728     SchedVar<JSlowLEAPredicate, [JWrite3OpsLEA]>,
729     SchedVar<NoSchedPred,       [WriteLEA]>
732 def : InstRW<[JWriteLEA], (instrs LEA32r, LEA64r, LEA64_32r)>;
734 def JSlowLEA16r : SchedWriteRes<[JALU01]> {
735   let Latency = 3;
736   let ResourceCycles = [4];
739 def : InstRW<[JSlowLEA16r], (instrs LEA16r)>;
741 ///////////////////////////////////////////////////////////////////////////////
742 // Dependency breaking instructions.
743 ///////////////////////////////////////////////////////////////////////////////
745 def : IsZeroIdiomFunction<[
746   // GPR Zero-idioms.
747   DepBreakingClass<[ SUB32rr, SUB64rr, XOR32rr, XOR64rr ], ZeroIdiomPredicate>,
749   // MMX Zero-idioms.
750   DepBreakingClass<[
751     MMX_PXORirr, MMX_PANDNirr, MMX_PSUBBirr,
752     MMX_PSUBDirr, MMX_PSUBQirr, MMX_PSUBWirr,
753     MMX_PSUBSBirr, MMX_PSUBSWirr, MMX_PSUBUSBirr, MMX_PSUBUSWirr,
754     MMX_PCMPGTBirr, MMX_PCMPGTDirr, MMX_PCMPGTWirr
755   ], ZeroIdiomPredicate>,
757   // SSE Zero-idioms.
758   DepBreakingClass<[
759     // fp variants.
760     XORPSrr, XORPDrr, ANDNPSrr, ANDNPDrr,
762     // int variants.
763     PXORrr, PANDNrr,
764     PSUBBrr, PSUBWrr, PSUBDrr, PSUBQrr,
765     PSUBSBrr, PSUBSWrr, PSUBUSBrr, PSUBUSWrr,
766     PCMPGTBrr, PCMPGTDrr, PCMPGTQrr, PCMPGTWrr
767   ], ZeroIdiomPredicate>,
769   // AVX Zero-idioms.
770   DepBreakingClass<[
771     // xmm fp variants.
772     VXORPSrr, VXORPDrr, VANDNPSrr, VANDNPDrr,
774     // xmm int variants.
775     VPXORrr, VPANDNrr,
776     VPSUBBrr, VPSUBWrr, VPSUBDrr, VPSUBQrr,
777     VPSUBSBrr, VPSUBSWrr, VPSUBUSBrr, VPSUBUSWrr,
778     VPCMPGTBrr, VPCMPGTWrr, VPCMPGTDrr, VPCMPGTQrr,
780     // ymm variants.
781     VXORPSYrr, VXORPDYrr, VANDNPSYrr, VANDNPDYrr
782   ], ZeroIdiomPredicate>,
784   DepBreakingClass<[ VPERM2F128rr ], ZeroIdiomVPERMPredicate>
787 def : IsDepBreakingFunction<[
788   // GPR
789   DepBreakingClass<[ SBB32rr, SBB64rr ], ZeroIdiomPredicate>,
790   DepBreakingClass<[ CMP32rr, CMP64rr ], CheckSameRegOperand<0, 1> >,
792   // MMX
793   DepBreakingClass<[
794     MMX_PCMPEQBirr, MMX_PCMPEQDirr, MMX_PCMPEQWirr
795   ], ZeroIdiomPredicate>,
797   // SSE
798   DepBreakingClass<[ 
799     PCMPEQBrr, PCMPEQWrr, PCMPEQDrr, PCMPEQQrr
800   ], ZeroIdiomPredicate>,
802   // AVX
803   DepBreakingClass<[
804     VPCMPEQBrr, VPCMPEQWrr, VPCMPEQDrr, VPCMPEQQrr
805   ], ZeroIdiomPredicate>
808 } // SchedModel