4dda178d0b073bfe8f616fb246573f2e32c000b2
[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 HWPort05  : ProcResGroup<[HWPort0, HWPort5]>;
55 def HWPort06 : ProcResGroup<[HWPort0, HWPort6]>;
56 def HWPort15  : ProcResGroup<[HWPort1, HWPort5]>;
57 def HWPort16  : ProcResGroup<[HWPort1, HWPort6]>;
58 def HWPort015 : ProcResGroup<[HWPort0, HWPort1, HWPort5]>;
59 def HWPort056: ProcResGroup<[HWPort0, HWPort5, HWPort6]>;
60 def HWPort0156: ProcResGroup<[HWPort0, HWPort1, HWPort5, HWPort6]>;
61
62 // 60 Entry Unified Scheduler
63 def HWPortAny : ProcResGroup<[HWPort0, HWPort1, HWPort2, HWPort3, HWPort4,
64                               HWPort5, HWPort6, HWPort7]> {
65   let BufferSize=60;
66 }
67
68 // Integer division issued on port 0.
69 def HWDivider : ProcResource<1>;
70
71 // Loads are 4 cycles, so ReadAfterLd registers needn't be available until 4
72 // cycles after the memory operand.
73 def : ReadAdvance<ReadAfterLd, 4>;
74
75 // Many SchedWrites are defined in pairs with and without a folded load.
76 // Instructions with folded loads are usually micro-fused, so they only appear
77 // as two micro-ops when queued in the reservation station.
78 // This multiclass defines the resource usage for variants with and without
79 // folded loads.
80 multiclass HWWriteResPair<X86FoldableSchedWrite SchedRW,
81                           ProcResourceKind ExePort,
82                           int Lat> {
83   // Register variant is using a single cycle on ExePort.
84   def : WriteRes<SchedRW, [ExePort]> { let Latency = Lat; }
85
86   // Memory variant also uses a cycle on port 2/3 and adds 4 cycles to the
87   // latency.
88   def : WriteRes<SchedRW.Folded, [HWPort23, ExePort]> {
89      let Latency = !add(Lat, 4);
90   }
91 }
92
93 // A folded store needs a cycle on port 4 for the store data, but it does not
94 // need an extra port 2/3 cycle to recompute the address.
95 def : WriteRes<WriteRMW, [HWPort4]>;
96
97 // Store_addr on 237.
98 // Store_data on 4.
99 def : WriteRes<WriteStore, [HWPort237, HWPort4]>;
100 def : WriteRes<WriteLoad,  [HWPort23]> { let Latency = 4; }
101 def : WriteRes<WriteMove,  [HWPort0156]>;
102 def : WriteRes<WriteZero,  []>;
103
104 defm : HWWriteResPair<WriteALU,   HWPort0156, 1>;
105 defm : HWWriteResPair<WriteIMul,  HWPort1,   3>;
106 def  : WriteRes<WriteIMulH, []> { let Latency = 3; }
107 defm : HWWriteResPair<WriteShift, HWPort06,  1>;
108 defm : HWWriteResPair<WriteJump,  HWPort06,   1>;
109
110 // This is for simple LEAs with one or two input operands.
111 // The complex ones can only execute on port 1, and they require two cycles on
112 // the port to read all inputs. We don't model that.
113 def : WriteRes<WriteLEA, [HWPort15]>;
114
115 // This is quite rough, latency depends on the dividend.
116 def : WriteRes<WriteIDiv, [HWPort0, HWDivider]> {
117   let Latency = 25;
118   let ResourceCycles = [1, 10];
119 }
120 def : WriteRes<WriteIDivLd, [HWPort23, HWPort0, HWDivider]> {
121   let Latency = 29;
122   let ResourceCycles = [1, 1, 10];
123 }
124
125 // Scalar and vector floating point.
126 defm : HWWriteResPair<WriteFAdd,   HWPort1, 3>;
127 defm : HWWriteResPair<WriteFMul,   HWPort0, 5>;
128 defm : HWWriteResPair<WriteFDiv,   HWPort0, 12>; // 10-14 cycles.
129 defm : HWWriteResPair<WriteFRcp,   HWPort0, 5>;
130 defm : HWWriteResPair<WriteFSqrt,  HWPort0, 15>;
131 defm : HWWriteResPair<WriteCvtF2I, HWPort1, 3>;
132 defm : HWWriteResPair<WriteCvtI2F, HWPort1, 4>;
133 defm : HWWriteResPair<WriteCvtF2F, HWPort1, 3>;
134 defm : HWWriteResPair<WriteFShuffle,  HWPort5,  1>;
135 defm : HWWriteResPair<WriteFBlend,  HWPort015,  1>;
136 defm : HWWriteResPair<WriteFShuffle256,  HWPort5,  3>;
137
138 def : WriteRes<WriteFVarBlend, [HWPort5]> {
139   let Latency = 2;
140   let ResourceCycles = [2];
141 }
142 def : WriteRes<WriteFVarBlendLd, [HWPort5, HWPort23]> {
143   let Latency = 6;
144   let ResourceCycles = [2, 1];
145 }
146
147 // Vector integer operations.
148 defm : HWWriteResPair<WriteVecShift, HWPort0,  1>;
149 defm : HWWriteResPair<WriteVecLogic, HWPort015, 1>;
150 defm : HWWriteResPair<WriteVecALU,   HWPort15,  1>;
151 defm : HWWriteResPair<WriteVecIMul,  HWPort0,   5>;
152 defm : HWWriteResPair<WriteShuffle,  HWPort5,  1>;
153 defm : HWWriteResPair<WriteBlend,  HWPort15,  1>;
154 defm : HWWriteResPair<WriteShuffle256,  HWPort5,  3>;
155
156 def : WriteRes<WriteVarBlend, [HWPort5]> {
157   let Latency = 2;
158   let ResourceCycles = [2];
159 }
160 def : WriteRes<WriteVarBlendLd, [HWPort5, HWPort23]> {
161   let Latency = 6;
162   let ResourceCycles = [2, 1];
163 }
164
165 def : WriteRes<WriteVarVecShift, [HWPort0, HWPort5]> {
166   let Latency = 2;
167   let ResourceCycles = [2, 1];
168 }
169 def : WriteRes<WriteVarVecShiftLd, [HWPort0, HWPort5, HWPort23]> {
170   let Latency = 6;
171   let ResourceCycles = [2, 1, 1];
172 }
173
174 def : WriteRes<WriteMPSAD, [HWPort0, HWPort5]> {
175   let Latency = 6;
176   let ResourceCycles = [1, 2];
177 }
178 def : WriteRes<WriteMPSADLd, [HWPort23, HWPort0, HWPort5]> {
179   let Latency = 6;
180   let ResourceCycles = [1, 1, 2];
181 }
182
183 // String instructions.
184 // Packed Compare Implicit Length Strings, Return Mask
185 def : WriteRes<WritePCmpIStrM, [HWPort0]> {
186   let Latency = 10;
187   let ResourceCycles = [3];
188 }
189 def : WriteRes<WritePCmpIStrMLd, [HWPort0, HWPort23]> {
190   let Latency = 10;
191   let ResourceCycles = [3, 1];
192 }
193
194 // Packed Compare Explicit Length Strings, Return Mask
195 def : WriteRes<WritePCmpEStrM, [HWPort0, HWPort16, HWPort5]> {
196   let Latency = 10;
197   let ResourceCycles = [3, 2, 4];
198 }
199 def : WriteRes<WritePCmpEStrMLd, [HWPort05, HWPort16, HWPort23]> {
200   let Latency = 10;
201   let ResourceCycles = [6, 2, 1];
202 }
203
204 // Packed Compare Implicit Length Strings, Return Index
205 def : WriteRes<WritePCmpIStrI, [HWPort0]> {
206   let Latency = 11;
207   let ResourceCycles = [3];
208 }
209 def : WriteRes<WritePCmpIStrILd, [HWPort0, HWPort23]> {
210   let Latency = 11;
211   let ResourceCycles = [3, 1];
212 }
213
214 // Packed Compare Explicit Length Strings, Return Index
215 def : WriteRes<WritePCmpEStrI, [HWPort05, HWPort16]> {
216   let Latency = 11;
217   let ResourceCycles = [6, 2];
218 }
219 def : WriteRes<WritePCmpEStrILd, [HWPort0, HWPort16, HWPort5, HWPort23]> {
220   let Latency = 11;
221   let ResourceCycles = [3, 2, 2, 1];
222 }
223
224 // AES Instructions.
225 def : WriteRes<WriteAESDecEnc, [HWPort5]> {
226   let Latency = 7;
227   let ResourceCycles = [1];
228 }
229 def : WriteRes<WriteAESDecEncLd, [HWPort5, HWPort23]> {
230   let Latency = 7;
231   let ResourceCycles = [1, 1];
232 }
233
234 def : WriteRes<WriteAESIMC, [HWPort5]> {
235   let Latency = 14;
236   let ResourceCycles = [2];
237 }
238 def : WriteRes<WriteAESIMCLd, [HWPort5, HWPort23]> {
239   let Latency = 14;
240   let ResourceCycles = [2, 1];
241 }
242
243 def : WriteRes<WriteAESKeyGen, [HWPort0, HWPort5]> {
244   let Latency = 10;
245   let ResourceCycles = [2, 8];
246 }
247 def : WriteRes<WriteAESKeyGenLd, [HWPort0, HWPort5, HWPort23]> {
248   let Latency = 10;
249   let ResourceCycles = [2, 7, 1];
250 }
251
252 // Carry-less multiplication instructions.
253 def : WriteRes<WriteCLMul, [HWPort0, HWPort5]> {
254   let Latency = 7;
255   let ResourceCycles = [2, 1];
256 }
257 def : WriteRes<WriteCLMulLd, [HWPort0, HWPort5, HWPort23]> {
258   let Latency = 7;
259   let ResourceCycles = [2, 1, 1];
260 }
261
262 def : WriteRes<WriteSystem,     [HWPort0156]> { let Latency = 100; }
263 def : WriteRes<WriteMicrocoded, [HWPort0156]> { let Latency = 100; }
264 def : WriteRes<WriteFence,  [HWPort23, HWPort4]>;
265 def : WriteRes<WriteNop, []>;
266
267 //================ Exceptions ================//
268
269 //-- Specific Scheduling Models --//
270 def WriteP0 : SchedWriteRes<[HWPort0]>;
271 def WriteP1 : SchedWriteRes<[HWPort1]>;
272 def WriteP1_P23 : SchedWriteRes<[HWPort1, HWPort23]> {
273   let NumMicroOps = 2;
274 }
275 def WriteP1_Lat3 : SchedWriteRes<[HWPort1]> {
276   let Latency = 3;
277 }
278 def WriteP1_Lat3Ld : SchedWriteRes<[HWPort1, HWPort23]> {
279   let Latency = 7;
280 }
281
282 def Write2P0156_Lat2 : SchedWriteRes<[HWPort0156]> {
283   let Latency = 2;
284   let ResourceCycles = [2];
285 }
286 def Write2P0156_Lat2Ld : SchedWriteRes<[HWPort0156, HWPort23]> {
287   let Latency = 6;
288   let ResourceCycles = [2, 1];
289 }
290
291 def Write2P237_P4 : SchedWriteRes<[HWPort237, HWPort4]> {
292   let Latency = 1;
293   let ResourceCycles = [2, 1];
294 }
295
296 def WriteP01 : SchedWriteRes<[HWPort01]>;
297
298 def Write2P01 : SchedWriteRes<[HWPort01]> {
299   let NumMicroOps = 2;
300 }
301 def Write3P01 : SchedWriteRes<[HWPort01]> {
302   let NumMicroOps = 3;
303 }
304
305 def WriteP06 : SchedWriteRes<[HWPort06]>;
306
307 def Write2P06 : SchedWriteRes<[HWPort06]> {
308   let Latency = 1;
309   let NumMicroOps = 2;
310   let ResourceCycles = [2];
311 }
312
313 def Write2P1 : SchedWriteRes<[HWPort1]> {
314   let NumMicroOps = 2;
315   let ResourceCycles = [2];
316 }
317 def Write2P1_P23 : SchedWriteRes<[HWPort1, HWPort23]> {
318   let NumMicroOps = 3;
319   let ResourceCycles = [2, 1];
320 }
321 def WriteP15 : SchedWriteRes<[HWPort15]>;
322 def WriteP15Ld : SchedWriteRes<[HWPort15, HWPort23]> {
323   let Latency = 4;
324 }
325
326 def Write3P06_Lat2 : SchedWriteRes<[HWPort06]> {
327   let Latency = 2;
328   let NumMicroOps = 3;
329   let ResourceCycles = [3];
330 }
331
332 def WriteP0156_P23 : SchedWriteRes<[HWPort0156, HWPort23]> {
333   let NumMicroOps = 2;
334 }
335
336 def WriteP0156_2P237_P4 : SchedWriteRes<[HWPort0156, HWPort237, HWPort4]> {
337   let Latency = 1;
338   let ResourceCycles = [1, 2, 1];
339 }
340
341 def Write2P0156_2P237_P4 : SchedWriteRes<[HWPort0156, HWPort237, HWPort4]> {
342   let Latency = 1;
343   let ResourceCycles = [2, 2, 1];
344 }
345
346 def Write2P0156_P23 : SchedWriteRes<[HWPort0156, HWPort23]> {
347   let NumMicroOps = 3;
348   let ResourceCycles = [2, 1];
349 }
350
351 def Write3P0156_2P237_P4 : SchedWriteRes<[HWPort0156, HWPort237, HWPort4]> {
352   let Latency = 1;
353   let ResourceCycles = [3, 2, 1];
354 }
355
356 // Notation:
357 // - r: register.
358 // - mm: 64 bit mmx register.
359 // - x = 128 bit xmm register.
360 // - (x)mm = mmx or xmm register.
361 // - y = 256 bit ymm register.
362 // - v = any vector register.
363 // - m = memory.
364
365 //=== Integer Instructions ===//
366 //-- Move instructions --//
367
368 // MOV.
369 // r16,m.
370 def : InstRW<[WriteALULd], (instregex "MOV16rm")>;
371
372 // MOVSX, MOVZX.
373 // r,m.
374 def : InstRW<[WriteLoad], (instregex "MOV(S|Z)X32rm(8|16)")>;
375
376 // CMOVcc.
377 // r,r.
378 def : InstRW<[Write2P0156_Lat2],
379       (instregex "CMOV(O|NO|B|AE|E|NE|BE|A|S|NS|P|NP|L|GE|LE|G)(16|32|64)rr")>;
380 // r,m.
381 def : InstRW<[Write2P0156_Lat2Ld, ReadAfterLd],
382       (instregex "CMOV(O|NO|B|AE|E|NE|BE|A|S|NS|P|NP|L|GE|LE|G)(16|32|64)rm")>;
383
384 // XCHG.
385 // r,r.
386 def WriteXCHG : SchedWriteRes<[HWPort0156]> {
387   let Latency = 2;
388   let ResourceCycles = [3];
389 }
390
391 def : InstRW<[WriteXCHG], (instregex "XCHG(8|16|32|64)rr", "XCHG(16|32|64)ar")>;
392
393 // r,m.
394 def WriteXCHGrm : SchedWriteRes<[]> {
395   let Latency = 21;
396   let NumMicroOps = 8;
397 }
398 def : InstRW<[WriteXCHGrm], (instregex "XCHG(8|16|32|64)rm")>;
399
400 // XLAT.
401 def WriteXLAT : SchedWriteRes<[]> {
402   let Latency = 7;
403   let NumMicroOps = 3;
404 }
405 def : InstRW<[WriteXLAT], (instregex "XLAT")>;
406
407 // PUSH.
408 // m.
409 def : InstRW<[Write2P237_P4], (instregex "PUSH(16|32)rmm")>;
410
411 // PUSHF.
412 def WritePushF : SchedWriteRes<[HWPort1, HWPort4, HWPort237, HWPort06]> {
413   let NumMicroOps = 4;
414 }
415 def : InstRW<[WritePushF], (instregex "PUSHF(16|32)")>;
416
417 // PUSHA.
418 def WritePushA : SchedWriteRes<[]> {
419   let NumMicroOps = 19;
420 }
421 def : InstRW<[WritePushA], (instregex "PUSHA(16|32)")>;
422
423 // POP.
424 // m.
425 def : InstRW<[Write2P237_P4], (instregex "POP(16|32)rmm")>;
426
427 // POPF.
428 def WritePopF : SchedWriteRes<[]> {
429   let NumMicroOps = 9;
430 }
431 def : InstRW<[WritePopF], (instregex "POPF(16|32)")>;
432
433 // POPA.
434 def WritePopA : SchedWriteRes<[]> {
435   let NumMicroOps = 18;
436 }
437 def : InstRW<[WritePopA], (instregex "POPA(16|32)")>;
438
439 // LAHF SAHF.
440 def : InstRW<[WriteP06], (instregex "(S|L)AHF")>;
441
442 // BSWAP.
443 // r32.
444 def WriteBSwap32 : SchedWriteRes<[HWPort15]>;
445 def : InstRW<[WriteBSwap32], (instregex "BSWAP32r")>;
446
447 // r64.
448 def WriteBSwap64 : SchedWriteRes<[HWPort06, HWPort15]> {
449   let NumMicroOps = 2;
450 }
451 def : InstRW<[WriteBSwap64], (instregex "BSWAP64r")>;
452
453 // MOVBE.
454 // r16,m16 / r64,m64.
455 def : InstRW<[Write2P0156_Lat2Ld], (instregex "MOVBE(16|64)rm")>;
456
457 // r32, m32.
458 def WriteMoveBE32rm : SchedWriteRes<[HWPort15, HWPort23]> {
459   let NumMicroOps = 2;
460 }
461 def : InstRW<[WriteMoveBE32rm], (instregex "MOVBE32rm")>;
462
463 // m16,r16.
464 def WriteMoveBE16mr : SchedWriteRes<[HWPort06, HWPort237, HWPort4]> {
465   let NumMicroOps = 3;
466 }
467 def : InstRW<[WriteMoveBE16mr], (instregex "MOVBE16mr")>;
468
469 // m32,r32.
470 def WriteMoveBE32mr : SchedWriteRes<[HWPort15, HWPort237, HWPort4]> {
471   let NumMicroOps = 3;
472 }
473 def : InstRW<[WriteMoveBE32mr], (instregex "MOVBE32mr")>;
474
475 // m64,r64.
476 def WriteMoveBE64mr : SchedWriteRes<[HWPort06, HWPort15, HWPort237, HWPort4]> {
477   let NumMicroOps = 4;
478 }
479 def : InstRW<[WriteMoveBE64mr], (instregex "MOVBE64mr")>;
480
481 //-- Arithmetic instructions --//
482
483 // ADD SUB.
484 // m,r/i.
485 def : InstRW<[Write2P0156_2P237_P4],
486               (instregex "(ADD|SUB)(8|16|32|64)m(r|i)",
487               "(ADD|SUB)(8|16|32|64)mi8", "(ADD|SUB)64mi32")>;
488
489 // ADC SBB.
490 // r,r/i.
491 def : InstRW<[Write2P0156_Lat2], (instregex "(ADC|SBB)(8|16|32|64)r(r|i)",
492                            "(ADC|SBB)(16|32|64)ri8",
493                            "(ADC|SBB)64ri32",
494                            "(ADC|SBB)(8|16|32|64)rr_REV")>;
495
496 // r,m.
497 def : InstRW<[Write2P0156_Lat2Ld, ReadAfterLd], (instregex "(ADC|SBB)(8|16|32|64)rm")>;
498
499 // m,r/i.
500 def : InstRW<[Write3P0156_2P237_P4],
501              (instregex "(ADC|SBB)(8|16|32|64)m(r|i)",
502               "(ADC|SBB)(16|32|64)mi8",
503               "(ADC|SBB)64mi32")>;
504
505 // INC DEC NOT NEG.
506 // m.
507 def : InstRW<[WriteP0156_2P237_P4],
508              (instregex "(INC|DEC|NOT|NEG)(8|16|32|64)m",
509               "(INC|DEC)64(16|32)m")>;
510
511 // MUL IMUL.
512 // r16.
513 def WriteMul16 : SchedWriteRes<[HWPort1, HWPort0156]> {
514   let Latency = 4;
515   let NumMicroOps = 4;
516 }
517 def : InstRW<[WriteMul16], (instregex "IMUL16r", "MUL16r")>;
518
519 // m16.
520 def WriteMul16Ld : SchedWriteRes<[HWPort1, HWPort0156, HWPort23]> {
521   let Latency = 8;
522   let NumMicroOps = 5;
523 }
524 def : InstRW<[WriteMul16Ld], (instregex "IMUL16m", "MUL16m")>;
525
526 // r32.
527 def WriteMul32 : SchedWriteRes<[HWPort1, HWPort0156]> {
528   let Latency = 4;
529   let NumMicroOps = 3;
530 }
531 def : InstRW<[WriteMul32], (instregex "IMUL32r", "MUL32r")>;
532
533 // m32.
534 def WriteMul32Ld : SchedWriteRes<[HWPort1, HWPort0156, HWPort23]> {
535   let Latency = 8;
536   let NumMicroOps = 4;
537 }
538 def : InstRW<[WriteMul32Ld], (instregex "IMUL32m", "MUL32m")>;
539
540 // r64.
541 def WriteMul64 : SchedWriteRes<[HWPort1, HWPort6]> {
542   let Latency = 3;
543   let NumMicroOps = 2;
544 }
545 def : InstRW<[WriteMul64], (instregex "IMUL64r", "MUL64r")>;
546
547 // m64.
548 def WriteMul64Ld : SchedWriteRes<[HWPort1, HWPort6, HWPort23]> {
549   let Latency = 7;
550   let NumMicroOps = 3;
551 }
552 def : InstRW<[WriteMul64Ld], (instregex "IMUL64m", "MUL64m")>;
553
554 // r16,r16.
555 def WriteMul16rri : SchedWriteRes<[HWPort1, HWPort0156]> {
556   let Latency = 4;
557   let NumMicroOps = 2;
558 }
559 def : InstRW<[WriteMul16rri], (instregex "IMUL16rri", "IMUL16rri8")>;
560
561 // r16,m16.
562 def WriteMul16rmi : SchedWriteRes<[HWPort1, HWPort0156, HWPort23]> {
563   let Latency = 8;
564   let NumMicroOps = 3;
565 }
566 def : InstRW<[WriteMul16rmi], (instregex "IMUL16rmi", "IMUL16rmi8")>;
567
568 // MULX.
569 // r32,r32,r32.
570 def WriteMulX32 : SchedWriteRes<[HWPort1, HWPort056]> {
571   let Latency = 4;
572   let NumMicroOps = 3;
573   let ResourceCycles = [1, 2];
574 }
575 def : InstRW<[WriteMulX32], (instregex "MULX32rr")>;
576
577 // r32,r32,m32.
578 def WriteMulX32Ld : SchedWriteRes<[HWPort1, HWPort056, HWPort23]> {
579   let Latency = 8;
580   let NumMicroOps = 4;
581   let ResourceCycles = [1, 2, 1];
582 }
583 def : InstRW<[WriteMulX32Ld], (instregex "MULX32rm")>;
584
585 // r64,r64,r64.
586 def WriteMulX64 : SchedWriteRes<[HWPort1, HWPort6]> {
587   let Latency = 4;
588   let NumMicroOps = 2;
589 }
590 def : InstRW<[WriteMulX64], (instregex "MULX64rr")>;
591
592 // r64,r64,m64.
593 def WriteMulX64Ld : SchedWriteRes<[HWPort1, HWPort6, HWPort23]> {
594   let Latency = 8;
595   let NumMicroOps = 3;
596 }
597 def : InstRW<[WriteMulX64Ld], (instregex "MULX64rm")>;
598
599 // DIV.
600 // r8.
601 def WriteDiv8 : SchedWriteRes<[HWPort0, HWPort1, HWPort5, HWPort6]> {
602   let Latency = 22;
603   let NumMicroOps = 9;
604 }
605 def : InstRW<[WriteDiv8], (instregex "DIV8r")>;
606
607 // r16.
608 def WriteDiv16 : SchedWriteRes<[HWPort0, HWPort1, HWPort5, HWPort6]> {
609   let Latency = 23;
610   let NumMicroOps = 10;
611 }
612 def : InstRW<[WriteDiv16], (instregex "DIV16r")>;
613
614 // r32.
615 def WriteDiv32 : SchedWriteRes<[HWPort0, HWPort1, HWPort5, HWPort6]> {
616   let Latency = 22;
617   let NumMicroOps = 10;
618 }
619 def : InstRW<[WriteDiv32], (instregex "DIV32r")>;
620
621 // r64.
622 def WriteDiv64 : SchedWriteRes<[HWPort0, HWPort1, HWPort5, HWPort6]> {
623   let Latency = 32;
624   let NumMicroOps = 36;
625 }
626 def : InstRW<[WriteDiv64], (instregex "DIV64r")>;
627
628 // IDIV.
629 // r8.
630 def WriteIDiv8 : SchedWriteRes<[HWPort0, HWPort1, HWPort5, HWPort6]> {
631   let Latency = 23;
632   let NumMicroOps = 9;
633 }
634 def : InstRW<[WriteIDiv8], (instregex "IDIV8r")>;
635
636 // r16.
637 def WriteIDiv16 : SchedWriteRes<[HWPort0, HWPort1, HWPort5, HWPort6]> {
638   let Latency = 23;
639   let NumMicroOps = 10;
640 }
641 def : InstRW<[WriteIDiv16], (instregex "IDIV16r")>;
642
643 // r32.
644 def WriteIDiv32 : SchedWriteRes<[HWPort0, HWPort1, HWPort5, HWPort6]> {
645   let Latency = 22;
646   let NumMicroOps = 9;
647 }
648 def : InstRW<[WriteIDiv32], (instregex "IDIV32r")>;
649
650 // r64.
651 def WriteIDiv64 : SchedWriteRes<[HWPort0, HWPort1, HWPort5, HWPort6]> {
652   let Latency = 39;
653   let NumMicroOps = 59;
654 }
655 def : InstRW<[WriteIDiv64], (instregex "IDIV64r")>;
656
657 //-- Logic instructions --//
658
659 // AND OR XOR.
660 // m,r/i.
661 def : InstRW<[Write2P0156_2P237_P4],
662              (instregex "(AND|OR|XOR)(8|16|32|64)m(r|i)",
663               "(AND|OR|XOR)(8|16|32|64)mi8", "(AND|OR|XOR)64mi32")>;
664
665 // SHR SHL SAR.
666 // m,i.
667 def WriteShiftRMW : SchedWriteRes<[HWPort06, HWPort237, HWPort4]> {
668   let NumMicroOps = 4;
669   let ResourceCycles = [2, 1, 1];
670 }
671 def : InstRW<[WriteShiftRMW], (instregex "S(A|H)(R|L)(8|16|32|64)m(i|1)")>;
672
673 // r,cl.
674 def : InstRW<[Write3P06_Lat2], (instregex "S(A|H)(R|L)(8|16|32|64)rCL")>;
675
676 // m,cl.
677 def WriteShiftClLdRMW : SchedWriteRes<[HWPort06, HWPort23, HWPort4]> {
678   let NumMicroOps = 6;
679   let ResourceCycles = [3, 2, 1];
680 }
681 def : InstRW<[WriteShiftClLdRMW], (instregex "S(A|H)(R|L)(8|16|32|64)mCL")>;
682
683 // ROR ROL.
684 // r,1.
685 def : InstRW<[Write2P06], (instregex "RO(R|L)(8|16|32|64)r1")>;
686
687 // m,i.
688 def WriteRotateRMW : SchedWriteRes<[HWPort06, HWPort237, HWPort4]> {
689   let NumMicroOps = 5;
690   let ResourceCycles = [2, 2, 1];
691 }
692 def : InstRW<[WriteRotateRMW], (instregex "RO(R|L)(8|16|32|64)mi")>;
693
694 // r,cl.
695 def : InstRW<[Write3P06_Lat2], (instregex "RO(R|L)(8|16|32|64)rCL")>;
696
697 // m,cl.
698 def WriteRotateRMWCL : SchedWriteRes<[]> {
699   let NumMicroOps = 6;
700 }
701 def : InstRW<[WriteRotateRMWCL], (instregex "RO(R|L)(8|16|32|64)mCL")>;
702
703 // RCR RCL.
704 // r,1.
705 def WriteRCr1 : SchedWriteRes<[HWPort06, HWPort0156]> {
706   let Latency = 2;
707   let NumMicroOps = 3;
708   let ResourceCycles = [2, 1];
709 }
710 def : InstRW<[WriteRCr1], (instregex "RC(R|L)(8|16|32|64)r1")>;
711
712 // m,1.
713 def WriteRCm1 : SchedWriteRes<[]> {
714   let NumMicroOps = 6;
715 }
716 def : InstRW<[WriteRCm1], (instregex "RC(R|L)(8|16|32|64)m1")>;
717
718 // r,i.
719 def WriteRCri : SchedWriteRes<[HWPort0156]> {
720   let Latency = 6;
721   let NumMicroOps = 8;
722 }
723 def : InstRW<[WriteRCri], (instregex "RC(R|L)(8|16|32|64)r(i|CL)")>;
724
725 // m,i.
726 def WriteRCmi : SchedWriteRes<[]> {
727   let NumMicroOps = 11;
728 }
729 def : InstRW<[WriteRCmi], (instregex "RC(R|L)(8|16|32|64)m(i|CL)")>;
730
731 // SHRD SHLD.
732 // r,r,i.
733 def WriteShDrr : SchedWriteRes<[HWPort1]> {
734   let Latency = 3;
735 }
736 def : InstRW<[WriteShDrr], (instregex "SH(R|L)D(16|32|64)rri8")>;
737
738 // m,r,i.
739 def WriteShDmr : SchedWriteRes<[]> {
740   let NumMicroOps = 5;
741 }
742 def : InstRW<[WriteShDmr], (instregex "SH(R|L)D(16|32|64)mri8")>;
743
744 // r,r,cl.
745 def WriteShlDCL : SchedWriteRes<[HWPort0156]> {
746   let Latency = 3;
747   let NumMicroOps = 4;
748 }
749 def : InstRW<[WriteShlDCL], (instregex "SHLD(16|32|64)rrCL")>;
750
751 // r,r,cl.
752 def WriteShrDCL : SchedWriteRes<[HWPort0156]> {
753   let Latency = 4;
754   let NumMicroOps = 4;
755 }
756 def : InstRW<[WriteShrDCL], (instregex "SHRD(16|32|64)rrCL")>;
757
758 // m,r,cl.
759 def WriteShDmrCL : SchedWriteRes<[]> {
760   let NumMicroOps = 7;
761 }
762 def : InstRW<[WriteShDmrCL], (instregex "SH(R|L)D(16|32|64)mrCL")>;
763
764 // BT.
765 // r,r/i.
766 def : InstRW<[WriteShift], (instregex "BT(16|32|64)r(r|i8)")>;
767
768 // m,r.
769 def WriteBTmr : SchedWriteRes<[]> {
770   let NumMicroOps = 10;
771 }
772 def : InstRW<[WriteBTmr], (instregex "BT(16|32|64)mr")>;
773
774 // m,i.
775 def : InstRW<[WriteShiftLd], (instregex "BT(16|32|64)mi8")>;
776
777 // BTR BTS BTC.
778 // r,r,i.
779 def : InstRW<[WriteShift], (instregex "BT(R|S|C)(16|32|64)r(r|i8)")>;
780
781 // m,r.
782 def WriteBTRSCmr : SchedWriteRes<[]> {
783   let NumMicroOps = 11;
784 }
785 def : InstRW<[WriteBTRSCmr], (instregex "BT(R|S|C)(16|32|64)mr")>;
786
787 // m,i.
788 def : InstRW<[WriteShiftLd], (instregex "BT(R|S|C)(16|32|64)mi8")>;
789
790 // BSF BSR.
791 // r,r.
792 def : InstRW<[WriteP1_Lat3], (instregex "BS(R|F)(16|32|64)rr")>;
793 // r,m.
794 def : InstRW<[WriteP1_Lat3Ld], (instregex "BS(R|F)(16|32|64)rm")>;
795
796 // SETcc.
797 // r.
798 def : InstRW<[WriteShift],
799              (instregex "SET(O|NO|B|AE|E|NE|BE|A|S|NS|P|NP|L|GE|LE|G)r")>;
800 // m.
801 def WriteSetCCm : SchedWriteRes<[HWPort06, HWPort237, HWPort4]> {
802   let NumMicroOps = 3;
803 }
804 def : InstRW<[WriteSetCCm],
805              (instregex "SET(O|NO|B|AE|E|NE|BE|A|S|NS|P|NP|L|GE|LE|G)m")>;
806
807 // CLD STD.
808 def WriteCldStd : SchedWriteRes<[HWPort15, HWPort6]> {
809   let NumMicroOps = 3;
810 }
811 def : InstRW<[WriteCldStd], (instregex "STD", "CLD")>;
812
813 // LZCNT TZCNT.
814 // r,r.
815 def : InstRW<[WriteP1_Lat3], (instregex "(L|TZCNT)(16|32|64)rr")>;
816 // r,m.
817 def : InstRW<[WriteP1_Lat3Ld], (instregex "(L|TZCNT)(16|32|64)rm")>;
818
819 // ANDN.
820 // r,r.
821 def : InstRW<[WriteP15], (instregex "ANDN(32|64)rr")>;
822 // r,m.
823 def : InstRW<[WriteP15Ld], (instregex "ANDN(32|64)rm")>;
824
825 // BLSI BLSMSK BLSR.
826 // r,r.
827 def : InstRW<[WriteP15], (instregex "BLS(I|MSK|R)(32|64)rr")>;
828 // r,m.
829 def : InstRW<[WriteP15Ld], (instregex "BLS(I|MSK|R)(32|64)rm")>;
830
831 // BEXTR.
832 // r,r,r.
833 def : InstRW<[Write2P0156_Lat2], (instregex "BEXTR(32|64)rr")>;
834 // r,m,r.
835 def : InstRW<[Write2P0156_Lat2Ld], (instregex "BEXTR(32|64)rm")>;
836
837 // BZHI.
838 // r,r,r.
839 def : InstRW<[WriteP15], (instregex "BZHI(32|64)rr")>;
840 // r,m,r.
841 def : InstRW<[WriteP15Ld], (instregex "BZHI(32|64)rm")>;
842
843 // PDEP PEXT.
844 // r,r,r.
845 def : InstRW<[WriteP1_Lat3], (instregex "PDEP(32|64)rr", "PEXT(32|64)rr")>;
846 // r,m,r.
847 def : InstRW<[WriteP1_Lat3Ld], (instregex "PDEP(32|64)rm", "PEXT(32|64)rm")>;
848
849 //-- Control transfer instructions --//
850
851 // J(E|R)CXZ.
852 def WriteJCXZ : SchedWriteRes<[HWPort0156, HWPort6]> {
853   let NumMicroOps = 2;
854 }
855 def : InstRW<[WriteJCXZ], (instregex "JCXZ", "JECXZ_(32|64)", "JRCXZ")>;
856
857 // LOOP.
858 def WriteLOOP : SchedWriteRes<[]> {
859   let NumMicroOps = 7;
860 }
861 def : InstRW<[WriteLOOP], (instregex "LOOP")>;
862
863 // LOOP(N)E
864 def WriteLOOPE : SchedWriteRes<[]> {
865   let NumMicroOps = 11;
866 }
867 def : InstRW<[WriteLOOPE], (instregex "LOOPE", "LOOPNE")>;
868
869 // CALL.
870 // r.
871 def WriteCALLr : SchedWriteRes<[HWPort237, HWPort4, HWPort6]> {
872   let NumMicroOps = 3;
873 }
874 def : InstRW<[WriteCALLr], (instregex "CALL(16|32)r")>;
875
876 // m.
877 def WriteCALLm : SchedWriteRes<[HWPort237, HWPort4, HWPort6]> {
878   let NumMicroOps = 4;
879   let ResourceCycles = [2, 1, 1];
880 }
881 def : InstRW<[WriteCALLm], (instregex "CALL(16|32)m")>;
882
883 // RET.
884 def WriteRET : SchedWriteRes<[HWPort237, HWPort6]> {
885   let NumMicroOps = 2;
886 }
887 def : InstRW<[WriteRET], (instregex "RET(L|Q|W)", "LRET(L|Q|W)")>;
888
889 // i.
890 def WriteRETI : SchedWriteRes<[HWPort23, HWPort6, HWPort015]> {
891   let NumMicroOps = 4;
892   let ResourceCycles = [1, 2, 1];
893 }
894 def : InstRW<[WriteRETI], (instregex "RETI(L|Q|W)", "LRETI(L|Q|W)")>;
895
896 // BOUND.
897 // r,m.
898 def WriteBOUND : SchedWriteRes<[]> {
899   let NumMicroOps = 15;
900 }
901 def : InstRW<[WriteBOUND], (instregex "BOUNDS(16|32)rm")>;
902
903 // INTO.
904 def WriteINTO : SchedWriteRes<[]> {
905   let NumMicroOps = 4;
906 }
907 def : InstRW<[WriteINTO], (instregex "INTO")>;
908
909 //-- String instructions --//
910
911 // LODSB/W.
912 def : InstRW<[Write2P0156_P23], (instregex "LODS(B|W)")>;
913
914 // LODSD/Q.
915 def : InstRW<[WriteP0156_P23], (instregex "LODS(L|Q)")>;
916
917 // STOS.
918 def WriteSTOS : SchedWriteRes<[HWPort23, HWPort0156, HWPort4]> {
919   let NumMicroOps = 3;
920 }
921 def : InstRW<[WriteSTOS], (instregex "STOS(B|L|Q|W)")>;
922
923 // MOVS.
924 def WriteMOVS : SchedWriteRes<[HWPort23, HWPort4, HWPort0156]> {
925   let Latency = 4;
926   let NumMicroOps = 5;
927   let ResourceCycles = [2, 1, 2];
928 }
929 def : InstRW<[WriteMOVS], (instregex "MOVS(B|L|Q|W)")>;
930
931 // SCAS.
932 def : InstRW<[Write2P0156_P23], (instregex "SCAS(B|W|L|Q)")>;
933
934 // CMPS.
935 def WriteCMPS : SchedWriteRes<[HWPort23, HWPort0156]> {
936   let Latency = 4;
937   let NumMicroOps = 5;
938   let ResourceCycles = [2, 3];
939 }
940 def : InstRW<[WriteCMPS], (instregex "CMPS(B|L|Q|W)")>;
941
942 //-- Synchronization instructions --//
943
944 // XADD.
945 def WriteXADD : SchedWriteRes<[]> {
946   let NumMicroOps = 5;
947 }
948 def : InstRW<[WriteXADD], (instregex "XADD(8|16|32|64)rm")>;
949
950 // CMPXCHG.
951 def WriteCMPXCHG : SchedWriteRes<[]> {
952   let NumMicroOps = 6;
953 }
954 def : InstRW<[WriteCMPXCHG], (instregex "CMPXCHG(8|16|32|64)rm")>;
955
956 // CMPXCHG8B.
957 def WriteCMPXCHG8B : SchedWriteRes<[]> {
958   let NumMicroOps = 15;
959 }
960 def : InstRW<[WriteCMPXCHG8B], (instregex "CMPXCHG8B")>;
961
962 // CMPXCHG16B.
963 def WriteCMPXCHG16B : SchedWriteRes<[]> {
964   let NumMicroOps = 22;
965 }
966 def : InstRW<[WriteCMPXCHG16B], (instregex "CMPXCHG16B")>;
967
968 //-- Other --//
969
970 // PAUSE.
971 def WritePAUSE : SchedWriteRes<[HWPort05, HWPort6]> {
972   let NumMicroOps = 5;
973   let ResourceCycles = [1, 3];
974 }
975 def : InstRW<[WritePAUSE], (instregex "PAUSE")>;
976
977 // LEAVE.
978 def : InstRW<[Write2P0156_P23], (instregex "LEAVE")>;
979
980 // XGETBV.
981 def WriteXGETBV : SchedWriteRes<[]> {
982   let NumMicroOps = 8;
983 }
984 def : InstRW<[WriteXGETBV], (instregex "XGETBV")>;
985
986 // RDTSC.
987 def WriteRDTSC : SchedWriteRes<[]> {
988   let NumMicroOps = 15;
989 }
990 def : InstRW<[WriteRDTSC], (instregex "RDTSC")>;
991
992 // RDPMC.
993 def WriteRDPMC : SchedWriteRes<[]> {
994   let NumMicroOps = 34;
995 }
996 def : InstRW<[WriteRDPMC], (instregex "RDPMC")>;
997
998 // RDRAND.
999 def WriteRDRAND : SchedWriteRes<[HWPort23, HWPort015]> {
1000   let NumMicroOps = 17;
1001   let ResourceCycles = [1, 16];
1002 }
1003 def : InstRW<[WriteRDRAND], (instregex "RDRAND(16|32|64)r")>;
1004
1005 //=== Floating Point x87 Instructions ===//
1006 //-- Move instructions --//
1007
1008 // FLD.
1009 // m80.
1010 def : InstRW<[WriteP01], (instregex "LD_Frr")>;
1011
1012 def WriteLD_F80m : SchedWriteRes<[HWPort01, HWPort23]> {
1013   let Latency = 4;
1014   let NumMicroOps = 4;
1015   let ResourceCycles = [2, 2];
1016 }
1017 def : InstRW<[WriteLD_F80m], (instregex "LD_F80m")>;
1018
1019 // FBLD.
1020 // m80.
1021 def WriteFBLD : SchedWriteRes<[]> {
1022   let Latency = 47;
1023   let NumMicroOps = 43;
1024 }
1025 def : InstRW<[WriteFBLD], (instregex "FBLDm")>;
1026
1027 // FST(P).
1028 // r.
1029 def : InstRW<[WriteP01], (instregex "ST_(F|FP)rr")>;
1030
1031 // m80.
1032 def WriteST_FP80m : SchedWriteRes<[HWPort0156, HWPort23, HWPort4]> {
1033   let NumMicroOps = 7;
1034   let ResourceCycles = [3, 2, 2];
1035 }
1036 def : InstRW<[WriteST_FP80m], (instregex "ST_FP80m")>;
1037
1038 // FBSTP.
1039 // m80.
1040 def WriteFBSTP : SchedWriteRes<[]> {
1041   let NumMicroOps = 226;
1042 }
1043 def : InstRW<[WriteFBSTP], (instregex "FBSTPm")>;
1044
1045 // FXCHG.
1046 def : InstRW<[WriteNop], (instregex "XCH_F")>;
1047
1048 // FILD.
1049 def WriteFILD : SchedWriteRes<[HWPort01, HWPort23]> {
1050   let Latency = 6;
1051   let NumMicroOps = 2;
1052 }
1053 def : InstRW<[WriteFILD], (instregex "ILD_F(16|32|64)m")>;
1054
1055 // FIST(P) FISTTP.
1056 def WriteFIST : SchedWriteRes<[HWPort1, HWPort23, HWPort4]> {
1057   let Latency = 7;
1058   let NumMicroOps = 3;
1059 }
1060 def : InstRW<[WriteFIST], (instregex "IST_(F|FP)(16|32)m")>;
1061
1062 // FLDZ.
1063 def : InstRW<[WriteP01], (instregex "LD_F0")>;
1064
1065 // FLD1.
1066 def : InstRW<[Write2P01], (instregex "LD_F1")>;
1067
1068 // FLDPI FLDL2E etc.
1069 def : InstRW<[Write2P01], (instregex "FLDPI", "FLDL2(T|E)" "FLDL(G|N)2")>;
1070
1071 // FCMOVcc.
1072 def WriteFCMOVcc : SchedWriteRes<[HWPort0, HWPort5]> {
1073   let Latency = 2;
1074   let NumMicroOps = 3;
1075   let ResourceCycles = [2, 1];
1076 }
1077 def : InstRW<[WriteFCMOVcc], (instregex "CMOV(B|BE|P|NB|NBE|NE|NP)_F")>;
1078
1079 // FNSTSW.
1080 // AX.
1081 def WriteFNSTSW : SchedWriteRes<[HWPort0, HWPort0156]> {
1082   let NumMicroOps = 2;
1083 }
1084 def : InstRW<[WriteFNSTSW], (instregex "FNSTSW16r")>;
1085
1086 // m16.
1087 def WriteFNSTSWm : SchedWriteRes<[HWPort0, HWPort4, HWPort237]> {
1088   let Latency = 6;
1089   let NumMicroOps = 3;
1090 }
1091 def : InstRW<[WriteFNSTSWm], (instregex "FNSTSWm")>;
1092
1093 // FLDCW.
1094 def WriteFLDCW : SchedWriteRes<[HWPort01, HWPort23, HWPort6]> {
1095   let Latency = 7;
1096   let NumMicroOps = 3;
1097 }
1098 def : InstRW<[WriteFLDCW], (instregex "FLDCW16m")>;
1099
1100 // FNSTCW.
1101 def WriteFNSTCW : SchedWriteRes<[HWPort237, HWPort4, HWPort6]> {
1102   let NumMicroOps = 3;
1103 }
1104 def : InstRW<[WriteFNSTCW], (instregex "FNSTCW16m")>;
1105
1106 // FINCSTP FDECSTP.
1107 def : InstRW<[WriteP01], (instregex "FINCSTP", "FDECSTP")>;
1108
1109 // FFREE.
1110 def : InstRW<[WriteP01], (instregex "FFREE")>;
1111
1112 // FNSAVE.
1113 def WriteFNSAVE : SchedWriteRes<[]> {
1114   let NumMicroOps = 147;
1115 }
1116 def : InstRW<[WriteFNSAVE], (instregex "FSAVEm")>;
1117
1118 // FRSTOR.
1119 def WriteFRSTOR : SchedWriteRes<[]> {
1120   let NumMicroOps = 90;
1121 }
1122 def : InstRW<[WriteFRSTOR], (instregex "FRSTORm")>;
1123
1124 //-- Arithmetic instructions --//
1125
1126 // FABS.
1127 def : InstRW<[WriteP0], (instregex "ABS_F")>;
1128
1129 // FCHS.
1130 def : InstRW<[WriteP0], (instregex "CHS_F")>;
1131
1132 // FCOM(P) FUCOM(P).
1133 // r.
1134 def : InstRW<[WriteP1], (instregex "COM_FST0r", "COMP_FST0r", "UCOM_Fr",
1135                          "UCOM_FPr")>;
1136 // m.
1137 def : InstRW<[WriteP1_P23], (instregex "FCOM(32|64)m", "FCOMP(32|64)m")>;
1138
1139 // FCOMPP FUCOMPP.
1140 // r.
1141 def : InstRW<[Write2P01], (instregex "FCOMPP", "UCOM_FPPr")>;
1142
1143 // FCOMI(P) FUCOMI(P).
1144 // m.
1145 def : InstRW<[Write3P01], (instregex "COM_FIr", "COM_FIPr", "UCOM_FIr",
1146                            "UCOM_FIPr")>;
1147
1148 // FICOM(P).
1149 def : InstRW<[Write2P1_P23], (instregex "FICOM(16|32)m", "FICOMP(16|32)m")>;
1150
1151 // FTST.
1152 def : InstRW<[WriteP1], (instregex "TST_F")>;
1153
1154 // FXAM.
1155 def : InstRW<[Write2P1], (instregex "FXAM")>;
1156
1157 // FPREM.
1158 def WriteFPREM : SchedWriteRes<[]> {
1159   let Latency = 19;
1160   let NumMicroOps = 28;
1161 }
1162 def : InstRW<[WriteFPREM], (instregex "FPREM")>;
1163
1164 // FPREM1.
1165 def WriteFPREM1 : SchedWriteRes<[]> {
1166   let Latency = 27;
1167   let NumMicroOps = 41;
1168 }
1169 def : InstRW<[WriteFPREM1], (instregex "FPREM1")>;
1170
1171 // FRNDINT.
1172 def WriteFRNDINT : SchedWriteRes<[]> {
1173   let Latency = 11;
1174   let NumMicroOps = 17;
1175 }
1176 def : InstRW<[WriteFRNDINT], (instregex "FRNDINT")>;
1177
1178 //-- Math instructions --//
1179
1180 // FSCALE.
1181 def WriteFSCALE : SchedWriteRes<[]> {
1182   let Latency = 75; // 49-125
1183   let NumMicroOps = 50; // 25-75
1184 }
1185 def : InstRW<[WriteFSCALE], (instregex "FSCALE")>;
1186
1187 // FXTRACT.
1188 def WriteFXTRACT : SchedWriteRes<[]> {
1189   let Latency = 15;
1190   let NumMicroOps = 17;
1191 }
1192 def : InstRW<[WriteFXTRACT], (instregex "FXTRACT")>;
1193
1194 } // SchedModel