X86: Turn redundant if into an assertion.
[oota-llvm.git] / lib / Target / X86 / X86SchedHaswell.td
1 //=- X86SchedHaswell.td - X86 Haswell 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 Haswell to support instruction
11 // scheduling and other instruction cost heuristics.
12 //
13 //===----------------------------------------------------------------------===//
14
15 def HaswellModel : SchedMachineModel {
16   // All x86 instructions are modeled as a single micro-op, and HW can decode 4
17   // instructions per cycle.
18   let IssueWidth = 4;
19   let MicroOpBufferSize = 192; // Based on the reorder buffer.
20   let LoadLatency = 4;
21   let MispredictPenalty = 16;
22
23   // Based on the LSD (loop-stream detector) queue size and benchmarking data.
24   let LoopMicroOpBufferSize = 50;
25
26   // FIXME: SSE4 and AVX are unimplemented. This flag is set to allow
27   // the scheduler to assign a default model to unrecognized opcodes.
28   let CompleteModel = 0;
29 }
30
31 let SchedModel = HaswellModel in {
32
33 // Haswell can issue micro-ops to 8 different ports in one cycle.
34
35 // Ports 0, 1, 5, and 6 handle all computation.
36 // Port 4 gets the data half of stores. Store data can be available later than
37 // the store address, but since we don't model the latency of stores, we can
38 // ignore that.
39 // Ports 2 and 3 are identical. They handle loads and the address half of
40 // stores. Port 7 can handle address calculations.
41 def HWPort0 : ProcResource<1>;
42 def HWPort1 : ProcResource<1>;
43 def HWPort2 : ProcResource<1>;
44 def HWPort3 : ProcResource<1>;
45 def HWPort4 : ProcResource<1>;
46 def HWPort5 : ProcResource<1>;
47 def HWPort6 : ProcResource<1>;
48 def HWPort7 : ProcResource<1>;
49
50 // Many micro-ops are capable of issuing on multiple ports.
51 def HWPort01  : ProcResGroup<[HWPort0, HWPort1]>;
52 def HWPort23  : ProcResGroup<[HWPort2, HWPort3]>;
53 def HWPort237 : ProcResGroup<[HWPort2, HWPort3, HWPort7]>;
54 def HWPort04  : ProcResGroup<[HWPort0, HWPort4]>;
55 def HWPort05  : ProcResGroup<[HWPort0, HWPort5]>;
56 def HWPort06  : ProcResGroup<[HWPort0, HWPort6]>;
57 def HWPort15  : ProcResGroup<[HWPort1, HWPort5]>;
58 def HWPort16  : ProcResGroup<[HWPort1, HWPort6]>;
59 def HWPort56  : ProcResGroup<[HWPort5, HWPort6]>;
60 def HWPort015 : ProcResGroup<[HWPort0, HWPort1, HWPort5]>;
61 def HWPort056 : ProcResGroup<[HWPort0, HWPort5, HWPort6]>;
62 def HWPort0156: ProcResGroup<[HWPort0, HWPort1, HWPort5, HWPort6]>;
63
64 // 60 Entry Unified Scheduler
65 def HWPortAny : ProcResGroup<[HWPort0, HWPort1, HWPort2, HWPort3, HWPort4,
66                               HWPort5, HWPort6, HWPort7]> {
67   let BufferSize=60;
68 }
69
70 // Integer division issued on port 0.
71 def HWDivider : ProcResource<1>;
72
73 // Loads are 4 cycles, so ReadAfterLd registers needn't be available until 4
74 // cycles after the memory operand.
75 def : ReadAdvance<ReadAfterLd, 4>;
76
77 // Many SchedWrites are defined in pairs with and without a folded load.
78 // Instructions with folded loads are usually micro-fused, so they only appear
79 // as two micro-ops when queued in the reservation station.
80 // This multiclass defines the resource usage for variants with and without
81 // folded loads.
82 multiclass HWWriteResPair<X86FoldableSchedWrite SchedRW,
83                           ProcResourceKind ExePort,
84                           int Lat> {
85   // Register variant is using a single cycle on ExePort.
86   def : WriteRes<SchedRW, [ExePort]> { let Latency = Lat; }
87
88   // Memory variant also uses a cycle on port 2/3 and adds 4 cycles to the
89   // latency.
90   def : WriteRes<SchedRW.Folded, [HWPort23, ExePort]> {
91      let Latency = !add(Lat, 4);
92   }
93 }
94
95 // A folded store needs a cycle on port 4 for the store data, but it does not
96 // need an extra port 2/3 cycle to recompute the address.
97 def : WriteRes<WriteRMW, [HWPort4]>;
98
99 // Store_addr on 237.
100 // Store_data on 4.
101 def : WriteRes<WriteStore, [HWPort237, HWPort4]>;
102 def : WriteRes<WriteLoad,  [HWPort23]> { let Latency = 4; }
103 def : WriteRes<WriteMove,  [HWPort0156]>;
104 def : WriteRes<WriteZero,  []>;
105
106 defm : HWWriteResPair<WriteALU,   HWPort0156, 1>;
107 defm : HWWriteResPair<WriteIMul,  HWPort1,   3>;
108 def  : WriteRes<WriteIMulH, []> { let Latency = 3; }
109 defm : HWWriteResPair<WriteShift, HWPort06,  1>;
110 defm : HWWriteResPair<WriteJump,  HWPort06,   1>;
111
112 // This is for simple LEAs with one or two input operands.
113 // The complex ones can only execute on port 1, and they require two cycles on
114 // the port to read all inputs. We don't model that.
115 def : WriteRes<WriteLEA, [HWPort15]>;
116
117 // This is quite rough, latency depends on the dividend.
118 def : WriteRes<WriteIDiv, [HWPort0, HWDivider]> {
119   let Latency = 25;
120   let ResourceCycles = [1, 10];
121 }
122 def : WriteRes<WriteIDivLd, [HWPort23, HWPort0, HWDivider]> {
123   let Latency = 29;
124   let ResourceCycles = [1, 1, 10];
125 }
126
127 // Scalar and vector floating point.
128 defm : HWWriteResPair<WriteFAdd,   HWPort1, 3>;
129 defm : HWWriteResPair<WriteFMul,   HWPort0, 5>;
130 defm : HWWriteResPair<WriteFDiv,   HWPort0, 12>; // 10-14 cycles.
131 defm : HWWriteResPair<WriteFRcp,   HWPort0, 5>;
132 defm : HWWriteResPair<WriteFSqrt,  HWPort0, 15>;
133 defm : HWWriteResPair<WriteCvtF2I, HWPort1, 3>;
134 defm : HWWriteResPair<WriteCvtI2F, HWPort1, 4>;
135 defm : HWWriteResPair<WriteCvtF2F, HWPort1, 3>;
136 defm : HWWriteResPair<WriteFShuffle,  HWPort5,  1>;
137 defm : HWWriteResPair<WriteFBlend,  HWPort015,  1>;
138 defm : HWWriteResPair<WriteFShuffle256,  HWPort5,  3>;
139
140 def : WriteRes<WriteFVarBlend, [HWPort5]> {
141   let Latency = 2;
142   let ResourceCycles = [2];
143 }
144 def : WriteRes<WriteFVarBlendLd, [HWPort5, HWPort23]> {
145   let Latency = 6;
146   let ResourceCycles = [2, 1];
147 }
148
149 // Vector integer operations.
150 defm : HWWriteResPair<WriteVecShift, HWPort0,  1>;
151 defm : HWWriteResPair<WriteVecLogic, HWPort015, 1>;
152 defm : HWWriteResPair<WriteVecALU,   HWPort15,  1>;
153 defm : HWWriteResPair<WriteVecIMul,  HWPort0,   5>;
154 defm : HWWriteResPair<WriteShuffle,  HWPort5,  1>;
155 defm : HWWriteResPair<WriteBlend,  HWPort15,  1>;
156 defm : HWWriteResPair<WriteShuffle256,  HWPort5,  3>;
157
158 def : WriteRes<WriteVarBlend, [HWPort5]> {
159   let Latency = 2;
160   let ResourceCycles = [2];
161 }
162 def : WriteRes<WriteVarBlendLd, [HWPort5, HWPort23]> {
163   let Latency = 6;
164   let ResourceCycles = [2, 1];
165 }
166
167 def : WriteRes<WriteVarVecShift, [HWPort0, HWPort5]> {
168   let Latency = 2;
169   let ResourceCycles = [2, 1];
170 }
171 def : WriteRes<WriteVarVecShiftLd, [HWPort0, HWPort5, HWPort23]> {
172   let Latency = 6;
173   let ResourceCycles = [2, 1, 1];
174 }
175
176 def : WriteRes<WriteMPSAD, [HWPort0, HWPort5]> {
177   let Latency = 6;
178   let ResourceCycles = [1, 2];
179 }
180 def : WriteRes<WriteMPSADLd, [HWPort23, HWPort0, HWPort5]> {
181   let Latency = 6;
182   let ResourceCycles = [1, 1, 2];
183 }
184
185 // String instructions.
186 // Packed Compare Implicit Length Strings, Return Mask
187 def : WriteRes<WritePCmpIStrM, [HWPort0]> {
188   let Latency = 10;
189   let ResourceCycles = [3];
190 }
191 def : WriteRes<WritePCmpIStrMLd, [HWPort0, HWPort23]> {
192   let Latency = 10;
193   let ResourceCycles = [3, 1];
194 }
195
196 // Packed Compare Explicit Length Strings, Return Mask
197 def : WriteRes<WritePCmpEStrM, [HWPort0, HWPort16, HWPort5]> {
198   let Latency = 10;
199   let ResourceCycles = [3, 2, 4];
200 }
201 def : WriteRes<WritePCmpEStrMLd, [HWPort05, HWPort16, HWPort23]> {
202   let Latency = 10;
203   let ResourceCycles = [6, 2, 1];
204 }
205
206 // Packed Compare Implicit Length Strings, Return Index
207 def : WriteRes<WritePCmpIStrI, [HWPort0]> {
208   let Latency = 11;
209   let ResourceCycles = [3];
210 }
211 def : WriteRes<WritePCmpIStrILd, [HWPort0, HWPort23]> {
212   let Latency = 11;
213   let ResourceCycles = [3, 1];
214 }
215
216 // Packed Compare Explicit Length Strings, Return Index
217 def : WriteRes<WritePCmpEStrI, [HWPort05, HWPort16]> {
218   let Latency = 11;
219   let ResourceCycles = [6, 2];
220 }
221 def : WriteRes<WritePCmpEStrILd, [HWPort0, HWPort16, HWPort5, HWPort23]> {
222   let Latency = 11;
223   let ResourceCycles = [3, 2, 2, 1];
224 }
225
226 // AES Instructions.
227 def : WriteRes<WriteAESDecEnc, [HWPort5]> {
228   let Latency = 7;
229   let ResourceCycles = [1];
230 }
231 def : WriteRes<WriteAESDecEncLd, [HWPort5, HWPort23]> {
232   let Latency = 7;
233   let ResourceCycles = [1, 1];
234 }
235
236 def : WriteRes<WriteAESIMC, [HWPort5]> {
237   let Latency = 14;
238   let ResourceCycles = [2];
239 }
240 def : WriteRes<WriteAESIMCLd, [HWPort5, HWPort23]> {
241   let Latency = 14;
242   let ResourceCycles = [2, 1];
243 }
244
245 def : WriteRes<WriteAESKeyGen, [HWPort0, HWPort5]> {
246   let Latency = 10;
247   let ResourceCycles = [2, 8];
248 }
249 def : WriteRes<WriteAESKeyGenLd, [HWPort0, HWPort5, HWPort23]> {
250   let Latency = 10;
251   let ResourceCycles = [2, 7, 1];
252 }
253
254 // Carry-less multiplication instructions.
255 def : WriteRes<WriteCLMul, [HWPort0, HWPort5]> {
256   let Latency = 7;
257   let ResourceCycles = [2, 1];
258 }
259 def : WriteRes<WriteCLMulLd, [HWPort0, HWPort5, HWPort23]> {
260   let Latency = 7;
261   let ResourceCycles = [2, 1, 1];
262 }
263
264 def : WriteRes<WriteSystem,     [HWPort0156]> { let Latency = 100; }
265 def : WriteRes<WriteMicrocoded, [HWPort0156]> { let Latency = 100; }
266 def : WriteRes<WriteFence,  [HWPort23, HWPort4]>;
267 def : WriteRes<WriteNop, []>;
268
269 //================ Exceptions ================//
270
271 //-- Specific Scheduling Models --//
272
273 // Starting with P0.
274 def WriteP0 : SchedWriteRes<[HWPort0]>;
275
276 def WriteP0_P1_Lat4 : SchedWriteRes<[HWPort0, HWPort1]> {
277   let Latency = 4;
278   let NumMicroOps = 2;
279   let ResourceCycles = [1, 1];
280 }
281
282 def WriteP0_P1_Lat4Ld : SchedWriteRes<[HWPort0, HWPort1, HWPort23]> {
283   let Latency = 8;
284   let NumMicroOps = 3;
285   let ResourceCycles = [1, 1, 1];
286 }
287
288 def WriteP01 : SchedWriteRes<[HWPort01]>;
289
290 def Write2P01 : SchedWriteRes<[HWPort01]> {
291   let NumMicroOps = 2;
292 }
293 def Write3P01 : SchedWriteRes<[HWPort01]> {
294   let NumMicroOps = 3;
295 }
296
297 def WriteP015 : SchedWriteRes<[HWPort015]>;
298
299 def WriteP01_P5 : SchedWriteRes<[HWPort01, HWPort5]> {
300   let NumMicroOps = 2;
301 }
302 def WriteP06 : SchedWriteRes<[HWPort06]>;
303
304 def Write2P06 : SchedWriteRes<[HWPort06]> {
305   let Latency = 1;
306   let NumMicroOps = 2;
307   let ResourceCycles = [2];
308 }
309
310 def Write3P06_Lat2 : SchedWriteRes<[HWPort06]> {
311   let Latency = 2;
312   let NumMicroOps = 3;
313   let ResourceCycles = [3];
314 }
315
316 def WriteP0156_P23 : SchedWriteRes<[HWPort0156, HWPort23]> {
317   let NumMicroOps = 2;
318 }
319
320 def Write2P0156_P23 : SchedWriteRes<[HWPort0156, HWPort23]> {
321   let NumMicroOps = 3;
322   let ResourceCycles = [2, 1];
323 }
324
325 def Write2P0156_Lat2 : SchedWriteRes<[HWPort0156]> {
326   let Latency = 2;
327   let ResourceCycles = [2];
328 }
329 def Write2P0156_Lat2Ld : SchedWriteRes<[HWPort0156, HWPort23]> {
330   let Latency = 6;
331   let ResourceCycles = [2, 1];
332 }
333
334 def Write5P0156 : SchedWriteRes<[HWPort0156]> {
335   let NumMicroOps = 5;
336   let ResourceCycles = [5];
337 }
338
339 def WriteP0156_2P237_P4 : SchedWriteRes<[HWPort0156, HWPort237, HWPort4]> {
340   let Latency = 1;
341   let ResourceCycles = [1, 2, 1];
342 }
343
344 def Write2P0156_2P237_P4 : SchedWriteRes<[HWPort0156, HWPort237, HWPort4]> {
345   let Latency = 1;
346   let ResourceCycles = [2, 2, 1];
347 }
348
349 def Write3P0156_2P237_P4 : SchedWriteRes<[HWPort0156, HWPort237, HWPort4]> {
350   let Latency = 1;
351   let ResourceCycles = [3, 2, 1];
352 }
353
354 // Starting with P1.
355 def WriteP1 : SchedWriteRes<[HWPort1]>;
356
357 def WriteP1_P23 : SchedWriteRes<[HWPort1, HWPort23]> {
358   let NumMicroOps = 2;
359 }
360 def WriteP1_Lat3 : SchedWriteRes<[HWPort1]> {
361   let Latency = 3;
362 }
363 def WriteP1_Lat3Ld : SchedWriteRes<[HWPort1, HWPort23]> {
364   let Latency = 7;
365 }
366
367 def Write2P1 : SchedWriteRes<[HWPort1]> {
368   let NumMicroOps = 2;
369   let ResourceCycles = [2];
370 }
371 def Write2P1_P23 : SchedWriteRes<[HWPort1, HWPort23]> {
372   let NumMicroOps = 3;
373   let ResourceCycles = [2, 1];
374 }
375 def WriteP15 : SchedWriteRes<[HWPort15]>;
376 def WriteP15Ld : SchedWriteRes<[HWPort15, HWPort23]> {
377   let Latency = 4;
378 }
379
380 def WriteP1_P5_Lat4 : SchedWriteRes<[HWPort1, HWPort5]> {
381   let Latency = 4;
382   let NumMicroOps = 2;
383   let ResourceCycles = [1, 1];
384 }
385
386 def WriteP1_P5_Lat4Ld : SchedWriteRes<[HWPort1, HWPort5, HWPort23]> {
387   let Latency = 8;
388   let NumMicroOps = 3;
389   let ResourceCycles = [1, 1, 1];
390 }
391
392 def WriteP1_P5_Lat6 : SchedWriteRes<[HWPort1, HWPort5]> {
393   let Latency = 6;
394   let NumMicroOps = 2;
395   let ResourceCycles = [1, 1];
396 }
397
398 def WriteP1_P5_Lat6Ld : SchedWriteRes<[HWPort1, HWPort5, HWPort23]> {
399   let Latency = 10;
400   let NumMicroOps = 3;
401   let ResourceCycles = [1, 1, 1];
402 }
403
404 // Starting with P2.
405 def Write2P237_P4 : SchedWriteRes<[HWPort237, HWPort4]> {
406   let Latency = 1;
407   let ResourceCycles = [2, 1];
408 }
409
410 // Starting with P5.
411 def WriteP5 : SchedWriteRes<[HWPort5]>;
412 def WriteP5Ld : SchedWriteRes<[HWPort5, HWPort23]> {
413   let Latency = 5;
414   let NumMicroOps = 2;
415   let ResourceCycles = [1, 1];
416 }
417
418 // Notation:
419 // - r: register.
420 // - mm: 64 bit mmx register.
421 // - x = 128 bit xmm register.
422 // - (x)mm = mmx or xmm register.
423 // - y = 256 bit ymm register.
424 // - v = any vector register.
425 // - m = memory.
426
427 //=== Integer Instructions ===//
428 //-- Move instructions --//
429
430 // MOV.
431 // r16,m.
432 def : InstRW<[WriteALULd], (instregex "MOV16rm")>;
433
434 // MOVSX, MOVZX.
435 // r,m.
436 def : InstRW<[WriteLoad], (instregex "MOV(S|Z)X32rm(8|16)")>;
437
438 // CMOVcc.
439 // r,r.
440 def : InstRW<[Write2P0156_Lat2],
441       (instregex "CMOV(O|NO|B|AE|E|NE|BE|A|S|NS|P|NP|L|GE|LE|G)(16|32|64)rr")>;
442 // r,m.
443 def : InstRW<[Write2P0156_Lat2Ld, ReadAfterLd],
444       (instregex "CMOV(O|NO|B|AE|E|NE|BE|A|S|NS|P|NP|L|GE|LE|G)(16|32|64)rm")>;
445
446 // XCHG.
447 // r,r.
448 def WriteXCHG : SchedWriteRes<[HWPort0156]> {
449   let Latency = 2;
450   let ResourceCycles = [3];
451 }
452
453 def : InstRW<[WriteXCHG], (instregex "XCHG(8|16|32|64)rr", "XCHG(16|32|64)ar")>;
454
455 // r,m.
456 def WriteXCHGrm : SchedWriteRes<[]> {
457   let Latency = 21;
458   let NumMicroOps = 8;
459 }
460 def : InstRW<[WriteXCHGrm], (instregex "XCHG(8|16|32|64)rm")>;
461
462 // XLAT.
463 def WriteXLAT : SchedWriteRes<[]> {
464   let Latency = 7;
465   let NumMicroOps = 3;
466 }
467 def : InstRW<[WriteXLAT], (instregex "XLAT")>;
468
469 // PUSH.
470 // m.
471 def : InstRW<[Write2P237_P4], (instregex "PUSH(16|32)rmm")>;
472
473 // PUSHF.
474 def WritePushF : SchedWriteRes<[HWPort1, HWPort4, HWPort237, HWPort06]> {
475   let NumMicroOps = 4;
476 }
477 def : InstRW<[WritePushF], (instregex "PUSHF(16|32)")>;
478
479 // PUSHA.
480 def WritePushA : SchedWriteRes<[]> {
481   let NumMicroOps = 19;
482 }
483 def : InstRW<[WritePushA], (instregex "PUSHA(16|32)")>;
484
485 // POP.
486 // m.
487 def : InstRW<[Write2P237_P4], (instregex "POP(16|32)rmm")>;
488
489 // POPF.
490 def WritePopF : SchedWriteRes<[]> {
491   let NumMicroOps = 9;
492 }
493 def : InstRW<[WritePopF], (instregex "POPF(16|32)")>;
494
495 // POPA.
496 def WritePopA : SchedWriteRes<[]> {
497   let NumMicroOps = 18;
498 }
499 def : InstRW<[WritePopA], (instregex "POPA(16|32)")>;
500
501 // LAHF SAHF.
502 def : InstRW<[WriteP06], (instregex "(S|L)AHF")>;
503
504 // BSWAP.
505 // r32.
506 def WriteBSwap32 : SchedWriteRes<[HWPort15]>;
507 def : InstRW<[WriteBSwap32], (instregex "BSWAP32r")>;
508
509 // r64.
510 def WriteBSwap64 : SchedWriteRes<[HWPort06, HWPort15]> {
511   let NumMicroOps = 2;
512 }
513 def : InstRW<[WriteBSwap64], (instregex "BSWAP64r")>;
514
515 // MOVBE.
516 // r16,m16 / r64,m64.
517 def : InstRW<[Write2P0156_Lat2Ld], (instregex "MOVBE(16|64)rm")>;
518
519 // r32, m32.
520 def WriteMoveBE32rm : SchedWriteRes<[HWPort15, HWPort23]> {
521   let NumMicroOps = 2;
522 }
523 def : InstRW<[WriteMoveBE32rm], (instregex "MOVBE32rm")>;
524
525 // m16,r16.
526 def WriteMoveBE16mr : SchedWriteRes<[HWPort06, HWPort237, HWPort4]> {
527   let NumMicroOps = 3;
528 }
529 def : InstRW<[WriteMoveBE16mr], (instregex "MOVBE16mr")>;
530
531 // m32,r32.
532 def WriteMoveBE32mr : SchedWriteRes<[HWPort15, HWPort237, HWPort4]> {
533   let NumMicroOps = 3;
534 }
535 def : InstRW<[WriteMoveBE32mr], (instregex "MOVBE32mr")>;
536
537 // m64,r64.
538 def WriteMoveBE64mr : SchedWriteRes<[HWPort06, HWPort15, HWPort237, HWPort4]> {
539   let NumMicroOps = 4;
540 }
541 def : InstRW<[WriteMoveBE64mr], (instregex "MOVBE64mr")>;
542
543 //-- Arithmetic instructions --//
544
545 // ADD SUB.
546 // m,r/i.
547 def : InstRW<[Write2P0156_2P237_P4],
548               (instregex "(ADD|SUB)(8|16|32|64)m(r|i)",
549               "(ADD|SUB)(8|16|32|64)mi8", "(ADD|SUB)64mi32")>;
550
551 // ADC SBB.
552 // r,r/i.
553 def : InstRW<[Write2P0156_Lat2], (instregex "(ADC|SBB)(8|16|32|64)r(r|i)",
554                            "(ADC|SBB)(16|32|64)ri8",
555                            "(ADC|SBB)64ri32",
556                            "(ADC|SBB)(8|16|32|64)rr_REV")>;
557
558 // r,m.
559 def : InstRW<[Write2P0156_Lat2Ld, ReadAfterLd], (instregex "(ADC|SBB)(8|16|32|64)rm")>;
560
561 // m,r/i.
562 def : InstRW<[Write3P0156_2P237_P4],
563              (instregex "(ADC|SBB)(8|16|32|64)m(r|i)",
564               "(ADC|SBB)(16|32|64)mi8",
565               "(ADC|SBB)64mi32")>;
566
567 // INC DEC NOT NEG.
568 // m.
569 def : InstRW<[WriteP0156_2P237_P4],
570              (instregex "(INC|DEC|NOT|NEG)(8|16|32|64)m",
571               "(INC|DEC)64(16|32)m")>;
572
573 // MUL IMUL.
574 // r16.
575 def WriteMul16 : SchedWriteRes<[HWPort1, HWPort0156]> {
576   let Latency = 4;
577   let NumMicroOps = 4;
578 }
579 def : InstRW<[WriteMul16], (instregex "IMUL16r", "MUL16r")>;
580
581 // m16.
582 def WriteMul16Ld : SchedWriteRes<[HWPort1, HWPort0156, HWPort23]> {
583   let Latency = 8;
584   let NumMicroOps = 5;
585 }
586 def : InstRW<[WriteMul16Ld], (instregex "IMUL16m", "MUL16m")>;
587
588 // r32.
589 def WriteMul32 : SchedWriteRes<[HWPort1, HWPort0156]> {
590   let Latency = 4;
591   let NumMicroOps = 3;
592 }
593 def : InstRW<[WriteMul32], (instregex "IMUL32r", "MUL32r")>;
594
595 // m32.
596 def WriteMul32Ld : SchedWriteRes<[HWPort1, HWPort0156, HWPort23]> {
597   let Latency = 8;
598   let NumMicroOps = 4;
599 }
600 def : InstRW<[WriteMul32Ld], (instregex "IMUL32m", "MUL32m")>;
601
602 // r64.
603 def WriteMul64 : SchedWriteRes<[HWPort1, HWPort6]> {
604   let Latency = 3;
605   let NumMicroOps = 2;
606 }
607 def : InstRW<[WriteMul64], (instregex "IMUL64r", "MUL64r")>;
608
609 // m64.
610 def WriteMul64Ld : SchedWriteRes<[HWPort1, HWPort6, HWPort23]> {
611   let Latency = 7;
612   let NumMicroOps = 3;
613 }
614 def : InstRW<[WriteMul64Ld], (instregex "IMUL64m", "MUL64m")>;
615
616 // r16,r16.
617 def WriteMul16rri : SchedWriteRes<[HWPort1, HWPort0156]> {
618   let Latency = 4;
619   let NumMicroOps = 2;
620 }
621 def : InstRW<[WriteMul16rri], (instregex "IMUL16rri", "IMUL16rri8")>;
622
623 // r16,m16.
624 def WriteMul16rmi : SchedWriteRes<[HWPort1, HWPort0156, HWPort23]> {
625   let Latency = 8;
626   let NumMicroOps = 3;
627 }
628 def : InstRW<[WriteMul16rmi], (instregex "IMUL16rmi", "IMUL16rmi8")>;
629
630 // MULX.
631 // r32,r32,r32.
632 def WriteMulX32 : SchedWriteRes<[HWPort1, HWPort056]> {
633   let Latency = 4;
634   let NumMicroOps = 3;
635   let ResourceCycles = [1, 2];
636 }
637 def : InstRW<[WriteMulX32], (instregex "MULX32rr")>;
638
639 // r32,r32,m32.
640 def WriteMulX32Ld : SchedWriteRes<[HWPort1, HWPort056, HWPort23]> {
641   let Latency = 8;
642   let NumMicroOps = 4;
643   let ResourceCycles = [1, 2, 1];
644 }
645 def : InstRW<[WriteMulX32Ld], (instregex "MULX32rm")>;
646
647 // r64,r64,r64.
648 def WriteMulX64 : SchedWriteRes<[HWPort1, HWPort6]> {
649   let Latency = 4;
650   let NumMicroOps = 2;
651 }
652 def : InstRW<[WriteMulX64], (instregex "MULX64rr")>;
653
654 // r64,r64,m64.
655 def WriteMulX64Ld : SchedWriteRes<[HWPort1, HWPort6, HWPort23]> {
656   let Latency = 8;
657   let NumMicroOps = 3;
658 }
659 def : InstRW<[WriteMulX64Ld], (instregex "MULX64rm")>;
660
661 // DIV.
662 // r8.
663 def WriteDiv8 : SchedWriteRes<[HWPort0, HWPort1, HWPort5, HWPort6]> {
664   let Latency = 22;
665   let NumMicroOps = 9;
666 }
667 def : InstRW<[WriteDiv8], (instregex "DIV8r")>;
668
669 // r16.
670 def WriteDiv16 : SchedWriteRes<[HWPort0, HWPort1, HWPort5, HWPort6]> {
671   let Latency = 23;
672   let NumMicroOps = 10;
673 }
674 def : InstRW<[WriteDiv16], (instregex "DIV16r")>;
675
676 // r32.
677 def WriteDiv32 : SchedWriteRes<[HWPort0, HWPort1, HWPort5, HWPort6]> {
678   let Latency = 22;
679   let NumMicroOps = 10;
680 }
681 def : InstRW<[WriteDiv32], (instregex "DIV32r")>;
682
683 // r64.
684 def WriteDiv64 : SchedWriteRes<[HWPort0, HWPort1, HWPort5, HWPort6]> {
685   let Latency = 32;
686   let NumMicroOps = 36;
687 }
688 def : InstRW<[WriteDiv64], (instregex "DIV64r")>;
689
690 // IDIV.
691 // r8.
692 def WriteIDiv8 : SchedWriteRes<[HWPort0, HWPort1, HWPort5, HWPort6]> {
693   let Latency = 23;
694   let NumMicroOps = 9;
695 }
696 def : InstRW<[WriteIDiv8], (instregex "IDIV8r")>;
697
698 // r16.
699 def WriteIDiv16 : SchedWriteRes<[HWPort0, HWPort1, HWPort5, HWPort6]> {
700   let Latency = 23;
701   let NumMicroOps = 10;
702 }
703 def : InstRW<[WriteIDiv16], (instregex "IDIV16r")>;
704
705 // r32.
706 def WriteIDiv32 : SchedWriteRes<[HWPort0, HWPort1, HWPort5, HWPort6]> {
707   let Latency = 22;
708   let NumMicroOps = 9;
709 }
710 def : InstRW<[WriteIDiv32], (instregex "IDIV32r")>;
711
712 // r64.
713 def WriteIDiv64 : SchedWriteRes<[HWPort0, HWPort1, HWPort5, HWPort6]> {
714   let Latency = 39;
715   let NumMicroOps = 59;
716 }
717 def : InstRW<[WriteIDiv64], (instregex "IDIV64r")>;
718
719 //-- Logic instructions --//
720
721 // AND OR XOR.
722 // m,r/i.
723 def : InstRW<[Write2P0156_2P237_P4],
724              (instregex "(AND|OR|XOR)(8|16|32|64)m(r|i)",
725               "(AND|OR|XOR)(8|16|32|64)mi8", "(AND|OR|XOR)64mi32")>;
726
727 // SHR SHL SAR.
728 // m,i.
729 def WriteShiftRMW : SchedWriteRes<[HWPort06, HWPort237, HWPort4]> {
730   let NumMicroOps = 4;
731   let ResourceCycles = [2, 1, 1];
732 }
733 def : InstRW<[WriteShiftRMW], (instregex "S(A|H)(R|L)(8|16|32|64)m(i|1)")>;
734
735 // r,cl.
736 def : InstRW<[Write3P06_Lat2], (instregex "S(A|H)(R|L)(8|16|32|64)rCL")>;
737
738 // m,cl.
739 def WriteShiftClLdRMW : SchedWriteRes<[HWPort06, HWPort23, HWPort4]> {
740   let NumMicroOps = 6;
741   let ResourceCycles = [3, 2, 1];
742 }
743 def : InstRW<[WriteShiftClLdRMW], (instregex "S(A|H)(R|L)(8|16|32|64)mCL")>;
744
745 // ROR ROL.
746 // r,1.
747 def : InstRW<[Write2P06], (instregex "RO(R|L)(8|16|32|64)r1")>;
748
749 // m,i.
750 def WriteRotateRMW : SchedWriteRes<[HWPort06, HWPort237, HWPort4]> {
751   let NumMicroOps = 5;
752   let ResourceCycles = [2, 2, 1];
753 }
754 def : InstRW<[WriteRotateRMW], (instregex "RO(R|L)(8|16|32|64)mi")>;
755
756 // r,cl.
757 def : InstRW<[Write3P06_Lat2], (instregex "RO(R|L)(8|16|32|64)rCL")>;
758
759 // m,cl.
760 def WriteRotateRMWCL : SchedWriteRes<[]> {
761   let NumMicroOps = 6;
762 }
763 def : InstRW<[WriteRotateRMWCL], (instregex "RO(R|L)(8|16|32|64)mCL")>;
764
765 // RCR RCL.
766 // r,1.
767 def WriteRCr1 : SchedWriteRes<[HWPort06, HWPort0156]> {
768   let Latency = 2;
769   let NumMicroOps = 3;
770   let ResourceCycles = [2, 1];
771 }
772 def : InstRW<[WriteRCr1], (instregex "RC(R|L)(8|16|32|64)r1")>;
773
774 // m,1.
775 def WriteRCm1 : SchedWriteRes<[]> {
776   let NumMicroOps = 6;
777 }
778 def : InstRW<[WriteRCm1], (instregex "RC(R|L)(8|16|32|64)m1")>;
779
780 // r,i.
781 def WriteRCri : SchedWriteRes<[HWPort0156]> {
782   let Latency = 6;
783   let NumMicroOps = 8;
784 }
785 def : InstRW<[WriteRCri], (instregex "RC(R|L)(8|16|32|64)r(i|CL)")>;
786
787 // m,i.
788 def WriteRCmi : SchedWriteRes<[]> {
789   let NumMicroOps = 11;
790 }
791 def : InstRW<[WriteRCmi], (instregex "RC(R|L)(8|16|32|64)m(i|CL)")>;
792
793 // SHRD SHLD.
794 // r,r,i.
795 def WriteShDrr : SchedWriteRes<[HWPort1]> {
796   let Latency = 3;
797 }
798 def : InstRW<[WriteShDrr], (instregex "SH(R|L)D(16|32|64)rri8")>;
799
800 // m,r,i.
801 def WriteShDmr : SchedWriteRes<[]> {
802   let NumMicroOps = 5;
803 }
804 def : InstRW<[WriteShDmr], (instregex "SH(R|L)D(16|32|64)mri8")>;
805
806 // r,r,cl.
807 def WriteShlDCL : SchedWriteRes<[HWPort0156]> {
808   let Latency = 3;
809   let NumMicroOps = 4;
810 }
811 def : InstRW<[WriteShlDCL], (instregex "SHLD(16|32|64)rrCL")>;
812
813 // r,r,cl.
814 def WriteShrDCL : SchedWriteRes<[HWPort0156]> {
815   let Latency = 4;
816   let NumMicroOps = 4;
817 }
818 def : InstRW<[WriteShrDCL], (instregex "SHRD(16|32|64)rrCL")>;
819
820 // m,r,cl.
821 def WriteShDmrCL : SchedWriteRes<[]> {
822   let NumMicroOps = 7;
823 }
824 def : InstRW<[WriteShDmrCL], (instregex "SH(R|L)D(16|32|64)mrCL")>;
825
826 // BT.
827 // r,r/i.
828 def : InstRW<[WriteShift], (instregex "BT(16|32|64)r(r|i8)")>;
829
830 // m,r.
831 def WriteBTmr : SchedWriteRes<[]> {
832   let NumMicroOps = 10;
833 }
834 def : InstRW<[WriteBTmr], (instregex "BT(16|32|64)mr")>;
835
836 // m,i.
837 def : InstRW<[WriteShiftLd], (instregex "BT(16|32|64)mi8")>;
838
839 // BTR BTS BTC.
840 // r,r,i.
841 def : InstRW<[WriteShift], (instregex "BT(R|S|C)(16|32|64)r(r|i8)")>;
842
843 // m,r.
844 def WriteBTRSCmr : SchedWriteRes<[]> {
845   let NumMicroOps = 11;
846 }
847 def : InstRW<[WriteBTRSCmr], (instregex "BT(R|S|C)(16|32|64)mr")>;
848
849 // m,i.
850 def : InstRW<[WriteShiftLd], (instregex "BT(R|S|C)(16|32|64)mi8")>;
851
852 // BSF BSR.
853 // r,r.
854 def : InstRW<[WriteP1_Lat3], (instregex "BS(R|F)(16|32|64)rr")>;
855 // r,m.
856 def : InstRW<[WriteP1_Lat3Ld], (instregex "BS(R|F)(16|32|64)rm")>;
857
858 // SETcc.
859 // r.
860 def : InstRW<[WriteShift],
861              (instregex "SET(O|NO|B|AE|E|NE|BE|A|S|NS|P|NP|L|GE|LE|G)r")>;
862 // m.
863 def WriteSetCCm : SchedWriteRes<[HWPort06, HWPort237, HWPort4]> {
864   let NumMicroOps = 3;
865 }
866 def : InstRW<[WriteSetCCm],
867              (instregex "SET(O|NO|B|AE|E|NE|BE|A|S|NS|P|NP|L|GE|LE|G)m")>;
868
869 // CLD STD.
870 def WriteCldStd : SchedWriteRes<[HWPort15, HWPort6]> {
871   let NumMicroOps = 3;
872 }
873 def : InstRW<[WriteCldStd], (instregex "STD", "CLD")>;
874
875 // LZCNT TZCNT.
876 // r,r.
877 def : InstRW<[WriteP1_Lat3], (instregex "(L|TZCNT)(16|32|64)rr")>;
878 // r,m.
879 def : InstRW<[WriteP1_Lat3Ld], (instregex "(L|TZCNT)(16|32|64)rm")>;
880
881 // ANDN.
882 // r,r.
883 def : InstRW<[WriteP15], (instregex "ANDN(32|64)rr")>;
884 // r,m.
885 def : InstRW<[WriteP15Ld], (instregex "ANDN(32|64)rm")>;
886
887 // BLSI BLSMSK BLSR.
888 // r,r.
889 def : InstRW<[WriteP15], (instregex "BLS(I|MSK|R)(32|64)rr")>;
890 // r,m.
891 def : InstRW<[WriteP15Ld], (instregex "BLS(I|MSK|R)(32|64)rm")>;
892
893 // BEXTR.
894 // r,r,r.
895 def : InstRW<[Write2P0156_Lat2], (instregex "BEXTR(32|64)rr")>;
896 // r,m,r.
897 def : InstRW<[Write2P0156_Lat2Ld], (instregex "BEXTR(32|64)rm")>;
898
899 // BZHI.
900 // r,r,r.
901 def : InstRW<[WriteP15], (instregex "BZHI(32|64)rr")>;
902 // r,m,r.
903 def : InstRW<[WriteP15Ld], (instregex "BZHI(32|64)rm")>;
904
905 // PDEP PEXT.
906 // r,r,r.
907 def : InstRW<[WriteP1_Lat3], (instregex "PDEP(32|64)rr", "PEXT(32|64)rr")>;
908 // r,m,r.
909 def : InstRW<[WriteP1_Lat3Ld], (instregex "PDEP(32|64)rm", "PEXT(32|64)rm")>;
910
911 //-- Control transfer instructions --//
912
913 // J(E|R)CXZ.
914 def WriteJCXZ : SchedWriteRes<[HWPort0156, HWPort6]> {
915   let NumMicroOps = 2;
916 }
917 def : InstRW<[WriteJCXZ], (instregex "JCXZ", "JECXZ_(32|64)", "JRCXZ")>;
918
919 // LOOP.
920 def WriteLOOP : SchedWriteRes<[]> {
921   let NumMicroOps = 7;
922 }
923 def : InstRW<[WriteLOOP], (instregex "LOOP")>;
924
925 // LOOP(N)E
926 def WriteLOOPE : SchedWriteRes<[]> {
927   let NumMicroOps = 11;
928 }
929 def : InstRW<[WriteLOOPE], (instregex "LOOPE", "LOOPNE")>;
930
931 // CALL.
932 // r.
933 def WriteCALLr : SchedWriteRes<[HWPort237, HWPort4, HWPort6]> {
934   let NumMicroOps = 3;
935 }
936 def : InstRW<[WriteCALLr], (instregex "CALL(16|32)r")>;
937
938 // m.
939 def WriteCALLm : SchedWriteRes<[HWPort237, HWPort4, HWPort6]> {
940   let NumMicroOps = 4;
941   let ResourceCycles = [2, 1, 1];
942 }
943 def : InstRW<[WriteCALLm], (instregex "CALL(16|32)m")>;
944
945 // RET.
946 def WriteRET : SchedWriteRes<[HWPort237, HWPort6]> {
947   let NumMicroOps = 2;
948 }
949 def : InstRW<[WriteRET], (instregex "RET(L|Q|W)", "LRET(L|Q|W)")>;
950
951 // i.
952 def WriteRETI : SchedWriteRes<[HWPort23, HWPort6, HWPort015]> {
953   let NumMicroOps = 4;
954   let ResourceCycles = [1, 2, 1];
955 }
956 def : InstRW<[WriteRETI], (instregex "RETI(L|Q|W)", "LRETI(L|Q|W)")>;
957
958 // BOUND.
959 // r,m.
960 def WriteBOUND : SchedWriteRes<[]> {
961   let NumMicroOps = 15;
962 }
963 def : InstRW<[WriteBOUND], (instregex "BOUNDS(16|32)rm")>;
964
965 // INTO.
966 def WriteINTO : SchedWriteRes<[]> {
967   let NumMicroOps = 4;
968 }
969 def : InstRW<[WriteINTO], (instregex "INTO")>;
970
971 //-- String instructions --//
972
973 // LODSB/W.
974 def : InstRW<[Write2P0156_P23], (instregex "LODS(B|W)")>;
975
976 // LODSD/Q.
977 def : InstRW<[WriteP0156_P23], (instregex "LODS(L|Q)")>;
978
979 // STOS.
980 def WriteSTOS : SchedWriteRes<[HWPort23, HWPort0156, HWPort4]> {
981   let NumMicroOps = 3;
982 }
983 def : InstRW<[WriteSTOS], (instregex "STOS(B|L|Q|W)")>;
984
985 // MOVS.
986 def WriteMOVS : SchedWriteRes<[HWPort23, HWPort4, HWPort0156]> {
987   let Latency = 4;
988   let NumMicroOps = 5;
989   let ResourceCycles = [2, 1, 2];
990 }
991 def : InstRW<[WriteMOVS], (instregex "MOVS(B|L|Q|W)")>;
992
993 // SCAS.
994 def : InstRW<[Write2P0156_P23], (instregex "SCAS(B|W|L|Q)")>;
995
996 // CMPS.
997 def WriteCMPS : SchedWriteRes<[HWPort23, HWPort0156]> {
998   let Latency = 4;
999   let NumMicroOps = 5;
1000   let ResourceCycles = [2, 3];
1001 }
1002 def : InstRW<[WriteCMPS], (instregex "CMPS(B|L|Q|W)")>;
1003
1004 //-- Synchronization instructions --//
1005
1006 // XADD.
1007 def WriteXADD : SchedWriteRes<[]> {
1008   let NumMicroOps = 5;
1009 }
1010 def : InstRW<[WriteXADD], (instregex "XADD(8|16|32|64)rm")>;
1011
1012 // CMPXCHG.
1013 def WriteCMPXCHG : SchedWriteRes<[]> {
1014   let NumMicroOps = 6;
1015 }
1016 def : InstRW<[WriteCMPXCHG], (instregex "CMPXCHG(8|16|32|64)rm")>;
1017
1018 // CMPXCHG8B.
1019 def WriteCMPXCHG8B : SchedWriteRes<[]> {
1020   let NumMicroOps = 15;
1021 }
1022 def : InstRW<[WriteCMPXCHG8B], (instregex "CMPXCHG8B")>;
1023
1024 // CMPXCHG16B.
1025 def WriteCMPXCHG16B : SchedWriteRes<[]> {
1026   let NumMicroOps = 22;
1027 }
1028 def : InstRW<[WriteCMPXCHG16B], (instregex "CMPXCHG16B")>;
1029
1030 //-- Other --//
1031
1032 // PAUSE.
1033 def WritePAUSE : SchedWriteRes<[HWPort05, HWPort6]> {
1034   let NumMicroOps = 5;
1035   let ResourceCycles = [1, 3];
1036 }
1037 def : InstRW<[WritePAUSE], (instregex "PAUSE")>;
1038
1039 // LEAVE.
1040 def : InstRW<[Write2P0156_P23], (instregex "LEAVE")>;
1041
1042 // XGETBV.
1043 def WriteXGETBV : SchedWriteRes<[]> {
1044   let NumMicroOps = 8;
1045 }
1046 def : InstRW<[WriteXGETBV], (instregex "XGETBV")>;
1047
1048 // RDTSC.
1049 def WriteRDTSC : SchedWriteRes<[]> {
1050   let NumMicroOps = 15;
1051 }
1052 def : InstRW<[WriteRDTSC], (instregex "RDTSC")>;
1053
1054 // RDPMC.
1055 def WriteRDPMC : SchedWriteRes<[]> {
1056   let NumMicroOps = 34;
1057 }
1058 def : InstRW<[WriteRDPMC], (instregex "RDPMC")>;
1059
1060 // RDRAND.
1061 def WriteRDRAND : SchedWriteRes<[HWPort23, HWPort015]> {
1062   let NumMicroOps = 17;
1063   let ResourceCycles = [1, 16];
1064 }
1065 def : InstRW<[WriteRDRAND], (instregex "RDRAND(16|32|64)r")>;
1066
1067 //=== Floating Point x87 Instructions ===//
1068 //-- Move instructions --//
1069
1070 // FLD.
1071 // m80.
1072 def : InstRW<[WriteP01], (instregex "LD_Frr")>;
1073
1074 def WriteLD_F80m : SchedWriteRes<[HWPort01, HWPort23]> {
1075   let Latency = 4;
1076   let NumMicroOps = 4;
1077   let ResourceCycles = [2, 2];
1078 }
1079 def : InstRW<[WriteLD_F80m], (instregex "LD_F80m")>;
1080
1081 // FBLD.
1082 // m80.
1083 def WriteFBLD : SchedWriteRes<[]> {
1084   let Latency = 47;
1085   let NumMicroOps = 43;
1086 }
1087 def : InstRW<[WriteFBLD], (instregex "FBLDm")>;
1088
1089 // FST(P).
1090 // r.
1091 def : InstRW<[WriteP01], (instregex "ST_(F|FP)rr")>;
1092
1093 // m80.
1094 def WriteST_FP80m : SchedWriteRes<[HWPort0156, HWPort23, HWPort4]> {
1095   let NumMicroOps = 7;
1096   let ResourceCycles = [3, 2, 2];
1097 }
1098 def : InstRW<[WriteST_FP80m], (instregex "ST_FP80m")>;
1099
1100 // FBSTP.
1101 // m80.
1102 def WriteFBSTP : SchedWriteRes<[]> {
1103   let NumMicroOps = 226;
1104 }
1105 def : InstRW<[WriteFBSTP], (instregex "FBSTPm")>;
1106
1107 // FXCHG.
1108 def : InstRW<[WriteNop], (instregex "XCH_F")>;
1109
1110 // FILD.
1111 def WriteFILD : SchedWriteRes<[HWPort01, HWPort23]> {
1112   let Latency = 6;
1113   let NumMicroOps = 2;
1114 }
1115 def : InstRW<[WriteFILD], (instregex "ILD_F(16|32|64)m")>;
1116
1117 // FIST(P) FISTTP.
1118 def WriteFIST : SchedWriteRes<[HWPort1, HWPort23, HWPort4]> {
1119   let Latency = 7;
1120   let NumMicroOps = 3;
1121 }
1122 def : InstRW<[WriteFIST], (instregex "IST_(F|FP)(16|32)m")>;
1123
1124 // FLDZ.
1125 def : InstRW<[WriteP01], (instregex "LD_F0")>;
1126
1127 // FLD1.
1128 def : InstRW<[Write2P01], (instregex "LD_F1")>;
1129
1130 // FLDPI FLDL2E etc.
1131 def : InstRW<[Write2P01], (instregex "FLDPI", "FLDL2(T|E)" "FLDL(G|N)2")>;
1132
1133 // FCMOVcc.
1134 def WriteFCMOVcc : SchedWriteRes<[HWPort0, HWPort5]> {
1135   let Latency = 2;
1136   let NumMicroOps = 3;
1137   let ResourceCycles = [2, 1];
1138 }
1139 def : InstRW<[WriteFCMOVcc], (instregex "CMOV(B|BE|P|NB|NBE|NE|NP)_F")>;
1140
1141 // FNSTSW.
1142 // AX.
1143 def WriteFNSTSW : SchedWriteRes<[HWPort0, HWPort0156]> {
1144   let NumMicroOps = 2;
1145 }
1146 def : InstRW<[WriteFNSTSW], (instregex "FNSTSW16r")>;
1147
1148 // m16.
1149 def WriteFNSTSWm : SchedWriteRes<[HWPort0, HWPort4, HWPort237]> {
1150   let Latency = 6;
1151   let NumMicroOps = 3;
1152 }
1153 def : InstRW<[WriteFNSTSWm], (instregex "FNSTSWm")>;
1154
1155 // FLDCW.
1156 def WriteFLDCW : SchedWriteRes<[HWPort01, HWPort23, HWPort6]> {
1157   let Latency = 7;
1158   let NumMicroOps = 3;
1159 }
1160 def : InstRW<[WriteFLDCW], (instregex "FLDCW16m")>;
1161
1162 // FNSTCW.
1163 def WriteFNSTCW : SchedWriteRes<[HWPort237, HWPort4, HWPort6]> {
1164   let NumMicroOps = 3;
1165 }
1166 def : InstRW<[WriteFNSTCW], (instregex "FNSTCW16m")>;
1167
1168 // FINCSTP FDECSTP.
1169 def : InstRW<[WriteP01], (instregex "FINCSTP", "FDECSTP")>;
1170
1171 // FFREE.
1172 def : InstRW<[WriteP01], (instregex "FFREE")>;
1173
1174 // FNSAVE.
1175 def WriteFNSAVE : SchedWriteRes<[]> {
1176   let NumMicroOps = 147;
1177 }
1178 def : InstRW<[WriteFNSAVE], (instregex "FSAVEm")>;
1179
1180 // FRSTOR.
1181 def WriteFRSTOR : SchedWriteRes<[]> {
1182   let NumMicroOps = 90;
1183 }
1184 def : InstRW<[WriteFRSTOR], (instregex "FRSTORm")>;
1185
1186 //-- Arithmetic instructions --//
1187
1188 // FABS.
1189 def : InstRW<[WriteP0], (instregex "ABS_F")>;
1190
1191 // FCHS.
1192 def : InstRW<[WriteP0], (instregex "CHS_F")>;
1193
1194 // FCOM(P) FUCOM(P).
1195 // r.
1196 def : InstRW<[WriteP1], (instregex "COM_FST0r", "COMP_FST0r", "UCOM_Fr",
1197                          "UCOM_FPr")>;
1198 // m.
1199 def : InstRW<[WriteP1_P23], (instregex "FCOM(32|64)m", "FCOMP(32|64)m")>;
1200
1201 // FCOMPP FUCOMPP.
1202 // r.
1203 def : InstRW<[Write2P01], (instregex "FCOMPP", "UCOM_FPPr")>;
1204
1205 // FCOMI(P) FUCOMI(P).
1206 // m.
1207 def : InstRW<[Write3P01], (instregex "COM_FIr", "COM_FIPr", "UCOM_FIr",
1208                            "UCOM_FIPr")>;
1209
1210 // FICOM(P).
1211 def : InstRW<[Write2P1_P23], (instregex "FICOM(16|32)m", "FICOMP(16|32)m")>;
1212
1213 // FTST.
1214 def : InstRW<[WriteP1], (instregex "TST_F")>;
1215
1216 // FXAM.
1217 def : InstRW<[Write2P1], (instregex "FXAM")>;
1218
1219 // FPREM.
1220 def WriteFPREM : SchedWriteRes<[]> {
1221   let Latency = 19;
1222   let NumMicroOps = 28;
1223 }
1224 def : InstRW<[WriteFPREM], (instregex "FPREM")>;
1225
1226 // FPREM1.
1227 def WriteFPREM1 : SchedWriteRes<[]> {
1228   let Latency = 27;
1229   let NumMicroOps = 41;
1230 }
1231 def : InstRW<[WriteFPREM1], (instregex "FPREM1")>;
1232
1233 // FRNDINT.
1234 def WriteFRNDINT : SchedWriteRes<[]> {
1235   let Latency = 11;
1236   let NumMicroOps = 17;
1237 }
1238 def : InstRW<[WriteFRNDINT], (instregex "FRNDINT")>;
1239
1240 //-- Math instructions --//
1241
1242 // FSCALE.
1243 def WriteFSCALE : SchedWriteRes<[]> {
1244   let Latency = 75; // 49-125
1245   let NumMicroOps = 50; // 25-75
1246 }
1247 def : InstRW<[WriteFSCALE], (instregex "FSCALE")>;
1248
1249 // FXTRACT.
1250 def WriteFXTRACT : SchedWriteRes<[]> {
1251   let Latency = 15;
1252   let NumMicroOps = 17;
1253 }
1254 def : InstRW<[WriteFXTRACT], (instregex "FXTRACT")>;
1255
1256 //-- Other instructions --//
1257
1258 // FNOP.
1259 def : InstRW<[WriteP01], (instregex "FNOP")>;
1260
1261 // WAIT.
1262 def : InstRW<[Write2P01], (instregex "WAIT")>;
1263
1264 // FNCLEX.
1265 def : InstRW<[Write5P0156], (instregex "FNCLEX")>;
1266
1267 // FNINIT.
1268 def WriteFNINIT : SchedWriteRes<[]> {
1269   let NumMicroOps = 26;
1270 }
1271 def : InstRW<[WriteFNINIT], (instregex "FNINIT")>;
1272
1273 //=== Integer MMX and XMM Instructions ===//
1274 //-- Move instructions --//
1275
1276 // MOVD.
1277 // r32/64 <- (x)mm.
1278 def : InstRW<[WriteP0], (instregex "MMX_MOVD64grr", "MMX_MOVD64from64rr",
1279                          "VMOVPDI2DIrr", "MOVPDI2DIrr")>;
1280
1281 // (x)mm <- r32/64.
1282 def : InstRW<[WriteP5], (instregex "MMX_MOVD64rr", "MMX_MOVD64to64rr",
1283                          "VMOVDI2PDIrr", "MOVDI2PDIrr")>;
1284
1285 // MOVQ.
1286 // r64 <- (x)mm.
1287 def : InstRW<[WriteP0], (instregex "VMOVPQIto64rr")>;
1288
1289 // (x)mm <- r64.
1290 def : InstRW<[WriteP5], (instregex "VMOV64toPQIrr", "VMOVZQI2PQIrr")>;
1291
1292 // (x)mm <- (x)mm.
1293 def : InstRW<[WriteP015], (instregex "MMX_MOVQ64rr")>;
1294
1295 // (V)MOVDQA/U.
1296 // x <- x.
1297 def : InstRW<[WriteP015], (instregex "MOVDQ(A|U)rr", "VMOVDQ(A|U)rr",
1298                            "MOVDQ(A|U)rr_REV", "VMOVDQ(A|U)rr_REV",
1299                            "VMOVDQ(A|U)Yrr", "VMOVDQ(A|U)Yrr_REV")>;
1300
1301 // MOVDQ2Q.
1302 def : InstRW<[WriteP01_P5], (instregex "MMX_MOVDQ2Qrr")>;
1303
1304 // MOVQ2DQ.
1305 def : InstRW<[WriteP015], (instregex "MMX_MOVQ2DQrr")>;
1306
1307
1308 // PACKSSWB/DW.
1309 // mm <- mm.
1310 def WriteMMXPACKSSrr : SchedWriteRes<[HWPort5]> {
1311   let Latency = 2;
1312   let NumMicroOps = 3;
1313   let ResourceCycles = [3];
1314 }
1315 def : InstRW<[WriteMMXPACKSSrr], (instregex "MMX_PACKSSDWirr",
1316                                   "MMX_PACKSSWBirr", "MMX_PACKUSWBirr")>;
1317
1318 // mm <- m64.
1319 def WriteMMXPACKSSrm : SchedWriteRes<[HWPort23, HWPort5]> {
1320   let Latency = 4;
1321   let NumMicroOps = 3;
1322   let ResourceCycles = [1, 3];
1323 }
1324 def : InstRW<[WriteMMXPACKSSrm], (instregex "MMX_PACKSSDWirm",
1325                                   "MMX_PACKSSWBirm", "MMX_PACKUSWBirm")>;
1326
1327 // VPMOVSX/ZX BW BD BQ DW DQ.
1328 // y <- x.
1329 def WriteVPMOVSX : SchedWriteRes<[HWPort5]> {
1330   let Latency = 3;
1331   let NumMicroOps = 1;
1332 }
1333 def : InstRW<[WriteVPMOVSX], (instregex "VPMOV(SX|ZX)(BW|BQ|DW|DQ)Yrr")>;
1334
1335 // PBLENDW.
1336 // x,x,i / v,v,v,i
1337 def WritePBLENDWr : SchedWriteRes<[HWPort5]>;
1338 def : InstRW<[WritePBLENDWr], (instregex "(V?)PBLENDW(Y?)rri")>;
1339
1340 // x,m,i / v,v,m,i
1341 def WritePBLENDWm : SchedWriteRes<[HWPort5, HWPort23]> {
1342   let NumMicroOps = 2;
1343   let Latency = 4;
1344   let ResourceCycles = [1, 1];
1345 }
1346 def : InstRW<[WritePBLENDWm, ReadAfterLd], (instregex "(V?)PBLENDW(Y?)rmi")>;
1347
1348 // VPBLENDD.
1349 // v,v,v,i.
1350 def WriteVPBLENDDr : SchedWriteRes<[HWPort015]>;
1351 def : InstRW<[WriteVPBLENDDr], (instregex "VPBLENDD(Y?)rri")>;
1352
1353 // v,v,m,i
1354 def WriteVPBLENDDm : SchedWriteRes<[HWPort015, HWPort23]> {
1355   let NumMicroOps = 2;
1356   let Latency = 4;
1357   let ResourceCycles = [1, 1];
1358 }
1359 def : InstRW<[WriteVPBLENDDm, ReadAfterLd], (instregex "VPBLENDD(Y?)rmi")>;
1360
1361 // MASKMOVQ.
1362 def WriteMASKMOVQ : SchedWriteRes<[HWPort0, HWPort4, HWPort23]> {
1363   let Latency = 13;
1364   let NumMicroOps = 4;
1365   let ResourceCycles = [1, 1, 2];
1366 }
1367 def : InstRW<[WriteMASKMOVQ], (instregex "MMX_MASKMOVQ(64)?")>;
1368
1369 // MASKMOVDQU.
1370 def WriteMASKMOVDQU : SchedWriteRes<[HWPort04, HWPort56, HWPort23]> {
1371   let Latency = 14;
1372   let NumMicroOps = 10;
1373   let ResourceCycles = [4, 2, 4];
1374 }
1375 def : InstRW<[WriteMASKMOVDQU], (instregex "(V?)MASKMOVDQU(64)?")>;
1376
1377 // VPMASKMOV D/Q.
1378 // v,v,m.
1379 def WriteVPMASKMOVr : SchedWriteRes<[HWPort5, HWPort23]> {
1380   let Latency = 4;
1381   let NumMicroOps = 3;
1382   let ResourceCycles = [2, 1];
1383 }
1384 def : InstRW<[WriteVPMASKMOVr, ReadAfterLd],
1385                                (instregex "VPMASKMOV(D|Q)(Y?)rm")>;
1386
1387 // m, v,v.
1388 def WriteVPMASKMOVm : SchedWriteRes<[HWPort0, HWPort1, HWPort4, HWPort23]> {
1389   let Latency = 13;
1390   let NumMicroOps = 4;
1391   let ResourceCycles = [1, 1, 1, 1];
1392 }
1393 def : InstRW<[WriteVPMASKMOVm], (instregex "VPMASKMOV(D|Q)(Y?)mr")>;
1394
1395 // PMOVMSKB.
1396 def WritePMOVMSKB : SchedWriteRes<[HWPort0]> {
1397   let Latency = 3;
1398 }
1399 def : InstRW<[WritePMOVMSKB], (instregex "(V|MMX_)?PMOVMSKB(Y?)rr")>;
1400
1401 // PEXTR B/W/D/Q.
1402 // r32,x,i.
1403 def WritePEXTRr : SchedWriteRes<[HWPort0, HWPort5]> {
1404   let Latency = 2;
1405   let NumMicroOps = 2;
1406   let ResourceCycles = [1, 1];
1407 }
1408 def : InstRW<[WritePEXTRr], (instregex "PEXTR(B|W|D|Q)rr", "MMX_PEXTRWirri")>;
1409
1410 // m8,x,i.
1411 def WritePEXTRm : SchedWriteRes<[HWPort23, HWPort4, HWPort5]> {
1412   let NumMicroOps = 3;
1413   let ResourceCycles = [1, 1, 1];
1414 }
1415 def : InstRW<[WritePEXTRm], (instregex "PEXTR(B|W|D|Q)mr")>;
1416
1417 // VPBROADCAST B/W.
1418 // x, m8/16.
1419 def WriteVPBROADCAST128Ld : SchedWriteRes<[HWPort01, HWPort23, HWPort5]> {
1420   let Latency = 5;
1421   let NumMicroOps = 3;
1422   let ResourceCycles = [1, 1, 1];
1423 }
1424 def : InstRW<[WriteVPBROADCAST128Ld, ReadAfterLd],
1425                                      (instregex "VPBROADCAST(B|W)rm")>;
1426
1427 // y, m8/16
1428 def WriteVPBROADCAST256Ld : SchedWriteRes<[HWPort01, HWPort23, HWPort5]> {
1429   let Latency = 7;
1430   let NumMicroOps = 3;
1431   let ResourceCycles = [1, 1, 1];
1432 }
1433 def : InstRW<[WriteVPBROADCAST256Ld, ReadAfterLd],
1434                                      (instregex "VPBROADCAST(B|W)Yrm")>;
1435
1436 // VPGATHERDD.
1437 // x.
1438 def WriteVPGATHERDD128 : SchedWriteRes<[]> {
1439   let NumMicroOps = 20;
1440 }
1441 def : InstRW<[WriteVPGATHERDD128, ReadAfterLd], (instregex "VPGATHERDDrm")>;
1442
1443 // y.
1444 def WriteVPGATHERDD256 : SchedWriteRes<[]> {
1445   let NumMicroOps = 34;
1446 }
1447 def : InstRW<[WriteVPGATHERDD256, ReadAfterLd], (instregex "VPGATHERDDYrm")>;
1448
1449 // VPGATHERQD.
1450 // x.
1451 def WriteVPGATHERQD128 : SchedWriteRes<[]> {
1452   let NumMicroOps = 15;
1453 }
1454 def : InstRW<[WriteVPGATHERQD128, ReadAfterLd], (instregex "VPGATHERQDrm")>;
1455
1456 // y.
1457 def WriteVPGATHERQD256 : SchedWriteRes<[]> {
1458   let NumMicroOps = 22;
1459 }
1460 def : InstRW<[WriteVPGATHERQD256, ReadAfterLd], (instregex "VPGATHERQDYrm")>;
1461
1462 // VPGATHERDQ.
1463 // x.
1464 def WriteVPGATHERDQ128 : SchedWriteRes<[]> {
1465   let NumMicroOps = 12;
1466 }
1467 def : InstRW<[WriteVPGATHERDQ128, ReadAfterLd], (instregex "VPGATHERDQrm")>;
1468
1469 // y.
1470 def WriteVPGATHERDQ256 : SchedWriteRes<[]> {
1471   let NumMicroOps = 20;
1472 }
1473 def : InstRW<[WriteVPGATHERDQ256, ReadAfterLd], (instregex "VPGATHERDQYrm")>;
1474
1475 // VPGATHERQQ.
1476 // x.
1477 def WriteVPGATHERQQ128 : SchedWriteRes<[]> {
1478   let NumMicroOps = 14;
1479 }
1480 def : InstRW<[WriteVPGATHERQQ128, ReadAfterLd], (instregex "VPGATHERQQrm")>;
1481
1482 // y.
1483 def WriteVPGATHERQQ256 : SchedWriteRes<[]> {
1484   let NumMicroOps = 22;
1485 }
1486 def : InstRW<[WriteVPGATHERQQ256, ReadAfterLd], (instregex "VPGATHERQQYrm")>;
1487
1488 //-- Arithmetic instructions --//
1489
1490 // PHADD|PHSUB (S) W/D.
1491 // v <- v,v.
1492 def WritePHADDSUBr : SchedWriteRes<[HWPort1, HWPort5]> {
1493   let Latency = 3;
1494   let NumMicroOps = 3;
1495   let ResourceCycles = [1, 2];
1496 }
1497 def : InstRW<[WritePHADDSUBr], (instregex "MMX_PHADD(W?)rr64",
1498                                "MMX_PHADDSWrr64",
1499                                "MMX_PHSUB(W|D)rr64",
1500                                "MMX_PHSUBSWrr64",
1501                                "(V?)PH(ADD|SUB)(W|D)(Y?)rr",
1502                                "(V?)PH(ADD|SUB)SWrr(256)?")>;
1503
1504 // v <- v,m.
1505 def WritePHADDSUBm : SchedWriteRes<[HWPort1, HWPort5, HWPort23]> {
1506   let Latency = 6;
1507   let NumMicroOps = 3;
1508   let ResourceCycles = [1, 2, 1];
1509 }
1510 def : InstRW<[WritePHADDSUBm, ReadAfterLd],
1511                               (instregex "MMX_PHADD(W?)rm64",
1512                                "MMX_PHADDSWrm64",
1513                                "MMX_PHSUB(W|D)rm64",
1514                                "MMX_PHSUBSWrm64",
1515                                "(V?)PH(ADD|SUB)(W|D)(Y?)rm",
1516                                "(V?)PH(ADD|SUB)SWrm(128|256)?")>;
1517
1518 // PCMPGTQ.
1519 // v <- v,v.
1520 def WritePCMPGTQr : SchedWriteRes<[HWPort0]> {
1521   let Latency = 5;
1522   let NumMicroOps = 1;
1523 }
1524 def : InstRW<[WritePCMPGTQr], (instregex "(V?)PCMPGTQ(Y?)rr")>;
1525
1526 // v <- v,m.
1527 def WritePCMPGTQm : SchedWriteRes<[HWPort0, HWPort23]> {
1528   let Latency = 5;
1529   let NumMicroOps = 2;
1530   let ResourceCycles = [1, 1];
1531 }
1532 def : InstRW<[WritePCMPGTQm, ReadAfterLd], (instregex "(V?)PCMPGTQ(Y?)rm")>;
1533
1534 // PMULLD.
1535 // x,x / y,y,y.
1536 def WritePMULLDr : SchedWriteRes<[HWPort0]> {
1537   let Latency = 10;
1538   let NumMicroOps = 2;
1539   let ResourceCycles = [2];
1540 }
1541 def : InstRW<[WritePMULLDr], (instregex "(V?)PMULLD(Y?)rr")>;
1542
1543 // x,m / y,y,m.
1544 def WritePMULLDm : SchedWriteRes<[HWPort0, HWPort23]> {
1545   let Latency = 10;
1546   let NumMicroOps = 3;
1547   let ResourceCycles = [2, 1];
1548 }
1549 def : InstRW<[WritePMULLDm, ReadAfterLd], (instregex "(V?)PMULLD(Y?)rm")>;
1550
1551 //-- Logic instructions --//
1552
1553 // PTEST.
1554 // v,v.
1555 def WritePTESTr : SchedWriteRes<[HWPort0, HWPort5]> {
1556   let Latency = 2;
1557   let NumMicroOps = 2;
1558   let ResourceCycles = [1, 1];
1559 }
1560 def : InstRW<[WritePTESTr], (instregex "(V?)PTEST(Y?)rr")>;
1561
1562 // v,m.
1563 def WritePTESTm : SchedWriteRes<[HWPort0, HWPort5, HWPort23]> {
1564   let Latency = 6;
1565   let NumMicroOps = 3;
1566   let ResourceCycles = [1, 1, 1];
1567 }
1568 def : InstRW<[WritePTESTr], (instregex "(V?)PTEST(Y?)rm")>;
1569
1570 // PSLL,PSRL,PSRA W/D/Q.
1571 // x,x / v,v,x.
1572 def WritePShift : SchedWriteRes<[HWPort0, HWPort5]> {
1573   let Latency = 2;
1574   let NumMicroOps = 2;
1575   let ResourceCycles = [1, 1];
1576 }
1577 def : InstRW<[WritePShift], (instregex "(V?)PS(LL|RL|RA)(W|D|Q)(Y?)rr")>;
1578
1579 // PSLL,PSRL DQ.
1580 def : InstRW<[WriteP5], (instregex "(V?)PS(R|L)LDQ(Y?)ri")>;
1581
1582 //-- Other --//
1583
1584 // EMMS.
1585 def WriteEMMS : SchedWriteRes<[]> {
1586   let Latency = 13;
1587   let NumMicroOps = 31;
1588 }
1589 def : InstRW<[WriteEMMS], (instregex "MMX_EMMS")>;
1590
1591 //=== Floating Point XMM and YMM Instructions ===//
1592 //-- Move instructions --//
1593
1594 // MOVMSKP S/D.
1595 // r32 <- x.
1596 def WriteMOVMSKPr : SchedWriteRes<[HWPort0]> {
1597   let Latency = 3;
1598 }
1599 def : InstRW<[WriteMOVMSKPr], (instregex "(V?)MOVMSKP(S|D)rr")>;
1600
1601 // r32 <- y.
1602 def WriteVMOVMSKPYr : SchedWriteRes<[HWPort0]> {
1603   let Latency = 2;
1604 }
1605 def : InstRW<[WriteVMOVMSKPYr], (instregex "VMOVMSKP(S|D)Yrr")>;
1606
1607 // VPERM2F128.
1608 def : InstRW<[WriteFShuffle256], (instregex "VPERM2F128rr")>;
1609 def : InstRW<[WriteFShuffle256Ld, ReadAfterLd], (instregex "VPERM2F128rm")>;
1610
1611 // BLENDVP S/D.
1612 def : InstRW<[WriteFVarBlend], (instregex "BLENDVP(S|D)rr0")>;
1613 def : InstRW<[WriteFVarBlendLd, ReadAfterLd], (instregex "BLENDVP(S|D)rm0")>;
1614
1615 // VBROADCASTF128.
1616 def : InstRW<[WriteLoad], (instregex "VBROADCASTF128")>;
1617
1618 // EXTRACTPS.
1619 // r32,x,i.
1620 def WriteEXTRACTPSr : SchedWriteRes<[HWPort0, HWPort5]> {
1621   let NumMicroOps = 2;
1622   let ResourceCycles = [1, 1];
1623 }
1624 def : InstRW<[WriteEXTRACTPSr], (instregex "(V?)EXTRACTPSrr")>;
1625
1626 // m32,x,i.
1627 def WriteEXTRACTPSm : SchedWriteRes<[HWPort0, HWPort5, HWPort23]> {
1628   let Latency = 4;
1629   let NumMicroOps = 3;
1630   let ResourceCycles = [1, 1, 1];
1631 }
1632 def : InstRW<[WriteEXTRACTPSm], (instregex "(V?)EXTRACTPSmr")>;
1633
1634 // VEXTRACTF128.
1635 // x,y,i.
1636 def : InstRW<[WriteFShuffle256], (instregex "VEXTRACTF128rr")>;
1637
1638 // m128,y,i.
1639 def WriteVEXTRACTF128m : SchedWriteRes<[HWPort23, HWPort4]> {
1640   let Latency = 4;
1641   let NumMicroOps = 2;
1642   let ResourceCycles = [1, 1];
1643 }
1644 def : InstRW<[WriteVEXTRACTF128m], (instregex "VEXTRACTF128mr")>;
1645
1646 // VINSERTF128.
1647 // y,y,x,i.
1648 def : InstRW<[WriteFShuffle256], (instregex "VINSERTF128rr")>;
1649
1650 // y,y,m128,i.
1651 def WriteVINSERTF128m : SchedWriteRes<[HWPort015, HWPort23]> {
1652   let Latency = 4;
1653   let NumMicroOps = 2;
1654   let ResourceCycles = [1, 1];
1655 }
1656 def : InstRW<[WriteFShuffle256, ReadAfterLd], (instregex "VINSERTF128rm")>;
1657
1658 // VMASKMOVP S/D.
1659 // v,v,m.
1660 def WriteVMASKMOVPrm : SchedWriteRes<[HWPort5, HWPort23]> {
1661   let Latency = 4;
1662   let NumMicroOps = 3;
1663   let ResourceCycles = [2, 1];
1664 }
1665 def : InstRW<[WriteVMASKMOVPrm], (instregex "VMASKMOVP(S|D)(Y?)rm")>;
1666
1667 // m128,x,x.
1668 def WriteVMASKMOVPmr : SchedWriteRes<[HWPort0, HWPort1, HWPort4, HWPort23]> {
1669   let Latency = 13;
1670   let NumMicroOps = 4;
1671   let ResourceCycles = [1, 1, 1, 1];
1672 }
1673 def : InstRW<[WriteVMASKMOVPmr], (instregex "VMASKMOVP(S|D)mr")>;
1674
1675 // m256,y,y.
1676 def WriteVMASKMOVPYmr : SchedWriteRes<[HWPort0, HWPort1, HWPort4, HWPort23]> {
1677   let Latency = 14;
1678   let NumMicroOps = 4;
1679   let ResourceCycles = [1, 1, 1, 1];
1680 }
1681 def : InstRW<[WriteVMASKMOVPYmr], (instregex "VMASKMOVP(S|D)Ymr")>;
1682
1683 // VGATHERDPS.
1684 // x.
1685 def WriteVGATHERDPS128 : SchedWriteRes<[]> {
1686   let NumMicroOps = 20;
1687 }
1688 def : InstRW<[WriteVGATHERDPS128, ReadAfterLd], (instregex "VGATHERDPSrm")>;
1689
1690 // y.
1691 def WriteVGATHERDPS256 : SchedWriteRes<[]> {
1692   let NumMicroOps = 34;
1693 }
1694 def : InstRW<[WriteVGATHERDPS256, ReadAfterLd], (instregex "VGATHERDPSYrm")>;
1695
1696 // VGATHERQPS.
1697 // x.
1698 def WriteVGATHERQPS128 : SchedWriteRes<[]> {
1699   let NumMicroOps = 15;
1700 }
1701 def : InstRW<[WriteVGATHERQPS128, ReadAfterLd], (instregex "VGATHERQPSrm")>;
1702
1703 // y.
1704 def WriteVGATHERQPS256 : SchedWriteRes<[]> {
1705   let NumMicroOps = 22;
1706 }
1707 def : InstRW<[WriteVGATHERQPS256, ReadAfterLd], (instregex "VGATHERQPSYrm")>;
1708
1709 // VGATHERDPD.
1710 // x.
1711 def WriteVGATHERDPD128 : SchedWriteRes<[]> {
1712   let NumMicroOps = 12;
1713 }
1714 def : InstRW<[WriteVGATHERDPD128, ReadAfterLd], (instregex "VGATHERDPDrm")>;
1715
1716 // y.
1717 def WriteVGATHERDPD256 : SchedWriteRes<[]> {
1718   let NumMicroOps = 20;
1719 }
1720 def : InstRW<[WriteVGATHERDPD256, ReadAfterLd], (instregex "VGATHERDPDYrm")>;
1721
1722 // VGATHERQPD.
1723 // x.
1724 def WriteVGATHERQPD128 : SchedWriteRes<[]> {
1725   let NumMicroOps = 14;
1726 }
1727 def : InstRW<[WriteVGATHERQPD128, ReadAfterLd], (instregex "VGATHERQPDrm")>;
1728
1729 // y.
1730 def WriteVGATHERQPD256 : SchedWriteRes<[]> {
1731   let NumMicroOps = 22;
1732 }
1733 def : InstRW<[WriteVGATHERQPD256, ReadAfterLd], (instregex "VGATHERQPDYrm")>;
1734
1735 //-- Conversion instructions --//
1736
1737 // CVTPD2PS.
1738 // x,x.
1739 def : InstRW<[WriteP1_P5_Lat4], (instregex "(V?)CVTPD2PSrr")>;
1740
1741 // x,m128.
1742 def : InstRW<[WriteP1_P5_Lat4Ld], (instregex "(V?)CVTPD2PS(X?)rm")>;
1743
1744 // x,y.
1745 def WriteCVTPD2PSYrr : SchedWriteRes<[HWPort1, HWPort5]> {
1746   let Latency = 5;
1747   let NumMicroOps = 2;
1748   let ResourceCycles = [1, 1];
1749 }
1750 def : InstRW<[WriteCVTPD2PSYrr], (instregex "(V?)CVTPD2PSYrr")>;
1751
1752 // x,m256.
1753 def WriteCVTPD2PSYrm : SchedWriteRes<[HWPort1, HWPort5, HWPort23]> {
1754   let Latency = 9;
1755   let NumMicroOps = 3;
1756   let ResourceCycles = [1, 1, 1];
1757 }
1758 def : InstRW<[WriteCVTPD2PSYrm], (instregex "(V?)CVTPD2PSYrm")>;
1759
1760 // CVTSD2SS.
1761 // x,x.
1762 def : InstRW<[WriteP1_P5_Lat4], (instregex "(Int_)?(V)?CVTSD2SSrr")>;
1763
1764 // x,m64.
1765 def : InstRW<[WriteP1_P5_Lat4Ld], (instregex "(Int_)?(V)?CVTSD2SSrm")>;
1766
1767 // CVTPS2PD.
1768 // x,x.
1769 def WriteCVTPS2PDrr : SchedWriteRes<[HWPort0, HWPort5]> {
1770   let Latency = 2;
1771   let NumMicroOps = 2;
1772   let ResourceCycles = [1, 1];
1773 }
1774 def : InstRW<[WriteCVTPS2PDrr], (instregex "(V?)CVTPS2PDrr")>;
1775
1776 // x,m64.
1777 // y,m128.
1778 def WriteCVTPS2PDrm : SchedWriteRes<[HWPort0, HWPort23]> {
1779   let Latency = 5;
1780   let NumMicroOps = 2;
1781   let ResourceCycles = [1, 1];
1782 }
1783 def : InstRW<[WriteCVTPS2PDrm], (instregex "(V?)CVTPS2PD(Y?)rm")>;
1784
1785 // y,x.
1786 def WriteVCVTPS2PDYrr : SchedWriteRes<[HWPort0, HWPort5]> {
1787   let Latency = 5;
1788   let NumMicroOps = 2;
1789   let ResourceCycles = [1, 1];
1790 }
1791 def : InstRW<[WriteVCVTPS2PDYrr], (instregex "VCVTPS2PDYrr")>;
1792
1793 // CVTSS2SD.
1794 // x,x.
1795 def WriteCVTSS2SDrr : SchedWriteRes<[HWPort0, HWPort5]> {
1796   let Latency = 2;
1797   let NumMicroOps = 2;
1798   let ResourceCycles = [1, 1];
1799 }
1800 def : InstRW<[WriteCVTSS2SDrr], (instregex "(Int_)?(V?)CVTSS2SDrr")>;
1801
1802 // x,m32.
1803 def WriteCVTSS2SDrm : SchedWriteRes<[HWPort0, HWPort23]> {
1804   let Latency = 5;
1805   let NumMicroOps = 2;
1806   let ResourceCycles = [1, 1];
1807 }
1808 def : InstRW<[WriteCVTSS2SDrm], (instregex "(Int_)?(V?)CVTSS2SDrm")>;
1809
1810 // CVTDQ2PD.
1811 // x,x.
1812 def : InstRW<[WriteP1_P5_Lat4], (instregex "(V)?CVTDQ2PDrr")>;
1813
1814 // y,x.
1815 def : InstRW<[WriteP1_P5_Lat6], (instregex "VCVTDQ2PDYrr")>;
1816
1817 // CVT(T)PD2DQ.
1818 // x,x.
1819 def : InstRW<[WriteP1_P5_Lat4], (instregex "(V?)CVT(T?)PD2DQrr")>;
1820 // x,m128.
1821 def : InstRW<[WriteP1_P5_Lat4Ld], (instregex "(V?)CVT(T?)PD2DQrm")>;
1822 // x,y.
1823 def : InstRW<[WriteP1_P5_Lat6], (instregex "VCVT(T?)PD2DQYrr")>;
1824 // x,m256.
1825 def : InstRW<[WriteP1_P5_Lat6Ld], (instregex "VCVT(T?)PD2DQYrm")>;
1826
1827 // CVT(T)PS2PI.
1828 // mm,x.
1829 def : InstRW<[WriteP1_P5_Lat4], (instregex "MMX_CVT(T?)PS2PIirr")>;
1830
1831 // CVTPI2PD.
1832 // x,mm.
1833 def : InstRW<[WriteP1_P5_Lat4], (instregex "MMX_CVT(T?)PI2PDirr")>;
1834
1835 // CVT(T)PD2PI.
1836 // mm,x.
1837 def : InstRW<[WriteP1_P5_Lat4], (instregex "MMX_CVT(T?)PD2PIirr")>;
1838
1839 // CVSTSI2SS.
1840 // x,r32.
1841 def : InstRW<[WriteP1_P5_Lat4], (instregex "(Int_)?(V?)CVT(T?)SI2SS(64)?rr")>;
1842
1843 // CVT(T)SS2SI.
1844 // r32,x.
1845 def : InstRW<[WriteP0_P1_Lat4], (instregex "(Int_)?(V?)CVT(T?)SS2SI(64)?rr")>;
1846 // r32,m32.
1847 def : InstRW<[WriteP0_P1_Lat4Ld], (instregex "(Int_)?(V?)CVT(T?)SS2SI(64)?rm")>;
1848
1849 // CVTSI2SD.
1850 // x,r32/64.
1851 def : InstRW<[WriteP0_P1_Lat4], (instregex "(Int_)?(V?)CVTSI2SS(64)?rr")>;
1852
1853 // CVTSD2SI.
1854 // r32/64
1855 def : InstRW<[WriteP0_P1_Lat4], (instregex "(Int_)?(V?)CVT(T?)SD2SI(64)?rr")>;
1856 // r32,m32.
1857 def : InstRW<[WriteP0_P1_Lat4Ld], (instregex "(Int_)?(V?)CVT(T?)SD2SI(64)?rm")>;
1858
1859 // VCVTPS2PH.
1860 // x,v,i.
1861 def : InstRW<[WriteP1_P5_Lat4], (instregex "VCVTPS2PH(Y?)rr")>;
1862 // m,v,i.
1863 def : InstRW<[WriteP1_P5_Lat4Ld, WriteRMW], (instregex "VCVTPS2PH(Y?)mr")>;
1864
1865 // VCVTPH2PS.
1866 // v,x.
1867 def : InstRW<[WriteP1_P5_Lat4], (instregex "VCVTPH2PS(Y?)rr")>;
1868
1869 //-- Arithmetic instructions --//
1870
1871 // HADD, HSUB PS/PD
1872 // x,x / v,v,v.
1873 def WriteHADDSUBPr : SchedWriteRes<[HWPort1, HWPort5]> {
1874   let Latency = 5;
1875   let NumMicroOps = 3;
1876   let ResourceCycles = [1, 2];
1877 }
1878 def : InstRW<[WriteHADDSUBPr], (instregex "(V?)H(ADD|SUB)P(S|D)(Y?)rr")>;
1879
1880 // x,m / v,v,m.
1881 def WriteHADDSUBPm : SchedWriteRes<[HWPort1, HWPort5, HWPort23]> {
1882   let Latency = 9;
1883   let NumMicroOps = 4;
1884   let ResourceCycles = [1, 2, 1];
1885 }
1886 def : InstRW<[WriteHADDSUBPm], (instregex "(V?)H(ADD|SUB)P(S|D)(Y?)rm")>;
1887
1888 // MULL SS/SD PS/PD.
1889 // x,x / v,v,v.
1890 def WriteMULr : SchedWriteRes<[HWPort01]> {
1891   let Latency = 5;
1892 }
1893 def : InstRW<[WriteMULr], (instregex "(V?)MUL(P|S)(S|D)rr")>;
1894
1895 // x,m / v,v,m.
1896 def WriteMULm : SchedWriteRes<[HWPort01, HWPort23]> {
1897   let Latency = 4;
1898   let NumMicroOps = 2;
1899   let ResourceCycles = [1, 1];
1900 }
1901 def : InstRW<[WriteMULm], (instregex "(V?)MUL(P|S)(S|D)rm")>;
1902
1903 // VDIVPS.
1904 // y,y,y.
1905 def WriteVDIVPSYrr : SchedWriteRes<[HWPort0, HWPort15]> {
1906   let Latency = 19; // 18-21 cycles.
1907   let NumMicroOps = 3;
1908   let ResourceCycles = [2, 1];
1909 }
1910 def : InstRW<[WriteVDIVPSYrr], (instregex "VDIVPSYrr")>;
1911
1912 // y,y,m256.
1913 def WriteVDIVPSYrm : SchedWriteRes<[HWPort0, HWPort15, HWPort23]> {
1914   let Latency = 23; // 18-21 + 4 cycles.
1915   let NumMicroOps = 4;
1916   let ResourceCycles = [2, 1, 1];
1917 }
1918 def : InstRW<[WriteVDIVPSYrm, ReadAfterLd], (instregex "VDIVPSYrm")>;
1919
1920 // VDIVPD.
1921 // y,y,y.
1922 def WriteVDIVPDYrr : SchedWriteRes<[HWPort0, HWPort15]> {
1923   let Latency = 27; // 19-35 cycles.
1924   let NumMicroOps = 3;
1925   let ResourceCycles = [2, 1];
1926 }
1927 def : InstRW<[WriteVDIVPDYrr], (instregex "VDIVPDYrr")>;
1928
1929 // y,y,m256.
1930 def WriteVDIVPDYrm : SchedWriteRes<[HWPort0, HWPort15, HWPort23]> {
1931   let Latency = 31; // 19-35 + 4 cycles.
1932   let NumMicroOps = 4;
1933   let ResourceCycles = [2, 1, 1];
1934 }
1935 def : InstRW<[WriteVDIVPDYrm, ReadAfterLd], (instregex "VDIVPDYrm")>;
1936
1937 // VRCPPS.
1938 // y,y.
1939 def WriteVRCPPSr : SchedWriteRes<[HWPort0, HWPort15]> {
1940   let Latency = 7;
1941   let NumMicroOps = 3;
1942   let ResourceCycles = [2, 1];
1943 }
1944 def : InstRW<[WriteVRCPPSr], (instregex "VRCPPSYr(_Int)?")>;
1945
1946 // y,m256.
1947 def WriteVRCPPSm : SchedWriteRes<[HWPort0, HWPort15, HWPort23]> {
1948   let Latency = 11;
1949   let NumMicroOps = 4;
1950   let ResourceCycles = [2, 1, 1];
1951 }
1952 def : InstRW<[WriteVRCPPSm], (instregex "VRCPPSYm(_Int)?")>;
1953
1954 // ROUND SS/SD PS/PD.
1955 // v,v,i.
1956 def WriteROUNDr : SchedWriteRes<[HWPort1]> {
1957   let Latency = 6;
1958   let NumMicroOps = 2;
1959   let ResourceCycles = [2];
1960 }
1961 def : InstRW<[WriteROUNDr], (instregex "(V?)ROUND(Y?)(S|P)(S|D)r(_Int)?")>;
1962
1963 // v,m,i.
1964 def WriteROUNDm : SchedWriteRes<[HWPort1, HWPort23]> {
1965   let Latency = 10;
1966   let NumMicroOps = 3;
1967   let ResourceCycles = [2, 1];
1968 }
1969 def : InstRW<[WriteROUNDm], (instregex "(V?)ROUND(Y?)(S|P)(S|D)m(_Int)?")>;
1970
1971 // DPPS.
1972 // x,x,i / v,v,v,i.
1973 def WriteDPPSr : SchedWriteRes<[HWPort0, HWPort1, HWPort5]> {
1974   let Latency = 14;
1975   let NumMicroOps = 4;
1976   let ResourceCycles = [2, 1, 1];
1977 }
1978 def : InstRW<[WriteDPPSr], (instregex "(V?)DPPS(Y?)rri")>;
1979
1980 // x,m,i / v,v,m,i.
1981 def WriteDPPSm : SchedWriteRes<[HWPort0, HWPort1, HWPort5, HWPort23, HWPort6]> {
1982   let Latency = 18;
1983   let NumMicroOps = 6;
1984   let ResourceCycles = [2, 1, 1, 1, 1];
1985 }
1986 def : InstRW<[WriteDPPSm, ReadAfterLd], (instregex "(V?)DPPS(Y?)rmi")>;
1987
1988 // DPPD.
1989 // x,x,i.
1990 def WriteDPPDr : SchedWriteRes<[HWPort0, HWPort1, HWPort5]> {
1991   let Latency = 9;
1992   let NumMicroOps = 3;
1993   let ResourceCycles = [1, 1, 1];
1994 }
1995 def : InstRW<[WriteDPPDr], (instregex "(V?)DPPDrri")>;
1996
1997 // x,m,i.
1998 def WriteDPPDm : SchedWriteRes<[HWPort0, HWPort1, HWPort5, HWPort23]> {
1999   let Latency = 13;
2000   let NumMicroOps = 4;
2001   let ResourceCycles = [1, 1, 1, 1];
2002 }
2003 def : InstRW<[WriteDPPDm], (instregex "(V?)DPPDrmi")>;
2004
2005 // VFMADD.
2006 // v,v,v.
2007 def WriteFMADDr : SchedWriteRes<[HWPort01]> {
2008   let Latency = 5;
2009   let NumMicroOps = 1;
2010 }
2011 def : InstRW<[WriteFMADDr],
2012     (instregex
2013     // 3p forms.
2014     "VF(N?)M(ADD|SUB|ADDSUB|SUBADD)P(S|D)(r213|r132|r231)r(Y)?",
2015     // 3s forms.
2016     "VF(N?)M(ADD|SUB)S(S|D)(r132|231|213)r",
2017     // 4s/4s_int forms.
2018     "VF(N?)M(ADD|SUB)S(S|D)4rr(_REV|_Int)?",
2019     // 4p forms.
2020     "VF(N?)M(ADD|SUB)P(S|D)4rr(Y)?(_REV)?")>;
2021
2022 // v,v,m.
2023 def WriteFMADDm : SchedWriteRes<[HWPort01, HWPort23]> {
2024   let Latency = 9;
2025   let NumMicroOps = 2;
2026   let ResourceCycles = [1, 1];
2027 }
2028 def : InstRW<[WriteFMADDm],
2029     (instregex
2030     // 3p forms.
2031     "VF(N?)M(ADD|SUB|ADDSUB|SUBADD)P(S|D)(r213|r132|r231)m(Y)?",
2032     // 3s forms.
2033     "VF(N?)M(ADD|SUB)S(S|D)(r132|231|213)m",
2034     // 4s/4s_int forms.
2035     "VF(N?)M(ADD|SUB)S(S|D)4(rm|mr)(_Int)?",
2036     // 4p forms.
2037     "VF(N?)M(ADD|SUB)P(S|D)4(rm|mr)(Y)?")>;
2038
2039 //-- Math instructions --//
2040
2041 // VSQRTPS.
2042 // y,y.
2043 def WriteVSQRTPSYr : SchedWriteRes<[HWPort0, HWPort15]> {
2044   let Latency = 19;
2045   let NumMicroOps = 3;
2046   let ResourceCycles = [2, 1];
2047 }
2048 def : InstRW<[WriteVSQRTPSYr], (instregex "VSQRTPSYr")>;
2049
2050 // y,m256.
2051 def WriteVSQRTPSYm : SchedWriteRes<[HWPort0, HWPort15, HWPort23]> {
2052   let Latency = 23;
2053   let NumMicroOps = 4;
2054   let ResourceCycles = [2, 1, 1];
2055 }
2056 def : InstRW<[WriteVSQRTPSYm], (instregex "VSQRTPSYm")>;
2057
2058 // VSQRTPD.
2059 // y,y.
2060 def WriteVSQRTPDYr : SchedWriteRes<[HWPort0, HWPort15]> {
2061   let Latency = 28;
2062   let NumMicroOps = 3;
2063   let ResourceCycles = [2, 1];
2064 }
2065 def : InstRW<[WriteVSQRTPDYr], (instregex "VSQRTPDYr")>;
2066
2067 // y,m256.
2068 def WriteVSQRTPDYm : SchedWriteRes<[HWPort0, HWPort15, HWPort23]> {
2069   let Latency = 32;
2070   let NumMicroOps = 4;
2071   let ResourceCycles = [2, 1, 1];
2072 }
2073 def : InstRW<[WriteVSQRTPDYm], (instregex "VSQRTPDYm")>;
2074
2075 // RSQRT SS/PS.
2076 // x,x.
2077 def WriteRSQRTr : SchedWriteRes<[HWPort0]> {
2078   let Latency = 5;
2079 }
2080 def : InstRW<[WriteRSQRTr], (instregex "(V?)RSQRT(SS|PS)r(_Int)?")>;
2081
2082 // x,m128.
2083 def WriteRSQRTm : SchedWriteRes<[HWPort0, HWPort23]> {
2084   let Latency = 9;
2085   let NumMicroOps = 2;
2086   let ResourceCycles = [1, 1];
2087 }
2088 def : InstRW<[WriteRSQRTm], (instregex "(V?)RSQRT(SS|PS)m(_Int)?")>;
2089
2090 // RSQRTPS 256.
2091 // y,y.
2092 def WriteRSQRTPSYr : SchedWriteRes<[HWPort0, HWPort15]> {
2093   let Latency = 7;
2094   let NumMicroOps = 3;
2095   let ResourceCycles = [2, 1];
2096 }
2097 def : InstRW<[WriteRSQRTPSYr], (instregex "VRSQRTPSYr(_Int)?")>;
2098
2099 // y,m256.
2100 def WriteRSQRTPSYm : SchedWriteRes<[HWPort0, HWPort15, HWPort23]> {
2101   let Latency = 11;
2102   let NumMicroOps = 4;
2103   let ResourceCycles = [2, 1, 1];
2104 }
2105 def : InstRW<[WriteRSQRTPSYm], (instregex "VRSQRTPSYm(_Int)?")>;
2106
2107 //-- Logic instructions --//
2108
2109 // AND, ANDN, OR, XOR PS/PD.
2110 // x,x / v,v,v.
2111 def : InstRW<[WriteP5], (instregex "(V?)(AND|ANDN|OR|XOR)P(S|D)(Y?)rr")>;
2112 // x,m / v,v,m.
2113 def : InstRW<[WriteP5Ld, ReadAfterLd],
2114                          (instregex "(V?)(AND|ANDN|OR|XOR)P(S|D)(Y?)rm")>;
2115
2116 //-- Other instructions --//
2117
2118 // VZEROUPPER.
2119 def WriteVZEROUPPER : SchedWriteRes<[]> {
2120   let NumMicroOps = 4;
2121 }
2122 def : InstRW<[WriteVZEROUPPER], (instregex "VZEROUPPER")>;
2123
2124 // VZEROALL.
2125 def WriteVZEROALL : SchedWriteRes<[]> {
2126   let NumMicroOps = 12;
2127 }
2128 def : InstRW<[WriteVZEROALL], (instregex "VZEROALL")>;
2129
2130 // LDMXCSR.
2131 def WriteLDMXCSR : SchedWriteRes<[HWPort0, HWPort6, HWPort23]> {
2132   let Latency = 6;
2133   let NumMicroOps = 3;
2134   let ResourceCycles = [1, 1, 1];
2135 }
2136 def : InstRW<[WriteLDMXCSR], (instregex "(V)?LDMXCSR")>;
2137
2138 // STMXCSR.
2139 def WriteSTMXCSR : SchedWriteRes<[HWPort0, HWPort4, HWPort6, HWPort237]> {
2140   let Latency = 7;
2141   let NumMicroOps = 4;
2142   let ResourceCycles = [1, 1, 1, 1];
2143 }
2144 def : InstRW<[WriteSTMXCSR], (instregex "(V)?STMXCSR")>;
2145
2146 } // SchedModel