]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/X86/X86ScheduleBdVer2.td
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / X86 / X86ScheduleBdVer2.td
1 //=- X86ScheduleBdVer2.td - X86 BdVer2 (Piledriver) 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 bdver2 (Piledriver) to support
11 // instruction scheduling and other instruction cost heuristics.
12 // Based on:
13 //  * AMD Software Optimization Guide for AMD Family 15h Processors.
14 //    https://support.amd.com/TechDocs/47414_15h_sw_opt_guide.pdf
15 //  * The microarchitecture of Intel, AMD and VIA CPUs, By Agner Fog
16 //    http://www.agner.org/optimize/microarchitecture.pdf
17 //  * https://www.realworldtech.com/bulldozer/
18 //    Yes, that is for Bulldozer aka bdver1, not Piledriver aka bdver2.
19 //
20 //===----------------------------------------------------------------------===//
21
22 def BdVer2Model : SchedMachineModel {
23   let IssueWidth = 4; // Up to 4 IPC can be decoded, issued, retired.
24   let MicroOpBufferSize = 128; // RCU reorder buffer size, which is unconfirmed.
25   let LoopMicroOpBufferSize = -1; // There does not seem to be a loop buffer.
26   let LoadLatency = 4; // L1 data cache has a 4-cycle load-to-use latency.
27   let HighLatency = 25; // FIXME: any better choice?
28   let MispredictPenalty = 20; // Minimum branch misdirection penalty.
29
30   let PostRAScheduler = 1; // Enable Post RegAlloc Scheduler pass.
31
32   // FIXME: Incomplete. This flag is set to allow the scheduler to assign
33   //        a default model to unrecognized opcodes.
34   let CompleteModel = 0;
35 } // SchedMachineModel
36
37 let SchedModel = BdVer2Model in {
38
39
40 //===----------------------------------------------------------------------===//
41 // Pipes
42 //===----------------------------------------------------------------------===//
43
44 // There are total of eight pipes.
45
46 //===----------------------------------------------------------------------===//
47 // Integer execution pipes
48 //
49
50 // Two EX (ALU) pipes.
51 def PdEX0  : ProcResource<1>; // ALU, Integer Pipe0
52 def PdEX1  : ProcResource<1>; // ALU, Integer Pipe1
53 def PdEX01 : ProcResGroup<[PdEX0, PdEX1]>;
54
55 // Two AGLU pipes, identical.
56 def PdAGLU01 : ProcResource<2>; // AGU, Integer Pipe[23]
57
58 //===----------------------------------------------------------------------===//
59 // Floating point execution pipes
60 //
61
62 // Four FPU pipes.
63
64 def PdFPU0 : ProcResource<1>; // Vector/FPU Pipe0
65 def PdFPU1 : ProcResource<1>; // Vector/FPU Pipe1
66 def PdFPU2 : ProcResource<1>; // Vector/FPU Pipe2
67 def PdFPU3 : ProcResource<1>; // Vector/FPU Pipe3
68
69 // FPU grouping
70 def PdFPU01 : ProcResGroup<[PdFPU0, PdFPU1]>;
71 def PdFPU23 : ProcResGroup<[PdFPU2, PdFPU3]>;
72
73
74 //===----------------------------------------------------------------------===//
75 // RCU
76 //===----------------------------------------------------------------------===//
77
78 // The Retire Control Unit on Piledriver can retire up to 4 macro-ops per cycle.
79 // On the other hand, the RCU reorder buffer size for Piledriver does not
80 // seem be specified in any trustworthy source.
81 // But as per https://www.realworldtech.com/bulldozer/6/ the Bulldozer had
82 // RCU reorder buffer size of 128. So that is a good guess for now.
83 def PdRCU : RetireControlUnit<128, 4>;
84
85
86 //===----------------------------------------------------------------------===//
87 // Pipelines
88 //===----------------------------------------------------------------------===//
89
90 // There are total of two pipelines, each one with it's own scheduler.
91
92 //===----------------------------------------------------------------------===//
93 // Integer Pipeline Scheduling
94 //
95
96 // There is one Integer Scheduler per core.
97
98 // Integer physical register file has 96 registers of 64-bit.
99 def PdIntegerPRF : RegisterFile<96, [GR64, CCR]>;
100
101 // Unified Integer, Memory Scheduler has 40 entries.
102 def PdEX : ProcResGroup<[PdEX0, PdEX1, PdAGLU01]> {
103   // Up to 4 IPC can be decoded, issued, retired.
104   let BufferSize = 40;
105 }
106
107
108 //===----------------------------------------------------------------------===//
109 // FPU Pipeline Scheduling
110 //
111
112 // The FPU unit is shared between the two cores.
113
114 // FP physical register file has 160 registers of 128-bit.
115 // Operations on 256-bit data types are cracked into two COPs.
116 def PdFpuPRF : RegisterFile<160, [VR64, VR128, VR256], [1, 1, 2]>;
117
118 // Unified FP Scheduler has 64 entries,
119 def PdFPU : ProcResGroup<[PdFPU0, PdFPU1, PdFPU2, PdFPU3]> {
120   // Up to 4 IPC can be decoded, issued, retired.
121   let BufferSize = 64;
122 }
123
124
125 //===----------------------------------------------------------------------===//
126 // Functional units
127 //===----------------------------------------------------------------------===//
128
129 //===----------------------------------------------------------------------===//
130 // Load-Store Units
131 //
132
133 let Super = PdAGLU01 in
134 def PdLoad  : ProcResource<2> {
135   // For Piledriver, the load queue is 40 entries deep.
136   let BufferSize = 40;
137 }
138
139 def PdLoadQueue : LoadQueue<PdLoad>;
140
141 let Super = PdAGLU01 in
142 def PdStore : ProcResource<1> {
143   // For Piledriver, the store queue is 24 entries deep.
144   let BufferSize = 24;
145 }
146
147 def PdStoreQueue : StoreQueue<PdStore>;
148
149 //===----------------------------------------------------------------------===//
150 // Integer Execution Units
151 //
152
153 def PdDiv    : ProcResource<1>; // PdEX0; unpipelined integer division
154 def PdCount  : ProcResource<1>; // PdEX0; POPCNT, LZCOUNT
155
156 def PdMul    : ProcResource<1>; // PdEX1; integer multiplication
157 def PdBranch : ProcResource<1>; // PdEX1; JMP, fused branches
158
159 //===----------------------------------------------------------------------===//
160 // Floating-Point Units
161 //
162
163 // Two FMAC/FPFMA units.
164 def PdFPFMA  : ProcResource<2>; // PdFPU0, PdFPU1
165
166 // One 128-bit integer multiply-accumulate unit.
167 def PdFPMMA  : ProcResource<1>; // PdFPU0
168
169 // One fp conversion unit.
170 def PdFPCVT  : ProcResource<1>; // PdFPU0
171
172 // One unit for shuffles, packs, permutes, shifts.
173 def PdFPXBR  : ProcResource<1>; // PdFPU1
174
175 // Two 128-bit packed integer units.
176 def PdFPMAL  : ProcResource<2>; // PdFPU2, PdFPU3
177
178 // One FP store unit.
179 def PdFPSTO  : ProcResource<1>; // PdFPU3
180
181
182 //===----------------------------------------------------------------------===//
183 // Basic helper classes.
184 //===----------------------------------------------------------------------===//
185
186 // Many SchedWrites are defined in pairs with and without a folded load.
187 // Instructions with folded loads are usually micro-fused, so they only appear
188 // as two micro-ops when dispatched by the schedulers.
189 // This multiclass defines the resource usage for variants with and without
190 // folded loads.
191 multiclass PdWriteRes<SchedWrite SchedRW,
192                       list<ProcResourceKind> ExePorts, int Lat = 1,
193                       list<int> Res = [], int UOps = 1> {
194   def : WriteRes<SchedRW, ExePorts> {
195     let Latency = Lat;
196     let ResourceCycles = Res;
197     let NumMicroOps = UOps;
198   }
199 }
200
201 multiclass __pdWriteResPair<X86FoldableSchedWrite SchedRW,
202                             list<ProcResourceKind> ExePorts, int Lat,
203                             list<int> Res, int UOps,
204                             int LoadLat, int LoadRes, int LoadUOps> {
205   defm : PdWriteRes<SchedRW, ExePorts, Lat, Res, UOps>;
206
207   defm : PdWriteRes<SchedRW.Folded,
208                     !listconcat([PdLoad], ExePorts),
209                     !add(Lat, LoadLat),
210                     !if(!and(!empty(Res), !eq(LoadRes, 1)),
211                       [],
212                       !listconcat([LoadRes], Res)),
213                     !add(UOps, LoadUOps)>;
214 }
215
216 multiclass PdWriteResExPair<X86FoldableSchedWrite SchedRW,
217                             list<ProcResourceKind> ExePorts, int Lat = 1,
218                             list<int> Res = [], int UOps = 1,
219                             int LoadUOps = 0> {
220   defm : __pdWriteResPair<SchedRW, ExePorts, Lat, Res, UOps,
221                           /*LoadLat*/4, /*LoadRes*/1, LoadUOps>;
222 }
223
224 multiclass PdWriteResXMMPair<X86FoldableSchedWrite SchedRW,
225                              list<ProcResourceKind> ExePorts, int Lat = 1,
226                              list<int> Res = [], int UOps = 1,
227                              int LoadUOps = 0> {
228   defm : __pdWriteResPair<SchedRW, ExePorts, Lat, Res, UOps,
229                            /*LoadLat*/5, /*LoadRes*/1, LoadUOps>;
230 }
231
232 multiclass PdWriteResYMMPair<X86FoldableSchedWrite SchedRW,
233                              list<ProcResourceKind> ExePorts, int Lat,
234                              list<int> Res, int UOps = 2,
235                              int LoadUOps = 0> {
236   defm : __pdWriteResPair<SchedRW, ExePorts, Lat, Res, UOps,
237                            /*LoadLat*/5, /*LoadRes*/2, LoadUOps>;
238 }
239
240 //===----------------------------------------------------------------------===//
241 // Here be dragons.
242 //===----------------------------------------------------------------------===//
243
244 // L1 data cache has a 4-cycle load-to-use latency, so ReadAfterLd registers
245 // needn't be available until 4 cycles after the memory operand.
246 def : ReadAdvance<ReadAfterLd, 4>;
247
248 // Vector loads are 5 cycles, so ReadAfterVec*Ld registers needn't be available
249 // until 5 cycles after the memory operand.
250 def : ReadAdvance<ReadAfterVecLd, 5>;
251 def : ReadAdvance<ReadAfterVecXLd, 5>;
252 def : ReadAdvance<ReadAfterVecYLd, 5>;
253
254 // A folded store needs a cycle on the PdStore for the store data.
255 def : WriteRes<WriteRMW, [PdStore]>;
256
257 ////////////////////////////////////////////////////////////////////////////////
258 // Loads, stores, and moves, not folded with other operations.
259 ////////////////////////////////////////////////////////////////////////////////
260
261 def : WriteRes<WriteLoad,    [PdLoad]> { let Latency = 5; }
262 def : WriteRes<WriteStore,   [PdStore]>;
263 def : WriteRes<WriteStoreNT, [PdStore]>;
264 def : WriteRes<WriteMove,    [PdEX01]>;
265
266 // Load/store MXCSR.
267 // FIXME: These are copy and pasted from WriteLoad/Store.
268 def : WriteRes<WriteLDMXCSR, [PdLoad]> { let Latency = 5; }
269 def : WriteRes<WriteSTMXCSR, [PdStore]> { let NumMicroOps = 2; }
270
271 // Treat misc copies as a move.
272 def : InstRW<[WriteMove], (instrs COPY)>;
273
274 ////////////////////////////////////////////////////////////////////////////////
275 // Idioms that clear a register, like xorps %xmm0, %xmm0.
276 // These can often bypass execution ports completely.
277 ////////////////////////////////////////////////////////////////////////////////
278
279 def : WriteRes<WriteZero, [/*No ExePorts*/]>;
280
281 ////////////////////////////////////////////////////////////////////////////////
282 // Branches don't produce values, so they have no latency, but they still
283 // consume resources. Indirect branches can fold loads.
284 ////////////////////////////////////////////////////////////////////////////////
285
286 defm : PdWriteResExPair<WriteJump,  [PdEX1, PdBranch]>;
287
288 ////////////////////////////////////////////////////////////////////////////////
289 // Special case scheduling classes.
290 ////////////////////////////////////////////////////////////////////////////////
291
292 def : WriteRes<WriteSystem,     [PdEX01]> { let Latency = 100; }
293 def : WriteRes<WriteMicrocoded, [PdEX01]> { let Latency = 100; }
294 def : WriteRes<WriteFence,      [PdStore]>;
295
296 def PdWriteXLAT : SchedWriteRes<[PdEX01]> {
297   let Latency = 6;
298 }
299 def : InstRW<[PdWriteXLAT], (instrs XLAT)>;
300
301 def PdWriteLARrr : SchedWriteRes<[PdEX01]> {
302   let Latency = 184;
303   let NumMicroOps = 45;
304 }
305 def : InstRW<[PdWriteLARrr], (instregex "LAR(16|32|64)rr",
306                                         "LSL(16|32|64)rr")>;
307
308 // Nops don't have dependencies, so there's no actual latency, but we set this
309 // to '1' to tell the scheduler that the nop uses an ALU slot for a cycle.
310 def : WriteRes<WriteNop, [PdEX01]>;
311
312 ////////////////////////////////////////////////////////////////////////////////
313 // Arithmetic.
314 ////////////////////////////////////////////////////////////////////////////////
315
316 defm : PdWriteResExPair<WriteALU,     [PdEX01]>;
317
318 def PdWriteLXADD : SchedWriteRes<[PdEX01]> {
319   let Latency = 6;
320   let NumMicroOps = 4;
321 }
322 def : InstRW<[PdWriteLXADD], (instrs LXADD8, LXADD16, LXADD32, LXADD64)>;
323
324 def PdWriteBMI1 : SchedWriteRes<[PdEX01]> {
325   let Latency = 2;
326   let NumMicroOps = 2;
327 }
328 def : InstRW<[PdWriteBMI1],
329              (instrs BLCFILL32rr, BLCFILL64rr, BLCI32rr, BLCI64rr,
330                      BLCIC32rr, BLCIC64rr, BLCMSK32rr, BLCMSK64rr,
331                      BLCS32rr, BLCS64rr, BLSFILL32rr, BLSFILL64rr,
332                      BLSIC32rr, BLSIC64rr, T1MSKC32rr, T1MSKC64rr,
333                      TZMSK32rr, TZMSK64rr)>;
334
335 def PdWriteBMI1m : SchedWriteRes<[PdEX01]> {
336   let Latency = 6;
337   let NumMicroOps = 2;
338 }
339 def : InstRW<[PdWriteBMI1m],
340              (instrs BLCFILL32rm, BLCFILL64rm, BLCI32rm, BLCI64rm,
341                      BLCIC32rm, BLCIC64rm, BLCMSK32rm, BLCMSK64rm,
342                      BLCS32rm, BLCS64rm, BLSFILL32rm, BLSFILL64rm,
343                      BLSIC32rm, BLSIC64rm, T1MSKC32rm, T1MSKC64rm,
344                      TZMSK32rm, TZMSK64rm)>;
345
346 defm : PdWriteResExPair<WriteADC,    [PdEX01],                  1,  [2]>;
347
348 defm : PdWriteRes<WriteBSWAP32,      [PdEX1]>;
349 defm : PdWriteRes<WriteBSWAP64,      [PdEX1]>;
350 defm : PdWriteRes<WriteCMPXCHG,      [PdEX1],                   3,  [],       5>;
351 defm : PdWriteRes<WriteCMPXCHGRMW,   [PdEX1, PdStore, PdLoad],  3,  [], 2>;
352 defm : PdWriteRes<WriteXCHG,         [PdEX1],                   1,  [],       2>;
353
354 def PdWriteCMPXCHG8rr : SchedWriteRes<[PdEX1]> {
355   let Latency = 3;
356   let NumMicroOps = 3;
357 }
358 def : InstRW<[PdWriteCMPXCHG8rr], (instrs CMPXCHG8rr)>;
359
360 def PdWriteCMPXCHG8rm : SchedWriteRes<[PdEX1]> {
361   let Latency = 3;
362   let NumMicroOps = 5;
363 }
364 def : InstRW<[PdWriteCMPXCHG8rm], (instrs CMPXCHG8rm)>;
365
366 def PdWriteCMPXCHG16rm_CMPXCHG32rm_CMPXCHG64rm : SchedWriteRes<[PdEX1]> {
367   let Latency = 3;
368   let NumMicroOps = 6;
369 }
370 def : InstRW<[PdWriteCMPXCHG16rm_CMPXCHG32rm_CMPXCHG64rm],
371              (instrs CMPXCHG16rm, CMPXCHG32rm, CMPXCHG64rm)>;
372
373 def PdWriteCMPXCHG8B : SchedWriteRes<[PdEX1]> {
374   let Latency = 3;
375   let NumMicroOps = 18;
376 }
377 def : InstRW<[PdWriteCMPXCHG8B], (instrs CMPXCHG8B)>;
378
379 def PdWriteCMPXCHG16B : SchedWriteRes<[PdEX1]> {
380   let Latency = 3;
381   let NumMicroOps = 22;
382 }
383 def : InstRW<[PdWriteCMPXCHG16B], (instrs CMPXCHG16B)>;
384
385 def PdWriteXCHG16rr : SchedWriteRes<[PdEX1]> {
386   let Latency = 2;
387   let NumMicroOps = 2;
388 }
389 def : InstRW<[PdWriteXCHG16rr], (instrs XCHG16rr)>;
390
391 def PdWriteXADD : SchedWriteRes<[PdEX1]> {
392   let Latency = 2;
393   let NumMicroOps = 4;
394 }
395 def : InstRW<[PdWriteXADD], (instrs XADD8rr, XADD16rr, XADD32rr, XADD64rr)>;
396
397 def PdWriteXADDm : SchedWriteRes<[PdEX1]> {
398 let Latency = 6;
399 let NumMicroOps = 4;
400 }
401 def : InstRW<[PdWriteXADDm], (instrs XADD8rm, XADD16rm, XADD32rm, XADD64rm)>;
402
403 defm : PdWriteResExPair<WriteIMul8,     [PdEX1, PdMul],          4>;
404 defm : PdWriteResExPair<WriteIMul16,    [PdEX1, PdMul],          4,  [],    2>;
405 defm : PdWriteResExPair<WriteIMul16Imm, [PdEX1, PdMul],          5,  [],    2>;
406 defm : PdWriteResExPair<WriteIMul16Reg, [PdEX1, PdMul],          4>;
407 defm : PdWriteResExPair<WriteIMul32,    [PdEX1, PdMul],          4>;
408 defm : PdWriteResExPair<WriteIMul32Imm, [PdEX1, PdMul],          4,  [],    1, 1>;
409 defm : PdWriteResExPair<WriteIMul32Reg, [PdEX1, PdMul],          4>;
410 defm : PdWriteResExPair<WriteIMul64,    [PdEX1, PdMul],          6,  [1, 4]>;
411 defm : PdWriteResExPair<WriteIMul64Imm, [PdEX1, PdMul],          6,  [1, 4],1, 1>;
412 defm : PdWriteResExPair<WriteIMul64Reg, [PdEX1, PdMul],          6,  [1, 4]>;
413 defm : X86WriteResUnsupported<WriteIMulH>; // BMI2 MULX
414
415 defm : PdWriteResExPair<WriteDiv8,    [PdEX1, PdDiv],           12,  [1, 12]>;
416 defm : PdWriteResExPair<WriteDiv16,   [PdEX1, PdDiv],           15,  [1, 15],   2>;
417 defm : PdWriteResExPair<WriteDiv32,   [PdEX1, PdDiv],           14,  [1, 14],   2>;
418 defm : PdWriteResExPair<WriteDiv64,   [PdEX1, PdDiv],           14,  [1, 14],   2>;
419
420 defm : PdWriteResExPair<WriteIDiv8,   [PdEX1, PdDiv],           12,  [1, 12]>;
421 defm : PdWriteResExPair<WriteIDiv16,  [PdEX1, PdDiv],           15,  [1, 17],   2>;
422 defm : PdWriteResExPair<WriteIDiv32,  [PdEX1, PdDiv],           14,  [1, 25],   2>;
423 defm : PdWriteResExPair<WriteIDiv64,  [PdEX1, PdDiv],           14,  [1, 14],   2>;
424
425 defm : PdWriteResExPair<WriteCRC32,   [PdEX01],                  3,  [4],       3>;
426
427 def PdWriteCRC32r32r16 : SchedWriteRes<[PdEX01]> {
428   let Latency = 5;
429   let ResourceCycles = [4];
430   let NumMicroOps = 5;
431 }
432 def : InstRW<[PdWriteCRC32r32r16], (instrs CRC32r32r16)>;
433
434 def PdWriteCRC32r32r32 : SchedWriteRes<[PdEX01]> {
435   let Latency = 6;
436   let ResourceCycles = [4];
437   let NumMicroOps = 7;
438 }
439 def : InstRW<[PdWriteCRC32r32r32], (instrs CRC32r32r32)>;
440
441 def PdWriteCRC32r64r64 : SchedWriteRes<[PdEX01]> {
442   let Latency = 10;
443   let ResourceCycles = [4];
444   let NumMicroOps = 11;
445 }
446 def : InstRW<[PdWriteCRC32r64r64], (instrs CRC32r64r64)>;
447
448 defm : PdWriteResExPair<WriteCMOV,    [PdEX01]>; // Conditional move.
449 defm : PdWriteResExPair<WriteCMOV2,   [PdEX01], 1, [], 1, 1>; // Conditional (CF + ZF flag) move.
450
451 def : InstRW<[WriteCMOV2.Folded], (instrs CMOVG16rm, CMOVG32rm, CMOVG64rm,
452                                           CMOVGE16rm, CMOVGE32rm, CMOVGE64rm,
453                                           CMOVL16rm, CMOVL32rm, CMOVL64rm,
454                                           CMOVLE16rm, CMOVLE32rm, CMOVLE64rm)>;
455
456 defm : PdWriteRes<WriteFCMOV,        [PdFPU0, PdFPFMA]>; // x87 conditional move.
457
458 def : WriteRes<WriteSETCC,           [PdEX01]>; // Setcc.
459 def : WriteRes<WriteSETCCStore,      [PdEX01, PdStore]>;
460
461 def PdWriteSETGEmSETGmSETLEmSETLm : SchedWriteRes<[PdEX01]> {
462   let ResourceCycles = [2];
463   let NumMicroOps = 2;
464 }
465 def : InstRW<[PdWriteSETGEmSETGmSETLEmSETLm], (instrs SETGEm, SETGm,
466                                                       SETLEm, SETLm)>;
467
468 defm : PdWriteRes<WriteLAHFSAHF,      [PdEX01],          2,  [],     2>;
469
470 def WriteLAHF : SchedWriteRes<[PdEX01]> {
471   let Latency = 2;
472   let NumMicroOps = 4;
473 }
474 def : InstRW<[WriteLAHF], (instrs LAHF)>;
475
476 def WriteSAHF : SchedWriteRes<[PdEX01]> {
477   let Latency = 2;
478   let NumMicroOps = 2;
479 }
480 def : InstRW<[WriteSAHF], (instrs SAHF)>;
481
482 defm : PdWriteRes<WriteBitTest,          [PdEX01],         1, [1],     1>;
483 defm : PdWriteRes<WriteBitTestImmLd,     [PdEX01, PdLoad], 5, [1, 1],  1>;
484 defm : PdWriteRes<WriteBitTestRegLd,     [PdEX01, PdLoad], 5, [1, 1],  7>;
485 defm : PdWriteRes<WriteBitTestSet,       [PdEX01],         2, [1],     2>;
486 defm : PdWriteRes<WriteBitTestSetImmLd,  [PdEX01, PdLoad], 6, [1, 1],  4>;
487 defm : PdWriteRes<WriteBitTestSetImmRMW, [PdEX01, PdLoad], 6, [1, 1],  4>;
488 defm : PdWriteRes<WriteBitTestSetRegLd,  [PdEX01, PdLoad], 6, [1, 1], 10>;
489 defm : PdWriteRes<WriteBitTestSetRegRMW, [PdEX01, PdLoad], 6, [1, 1], 10>;
490
491 // This is for simple LEAs with one or two input operands.
492 // FIXME: SAGU 3-operand LEA
493 def : WriteRes<WriteLEA,              [PdEX01]> { let NumMicroOps = 2; }
494
495 // Bit counts.
496 defm : PdWriteResExPair<WriteBSF,     [PdEX01],          3,  [4],     6, 2>;
497 defm : PdWriteResExPair<WriteBSR,     [PdEX01],          4,  [4],     7, 2>;
498 defm : PdWriteResExPair<WritePOPCNT,  [PdEX01],          4>;
499 defm : PdWriteResExPair<WriteLZCNT,   [PdEX01],          2,  [],      2>;
500 defm : PdWriteResExPair<WriteTZCNT,   [PdEX01],          2,  [2],     2>;
501
502 // BMI1 BEXTR, BMI2 BZHI
503 defm : PdWriteResExPair<WriteBEXTR,   [PdEX01],          2,  [],     2>;
504 defm : PdWriteResExPair<WriteBLS,     [PdEX01],          2,  [],     2>;
505 defm : PdWriteResExPair<WriteBZHI,    [PdEX01]>;
506
507 ////////////////////////////////////////////////////////////////////////////////
508 // Integer shifts and rotates.
509 ////////////////////////////////////////////////////////////////////////////////
510
511 defm : PdWriteResExPair<WriteShift,    [PdEX01]>;
512 defm : PdWriteResExPair<WriteShiftCL,  [PdEX01]>;
513 defm : PdWriteResExPair<WriteRotate,   [PdEX01]>;
514 defm : PdWriteResExPair<WriteRotateCL, [PdEX01]>;
515
516 def PdWriteRCL8rCL : SchedWriteRes<[PdEX01]> {
517   let Latency = 12;
518   let NumMicroOps = 26;
519 }
520 def : InstRW<[PdWriteRCL8rCL], (instrs RCL8rCL)>;
521
522 def PdWriteRCR8ri : SchedWriteRes<[PdEX01]> {
523   let Latency = 12;
524   let NumMicroOps = 23;
525 }
526 def : InstRW<[PdWriteRCR8ri], (instrs RCR8ri)>;
527
528 def PdWriteRCR8rCL : SchedWriteRes<[PdEX01]> {
529   let Latency = 11;
530   let NumMicroOps = 24;
531 }
532 def : InstRW<[PdWriteRCR8rCL], (instrs RCR8rCL)>;
533
534 def PdWriteRCL16rCL : SchedWriteRes<[PdEX01]> {
535   let Latency = 10;
536   let NumMicroOps = 22;
537 }
538 def : InstRW<[PdWriteRCL16rCL], (instrs RCL16rCL)>;
539
540 def PdWriteRCR16ri : SchedWriteRes<[PdEX01]> {
541   let Latency = 10;
542   let NumMicroOps = 19;
543 }
544 def : InstRW<[PdWriteRCR16ri], (instrs RCR16ri)>;
545
546 def PdWriteRCL32rCLRCL64rCL : SchedWriteRes<[PdEX01]> {
547   let Latency = 7;
548   let NumMicroOps = 17;
549 }
550 def : InstRW<[PdWriteRCL32rCLRCL64rCL], (instrs RCL32rCL, RCL64rCL)>;
551
552 def PdWriteRCR64rCL : SchedWriteRes<[PdEX01]> {
553   let Latency = 7;
554   let NumMicroOps = 16;
555 }
556 def : InstRW<[PdWriteRCR64rCL], (instrs RCR64rCL)>;
557
558 def PdWriteRCR32rCL : SchedWriteRes<[PdEX01]> {
559   let Latency = 7;
560   let NumMicroOps = 16;
561 }
562 def : InstRW<[PdWriteRCR32rCL ], (instrs RCR32rCL)>;
563
564 def PdWriteRCR32riRCR64ri : SchedWriteRes<[PdEX01]> {
565   let Latency = 7;
566   let NumMicroOps = 15;
567 }
568 def : InstRW<[PdWriteRCR32riRCR64ri], (instrs RCR32ri, RCR64ri)>;
569
570
571 def PdWriteRCR16rCL : SchedWriteRes<[PdEX01]> {
572   let Latency = 9;
573   let NumMicroOps = 20;
574 }
575 def : InstRW<[PdWriteRCR16rCL], (instrs RCR16rCL)>;
576
577 def PdWriteRCL16ri : SchedWriteRes<[PdEX01]> {
578   let Latency = 11;
579   let NumMicroOps = 21;
580 }
581 def : InstRW<[PdWriteRCL16ri], (instrs RCL16ri)>;
582
583 def PdWriteRCL3264ri : SchedWriteRes<[PdEX01]> {
584   let Latency = 8;
585   let NumMicroOps = 16;
586 }
587 def : InstRW<[PdWriteRCL3264ri], (instrs RCL32ri, RCL64ri)>;
588
589 def PdWriteRCL8ri : SchedWriteRes<[PdEX01]> {
590   let Latency = 13;
591   let NumMicroOps = 25;
592 }
593 def : InstRW<[PdWriteRCL8ri], (instrs RCL8ri)>;
594
595 // SHLD/SHRD.
596 defm : PdWriteRes<WriteSHDrri,       [PdEX01],         4, [6], 6>;
597 defm : PdWriteRes<WriteSHDrrcl,      [PdEX01],         4, [8], 7>;
598
599 def PdWriteSHLD32rri8SHRD16rri8 : SchedWriteRes<[PdEX01]> {
600   let Latency = 3;
601   let ResourceCycles = [6];
602   let NumMicroOps = 6;
603 }
604 def : InstRW<[PdWriteSHLD32rri8SHRD16rri8 ], (instrs SHLD32rri8, SHRD16rri8)>;
605
606 def PdWriteSHLD16rrCLSHLD32rrCLSHRD32rrCL : SchedWriteRes<[PdEX01]> {
607   let Latency = 4;
608   let ResourceCycles = [8];
609   let NumMicroOps = 7;
610 }
611 def : InstRW<[PdWriteSHLD16rrCLSHLD32rrCLSHRD32rrCL], (instrs SHLD16rrCL,
612                                                               SHLD32rrCL,
613                                                               SHRD32rrCL)>;
614
615 defm : PdWriteRes<WriteSHDmri,       [PdLoad, PdEX01], 4, [1, 22], 8>;
616 defm : PdWriteRes<WriteSHDmrcl,      [PdLoad, PdEX01], 4, [1, 22], 8>;
617
618 ////////////////////////////////////////////////////////////////////////////////
619 // Floating point. This covers both scalar and vector operations.
620 ////////////////////////////////////////////////////////////////////////////////
621
622 defm : PdWriteRes<WriteFLD0,               [PdFPU1, PdFPSTO], 3>;
623 defm : PdWriteRes<WriteFLD1,               [PdFPU1, PdFPSTO], 3>;
624 defm : PdWriteRes<WriteFLDC,               [PdFPU1, PdFPSTO], 3>;
625
626 defm : PdWriteRes<WriteFLoad,              [PdLoad, PdFPU01, PdFPFMA], 5>;
627 defm : PdWriteRes<WriteFLoadX,             [PdLoad, PdFPU01, PdFPFMA], 5>;
628 defm : PdWriteRes<WriteFLoadY,             [PdLoad, PdFPU01, PdFPFMA], 5, [], 2>;
629
630 defm : PdWriteRes<WriteFMaskedLoad,        [PdLoad, PdFPU01, PdFPFMA], 6, [1, 1, 2]>;
631 defm : PdWriteRes<WriteFMaskedLoadY,       [PdLoad, PdFPU01, PdFPFMA], 6, [2, 2, 4], 2>;
632
633 defm : PdWriteRes<WriteFStore,             [PdStore, PdFPU1,  PdFPSTO], 2>;
634 defm : PdWriteRes<WriteFStoreX,            [PdStore, PdFPU1,  PdFPSTO]>;
635 defm : PdWriteRes<WriteFStoreY,            [PdStore, PdFPU1,  PdFPSTO], 1, [], 4>;
636
637 def PdWriteMOVHPm : SchedWriteRes<[PdStore, PdFPU1,  PdFPSTO]> {
638   let Latency = 2;
639   let NumMicroOps = 2;
640 }
641 def : InstRW<[PdWriteMOVHPm], (instrs MOVHPDmr, MOVHPSmr, VMOVHPDmr, VMOVHPSmr)>;
642
643 def PdWriteVMOVUPDYmrVMOVUPSYmr : SchedWriteRes<[PdStore, PdFPU1,  PdFPSTO]> {
644   let NumMicroOps = 8;
645 }
646 def : InstRW<[PdWriteVMOVUPDYmrVMOVUPSYmr], (instrs VMOVUPDYmr, VMOVUPSYmr)>;
647
648 defm : PdWriteRes<WriteFStoreNT,           [PdStore, PdFPU1,  PdFPSTO], 3>;
649 defm : PdWriteRes<WriteFStoreNTX,          [PdStore, PdFPU1,  PdFPSTO], 3>;
650 defm : PdWriteRes<WriteFStoreNTY,          [PdStore, PdFPU1,  PdFPSTO], 3, [2, 2, 2], 4>;
651
652 defm : PdWriteRes<WriteFMaskedStore,       [PdStore, PdFPU01, PdFPFMA], 6, [1, 1, 4], 18>;
653 defm : PdWriteRes<WriteFMaskedStoreY,      [PdStore, PdFPU01, PdFPFMA], 6, [2, 2, 4], 34>;
654
655 defm : PdWriteRes<WriteFMove,              [PdFPU01, PdFPFMA]>;
656 defm : PdWriteRes<WriteFMoveX,             [PdFPU01, PdFPFMA]>;
657 defm : PdWriteRes<WriteFMoveY,             [PdFPU01, PdFPFMA], 2, [2, 2], 2>;
658
659 defm : PdWriteRes<WriteEMMS,               [PdFPU01, PdFPFMA], 2>;
660
661 defm : PdWriteResXMMPair<WriteFAdd,         [PdFPU0, PdFPFMA],  5>;
662 defm : PdWriteResXMMPair<WriteFAddX,        [PdFPU0, PdFPFMA],  5>;
663 defm : PdWriteResYMMPair<WriteFAddY,        [PdFPU0, PdFPFMA],  5, [2, 1]>;
664 defm : X86WriteResPairUnsupported<WriteFAddZ>;
665
666 defm : PdWriteResXMMPair<WriteFAdd64,       [PdFPU0, PdFPFMA],  5>;
667 defm : PdWriteResXMMPair<WriteFAdd64X,      [PdFPU0, PdFPFMA],  5>;
668 defm : PdWriteResYMMPair<WriteFAdd64Y,      [PdFPU0, PdFPFMA],  5, [2, 1]>;
669 defm : X86WriteResPairUnsupported<WriteFAdd64Z>;
670
671 defm : PdWriteResXMMPair<WriteFCmp,         [PdFPU0, PdFPFMA],  2>;
672 defm : PdWriteResXMMPair<WriteFCmpX,        [PdFPU0, PdFPFMA],  2>;
673 defm : PdWriteResYMMPair<WriteFCmpY,        [PdFPU0, PdFPFMA],  2, [2, 1]>;
674 defm : X86WriteResPairUnsupported<WriteFCmpZ>;
675
676 defm : PdWriteResXMMPair<WriteFCmp64,       [PdFPU0, PdFPFMA],  2>;
677 defm : PdWriteResXMMPair<WriteFCmp64X,      [PdFPU0, PdFPFMA],  2>;
678 defm : PdWriteResYMMPair<WriteFCmp64Y,      [PdFPU0, PdFPFMA],  2, [2, 1]>;
679 defm : X86WriteResPairUnsupported<WriteFCmp64Z>;
680
681 defm : PdWriteResXMMPair<WriteFCom,         [PdFPU0, PdFPFMA, PdEX0], 1, [], 2>;
682
683 def PdWriteFCOMPm : SchedWriteRes<[PdFPU1, PdFPFMA]> {
684   let Latency = 6;
685 }
686 def : InstRW<[PdWriteFCOMPm], (instrs FCOM32m, FCOM64m, FCOMP32m, FCOMP64m)>;
687
688 def PdWriteTST_F_UCOM_FPPr : SchedWriteRes<[PdFPU1, PdFPFMA]>;
689 def : InstRW<[PdWriteTST_F_UCOM_FPPr], (instrs TST_F, UCOM_FPPr)>;
690
691 defm : PdWriteResXMMPair<WriteFMul,         [PdFPU1, PdFPFMA],  5>;
692 defm : PdWriteResXMMPair<WriteFMulX,        [PdFPU1, PdFPFMA],  5>;
693 defm : PdWriteResYMMPair<WriteFMulY,        [PdFPU1, PdFPFMA],  5, [2, 1]>;
694 defm : X86WriteResPairUnsupported<WriteFMulZ>;
695
696 defm : PdWriteResXMMPair<WriteFMul64,       [PdFPU1, PdFPFMA],  5>;
697 defm : PdWriteResXMMPair<WriteFMul64X,      [PdFPU1, PdFPFMA],  5>;
698 defm : PdWriteResYMMPair<WriteFMul64Y,      [PdFPU1, PdFPFMA],  5, [2, 1]>;
699 defm : X86WriteResPairUnsupported<WriteFMul64Z>;
700
701 defm : PdWriteResXMMPair<WriteFMA,          [PdFPU, PdFPFMA], 5>;
702 defm : PdWriteResXMMPair<WriteFMAX,         [PdFPU, PdFPFMA], 5>;
703 defm : PdWriteResYMMPair<WriteFMAY,         [PdFPU, PdFPFMA], 5,   [1, 1]>;
704 defm : X86WriteResPairUnsupported<WriteFMAZ>;
705
706
707 defm : PdWriteResXMMPair<WriteDPPD,         [PdFPU1, PdFPFMA], 15, [1, 3],  15, 2>;
708
709 defm : PdWriteResXMMPair<WriteDPPS,         [PdFPU1, PdFPFMA], 25, [1, 3],  16, 2>;
710 defm : PdWriteResYMMPair<WriteDPPSY,        [PdFPU1, PdFPFMA], 27, [2, 6], /*or 29*/ 25, 4>;
711 defm : X86WriteResPairUnsupported<WriteDPPSZ>;
712
713 def PdWriteVDPPSrri : SchedWriteRes<[PdFPU1, PdFPFMA]> {
714   let Latency = 25;
715   let ResourceCycles = [1, 3];
716   let NumMicroOps = 17;
717 }
718 def : InstRW<[PdWriteVDPPSrri], (instrs VDPPSrri)>;
719
720 defm : PdWriteResXMMPair<WriteFRcp,         [PdFPU1, PdFPFMA],  5>;
721 defm : PdWriteResXMMPair<WriteFRcpX,        [PdFPU1, PdFPFMA],  5>;
722 defm : PdWriteResYMMPair<WriteFRcpY,        [PdFPU1, PdFPFMA],  5, [2, 1]>;
723 defm : X86WriteResPairUnsupported<WriteFRcpZ>;
724
725 defm : PdWriteResXMMPair<WriteFRsqrt,       [PdFPU1, PdFPFMA],  5>;
726 defm : PdWriteResXMMPair<WriteFRsqrtX,      [PdFPU1, PdFPFMA],  5>;
727 defm : PdWriteResYMMPair<WriteFRsqrtY,      [PdFPU1, PdFPFMA],  5, [2, 1]>;
728 defm : X86WriteResPairUnsupported<WriteFRsqrtZ>;
729
730 defm : PdWriteResXMMPair<WriteFDiv,         [PdFPU1, PdFPFMA], 9, [1, 19]>;
731 defm : PdWriteResXMMPair<WriteFDivX,        [PdFPU1, PdFPFMA], 9, [1, 19]>;
732 defm : PdWriteResYMMPair<WriteFDivY,        [PdFPU1, PdFPFMA], 9, [2, 38]>;
733 defm : X86WriteResPairUnsupported<WriteFDivZ>;
734
735 defm : PdWriteResXMMPair<WriteFDiv64,       [PdFPU1, PdFPFMA], 9, [1, 19]>;
736 defm : PdWriteResXMMPair<WriteFDiv64X,      [PdFPU1, PdFPFMA], 9, [1, 19]>;
737 defm : PdWriteResYMMPair<WriteFDiv64Y,      [PdFPU1, PdFPFMA], 9, [2, 38]>;
738 defm : X86WriteResPairUnsupported<WriteFDiv64Z>;
739
740 defm : PdWriteResXMMPair<WriteFSqrt,        [PdFPU1, PdFPFMA], 9, [1, 21]>;
741 defm : PdWriteResXMMPair<WriteFSqrtX,       [PdFPU1, PdFPFMA], 9, [1, 21]>;
742 defm : PdWriteResYMMPair<WriteFSqrtY,       [PdFPU1, PdFPFMA], 9, [2, 42]>;
743 defm : X86WriteResPairUnsupported<WriteFSqrtZ>;
744
745 defm : PdWriteResXMMPair<WriteFSqrt64,      [PdFPU1, PdFPFMA], 9, [1, 27]>;
746 defm : PdWriteResXMMPair<WriteFSqrt64X,     [PdFPU1, PdFPFMA], 9, [1, 27]>;
747 defm : PdWriteResYMMPair<WriteFSqrt64Y,     [PdFPU1, PdFPFMA], 9, [2, 54]>;
748 defm : X86WriteResPairUnsupported<WriteFSqrt64Z>;
749
750 defm : PdWriteResXMMPair<WriteFSqrt80,      [PdFPU1, PdFPFMA],  1, [1, 35]>;
751 defm : PdWriteResXMMPair<WriteFSign,        [PdFPU1, PdFPFMA]>;
752
753 defm : PdWriteResXMMPair<WriteFRnd,         [PdFPU1, PdFPSTO],  4>;
754 defm : PdWriteResYMMPair<WriteFRndY,        [PdFPU1, PdFPSTO],  4, [2, 1], 2>;
755 defm : X86WriteResPairUnsupported<WriteFRndZ>;
756
757 def PdWriteVFRCZ : SchedWriteRes<[PdFPU1, PdFPSTO]> {
758   let Latency = 10;
759   let NumMicroOps = 2;
760 }
761 def : InstRW<[PdWriteVFRCZ], (instrs VFRCZPDrr, VFRCZPSrr,
762                                      VFRCZSDrr, VFRCZSSrr)>;
763
764 def PdWriteVFRCZm : SchedWriteRes<[PdFPU1, PdFPSTO]> {
765   let Latency = 15;
766   let NumMicroOps = 2;
767 }
768 def : InstRW<[PdWriteVFRCZm], (instrs VFRCZPDrm, VFRCZPSrm,
769                                       VFRCZSDrm, VFRCZSSrm)>;
770
771 def PdWriteVFRCZY : SchedWriteRes<[PdFPU1, PdFPSTO]> {
772   let Latency = 10;
773   let ResourceCycles = [2, 1];
774   let NumMicroOps = 4;
775 }
776 def : InstRW<[PdWriteVFRCZY], (instrs VFRCZPSYrr, VFRCZPDYrr)>;
777
778 def PdWriteVFRCZYm : SchedWriteRes<[PdFPU1, PdFPSTO]> {
779   let Latency = 15;
780   let ResourceCycles = [2, 1];
781   let NumMicroOps = 8;
782 }
783 def : InstRW<[PdWriteVFRCZYm], (instrs VFRCZPSYrm, VFRCZPDYrm)>;
784
785 defm : PdWriteResXMMPair<WriteFLogic,       [PdFPU01, PdFPFMA],  2>;
786 defm : PdWriteResYMMPair<WriteFLogicY,      [PdFPU01, PdFPFMA],  2, [2, 2]>;
787 defm : X86WriteResPairUnsupported<WriteFLogicZ>;
788
789 defm : PdWriteResXMMPair<WriteFTest,        [PdFPU0, PdFPFMA, PdEX0],  1, [], 2>;
790 defm : PdWriteResYMMPair<WriteFTestY,       [PdFPU01, PdFPFMA, PdEX0], 1, [2, 2, 1], 4, 2>;
791 defm : X86WriteResPairUnsupported<WriteFTestZ>;
792
793 defm : PdWriteResXMMPair<WriteFShuffle,     [PdFPU01, PdFPFMA],  2>;
794 defm : PdWriteResYMMPair<WriteFShuffleY,    [PdFPU01, PdFPFMA],  2, [2, 2], 2>;
795 defm : X86WriteResPairUnsupported<WriteFShuffleZ>;
796
797 def PdWriteVBROADCASTF128 : SchedWriteRes<[PdFPU01, PdFPFMA]> {
798   let Latency = 7;
799   let NumMicroOps = 2;
800 }
801 def : InstRW<[PdWriteVBROADCASTF128], (instrs VBROADCASTF128)>;
802
803 defm : PdWriteResXMMPair<WriteFVarShuffle,  [PdFPU01, PdFPFMA],  3, [1, 4]>;
804 defm : PdWriteResYMMPair<WriteFVarShuffleY, [PdFPU01, PdFPFMA],  3, [2, 6], 2>;
805 defm : X86WriteResPairUnsupported<WriteFVarShuffleZ>;
806
807 defm : PdWriteResXMMPair<WriteFBlend,       [PdFPU01, PdFPFMA],  2>;
808 defm : PdWriteResYMMPair<WriteFBlendY,      [PdFPU01, PdFPFMA],  2, [2, 2], 2>;
809 defm : X86WriteResPairUnsupported<WriteFBlendZ>;
810
811 defm : PdWriteResXMMPair<WriteFVarBlend,    [PdFPU01, PdFPFMA],  2, [1, 4]>;
812 defm : PdWriteResYMMPair<WriteFVarBlendY,   [PdFPU01, PdFPFMA],  2, [2, 6], 2>;
813 defm : X86WriteResPairUnsupported<WriteFVarBlendZ>;
814
815 defm : PdWriteResXMMPair<WriteFShuffle256,  [PdFPU01, PdFPFMA],  2, [], 2>;
816 defm : X86WriteResPairUnsupported<WriteFVarShuffle256>;
817
818 def PdWriteVEXTRACTF128rr : SchedWriteRes<[PdFPU01, PdFPFMA]> {
819   let Latency = 2;
820 }
821 def : InstRW<[PdWriteVEXTRACTF128rr], (instrs VEXTRACTF128rr)>;
822
823 def PdWriteVEXTRACTF128mr : SchedWriteRes<[PdFPU01, PdFPFMA]> {
824   let Latency = 7;
825   let NumMicroOps = 2;
826 }
827 def : InstRW<[PdWriteVEXTRACTF128mr], (instrs VEXTRACTF128mr)>;
828
829 def PdWriteVPERM2F128rr : SchedWriteRes<[PdFPU01, PdFPFMA]> {
830   let Latency = 4;
831   let NumMicroOps = 8;
832 }
833 def : InstRW<[PdWriteVPERM2F128rr], (instrs VPERM2F128rr)>;
834
835 def PdWriteVPERM2F128rm : SchedWriteRes<[PdFPU01, PdFPFMA]> {
836   let Latency = 8; // 4 + 4
837   let NumMicroOps = 10;
838 }
839 def : InstRW<[PdWriteVPERM2F128rm], (instrs VPERM2F128rm)>;
840
841 ////////////////////////////////////////////////////////////////////////////////
842 // Conversions.
843 ////////////////////////////////////////////////////////////////////////////////
844
845 defm : PdWriteResXMMPair<WriteCvtSS2I,   [PdFPU1, PdFPSTO, PdFPFMA, PdEX0], 13, [], 2>;
846
847 defm : PdWriteResXMMPair<WriteCvtPS2I,   [PdFPU1, PdFPSTO], 4>;
848 defm : PdWriteResYMMPair<WriteCvtPS2IY,  [PdFPU1, PdFPSTO], 4, [2, 1]>;
849 defm : X86WriteResPairUnsupported<WriteCvtPS2IZ>;
850
851 defm : PdWriteResXMMPair<WriteCvtSD2I,   [PdFPU1, PdFPSTO, PdFPFMA, PdEX0], 13, [], 2>;
852
853 defm : PdWriteResXMMPair<WriteCvtPD2I,   [PdFPU1, PdFPSTO],          8, [],        2>;
854 defm : PdWriteResYMMPair<WriteCvtPD2IY,  [PdFPU1, PdFPSTO, PdFPFMA], 8, [2, 1, 1], 4>;
855 defm : X86WriteResPairUnsupported<WriteCvtPD2IZ>;
856
857 def PdWriteMMX_CVTTPD2PIirr : SchedWriteRes<[PdFPU1, PdFPSTO]> {
858   let Latency = 6;
859   let NumMicroOps = 2;
860 }
861 def : InstRW<[PdWriteMMX_CVTTPD2PIirr], (instrs MMX_CVTTPD2PIirr)>;
862
863 // FIXME: f+3 ST, LD+STC latency
864 defm : PdWriteResXMMPair<WriteCvtI2SS,   [PdFPU1, PdFPSTO], 4, [], 2>;
865 // FIXME: .Folded version is one NumMicroOp *less*..
866
867 defm : PdWriteResXMMPair<WriteCvtI2PS,   [PdFPU1, PdFPSTO], 4>;
868 defm : PdWriteResYMMPair<WriteCvtI2PSY,  [PdFPU1, PdFPSTO], 4, [2, 1]>;
869 defm : X86WriteResPairUnsupported<WriteCvtI2PSZ>;
870
871 defm : PdWriteResXMMPair<WriteCvtI2SD,   [PdFPU1, PdFPSTO], 4, [], 2>;
872 // FIXME: .Folded version is one NumMicroOp *less*..
873
874 def WriteCVTSI642SDrr : SchedWriteRes<[PdFPU1, PdFPSTO]> {
875   let Latency = 13;
876   let NumMicroOps = 2;
877 }
878 def : InstRW<[WriteCVTSI642SDrr], (instrs CVTSI642SDrr, CVTSI642SSrr)>;
879
880 defm : PdWriteResXMMPair<WriteCvtI2PD,   [PdFPU1, PdFPSTO], 8, [],     2>;
881 defm : PdWriteResYMMPair<WriteCvtI2PDY,  [PdFPU1, PdFPSTO], 8, [2, 1], 4, 1>;
882 defm : X86WriteResPairUnsupported<WriteCvtI2PDZ>;
883
884 defm : PdWriteResXMMPair<WriteCvtSS2SD,  [PdFPU1, PdFPSTO], 4>;
885
886 defm : PdWriteResXMMPair<WriteCvtPS2PD,  [PdFPU1, PdFPSTO], 8, [],     2>;
887 defm : PdWriteResYMMPair<WriteCvtPS2PDY, [PdFPU1, PdFPSTO], 8, [2, 1], 4, 1>;
888 defm : X86WriteResPairUnsupported<WriteCvtPS2PDZ>;
889
890 defm : PdWriteResXMMPair<WriteCvtSD2SS,  [PdFPU1, PdFPSTO], 4>;
891
892 defm : PdWriteResXMMPair<WriteCvtPD2PS,  [PdFPU1, PdFPSTO],          8, [],        2>;
893 defm : PdWriteResYMMPair<WriteCvtPD2PSY, [PdFPU1, PdFPSTO, PdFPFMA], 8, [2, 1, 1], 4>;
894 defm : X86WriteResPairUnsupported<WriteCvtPD2PSZ>;
895
896 def WriteMMX_CVTPD2PIirrMMX_CVTPI2PDirr : SchedWriteRes<[PdFPU1, PdFPSTO]> {
897   let Latency = 6;
898   let NumMicroOps = 2;
899 }
900 def : InstRW<[WriteMMX_CVTPD2PIirrMMX_CVTPI2PDirr], (instrs MMX_CVTPD2PIirr,
901                                                             MMX_CVTPI2PDirr)>;
902
903 def WriteMMX_CVTPI2PSirr : SchedWriteRes<[PdFPU1, PdFPSTO]> {
904   let Latency = 4;
905   let NumMicroOps = 2;
906 }
907 def : InstRW<[WriteMMX_CVTPI2PSirr], (instrs MMX_CVTPI2PSirr)>;
908
909 defm : PdWriteResXMMPair<WriteCvtPH2PS,  [PdFPU1, PdFPSTO], 8, [],     2, 1>;
910 defm : PdWriteResYMMPair<WriteCvtPH2PSY, [PdFPU1, PdFPSTO], 8, [2, 1], 4, 3>;
911 defm : X86WriteResPairUnsupported<WriteCvtPH2PSZ>;
912
913 defm : PdWriteRes<WriteCvtPS2PH,        [PdFPU1, PdFPSTO],          8, [],        2>;
914 defm : PdWriteRes<WriteCvtPS2PHY,       [PdFPU1, PdFPSTO, PdFPFMA], 8, [2, 1, 1], 4>;
915 defm : X86WriteResUnsupported<WriteCvtPS2PHZ>;
916
917 defm : PdWriteRes<WriteCvtPS2PHSt,      [PdFPU1, PdFPSTO, PdStore],          4, [],           3>;
918 defm : PdWriteRes<WriteCvtPS2PHYSt,     [PdFPU1, PdFPSTO, PdFPFMA, PdStore], 4, [2, 1, 1, 1], 4>;
919 defm : X86WriteResUnsupported<WriteCvtPS2PHZSt>;
920
921 ////////////////////////////////////////////////////////////////////////////////
922 // Vector integer operations.
923 ////////////////////////////////////////////////////////////////////////////////
924
925 defm : PdWriteRes<WriteVecLoad,             [PdLoad, PdFPU01, PdFPMAL], 5>;
926 defm : PdWriteRes<WriteVecLoadX,            [PdLoad, PdFPU01, PdFPMAL], 5>;
927 defm : PdWriteRes<WriteVecLoadY,            [PdLoad, PdFPU01, PdFPMAL], 5, [], 2>;
928
929 defm : PdWriteRes<WriteVecLoadNT,           [PdLoad, PdFPU01, PdFPMAL], 5>;
930 defm : PdWriteRes<WriteVecLoadNTY,          [PdLoad, PdFPU01, PdFPMAL], 5>;
931
932 defm : PdWriteRes<WriteVecMaskedLoad,       [PdLoad, PdFPU01, PdFPMAL], 6, [1, 1, 2]>;
933 defm : PdWriteRes<WriteVecMaskedLoadY,      [PdLoad, PdFPU01, PdFPMAL], 6, [2, 2, 4], 2>;
934
935 defm : PdWriteRes<WriteVecStore,            [PdStore, PdFPU1,   PdFPSTO], 2>;
936 defm : PdWriteRes<WriteVecStoreX,           [PdStore, PdFPU1,   PdFPSTO]>;
937 defm : PdWriteRes<WriteVecStoreY,           [PdStore, PdFPU1,   PdFPSTO], 1, [], 4>;
938
939 def PdWriteVMOVDQUYmr : SchedWriteRes<[PdStore, PdFPU1,   PdFPSTO]> {
940   let NumMicroOps = 8;
941 }
942 def : InstRW<[PdWriteVMOVDQUYmr], (instrs VMOVDQUYmr)>;
943
944 defm : PdWriteRes<WriteVecStoreNT,          [PdStore, PdFPU1,   PdFPSTO], 2>;
945 defm : PdWriteRes<WriteVecStoreNTY,         [PdStore, PdFPU1,   PdFPSTO], 2, [2, 2, 2], 4>;
946
947 defm : PdWriteRes<WriteVecMaskedStore,      [PdStore, PdFPU01, PdFPMAL], 6, [1, 1, 4]>;
948 defm : PdWriteRes<WriteVecMaskedStoreY,     [PdStore, PdFPU01, PdFPMAL], 6, [2, 2, 4], 2>;
949
950 defm : PdWriteRes<WriteVecMove,             [PdFPU01, PdFPMAL], 2>;
951 defm : PdWriteRes<WriteVecMoveX,            [PdFPU01, PdFPMAL], 2>;
952 defm : PdWriteRes<WriteVecMoveY,            [PdFPU01, PdFPMAL], 2, [2, 2], 2>;
953
954 defm : PdWriteRes<WriteVecMoveToGpr,        [PdFPU0, PdFPFMA, PdEX0], 10>;
955 defm : PdWriteRes<WriteVecMoveFromGpr,      [PdFPU01, PdFPFMA], 10, [], 2>;
956
957 defm : PdWriteResXMMPair<WriteVecALU,        [PdFPU01, PdFPMAL], 2>;
958 defm : PdWriteResXMMPair<WriteVecALUX,       [PdFPU01, PdFPMAL], 2>;
959 defm : X86WriteResPairUnsupported<WriteVecALUY>;
960 defm : X86WriteResPairUnsupported<WriteVecALUZ>;
961
962 defm : PdWriteResXMMPair<WriteVecShift,      [PdFPU01, PdFPMAL], 3>;
963 defm : PdWriteResXMMPair<WriteVecShiftX,     [PdFPU01, PdFPMAL], 3>;
964 defm : X86WriteResPairUnsupported<WriteVecShiftY>;
965 defm : X86WriteResPairUnsupported<WriteVecShiftZ>;
966
967 defm : PdWriteResXMMPair<WriteVecShiftImm,   [PdFPU01, PdFPMAL], 2>;
968 defm : PdWriteResXMMPair<WriteVecShiftImmX,  [PdFPU01, PdFPMAL], 2>;
969 defm : X86WriteResPairUnsupported<WriteVecShiftImmY>;
970 defm : X86WriteResPairUnsupported<WriteVecShiftImmZ>;
971
972 defm : PdWriteResXMMPair<WriteVecIMul,       [PdFPU0, PdFPMMA], 4>;
973 defm : PdWriteResXMMPair<WriteVecIMulX,      [PdFPU0, PdFPMMA], 4>;
974 defm : X86WriteResPairUnsupported<WriteVecIMulY>;
975 defm : X86WriteResPairUnsupported<WriteVecIMulZ>;
976
977 defm : PdWriteResXMMPair<WritePMULLD,        [PdFPU0, PdFPU01, PdFPMMA, PdFPMAL], 5, [2, 1, 2, 1]>;
978 defm : X86WriteResPairUnsupported<WritePMULLDY>;
979 defm : X86WriteResPairUnsupported<WritePMULLDZ>;
980
981 def JWriteVPMACS : SchedWriteRes<[PdFPU0, PdFPU01, PdFPMMA, PdFPMAL]> {
982   let Latency = 4;
983   let ResourceCycles = [2, 1, 2, 1];
984 }
985 def : InstRW<[JWriteVPMACS], (instrs VPMACSDQHrr, VPMACSDQLrr, VPMACSSDQHrr,
986                                      VPMACSSDQLrr)>;
987
988 defm : PdWriteResXMMPair<WriteMPSAD,         [PdFPU0, PdFPMMA], 9, [1, 2], 9>;
989 defm : X86WriteResPairUnsupported<WriteMPSADY>;
990 defm : X86WriteResPairUnsupported<WriteMPSADZ>;
991
992 defm : PdWriteResXMMPair<WritePSADBW,        [PdFPU01, PdFPMAL], 4, [], 2>;
993 defm : PdWriteResXMMPair<WritePSADBWX,       [PdFPU01, PdFPMAL], 4, [], 2>;
994 defm : X86WriteResPairUnsupported<WritePSADBWY>;
995 defm : X86WriteResPairUnsupported<WritePSADBWZ>;
996
997 defm : PdWriteResXMMPair<WritePHMINPOS,      [PdFPU0,  PdFPMAL], 4, [], 2>;
998
999 defm : PdWriteResXMMPair<WriteShuffle,       [PdFPU01, PdFPMAL], 2>;
1000 defm : PdWriteResXMMPair<WriteShuffleX,      [PdFPU01, PdFPMAL], 2>;
1001 defm : PdWriteResYMMPair<WriteShuffleY,      [PdFPU01, PdFPMAL], 2,   [1, 1]>;
1002 defm : X86WriteResPairUnsupported<WriteShuffleZ>;
1003
1004 defm : PdWriteResXMMPair<WriteVarShuffle,    [PdFPU01, PdFPMAL], 3, [1, 4]>;
1005 defm : PdWriteResXMMPair<WriteVarShuffleX,   [PdFPU01, PdFPMAL], 3, [1, 4]>;
1006 defm : X86WriteResPairUnsupported<WriteVarShuffleY>;
1007 defm : X86WriteResPairUnsupported<WriteVarShuffleZ>;
1008
1009 defm : PdWriteResXMMPair<WriteBlend,         [PdFPU01, PdFPMAL], 2>;
1010 defm : X86WriteResPairUnsupported<WriteBlendY>;
1011 defm : X86WriteResPairUnsupported<WriteBlendZ>;
1012
1013 defm : PdWriteResXMMPair<WriteVarBlend,      [PdFPU01, PdFPMAL], 2, [1, 4]>;
1014 defm : X86WriteResPairUnsupported<WriteVarBlendY>;
1015 defm : X86WriteResPairUnsupported<WriteVarBlendZ>;
1016
1017 defm : PdWriteResXMMPair<WriteVecLogic,      [PdFPU01, PdFPMAL], 2>;
1018 defm : PdWriteResXMMPair<WriteVecLogicX,     [PdFPU01, PdFPMAL], 2>;
1019 defm : X86WriteResPairUnsupported<WriteVecLogicY>;
1020 defm : X86WriteResPairUnsupported<WriteVecLogicZ>;
1021
1022 defm : PdWriteResXMMPair<WriteVecTest,       [PdFPU0, PdFPFMA, PdEX0],  1, [], 2>;
1023 defm : PdWriteResYMMPair<WriteVecTestY,      [PdFPU01, PdFPFMA, PdEX0], 1, [2, 2, 1], 4, 2>;
1024 defm : X86WriteResPairUnsupported<WriteVecTestZ>;
1025
1026 defm : PdWriteResXMMPair<WriteShuffle256,    [PdFPU01, PdFPMAL]>;
1027 defm : PdWriteResXMMPair<WriteVarShuffle256, [PdFPU01, PdFPMAL]>;
1028
1029 defm : PdWriteResXMMPair<WriteVarVecShift,   [PdFPU01, PdFPMAL], 3>;
1030 defm : X86WriteResPairUnsupported<WriteVarVecShiftY>;
1031 defm : X86WriteResPairUnsupported<WriteVarVecShiftZ>;
1032
1033 ////////////////////////////////////////////////////////////////////////////////
1034 // Vector insert/extract operations.
1035 ////////////////////////////////////////////////////////////////////////////////
1036
1037 defm : PdWriteRes<WriteVecInsert,    [PdFPU01, PdFPMAL], 2, [], 2>;
1038 defm : PdWriteRes<WriteVecInsertLd,  [PdFPU01, PdFPMAL, PdLoad], 6, [], 2>;
1039
1040 defm : PdWriteRes<WriteVecExtract,   [PdFPU0, PdFPFMA, PdEX0], 13, [], 2>;
1041 defm : PdWriteRes<WriteVecExtractSt, [PdFPU1, PdFPSTO, PdStore], 13, [], 2>;
1042
1043 def PdWriteEXTRQ : SchedWriteRes<[PdFPU01, PdFPMAL]> {
1044   let Latency = 3;
1045 }
1046 def : InstRW<[PdWriteEXTRQ], (instrs EXTRQ, EXTRQI)>;
1047
1048 ////////////////////////////////////////////////////////////////////////////////
1049 // SSE42 String instructions.
1050 ////////////////////////////////////////////////////////////////////////////////
1051
1052 defm : PdWriteResXMMPair<WritePCmpIStrI, [PdFPU1, PdFPFMA, PdEX0], 14, [1, 2, 1], 7, 1>;
1053 defm : PdWriteResXMMPair<WritePCmpIStrM, [PdFPU1, PdFPFMA, PdEX0],  6, [1, 2, 1], 7, 2>;
1054
1055 defm : PdWriteResXMMPair<WritePCmpEStrI, [PdFPU1, PdStore, PdLoad, PdFPMAL, PdFPFMA, PdEX0], 15, [1, 2, 6, 4, 1, 1], 27, 1>;
1056 defm : PdWriteResXMMPair<WritePCmpEStrM, [PdFPU1, PdStore, PdLoad, PdFPMAL, PdFPFMA, PdEX0], 10, [1, 2, 6, 4, 1, 1], 27, 1>;
1057
1058 ////////////////////////////////////////////////////////////////////////////////
1059 // MOVMSK Instructions.
1060 ////////////////////////////////////////////////////////////////////////////////
1061
1062 defm : PdWriteRes<WriteFMOVMSK, [PdFPU0, PdFPFMA, PdEX0],   10, [], 2>;
1063
1064 defm : PdWriteRes<WriteVecMOVMSK, [PdFPU0, PdFPFMA, PdEX0], 13, [], 2>;
1065 defm : X86WriteResUnsupported<WriteVecMOVMSKY>;
1066 // defm : X86WriteResUnsupported<WriteVecMOVMSKZ>;
1067
1068 defm : PdWriteRes<WriteMMXMOVMSK, [PdFPU0, PdFPFMA, PdEX0], 10, [], 2>;
1069
1070 ////////////////////////////////////////////////////////////////////////////////
1071 // AES Instructions.
1072 ////////////////////////////////////////////////////////////////////////////////
1073
1074 defm : PdWriteResXMMPair<WriteAESIMC,    [PdFPU0, PdFPMMA], 5>;
1075 defm : PdWriteResXMMPair<WriteAESKeyGen, [PdFPU0, PdFPMMA], 5>;
1076 defm : PdWriteResXMMPair<WriteAESDecEnc, [PdFPU0, PdFPMMA], 9, [], 2>;
1077
1078 ////////////////////////////////////////////////////////////////////////////////
1079 // Horizontal add/sub  instructions.
1080 ////////////////////////////////////////////////////////////////////////////////
1081
1082 defm : PdWriteResXMMPair<WriteFHAdd,  [PdFPU0, PdFPFMA], 11, [],     3, 1>;
1083 defm : PdWriteResYMMPair<WriteFHAddY, [PdFPU0, PdFPFMA], 11, [2, 1], 8, 2>;
1084 defm : X86WriteResPairUnsupported<WriteFHAddZ>;
1085
1086 defm : PdWriteResXMMPair<WritePHAdd,  [PdFPU01, PdFPMAL], 5, [], 3, 1>;
1087 defm : PdWriteResXMMPair<WritePHAddX, [PdFPU01, PdFPMAL], 2>;
1088 defm : X86WriteResPairUnsupported<WritePHAddY>;
1089 defm : X86WriteResPairUnsupported<WritePHAddZ>;
1090
1091 def : InstRW<[WritePHAdd], (instrs PHADDDrr, PHSUBDrr,
1092                                    PHADDWrr, PHSUBWrr,
1093                                    PHADDSWrr, PHSUBSWrr,
1094                                    VPHADDDrr, VPHSUBDrr,
1095                                    VPHADDWrr, VPHSUBWrr,
1096                                    VPHADDSWrr, VPHSUBSWrr)>;
1097
1098 def : InstRW<[WritePHAdd.Folded], (instrs PHADDDrm, PHSUBDrm,
1099                                           PHADDWrm, PHSUBWrm,
1100                                           PHADDSWrm, PHSUBSWrm,
1101                                           VPHADDDrm, VPHSUBDrm,
1102                                           VPHADDWrm, VPHSUBWrm,
1103                                           VPHADDSWrm, VPHSUBSWrm)>;
1104
1105 ////////////////////////////////////////////////////////////////////////////////
1106 // Carry-less multiplication instructions.
1107 ////////////////////////////////////////////////////////////////////////////////
1108
1109 defm : PdWriteResXMMPair<WriteCLMul, [PdFPU0, PdFPMMA], 12, [], 5, 1>;
1110
1111 def PdWriteVPCLMULQDQrr : SchedWriteRes<[PdFPU0, PdFPMMA]> {
1112   let Latency = 13;
1113   let NumMicroOps = 6;
1114 }
1115 def : InstRW<[PdWriteVPCLMULQDQrr], (instrs VPCLMULQDQrr)>;
1116
1117 ////////////////////////////////////////////////////////////////////////////////
1118 // SSE4A instructions.
1119 ////////////////////////////////////////////////////////////////////////////////
1120
1121 def PdWriteINSERTQ : SchedWriteRes<[PdFPU01, PdFPMAL]> {
1122   let Latency = 3;
1123   let ResourceCycles = [1, 4];
1124 }
1125 def : InstRW<[PdWriteINSERTQ], (instrs INSERTQ, INSERTQI)>;
1126
1127 ////////////////////////////////////////////////////////////////////////////////
1128 // AVX instructions.
1129 ////////////////////////////////////////////////////////////////////////////////
1130
1131 def PdWriteVBROADCASTYLd : SchedWriteRes<[PdLoad, PdFPU01, PdFPFMA]> {
1132   let Latency = 6;
1133   let ResourceCycles = [1, 2, 4];
1134   let NumMicroOps = 2;
1135 }
1136 def : InstRW<[PdWriteVBROADCASTYLd, ReadAfterLd], (instrs VBROADCASTSDYrm,
1137                                                           VBROADCASTSSYrm)>;
1138
1139 def PdWriteVZEROALL : SchedWriteRes<[]> {
1140   let Latency = 90;
1141   let NumMicroOps = 32;
1142 }
1143 def : InstRW<[PdWriteVZEROALL], (instrs VZEROALL)>;
1144
1145 def PdWriteVZEROUPPER : SchedWriteRes<[]> {
1146   let Latency = 46;
1147   let NumMicroOps = 16;
1148 }
1149 def : InstRW<[PdWriteVZEROUPPER], (instrs VZEROUPPER)>;
1150
1151 ///////////////////////////////////////////////////////////////////////////////
1152 //  SchedWriteVariant definitions.
1153 ///////////////////////////////////////////////////////////////////////////////
1154
1155 def PdWriteZeroLatency : SchedWriteRes<[]> {
1156   let Latency = 0;
1157 }
1158
1159 def PdWriteZeroIdiom : SchedWriteVariant<[
1160   SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [PdWriteZeroLatency]>,
1161   SchedVar<MCSchedPredicate<TruePred>,           [WriteALU]>
1162 ]>;
1163 def : InstRW<[PdWriteZeroIdiom], (instrs SUB32rr, SUB64rr,
1164                                          XOR32rr, XOR64rr)>;
1165
1166 def PdWriteFZeroIdiom : SchedWriteVariant<[
1167   SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [PdWriteZeroLatency]>,
1168   SchedVar<MCSchedPredicate<TruePred>,           [WriteFLogic]>
1169 ]>;
1170 def : InstRW<[PdWriteFZeroIdiom], (instrs XORPSrr,  VXORPSrr,
1171                                           XORPDrr,  VXORPDrr,
1172                                           ANDNPSrr, VANDNPSrr,
1173                                           ANDNPDrr, VANDNPDrr)>;
1174
1175 // VXORPSYrr, VXORPDYrr, VANDNPSYrr, VANDNPDYrr "zero-idioms" have latency of 1.
1176
1177 def PdWriteVZeroIdiomLogic : SchedWriteVariant<[
1178   SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [PdWriteZeroLatency]>,
1179   SchedVar<MCSchedPredicate<TruePred>,           [WriteVecLogic]>
1180 ]>;
1181 def : InstRW<[PdWriteVZeroIdiomLogic], (instrs MMX_PXORirr, MMX_PANDNirr)>;
1182
1183 def PdWriteVZeroIdiomLogicX : SchedWriteVariant<[
1184   SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [PdWriteZeroLatency]>,
1185   SchedVar<MCSchedPredicate<TruePred>,           [WriteVecLogicX]>
1186 ]>;
1187 def : InstRW<[PdWriteVZeroIdiomLogicX], (instrs PXORrr,  VPXORrr,
1188                                                 PANDNrr, VPANDNrr)>;
1189
1190 def PdWriteVZeroIdiomALU : SchedWriteVariant<[
1191   SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [PdWriteZeroLatency]>,
1192   SchedVar<MCSchedPredicate<TruePred>,           [WriteVecALU]>
1193 ]>;
1194 def : InstRW<[PdWriteVZeroIdiomALU], (instrs MMX_PSUBBirr,   MMX_PSUBDirr,
1195                                              MMX_PSUBQirr,   MMX_PSUBWirr,
1196                                              MMX_PCMPGTBirr,
1197                                              MMX_PCMPGTDirr,
1198                                              MMX_PCMPGTWirr)>;
1199
1200 def PdWriteVZeroIdiomALUX : SchedWriteVariant<[
1201     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [PdWriteZeroLatency]>,
1202     SchedVar<MCSchedPredicate<TruePred>,           [WriteVecALUX]>
1203 ]>;
1204 def : InstRW<[PdWriteVZeroIdiomALUX], (instrs PSUBBrr, VPSUBBrr,
1205                                               PSUBDrr, VPSUBDrr,
1206                                               PSUBQrr, VPSUBQrr,
1207                                               PSUBWrr, VPSUBWrr,
1208                                               PCMPGTBrr, VPCMPGTBrr,
1209                                               PCMPGTDrr, VPCMPGTDrr,
1210                                               PCMPGTWrr, VPCMPGTWrr)>;
1211
1212 ///////////////////////////////////////////////////////////////////////////////
1213 // Dependency breaking instructions.
1214 ///////////////////////////////////////////////////////////////////////////////
1215
1216 // VPCMPGTQ, but not PCMPGTQ!
1217
1218 def : IsZeroIdiomFunction<[
1219   // GPR Zero-idioms.
1220   DepBreakingClass<[ SUB32rr, SUB64rr, XOR32rr, XOR64rr ], ZeroIdiomPredicate>,
1221
1222   // MMX Zero-idioms.
1223   DepBreakingClass<[
1224     MMX_PXORirr, MMX_PANDNirr, MMX_PSUBBirr,
1225     MMX_PSUBDirr, MMX_PSUBQirr, MMX_PSUBWirr,
1226     MMX_PSUBSBirr, MMX_PSUBSWirr, MMX_PSUBUSBirr, MMX_PSUBUSWirr,
1227     MMX_PCMPGTBirr, MMX_PCMPGTDirr, MMX_PCMPGTWirr
1228   ], ZeroIdiomPredicate>,
1229
1230   // SSE Zero-idioms.
1231   DepBreakingClass<[
1232     // fp variants.
1233     XORPSrr, XORPDrr, ANDNPSrr, ANDNPDrr,
1234
1235     // int variants.
1236     PXORrr, PANDNrr,
1237     PSUBBrr, PSUBWrr, PSUBDrr, PSUBQrr,
1238     PSUBSBrr, PSUBSWrr, PSUBUSBrr, PSUBUSWrr,
1239     PCMPGTBrr, PCMPGTDrr, PCMPGTWrr
1240   ], ZeroIdiomPredicate>,
1241
1242   // AVX Zero-idioms.
1243   DepBreakingClass<[
1244     // xmm fp variants.
1245     VXORPSrr, VXORPDrr, VANDNPSrr, VANDNPDrr,
1246
1247     // xmm int variants.
1248     VPXORrr, VPANDNrr,
1249     VPSUBBrr, VPSUBWrr, VPSUBDrr, VPSUBQrr,
1250     VPSUBSBrr, VPSUBSWrr, VPSUBUSBrr, VPSUBUSWrr,
1251     VPCMPGTBrr, VPCMPGTWrr, VPCMPGTDrr, VPCMPGTQrr,
1252
1253     // ymm variants.
1254     VXORPSYrr, VXORPDYrr, VANDNPSYrr, VANDNPDYrr
1255   ], ZeroIdiomPredicate>
1256 ]>;
1257
1258 def : IsDepBreakingFunction<[
1259   // GPR
1260   DepBreakingClass<[ SBB32rr, SBB64rr ], ZeroIdiomPredicate>,
1261   DepBreakingClass<[ CMP32rr, CMP64rr ], CheckSameRegOperand<0, 1> >,
1262
1263   // MMX
1264   DepBreakingClass<[
1265     MMX_PCMPEQBirr, MMX_PCMPEQDirr, MMX_PCMPEQWirr
1266   ], ZeroIdiomPredicate>,
1267
1268   // SSE
1269   DepBreakingClass<[
1270     PCMPEQBrr, PCMPEQWrr, PCMPEQDrr
1271     // But not PCMPEQQrr.
1272   ], ZeroIdiomPredicate>,
1273
1274   // AVX
1275   DepBreakingClass<[
1276     VPCMPEQBrr, VPCMPEQWrr, VPCMPEQDrr
1277     // But not VPCMPEQQrr.
1278   ], ZeroIdiomPredicate>
1279 ]>;
1280
1281
1282 } // SchedModel