]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/X86/X86ScheduleBtVer2.td
Merge ACPICA 20180810.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / X86 / X86ScheduleBtVer2.td
1 //=- X86ScheduleBtVer2.td - X86 BtVer2 (Jaguar) Scheduling ---*- tablegen -*-=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the machine model for AMD btver2 (Jaguar) to support
11 // instruction scheduling and other instruction cost heuristics. Based off AMD Software
12 // Optimization Guide for AMD Family 16h Processors & Instruction Latency appendix.
13 //
14 //===----------------------------------------------------------------------===//
15
16 def BtVer2Model : SchedMachineModel {
17   // All x86 instructions are modeled as a single micro-op, and btver2 can
18   // decode 2 instructions per cycle.
19   let IssueWidth = 2;
20   let MicroOpBufferSize = 64; // Retire Control Unit
21   let LoadLatency = 5; // FPU latency (worse case cf Integer 3 cycle latency)
22   let HighLatency = 25;
23   let MispredictPenalty = 14; // Minimum branch misdirection penalty
24   let PostRAScheduler = 1;
25
26   // FIXME: SSE4/AVX is unimplemented. This flag is set to allow
27   // the scheduler to assign a default model to unrecognized opcodes.
28   let CompleteModel = 0;
29 }
30
31 let SchedModel = BtVer2Model in {
32
33 // Jaguar can issue up to 6 micro-ops in one cycle
34 def JALU0 : ProcResource<1>; // Integer Pipe0: integer ALU0 (also handle FP->INT jam)
35 def JALU1 : ProcResource<1>; // Integer Pipe1: integer ALU1/MUL/DIV
36 def JLAGU : ProcResource<1>; // Integer Pipe2: LAGU
37 def JSAGU : ProcResource<1>; // Integer Pipe3: SAGU (also handles 3-operand LEA)
38 def JFPU0 : ProcResource<1>; // Vector/FPU Pipe0: VALU0/VIMUL/FPA
39 def JFPU1 : ProcResource<1>; // Vector/FPU Pipe1: VALU1/STC/FPM
40
41 // Any pipe - FIXME we need this until we can discriminate between int/fpu load/store/moves properly
42 def JAny : ProcResGroup<[JALU0, JALU1, JLAGU, JSAGU, JFPU0, JFPU1]>;
43
44 // Integer Pipe Scheduler
45 def JALU01 : ProcResGroup<[JALU0, JALU1]> {
46   let BufferSize=20;
47 }
48
49 // AGU Pipe Scheduler
50 def JLSAGU : ProcResGroup<[JLAGU, JSAGU]> {
51   let BufferSize=12;
52 }
53
54 // Fpu Pipe Scheduler
55 def JFPU01 : ProcResGroup<[JFPU0, JFPU1]> {
56   let BufferSize=18;
57 }
58
59 def JDiv    : ProcResource<1>; // integer division
60 def JMul    : ProcResource<1>; // integer multiplication
61 def JVALU0  : ProcResource<1>; // vector integer
62 def JVALU1  : ProcResource<1>; // vector integer
63 def JVIMUL  : ProcResource<1>; // vector integer multiplication
64 def JSTC    : ProcResource<1>; // vector store/convert
65 def JFPM    : ProcResource<1>; // FP multiplication
66 def JFPA    : ProcResource<1>; // FP addition
67
68 // Integer loads are 3 cycles, so ReadAfterLd registers needn't be available until 3
69 // cycles after the memory operand.
70 def : ReadAdvance<ReadAfterLd, 3>;
71
72 // Many SchedWrites are defined in pairs with and without a folded load.
73 // Instructions with folded loads are usually micro-fused, so they only appear
74 // as two micro-ops when dispatched by the schedulers.
75 // This multiclass defines the resource usage for variants with and without
76 // folded loads.
77 multiclass JWriteResIntPair<X86FoldableSchedWrite SchedRW,
78                           ProcResourceKind ExePort,
79                           int Lat> {
80   // Register variant is using a single cycle on ExePort.
81   def : WriteRes<SchedRW, [ExePort]> { let Latency = Lat; }
82
83   // Memory variant also uses a cycle on JLAGU and adds 3 cycles to the
84   // latency.
85   def : WriteRes<SchedRW.Folded, [JLAGU, ExePort]> {
86      let Latency = !add(Lat, 3);
87   }
88 }
89
90 multiclass JWriteResFpuPair<X86FoldableSchedWrite SchedRW,
91                           ProcResourceKind ExePort,
92                           int Lat> {
93   // Register variant is using a single cycle on ExePort.
94   def : WriteRes<SchedRW, [ExePort]> { let Latency = Lat; }
95
96   // Memory variant also uses a cycle on JLAGU and adds 5 cycles to the
97   // latency.
98   def : WriteRes<SchedRW.Folded, [JLAGU, ExePort]> {
99      let Latency = !add(Lat, 5);
100   }
101 }
102
103 // A folded store needs a cycle on the SAGU for the store data.
104 def : WriteRes<WriteRMW, [JSAGU]>;
105
106 ////////////////////////////////////////////////////////////////////////////////
107 // Arithmetic.
108 ////////////////////////////////////////////////////////////////////////////////
109
110 defm : JWriteResIntPair<WriteALU,   JALU01, 1>;
111 defm : JWriteResIntPair<WriteIMul,  JALU1,  3>;
112
113 def  : WriteRes<WriteIMulH, [JALU1]> {
114   let Latency = 6;
115   let ResourceCycles = [4];
116 }
117
118 // FIXME 8/16 bit divisions
119 def : WriteRes<WriteIDiv, [JALU1, JDiv]> {
120   let Latency = 25;
121   let ResourceCycles = [1, 25];
122 }
123 def : WriteRes<WriteIDivLd, [JALU1, JLAGU, JDiv]> {
124   let Latency = 41;
125   let ResourceCycles = [1, 1, 25];
126 }
127
128 // This is for simple LEAs with one or two input operands.
129 // FIXME: SAGU 3-operand LEA
130 def : WriteRes<WriteLEA, [JALU01]>;
131
132 ////////////////////////////////////////////////////////////////////////////////
133 // Integer shifts and rotates.
134 ////////////////////////////////////////////////////////////////////////////////
135
136 defm : JWriteResIntPair<WriteShift, JALU01, 1>;
137
138 def WriteSHLDrri : SchedWriteRes<[JALU01]> {
139   let Latency = 3;
140   let ResourceCycles = [6];
141   let NumMicroOps = 6;
142 }
143 def: InstRW<[WriteSHLDrri], (instregex "SHLD(16|32|64)rri8")>;
144 def: InstRW<[WriteSHLDrri], (instregex "SHRD(16|32|64)rri8")>;
145
146 def WriteSHLDrrCL : SchedWriteRes<[JALU01]> {
147   let Latency = 4;
148   let ResourceCycles = [8];
149   let NumMicroOps = 7;
150 }
151 def: InstRW<[WriteSHLDrrCL], (instregex "SHLD(16|32|64)rrCL")>;
152 def: InstRW<[WriteSHLDrrCL], (instregex "SHRD(16|32|64)rrCL")>;
153
154 def WriteSHLDm : SchedWriteRes<[JLAGU, JALU01]> {
155   let Latency = 9;
156   let ResourceCycles = [1, 22];
157   let NumMicroOps = 8;
158 }
159 def: InstRW<[WriteSHLDm], (instregex "SHLD(16|32|64)mr(i8|CL)")>;
160 def: InstRW<[WriteSHLDm], (instregex "SHRD(16|32|64)mr(i8|CL)")>;
161
162 ////////////////////////////////////////////////////////////////////////////////
163 // Loads, stores, and moves, not folded with other operations.
164 // FIXME: Split x86 and SSE load/store/moves
165 ////////////////////////////////////////////////////////////////////////////////
166
167 def : WriteRes<WriteLoad,  [JLAGU]> { let Latency = 5; }
168 def : WriteRes<WriteStore, [JSAGU]>;
169 def : WriteRes<WriteMove,  [JALU01]>;
170
171 // Treat misc copies as a move.
172 def : InstRW<[WriteMove], (instrs COPY)>;
173
174 ////////////////////////////////////////////////////////////////////////////////
175 // Idioms that clear a register, like xorps %xmm0, %xmm0.
176 // These can often bypass execution ports completely.
177 ////////////////////////////////////////////////////////////////////////////////
178
179 def : WriteRes<WriteZero,  []>;
180
181 ////////////////////////////////////////////////////////////////////////////////
182 // Branches don't produce values, so they have no latency, but they still
183 // consume resources. Indirect branches can fold loads.
184 ////////////////////////////////////////////////////////////////////////////////
185
186 defm : JWriteResIntPair<WriteJump,  JALU01, 1>;
187
188 ////////////////////////////////////////////////////////////////////////////////
189 // Floating point. This covers both scalar and vector operations.
190 // FIXME: should we bother splitting JFPU pipe + unit stages for fast instructions?
191 // FIXME: Double precision latencies
192 // FIXME: SS vs PS latencies
193 // FIXME: ymm latencies
194 ////////////////////////////////////////////////////////////////////////////////
195
196 defm : JWriteResFpuPair<WriteFAdd,        JFPU0,  3>;
197 defm : JWriteResFpuPair<WriteFMul,        JFPU1,  2>;
198 defm : JWriteResFpuPair<WriteFMA,         JFPU1,  2>; // NOTE: Doesn't exist on Jaguar.
199 defm : JWriteResFpuPair<WriteFRcp,        JFPU1,  2>;
200 defm : JWriteResFpuPair<WriteFRsqrt,      JFPU1,  2>;
201 defm : JWriteResFpuPair<WriteFShuffle,   JFPU01,  1>;
202 defm : JWriteResFpuPair<WriteFBlend,     JFPU01,  1>;
203 defm : JWriteResFpuPair<WriteFShuffle256, JFPU01, 1>;
204
205 def : WriteRes<WriteFSqrt, [JFPU1, JLAGU, JFPM]> {
206   let Latency = 21;
207   let ResourceCycles = [1, 1, 21];
208 }
209 def : WriteRes<WriteFSqrtLd, [JFPU1, JLAGU, JFPM]> {
210   let Latency = 26;
211   let ResourceCycles = [1, 1, 21];
212 }
213
214 def : WriteRes<WriteFDiv, [JFPU1, JLAGU, JFPM]> {
215   let Latency = 19;
216   let ResourceCycles = [1, 1, 19];
217 }
218 def : WriteRes<WriteFDivLd, [JFPU1, JLAGU, JFPM]> {
219   let Latency = 24;
220   let ResourceCycles = [1, 1, 19];
221 }
222
223 // FIXME: integer pipes
224 defm : JWriteResFpuPair<WriteCvtF2I,    JFPU1,  3>; // Float -> Integer.
225 defm : JWriteResFpuPair<WriteCvtI2F,    JFPU1,  3>; // Integer -> Float.
226 defm : JWriteResFpuPair<WriteCvtF2F,    JFPU1,  3>; // Float -> Float size conversion.
227
228 def : WriteRes<WriteFVarBlend, [JFPU01]> {
229   let Latency = 2;
230   let ResourceCycles = [4];
231   let NumMicroOps = 3;
232 }
233 def : WriteRes<WriteFVarBlendLd, [JLAGU, JFPU01]> {
234   let Latency = 7;
235   let ResourceCycles = [1, 4];
236   let NumMicroOps = 3;
237 }
238
239 // Vector integer operations.
240 defm : JWriteResFpuPair<WriteVecALU,   JFPU01,  1>;
241 defm : JWriteResFpuPair<WriteVecShift, JFPU01,  1>;
242 defm : JWriteResFpuPair<WriteVecIMul,  JFPU0,   2>;
243 defm : JWriteResFpuPair<WriteShuffle,  JFPU01,  1>;
244 defm : JWriteResFpuPair<WriteBlend,    JFPU01,  1>;
245 defm : JWriteResFpuPair<WriteVecLogic, JFPU01,  1>;
246 defm : JWriteResFpuPair<WriteShuffle256, JFPU01, 1>;
247
248 def : WriteRes<WriteVarBlend, [JFPU01]> {
249   let Latency = 2;
250   let ResourceCycles = [4];
251   let NumMicroOps = 3;
252 }
253 def : WriteRes<WriteVarBlendLd, [JLAGU, JFPU01]> {
254   let Latency = 7;
255   let ResourceCycles = [1, 4];
256   let NumMicroOps = 3;
257 }
258
259 // FIXME: why do we need to define AVX2 resource on CPU that doesn't have AVX2?
260 def : WriteRes<WriteVarVecShift, [JFPU01]> {}
261 def : WriteRes<WriteVarVecShiftLd, [JLAGU, JFPU01]> {
262   let Latency = 6;
263   let ResourceCycles = [1, 2];
264 }
265
266 def : WriteRes<WriteMPSAD, [JFPU0]> {
267   let Latency = 3;
268   let ResourceCycles = [2];
269 }
270 def : WriteRes<WriteMPSADLd, [JLAGU, JFPU0]> {
271   let Latency = 8;
272   let ResourceCycles = [1, 2];
273 }
274
275 ////////////////////////////////////////////////////////////////////////////////
276 // String instructions.
277 // Packed Compare Implicit Length Strings, Return Mask
278 // FIXME: approximate latencies + pipe dependencies
279 ////////////////////////////////////////////////////////////////////////////////
280
281 def : WriteRes<WritePCmpIStrM, [JFPU1,JFPU0]> {
282   let Latency = 8;
283   let ResourceCycles = [2, 2];
284   let NumMicroOps = 3;
285 }
286 def : WriteRes<WritePCmpIStrMLd, [JLAGU, JFPU1, JFPU0]> {
287   let Latency = 13;
288   let ResourceCycles = [1, 2, 2];
289   let NumMicroOps = 3;
290 }
291
292 // Packed Compare Explicit Length Strings, Return Mask
293 def : WriteRes<WritePCmpEStrM, [JFPU1, JLAGU, JFPU01,JFPU1, JFPU0]> {
294   let Latency = 14;
295   let ResourceCycles = [5, 5, 5, 5, 5];
296   let NumMicroOps = 9;
297 }
298 def : WriteRes<WritePCmpEStrMLd, [JLAGU, JFPU1, JLAGU, JFPU01,JFPU1, JFPU0]> {
299   let Latency = 19;
300   let ResourceCycles = [1, 5, 5, 5, 5, 5];
301   let NumMicroOps = 9;
302 }
303
304 // Packed Compare Implicit Length Strings, Return Index
305 def : WriteRes<WritePCmpIStrI, [JFPU1, JFPU0]> {
306   let Latency = 7;
307   let ResourceCycles = [2, 2];
308 }
309 def : WriteRes<WritePCmpIStrILd, [JLAGU, JFPU1, JFPU0]> {
310   let Latency = 12;
311   let ResourceCycles = [1, 2, 2];
312 }
313
314 // Packed Compare Explicit Length Strings, Return Index
315 def : WriteRes<WritePCmpEStrI, [JFPU1, JLAGU, JFPU01,JFPU1, JFPU0]> {
316   let Latency = 14;
317   let ResourceCycles = [5, 5, 5, 5, 5];
318   let NumMicroOps = 9;
319 }
320 def : WriteRes<WritePCmpEStrILd, [JLAGU, JFPU1, JLAGU, JFPU01,JFPU1, JFPU0]> {
321   let Latency = 19;
322   let ResourceCycles = [1, 5, 5, 5, 5, 5];
323   let NumMicroOps = 9;
324 }
325
326 ////////////////////////////////////////////////////////////////////////////////
327 // AES Instructions.
328 ////////////////////////////////////////////////////////////////////////////////
329
330 def : WriteRes<WriteAESDecEnc, [JFPU01, JVIMUL]> {
331   let Latency = 3;
332   let ResourceCycles = [1, 1];
333 }
334 def : WriteRes<WriteAESDecEncLd, [JFPU01, JLAGU, JVIMUL]> {
335   let Latency = 8;
336   let ResourceCycles = [1, 1, 1];
337 }
338
339 def : WriteRes<WriteAESIMC, [JVIMUL]> {
340   let Latency = 2;
341   let ResourceCycles = [1];
342 }
343 def : WriteRes<WriteAESIMCLd, [JLAGU, JVIMUL]> {
344   let Latency = 7;
345   let ResourceCycles = [1, 1];
346 }
347
348 def : WriteRes<WriteAESKeyGen, [JVIMUL]> {
349   let Latency = 2;
350   let ResourceCycles = [1];
351 }
352 def : WriteRes<WriteAESKeyGenLd, [JLAGU, JVIMUL]> {
353   let Latency = 7;
354   let ResourceCycles = [1, 1];
355 }
356
357 ////////////////////////////////////////////////////////////////////////////////
358 // Horizontal add/sub  instructions.
359 ////////////////////////////////////////////////////////////////////////////////
360
361 def : WriteRes<WriteFHAdd, [JFPU0]> {
362   let Latency = 3;
363 }
364
365 def : WriteRes<WriteFHAddLd, [JLAGU, JFPU0]> {
366   let Latency = 8;
367 }
368
369 def : WriteRes<WritePHAdd, [JFPU01]> {
370   let ResourceCycles = [1];
371 }
372 def : WriteRes<WritePHAddLd, [JLAGU, JFPU01 ]> {
373   let Latency = 6;
374   let ResourceCycles = [1, 1];
375 }
376
377 def WriteFHAddY: SchedWriteRes<[JFPU0]> {
378   let Latency = 3;
379   let ResourceCycles = [2];
380 }
381 def : InstRW<[WriteFHAddY], (instregex "VH(ADD|SUB)P(S|D)Yrr")>;
382
383 def WriteFHAddYLd: SchedWriteRes<[JLAGU, JFPU0]> {
384   let Latency = 8;
385   let ResourceCycles = [1, 2];
386 }
387 def : InstRW<[WriteFHAddYLd], (instregex "VH(ADD|SUB)P(S|D)Yrm")>;
388
389 ////////////////////////////////////////////////////////////////////////////////
390 // Carry-less multiplication instructions.
391 ////////////////////////////////////////////////////////////////////////////////
392
393 def : WriteRes<WriteCLMul, [JVIMUL]> {
394   let Latency = 2;
395   let ResourceCycles = [1];
396 }
397 def : WriteRes<WriteCLMulLd, [JLAGU, JVIMUL]> {
398   let Latency = 7;
399   let ResourceCycles = [1, 1];
400 }
401
402 // FIXME: pipe for system/microcode?
403 def : WriteRes<WriteSystem,     [JAny]> { let Latency = 100; }
404 def : WriteRes<WriteMicrocoded, [JAny]> { let Latency = 100; }
405 def : WriteRes<WriteFence,  [JSAGU]>;
406 def : WriteRes<WriteNop, []>;
407
408 ////////////////////////////////////////////////////////////////////////////////
409 // SSE4.1 instructions.
410 ////////////////////////////////////////////////////////////////////////////////
411
412 def WriteDPPS: SchedWriteRes<[JFPU0, JFPU1]> {
413   let Latency = 11;
414   let ResourceCycles = [3,3];
415   let NumMicroOps = 5;
416 }
417 def : InstRW<[WriteDPPS], (instregex "(V)?DPPSrri")>;
418
419 def WriteDPPSLd: SchedWriteRes<[JLAGU, JFPU0, JFPU1]> {
420   let Latency = 16;
421   let ResourceCycles = [1,3,3];
422   let NumMicroOps = 6;
423 }
424 def : InstRW<[WriteDPPSLd], (instregex "(V)?DPPSrmi")>;
425
426 def WriteDPPD: SchedWriteRes<[JFPU0, JFPU1]> {
427   let Latency = 9;
428   let ResourceCycles = [3,3];
429   let NumMicroOps = 3;
430 }
431 def : InstRW<[WriteDPPD], (instregex "(V)?DPPDrri")>;
432
433 def WriteDPPDLd: SchedWriteRes<[JLAGU, JFPU0, JFPU1]> {
434   let Latency = 14;
435   let ResourceCycles = [1,3,3];
436   let NumMicroOps = 3;
437 }
438 def : InstRW<[WriteDPPDLd], (instregex "(V)?DPPDrmi")>;
439
440 ////////////////////////////////////////////////////////////////////////////////
441 // SSE4A instructions.
442 ////////////////////////////////////////////////////////////////////////////////
443
444 def WriteEXTRQ: SchedWriteRes<[JFPU01]> {
445   let Latency = 1;
446   let ResourceCycles = [1];
447 }
448 def : InstRW<[WriteEXTRQ], (instregex "EXTRQ")>;
449
450 def WriteINSERTQ: SchedWriteRes<[JFPU01]> {
451   let Latency = 2;
452   let ResourceCycles = [4];
453 }
454 def : InstRW<[WriteINSERTQ], (instregex "INSERTQ")>;
455
456 ////////////////////////////////////////////////////////////////////////////////
457 // F16C instructions.
458 ////////////////////////////////////////////////////////////////////////////////
459
460 def WriteCVT3: SchedWriteRes<[JFPU1]> {
461   let Latency = 3;
462 }
463 def : InstRW<[WriteCVT3], (instregex "VCVTPS2PHrr")>;
464 def : InstRW<[WriteCVT3], (instregex "VCVTPH2PSrr")>;
465
466 def WriteCVT3St: SchedWriteRes<[JFPU1, JSAGU]> {
467   let Latency = 3;
468   let ResourceCycles = [1, 1];
469 }
470 def : InstRW<[WriteCVT3St], (instregex "VCVTPS2PHmr")>;
471
472 def WriteCVT3Ld: SchedWriteRes<[JLAGU, JFPU1]> {
473   let Latency = 8;
474   let ResourceCycles = [1, 1];
475 }
476 def : InstRW<[WriteCVT3Ld], (instregex "VCVTPH2PSrm")>;
477
478 def WriteCVTPS2PHY: SchedWriteRes<[JFPU1, JFPU01]> {
479   let Latency = 6;
480   let ResourceCycles = [2,2];
481   let NumMicroOps = 3;
482 }
483 def : InstRW<[WriteCVTPS2PHY], (instregex "VCVTPS2PHYrr")>;
484
485 def WriteCVTPS2PHYSt: SchedWriteRes<[JFPU1, JFPU01, JSAGU]> {
486   let Latency = 11;
487   let ResourceCycles = [2,2,1];
488   let NumMicroOps = 3;
489 }
490 def : InstRW<[WriteCVTPS2PHYSt], (instregex "VCVTPS2PHYmr")>;
491
492 def WriteCVTPH2PSY: SchedWriteRes<[JFPU1]> {
493   let Latency = 3;
494   let ResourceCycles = [2];
495   let NumMicroOps = 2;
496 }
497 def : InstRW<[WriteCVTPH2PSY], (instregex "VCVTPH2PSYrr")>;
498
499 def WriteCVTPH2PSYLd: SchedWriteRes<[JLAGU, JFPU1]> {
500   let Latency = 8;
501   let ResourceCycles = [1,2];
502   let NumMicroOps = 2;
503 }
504 def : InstRW<[WriteCVTPH2PSYLd], (instregex "VCVTPH2PSYrm")>;
505
506 ////////////////////////////////////////////////////////////////////////////////
507 // AVX instructions.
508 ////////////////////////////////////////////////////////////////////////////////
509
510 def WriteVDPPSY: SchedWriteRes<[JFPU1, JFPU0]> {
511   let Latency = 12;
512   let ResourceCycles = [6, 6];
513   let NumMicroOps = 10;
514 }
515 def : InstRW<[WriteVDPPSY], (instregex "VDPPSYrr")>;
516
517 def WriteVDPPSYLd: SchedWriteRes<[JLAGU, JFPU1, JFPU0]> {
518   let Latency = 17;
519   let ResourceCycles = [1, 6, 6];
520   let NumMicroOps = 11;
521 }
522 def : InstRW<[WriteVDPPSYLd, ReadAfterLd], (instregex "VDPPSYrm")>;
523
524 def WriteFAddY: SchedWriteRes<[JFPU0]> {
525   let Latency = 3;
526   let ResourceCycles = [2];
527 }
528 def : InstRW<[WriteFAddY], (instregex "VADD(SUB)?P(S|D)Yrr", "VSUBP(S|D)Yrr")>;
529
530 def WriteFAddYLd: SchedWriteRes<[JLAGU, JFPU0]> {
531   let Latency = 8;
532   let ResourceCycles = [1, 2];
533 }
534 def : InstRW<[WriteFAddYLd, ReadAfterLd], (instregex "VADD(SUB)?P(S|D)Yrm", "VSUBP(S|D)Yrm")>;
535
536 def WriteFDivY: SchedWriteRes<[JFPU1]> {
537   let Latency = 38;
538   let ResourceCycles = [38];
539 }
540 def : InstRW<[WriteFDivY], (instregex "VDIVP(D|S)Yrr")>;
541
542 def WriteFDivYLd: SchedWriteRes<[JLAGU, JFPU1]> {
543   let Latency = 43;
544   let ResourceCycles = [1, 38];
545 }
546 def : InstRW<[WriteFDivYLd, ReadAfterLd], (instregex "VDIVP(S|D)Yrm")>;
547
548 def WriteVMULYPD: SchedWriteRes<[JFPU1]> {
549   let Latency = 4;
550   let ResourceCycles = [4];
551 }
552 def : InstRW<[WriteVMULYPD], (instregex "VMULPDYrr")>;
553
554 def WriteVMULYPDLd: SchedWriteRes<[JLAGU, JFPU1]> {
555   let Latency = 9;
556   let ResourceCycles = [1, 4];
557 }
558 def : InstRW<[WriteVMULYPDLd, ReadAfterLd], (instregex "VMULPDYrm")>;
559
560 def WriteVMULYPS: SchedWriteRes<[JFPU1]> {
561   let Latency = 2;
562   let ResourceCycles = [2];
563 }
564 def : InstRW<[WriteVMULYPS], (instregex "VMULPSYrr", "VRCPPSYr", "VRSQRTPSYr")>;
565
566 def WriteVMULYPSLd: SchedWriteRes<[JLAGU, JFPU1]> {
567   let Latency = 7;
568   let ResourceCycles = [1, 2];
569 }
570 def : InstRW<[WriteVMULYPSLd, ReadAfterLd], (instregex "VMULPSYrm", "VRCPPSYm", "VRSQRTPSYm")>;
571
572 def WriteVCVTY: SchedWriteRes<[JSTC]> {
573   let Latency = 3;
574   let ResourceCycles = [2];
575 }
576 def : InstRW<[WriteVCVTY], (instregex "VCVTDQ2P(S|D)Yrr")>;
577 def : InstRW<[WriteVCVTY], (instregex "VROUNDYP(S|D)r")>;
578 def : InstRW<[WriteVCVTY], (instregex "VCVTPS2DQYrr")>;
579 def : InstRW<[WriteVCVTY], (instregex "VCVTTPS2DQYrr")>;
580
581 def WriteVCVTYLd: SchedWriteRes<[JLAGU, JSTC]> {
582   let Latency = 8;
583   let ResourceCycles = [1, 2];
584 }
585 def : InstRW<[WriteVCVTYLd, ReadAfterLd], (instregex "VCVTDQ2P(S|D)Yrm")>;
586 def : InstRW<[WriteVCVTYLd, ReadAfterLd], (instregex "VROUNDYP(S|D)m")>;
587 def : InstRW<[WriteVCVTYLd, ReadAfterLd], (instregex "VCVTPS2DQYrm")>;
588 def : InstRW<[WriteVCVTYLd, ReadAfterLd], (instregex "VCVTTPS2DQYrm")>;
589
590 def WriteVMONTPSt: SchedWriteRes<[JSTC, JLAGU]> {
591   let Latency = 3;
592   let ResourceCycles = [2,1];
593 }
594 def : InstRW<[WriteVMONTPSt], (instregex "VMOVNTP(S|D)Ymr")>;
595 def : InstRW<[WriteVMONTPSt], (instregex "VMOVNTDQYmr")>;
596
597 def WriteVCVTPDY: SchedWriteRes<[JSTC, JFPU01]> {
598   let Latency = 6;
599   let ResourceCycles = [2, 4];
600 }
601 def : InstRW<[WriteVCVTPDY], (instregex "VCVTPD2(DQ|PS)Yrr")>;
602 def : InstRW<[WriteVCVTPDY], (instregex "VCVTTPD2DQYrr")>;
603
604 def WriteVCVTPDYLd: SchedWriteRes<[JLAGU, JSTC, JFPU01]> {
605   let Latency = 11;
606   let ResourceCycles = [1, 2, 4];
607 }
608 def : InstRW<[WriteVCVTPDYLd, ReadAfterLd], (instregex "VCVTPD2(DQ|PS)Yrm")>;
609 def : InstRW<[WriteVCVTPDYLd, ReadAfterLd], (instregex "VCVTTPD2DQYrm")>;
610
611 def WriteVBlendVPY: SchedWriteRes<[JFPU01]> {
612   let Latency = 3;
613   let ResourceCycles = [6];
614 }
615 def : InstRW<[WriteVBlendVPY], (instregex "VBLENDVP(S|D)Yrr", "VPERMILP(D|S)Yrr")>;
616
617 def WriteVBlendVPYLd: SchedWriteRes<[JLAGU, JFPU01]> {
618   let Latency = 8;
619   let ResourceCycles = [1, 6];
620 }
621 def : InstRW<[WriteVBlendVPYLd, ReadAfterLd], (instregex "VBLENDVP(S|D)Yrm")>;
622
623 def WriteVBROADCASTYLd: SchedWriteRes<[JLAGU, JFPU01]> {
624   let Latency = 6;
625   let ResourceCycles = [1, 4];
626 }
627 def : InstRW<[WriteVBROADCASTYLd, ReadAfterLd], (instregex "VBROADCASTS(S|D)Yrm")>;
628
629 def WriteFPAY22: SchedWriteRes<[JFPU0]> {
630   let Latency = 2;
631   let ResourceCycles = [2];
632 }
633 def : InstRW<[WriteFPAY22], (instregex "VCMPP(S|D)Yrri", "VM(AX|IN)P(D|S)Yrr")>;
634
635 def WriteFPAY22Ld: SchedWriteRes<[JLAGU, JFPU0]> {
636   let Latency = 7;
637   let ResourceCycles = [1, 2];
638 }
639 def : InstRW<[WriteFPAY22Ld, ReadAfterLd], (instregex "VCMPP(S|D)Yrmi", "VM(AX|IN)P(D|S)Yrm")>;
640
641 def WriteVHAddSubY: SchedWriteRes<[JFPU0]> {
642   let Latency = 3;
643   let ResourceCycles = [2];
644 }
645 def : InstRW<[WriteVHAddSubY], (instregex "VH(ADD|SUB)P(D|S)Yrr")>;
646
647 def WriteVHAddSubYLd: SchedWriteRes<[JLAGU, JFPU0]> {
648   let Latency = 8;
649   let ResourceCycles = [1, 2];
650 }
651 def : InstRW<[WriteVHAddSubYLd], (instregex "VH(ADD|SUB)P(D|S)Yrm")>;
652
653 def WriteVMaskMovLd: SchedWriteRes<[JLAGU,JFPU01]> {
654   let Latency = 6;
655   let ResourceCycles = [1, 2];
656 }
657 def : InstRW<[WriteVMaskMovLd], (instregex "VMASKMOVP(D|S)rm")>;
658
659 def WriteVMaskMovYLd: SchedWriteRes<[JLAGU,JFPU01]> {
660   let Latency = 6;
661   let ResourceCycles = [1, 4];
662 }
663 def : InstRW<[WriteVMaskMovYLd], (instregex "VMASKMOVP(D|S)Yrm")>;
664
665 def WriteVMaskMovSt: SchedWriteRes<[JFPU01,JSAGU]> {
666   let Latency = 6;
667   let ResourceCycles = [4, 1];
668 }
669 def : InstRW<[WriteVMaskMovSt], (instregex "VMASKMOVP(D|S)mr")>;
670
671 def WriteVMaskMovYSt: SchedWriteRes<[JFPU01,JSAGU]> {
672   let Latency = 6;
673   let ResourceCycles = [4, 1];
674 }
675 def : InstRW<[WriteVMaskMovYSt], (instregex "VMASKMOVP(D|S)Ymr")>;
676
677 // TODO: In fact we have latency '2+i'. The +i represents an additional 1 cycle transfer
678 // operation which moves the floating point result to the integer unit. During this
679 // additional cycle the floating point unit execution resources are not occupied
680 // and ALU0 in the integer unit is occupied instead.
681 def WriteVMOVMSK: SchedWriteRes<[JFPU0]> {
682   let Latency = 3;
683 }
684 def : InstRW<[WriteVMOVMSK], (instregex "VMOVMSKP(D|S)(Y)?rr")>;
685
686 // TODO: In fact we have latency '3+i'. The +i represents an additional 1 cycle transfer
687 // operation which moves the floating point result to the integer unit. During this
688 // additional cycle the floating point unit execution resources are not occupied
689 // and ALU0 in the integer unit is occupied instead.
690 def WriteVTESTY: SchedWriteRes<[JFPU01, JFPU0]> {
691   let Latency = 4;
692   let ResourceCycles = [2, 2];
693   let NumMicroOps = 3;
694 }
695 def : InstRW<[WriteVTESTY], (instregex "VTESTP(S|D)Yrr")>;
696 def : InstRW<[WriteVTESTY], (instregex "VPTESTYrr")>;
697
698 def WriteVTESTYLd: SchedWriteRes<[JLAGU, JFPU01, JFPU0]> {
699   let Latency = 9;
700   let ResourceCycles = [1, 2, 2];
701   let NumMicroOps = 3;
702 }
703 def : InstRW<[WriteVTESTYLd], (instregex "VTESTP(S|D)Yrm")>;
704 def : InstRW<[WriteVTESTYLd], (instregex "VPTESTYrm")>;
705
706 def WriteVTEST: SchedWriteRes<[JFPU0]> {
707   let Latency = 3;
708 }
709 def : InstRW<[WriteVTEST], (instregex "VTESTP(S|D)rr")>;
710 def : InstRW<[WriteVTEST], (instregex "VPTESTrr")>;
711
712 def WriteVTESTLd: SchedWriteRes<[JLAGU, JFPU0]> {
713   let Latency = 8;
714 }
715 def : InstRW<[WriteVTESTLd], (instregex "VTESTP(S|D)rm")>;
716 def : InstRW<[WriteVTESTLd], (instregex "VPTESTrm")>;
717
718 def WriteVSQRTYPD: SchedWriteRes<[JFPU1]> {
719   let Latency = 54;
720   let ResourceCycles = [54];
721 }
722 def : InstRW<[WriteVSQRTYPD], (instregex "VSQRTPDYr")>;
723
724 def WriteVSQRTYPDLd: SchedWriteRes<[JLAGU, JFPU1]> {
725   let Latency = 59;
726   let ResourceCycles = [1, 54];
727 }
728 def : InstRW<[WriteVSQRTYPDLd], (instregex "VSQRTPDYm")>;
729
730 def WriteVSQRTYPS: SchedWriteRes<[JFPU1]> {
731   let Latency = 42;
732   let ResourceCycles = [42];
733 }
734 def : InstRW<[WriteVSQRTYPS], (instregex "VSQRTPSYr")>;
735
736 def WriteVSQRTYPSLd: SchedWriteRes<[JLAGU, JFPU1]> {
737   let Latency = 47;
738   let ResourceCycles = [1, 42];
739 }
740 def : InstRW<[WriteVSQRTYPSLd], (instregex "VSQRTPSYm")>;
741
742 def WriteJVZEROALL: SchedWriteRes<[]> {
743   let Latency = 90;
744   let NumMicroOps = 73;
745 }
746 def : InstRW<[WriteJVZEROALL], (instregex "VZEROALL")>;
747
748 def WriteJVZEROUPPER: SchedWriteRes<[]> {
749   let Latency = 46;
750   let NumMicroOps = 37;
751 }
752 def : InstRW<[WriteJVZEROUPPER], (instregex "VZEROUPPER")>;
753 } // SchedModel
754