]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/X86/X86ScheduleZnver1.td
Merge ^/head r327150 through r327164.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / X86 / X86ScheduleZnver1.td
1 //=- X86ScheduleZnver1.td - X86 Znver1 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 Znver1 to support instruction
11 // scheduling and other instruction cost heuristics.
12 //
13 //===----------------------------------------------------------------------===//
14
15 def Znver1Model : SchedMachineModel {
16   // Zen can decode 4 instructions per cycle.
17   let IssueWidth = 4;
18   // Based on the reorder buffer we define MicroOpBufferSize
19   let MicroOpBufferSize = 192;
20   let LoadLatency = 4;
21   let MispredictPenalty = 17;
22   let HighLatency = 25;
23   let PostRAScheduler = 1;
24
25   // FIXME: This variable is required for incomplete model.
26   // We haven't catered all instructions.
27   // So, we reset the value of this variable so as to
28   // say that the model is incomplete.
29   let CompleteModel = 0;
30 }
31
32 let SchedModel = Znver1Model in {
33
34 // Zen can issue micro-ops to 10 different units in one cycle.
35 // These are
36 //  * Four integer ALU units (ZALU0, ZALU1, ZALU2, ZALU3)
37 //  * Two AGU units (ZAGU0, ZAGU1)
38 //  * Four FPU units (ZFPU0, ZFPU1, ZFPU2, ZFPU3)
39 // AGUs feed load store queues @two loads and 1 store per cycle.
40
41 // Four ALU units are defined below
42 def ZnALU0 : ProcResource<1>;
43 def ZnALU1 : ProcResource<1>;
44 def ZnALU2 : ProcResource<1>;
45 def ZnALU3 : ProcResource<1>;
46
47 // Two AGU units are defined below
48 def ZnAGU0 : ProcResource<1>;
49 def ZnAGU1 : ProcResource<1>;
50
51 // Four FPU units are defined below
52 def ZnFPU0 : ProcResource<1>;
53 def ZnFPU1 : ProcResource<1>;
54 def ZnFPU2 : ProcResource<1>;
55 def ZnFPU3 : ProcResource<1>;
56
57 // FPU grouping
58 def ZnFPU     : ProcResGroup<[ZnFPU0, ZnFPU1, ZnFPU2, ZnFPU3]>;
59 def ZnFPU013  : ProcResGroup<[ZnFPU0, ZnFPU1, ZnFPU3]>;
60 def ZnFPU01   : ProcResGroup<[ZnFPU0, ZnFPU1]>;
61 def ZnFPU12   : ProcResGroup<[ZnFPU1, ZnFPU2]>;
62 def ZnFPU13   : ProcResGroup<[ZnFPU1, ZnFPU3]>;
63 def ZnFPU23   : ProcResGroup<[ZnFPU2, ZnFPU3]>;
64 def ZnFPU02   : ProcResGroup<[ZnFPU0, ZnFPU2]>;
65 def ZnFPU03   : ProcResGroup<[ZnFPU0, ZnFPU3]>;
66
67 // Below are the grouping of the units.
68 // Micro-ops to be issued to multiple units are tackled this way.
69
70 // ALU grouping
71 // ZnALU03 - 0,3 grouping
72 def ZnALU03: ProcResGroup<[ZnALU0, ZnALU3]>;
73
74 // 56 Entry (14x4 entries) Int Scheduler
75 def ZnALU : ProcResGroup<[ZnALU0, ZnALU1, ZnALU2, ZnALU3]> {
76   let BufferSize=56;
77 }
78
79 // 28 Entry (14x2) AGU group. AGUs can't be used for all ALU operations
80 // but are relevant for some instructions
81 def ZnAGU : ProcResGroup<[ZnAGU0, ZnAGU1]> {
82   let BufferSize=28;
83 }
84
85 // Integer Multiplication issued on ALU1.
86 def ZnMultiplier : ProcResource<1>;
87
88 // Integer division issued on ALU2.
89 def ZnDivider : ProcResource<1>;
90
91 // 4 Cycles load-to use Latency is captured
92 def : ReadAdvance<ReadAfterLd, 4>;
93
94 // (a folded load is an instruction that loads and does some operation)
95 // Ex: ADDPD xmm,[mem]-> This instruction has two micro-ops
96 // Instructions with folded loads are usually micro-fused, so they only appear
97 // as two micro-ops.
98 //      a. load and
99 //      b. addpd
100 // This multiclass is for folded loads for integer units.
101 multiclass ZnWriteResPair<X86FoldableSchedWrite SchedRW,
102                           ProcResourceKind ExePort,
103                           int Lat> {
104   // Register variant takes 1-cycle on Execution Port.
105   def : WriteRes<SchedRW, [ExePort]> { let Latency = Lat; }
106
107   // Memory variant also uses a cycle on ZnAGU
108   // adds 4 cycles to the latency.
109   def : WriteRes<SchedRW.Folded, [ZnAGU, ExePort]> {
110      let NumMicroOps = 2;
111      let Latency = !add(Lat, 4);
112   }
113 }
114
115 // This multiclass is for folded loads for floating point units.
116 multiclass ZnWriteResFpuPair<X86FoldableSchedWrite SchedRW,
117                           ProcResourceKind ExePort,
118                           int Lat> {
119   // Register variant takes 1-cycle on Execution Port.
120   def : WriteRes<SchedRW, [ExePort]> { let Latency = Lat; }
121
122   // Memory variant also uses a cycle on ZnAGU
123   // adds 7 cycles to the latency.
124   def : WriteRes<SchedRW.Folded, [ZnAGU, ExePort]> {
125      let Latency = !add(Lat, 7);
126   }
127 }
128
129 // WriteRMW is set for instructions with Memory write
130 // operation in codegen
131 def : WriteRes<WriteRMW, [ZnAGU]>;
132
133 def : WriteRes<WriteStore, [ZnAGU]>;
134 def : WriteRes<WriteMove,  [ZnALU]>;
135 def : WriteRes<WriteLoad,  [ZnAGU]> { let Latency = 8; }
136
137 def : WriteRes<WriteZero,  []>;
138 def : WriteRes<WriteLEA, [ZnALU]>;
139 defm : ZnWriteResPair<WriteALU,   ZnALU, 1>;
140 defm : ZnWriteResPair<WriteShift, ZnALU, 1>;
141 defm : ZnWriteResPair<WriteJump,  ZnALU, 1>;
142
143 // Treat misc copies as a move.
144 def : InstRW<[WriteMove], (instrs COPY)>;
145
146 // IDIV
147 def : WriteRes<WriteIDiv, [ZnALU2, ZnDivider]> {
148   let Latency = 41;
149   let ResourceCycles = [1, 41];
150 }
151
152 def : WriteRes<WriteIDivLd, [ZnALU2, ZnAGU, ZnDivider]> {
153   let Latency = 45;
154   let ResourceCycles = [1, 4, 41];
155 }
156
157 // IMUL
158 def  : WriteRes<WriteIMulH, [ZnALU1, ZnMultiplier]>{
159   let Latency = 4;
160 }
161 def : WriteRes<WriteIMul, [ZnALU1, ZnMultiplier]> {
162   let Latency = 4;
163 }
164
165 def : WriteRes<WriteIMulLd,[ZnALU1, ZnMultiplier]> {
166   let Latency = 8;
167 }
168
169 // Floating point operations
170 defm : ZnWriteResFpuPair<WriteFHAdd,     ZnFPU0,  3>;
171 defm : ZnWriteResFpuPair<WriteFAdd,      ZnFPU0,  3>;
172 defm : ZnWriteResFpuPair<WriteFBlend,    ZnFPU01, 1>;
173 defm : ZnWriteResFpuPair<WriteFVarBlend, ZnFPU01, 1>;
174 defm : ZnWriteResFpuPair<WriteVarBlend,  ZnFPU0,  1>;
175 defm : ZnWriteResFpuPair<WriteCvtI2F,    ZnFPU3,  5>;
176 defm : ZnWriteResFpuPair<WriteCvtF2F,    ZnFPU3,  5>;
177 defm : ZnWriteResFpuPair<WriteCvtF2I,    ZnFPU3,  5>;
178 defm : ZnWriteResFpuPair<WriteFDiv,      ZnFPU3, 15>;
179 defm : ZnWriteResFpuPair<WriteFShuffle,  ZnFPU12, 1>;
180 defm : ZnWriteResFpuPair<WriteFMul,      ZnFPU0,  5>;
181 defm : ZnWriteResFpuPair<WriteFMA,       ZnFPU03, 5>;
182 defm : ZnWriteResFpuPair<WriteFRcp,      ZnFPU01, 5>;
183 defm : ZnWriteResFpuPair<WriteFRsqrt,    ZnFPU01, 5>;
184 defm : ZnWriteResFpuPair<WriteFSqrt,     ZnFPU3, 20>;
185
186 // Vector integer operations which uses FPU units
187 defm : ZnWriteResFpuPair<WriteVecShift,   ZnFPU,   1>;
188 defm : ZnWriteResFpuPair<WriteVecLogic,   ZnFPU,   1>;
189 defm : ZnWriteResFpuPair<WritePHAdd,      ZnFPU,   1>;
190 defm : ZnWriteResFpuPair<WriteVecALU,     ZnFPU,   1>;
191 defm : ZnWriteResFpuPair<WriteVecIMul,    ZnFPU0,  4>;
192 defm : ZnWriteResFpuPair<WriteShuffle,    ZnFPU,   1>;
193 defm : ZnWriteResFpuPair<WriteBlend,      ZnFPU01, 1>;
194 defm : ZnWriteResFpuPair<WriteShuffle256, ZnFPU,   2>;
195
196 // Vector Shift Operations
197 defm : ZnWriteResFpuPair<WriteVarVecShift, ZnFPU12, 1>;
198
199 // AES Instructions.
200 defm : ZnWriteResFpuPair<WriteAESDecEnc, ZnFPU01, 4>;
201 defm : ZnWriteResFpuPair<WriteAESIMC, ZnFPU01, 4>;
202 defm : ZnWriteResFpuPair<WriteAESKeyGen, ZnFPU01, 4>;
203
204 def : WriteRes<WriteFence,  [ZnAGU]>;
205 def : WriteRes<WriteNop, []>;
206
207 // Following instructions with latency=100 are microcoded.
208 // We set long latency so as to block the entire pipeline.
209 defm : ZnWriteResFpuPair<WriteFShuffle256, ZnFPU, 100>;
210
211 //Microcoded Instructions
212 let Latency = 100 in {
213   def : WriteRes<WriteMicrocoded, []>;
214   def : WriteRes<WriteSystem, []>;
215   def : WriteRes<WriteMPSAD, []>;
216   def : WriteRes<WriteMPSADLd, []>;
217   def : WriteRes<WriteCLMul, []>;
218   def : WriteRes<WriteCLMulLd, []>;
219   def : WriteRes<WritePCmpIStrM, []>;
220   def : WriteRes<WritePCmpIStrMLd, []>;
221   def : WriteRes<WritePCmpEStrI, []>;
222   def : WriteRes<WritePCmpEStrILd, []>;
223   def : WriteRes<WritePCmpEStrM, []>;
224   def : WriteRes<WritePCmpEStrMLd, []>;
225   def : WriteRes<WritePCmpIStrI, []>;
226   def : WriteRes<WritePCmpIStrILd, []>;
227   }
228
229 //=== Regex based itineraries ===//
230 // Notation:
231 // - r: register.
232 // - m = memory.
233 // - i = immediate
234 // - mm: 64 bit mmx register.
235 // - x = 128 bit xmm register.
236 // - (x)mm = mmx or xmm register.
237 // - y = 256 bit ymm register.
238 // - v = any vector register.
239
240 //=== Integer Instructions ===//
241 //-- Move instructions --//
242 // MOV.
243 // r16,m.
244 def : InstRW<[WriteALULd, ReadAfterLd], (instregex "MOV16rm")>;
245
246 // MOVSX, MOVZX.
247 // r,m.
248 def : InstRW<[WriteLoad], (instregex "MOV(S|Z)X32rm(8|16)")>;
249
250 // CMOVcc.
251 // r,r.
252 def : InstRW<[WriteALU],
253       (instregex "CMOV(O|NO|B|AE|E|NE|BE|A|S|NS|P|NP|L|GE|LE|G)(16|32|64)rr")>;
254 // r,m.
255 def : InstRW<[WriteALULd, ReadAfterLd],
256       (instregex "CMOV(O|NO|B|AE|E|NE|BE|A|S|NS|P|NP|L|GE|LE|G)(16|32|64)rm")>;
257
258 // XCHG.
259 // r,r.
260 def ZnWriteXCHG : SchedWriteRes<[ZnALU]> {
261   let NumMicroOps = 2;
262   let ResourceCycles = [2];
263 }
264
265 def : InstRW<[ZnWriteXCHG], (instregex "XCHG(8|16|32|64)rr", "XCHG(16|32|64)ar")>;
266
267 // r,m.
268 def ZnWriteXCHGrm : SchedWriteRes<[ZnAGU, ZnALU]> {
269   let Latency = 5;
270   let NumMicroOps = 2;
271 }
272 def : InstRW<[ZnWriteXCHGrm, ReadAfterLd], (instregex "XCHG(8|16|32|64)rm")>;
273
274 def : InstRW<[WriteMicrocoded], (instregex "XLAT")>;
275
276 // POP16.
277 // r.
278 def ZnWritePop16r : SchedWriteRes<[ZnAGU]>{
279   let Latency = 5;
280   let NumMicroOps = 2;
281 }
282 def : InstRW<[ZnWritePop16r], (instregex "POP16rmm")>;
283 def : InstRW<[WriteMicrocoded], (instregex "POPF(16|32)")>;
284 def : InstRW<[WriteMicrocoded], (instregex "POPA(16|32)")>;
285
286
287 // PUSH.
288 // r. Has default values.
289 // m.
290 def ZnWritePUSH : SchedWriteRes<[ZnAGU]>{
291   let Latency = 4;
292 }
293 def : InstRW<[ZnWritePUSH], (instregex "PUSH(16|32)rmm")>;
294
295 //PUSHF
296 def : InstRW<[WriteMicrocoded], (instregex "PUSHF(16|32)")>;
297
298 // PUSHA.
299 def ZnWritePushA : SchedWriteRes<[ZnAGU]> {
300   let Latency = 8;
301 }
302 def : InstRW<[ZnWritePushA], (instregex "PUSHA(16|32)")>;
303
304 //LAHF
305 def : InstRW<[WriteMicrocoded], (instregex "LAHF")>;
306
307 // SAHF.
308 def ZnWriteSAHF : SchedWriteRes<[ZnALU]> {
309   let Latency = 2;
310   let NumMicroOps = 2;
311 }
312 def : InstRW<[ZnWriteSAHF], (instregex "SAHF")>;
313
314 // BSWAP.
315 def ZnWriteBSwap : SchedWriteRes<[ZnALU]> {
316   let ResourceCycles = [4];
317 }
318 def : InstRW<[ZnWriteBSwap], (instregex "BSWAP")>;
319
320 // MOVBE.
321 // r,m.
322 def ZnWriteMOVBE : SchedWriteRes<[ZnAGU, ZnALU]> {
323   let Latency = 5;
324 }
325 def : InstRW<[ZnWriteMOVBE, ReadAfterLd], (instregex "MOVBE(16|32|64)rm")>;
326
327 // m16,r16.
328 def : InstRW<[ZnWriteMOVBE], (instregex "MOVBE(16|32|64)mr")>;
329
330 //-- Arithmetic instructions --//
331
332 // ADD SUB.
333 // m,r/i.
334 def : InstRW<[WriteALULd], (instregex "(ADD|SUB)(8|16|32|64)m(r|i)",
335                           "(ADD|SUB)(8|16|32|64)mi8",
336                           "(ADD|SUB)64mi32")>;
337
338 // ADC SBB.
339 // r,r/i.
340 def : InstRW<[WriteALU], (instregex "(ADC|SBB)(8|16|32|64)r(r|i)",
341                           "(ADC|SBB)(16|32|64)ri8",
342                           "(ADC|SBB)64ri32",
343                           "(ADC|SBB)(8|16|32|64)rr_REV")>;
344
345 // r,m.
346 def : InstRW<[WriteALULd, ReadAfterLd],
347             (instregex "(ADC|SBB)(8|16|32|64)rm")>;
348
349 // m,r/i.
350 def : InstRW<[WriteALULd],
351              (instregex "(ADC|SBB)(8|16|32|64)m(r|i)",
352               "(ADC|SBB)(16|32|64)mi8",
353               "(ADC|SBB)64mi32")>;
354
355 // INC DEC NOT NEG.
356 // m.
357 def : InstRW<[WriteALULd],
358              (instregex "(INC|DEC|NOT|NEG)(8|16|32|64)m",
359               "(INC|DEC)64(16|32)m")>;
360
361 // MUL IMUL.
362 // r16.
363 def ZnWriteMul16 : SchedWriteRes<[ZnALU1, ZnMultiplier]> {
364   let Latency = 3;
365 }
366 def : InstRW<[ZnWriteMul16], (instregex "IMUL16r", "MUL16r")>;
367
368 // m16.
369 def ZnWriteMul16Ld : SchedWriteRes<[ZnAGU, ZnALU1, ZnMultiplier]> {
370   let Latency = 8;
371 }
372 def : InstRW<[ZnWriteMul16Ld, ReadAfterLd], (instregex "IMUL16m", "MUL16m")>;
373
374 // r32.
375 def ZnWriteMul32 : SchedWriteRes<[ZnALU1, ZnMultiplier]> {
376   let Latency = 3;
377 }
378 def : InstRW<[ZnWriteMul32], (instregex "IMUL32r", "MUL32r")>;
379
380 // m32.
381 def ZnWriteMul32Ld : SchedWriteRes<[ZnAGU, ZnALU1, ZnMultiplier]> {
382   let Latency = 8;
383 }
384 def : InstRW<[ZnWriteMul32Ld, ReadAfterLd], (instregex "IMUL32m", "MUL32m")>;
385
386 // r64.
387 def ZnWriteMul64 : SchedWriteRes<[ZnALU1, ZnMultiplier]> {
388   let Latency = 4;
389   let NumMicroOps = 2;
390 }
391 def : InstRW<[ZnWriteMul64], (instregex "IMUL64r", "MUL64r")>;
392
393 // m64.
394 def ZnWriteMul64Ld : SchedWriteRes<[ZnAGU, ZnALU1, ZnMultiplier]> {
395   let Latency = 9;
396   let NumMicroOps = 2;
397 }
398 def : InstRW<[ZnWriteMul64Ld, ReadAfterLd], (instregex "IMUL64m", "MUL64m")>;
399
400 // r16,r16.
401 def ZnWriteMul16rri : SchedWriteRes<[ZnALU1, ZnMultiplier]> {
402   let Latency = 3;
403 }
404 def : InstRW<[ZnWriteMul16rri], (instregex "IMUL16rri", "IMUL16rri8")>;
405
406 // r16,m16.
407 def ZnWriteMul16rmi : SchedWriteRes<[ZnAGU, ZnALU1, ZnMultiplier]> {
408   let Latency = 8;
409 }
410 def : InstRW<[ZnWriteMul16rmi, ReadAfterLd], (instregex "IMUL16rmi", "IMUL16rmi8")>;
411
412 // MULX.
413 // r32,r32,r32.
414 def ZnWriteMulX32 : SchedWriteRes<[ZnALU1, ZnMultiplier]> {
415   let Latency = 3;
416   let ResourceCycles = [1, 2];
417 }
418 def : InstRW<[ZnWriteMulX32], (instregex "MULX32rr")>;
419
420 // r32,r32,m32.
421 def ZnWriteMulX32Ld : SchedWriteRes<[ZnAGU, ZnALU1, ZnMultiplier]> {
422   let Latency = 8;
423   let ResourceCycles = [1, 2, 2];
424 }
425 def : InstRW<[ZnWriteMulX32Ld, ReadAfterLd], (instregex "MULX32rm")>;
426
427 // r64,r64,r64.
428 def ZnWriteMulX64 : SchedWriteRes<[ZnALU1]> {
429   let Latency = 3;
430 }
431 def : InstRW<[ZnWriteMulX64], (instregex "MULX64rr")>;
432
433 // r64,r64,m64.
434 def ZnWriteMulX64Ld : SchedWriteRes<[ZnAGU, ZnALU1, ZnMultiplier]> {
435   let Latency = 8;
436 }
437 def : InstRW<[ZnWriteMulX64Ld, ReadAfterLd], (instregex "MULX64rm")>;
438
439 // DIV, IDIV.
440 // r8.
441 def ZnWriteDiv8 : SchedWriteRes<[ZnALU2, ZnDivider]> {
442   let Latency = 15;
443 }
444 def : InstRW<[ZnWriteDiv8], (instregex "DIV8r", "IDIV8r")>;
445
446 // r16.
447 def ZnWriteDiv16 : SchedWriteRes<[ZnALU2, ZnDivider]> {
448   let Latency = 17;
449   let NumMicroOps = 2;
450 }
451 def : InstRW<[ZnWriteDiv16], (instregex "DIV16r", "IDIV16r")>;
452
453 // r32.
454 def ZnWriteDiv32 : SchedWriteRes<[ZnALU2, ZnDivider]> {
455   let Latency = 25;
456   let NumMicroOps = 2;
457 }
458 def : InstRW<[ZnWriteDiv32], (instregex "DIV32r", "IDIV32r")>;
459
460 // r64.
461 def ZnWriteDiv64 : SchedWriteRes<[ZnALU2, ZnDivider]> {
462   let Latency = 41;
463   let NumMicroOps = 2;
464 }
465 def : InstRW<[ZnWriteDiv64], (instregex "DIV64r", "IDIV64r")>;
466
467 //-- Control transfer instructions --//
468
469 // J(E|R)CXZ.
470 def ZnWriteJCXZ : SchedWriteRes<[ZnALU03]>;
471 def : InstRW<[ZnWriteJCXZ], (instregex "JCXZ", "JECXZ_(32|64)", "JRCXZ")>;
472
473 // INTO
474 def : InstRW<[WriteMicrocoded], (instregex "INTO")>;
475
476 // LOOP.
477 def ZnWriteLOOP : SchedWriteRes<[ZnALU03]>;
478 def : InstRW<[ZnWriteLOOP], (instregex "LOOP")>;
479
480 // LOOP(N)E, LOOP(N)Z
481 def ZnWriteLOOPE : SchedWriteRes<[ZnALU03]>;
482 def : InstRW<[ZnWriteLOOPE], (instregex "LOOPE", "LOOPNE",
483                               "LOOPZ", "LOOPNZ")>;
484
485 // CALL.
486 // r.
487 def ZnWriteCALLr : SchedWriteRes<[ZnAGU, ZnALU03]>;
488 def : InstRW<[ZnWriteCALLr], (instregex "CALL(16|32)r")>;
489
490 def : InstRW<[WriteMicrocoded], (instregex "CALL(16|32)m")>;
491
492 // RET.
493 def ZnWriteRET : SchedWriteRes<[ZnALU03]> {
494   let NumMicroOps = 2;
495 }
496 def : InstRW<[ZnWriteRET], (instregex "RET(L|Q|W)", "LRET(L|Q|W)",
497                             "IRET(D|Q)", "RETF")>;
498
499 //-- Logic instructions --//
500
501 // AND OR XOR.
502 // m,r/i.
503 def : InstRW<[WriteALULd],
504              (instregex "(AND|OR|XOR)(8|16|32|64)m(r|i)",
505               "(AND|OR|XOR)(8|16|32|64)mi8", "(AND|OR|XOR)64mi32")>;
506
507 // ANDN.
508 // r,r.
509 def : InstRW<[WriteALU], (instregex "ANDN(32|64)rr")>;
510 // r,m.
511 def : InstRW<[WriteALULd, ReadAfterLd], (instregex "ANDN(32|64)rm")>;
512
513 // Define ALU latency variants
514 def ZnWriteALULat2 : SchedWriteRes<[ZnALU]> {
515   let Latency = 2;
516 }
517 def ZnWriteALULat2Ld : SchedWriteRes<[ZnAGU, ZnALU]> {
518   let Latency = 6;
519 }
520
521 def ZnWriteALULat3 : SchedWriteRes<[ZnALU]> {
522   let Latency = 3;
523 }
524 def ZnWriteALULat3Ld : SchedWriteRes<[ZnAGU, ZnALU]> {
525   let Latency = 7;
526 }
527
528 // BSF BSR.
529 // r,r.
530 def : InstRW<[ZnWriteALULat3], (instregex "BS(R|F)(16|32|64)rr")>;
531 // r,m.
532 def : InstRW<[ZnWriteALULat3Ld, ReadAfterLd], (instregex "BS(R|F)(16|32|64)rm")>;
533
534 // BT.
535 // r,r/i.
536 def : InstRW<[WriteShift], (instregex "BT(16|32|64)r(r|i8)")>;
537
538 def : InstRW<[WriteShiftLd], (instregex "BT(16|32|64)mr")>;
539 def : InstRW<[WriteShiftLd], (instregex "BT(16|32|64)mi8")>;
540
541 // BTR BTS BTC.
542 // r,r,i.
543 def ZnWriteBTRSC : SchedWriteRes<[ZnALU]> {
544   let Latency = 2;
545   let NumMicroOps = 2;
546 }
547 def : InstRW<[ZnWriteBTRSC], (instregex "BT(R|S|C)(16|32|64)r(r|i8)")>;
548
549
550 // m,r,i.
551 def ZnWriteBTRSCm : SchedWriteRes<[ZnAGU, ZnALU]> {
552   let Latency = 6;
553   let NumMicroOps = 2;
554 }
555 // m,r,i.
556 def : InstRW<[ZnWriteBTRSCm], (instregex "BT(R|S|C)(16|32|64)m(r|i8)")>;
557
558 // BLSI BLSMSK BLSR.
559 // r,r.
560 def : InstRW<[ZnWriteALULat2], (instregex "BLS(I|MSK|R)(32|64)rr")>;
561 // r,m.
562 def : InstRW<[ZnWriteALULat2Ld, ReadAfterLd], (instregex "BLS(I|MSK|R)(32|64)rm")>;
563
564 // BEXTR.
565 // r,r,r.
566 def : InstRW<[WriteALU], (instregex "BEXTR(32|64)rr")>;
567 // r,m,r.
568 def : InstRW<[WriteALULd, ReadAfterLd], (instregex "BEXTR(32|64)rm")>;
569
570 // BZHI.
571 // r,r,r.
572 def : InstRW<[WriteALU], (instregex "BZHI(32|64)rr")>;
573 // r,m,r.
574 def : InstRW<[WriteALULd, ReadAfterLd], (instregex "BZHI(32|64)rm")>;
575
576 // CLD STD.
577 def : InstRW<[WriteALU], (instregex "STD", "CLD")>;
578
579 // PDEP PEXT.
580 // r,r,r.
581 def : InstRW<[WriteMicrocoded], (instregex "PDEP(32|64)rr", "PEXT(32|64)rr")>;
582 // r,m,r.
583 def : InstRW<[WriteMicrocoded], (instregex "PDEP(32|64)rm", "PEXT(32|64)rm")>;
584
585 // ROR ROL.
586 def : InstRW<[WriteShift], (instregex "RO(R|L)(8|16|32|64)r1")>;
587
588 // RCR RCL.
589 // r,1.
590 def : InstRW<[WriteShift], (instregex "RC(R|L)(8|16|32|64)r1")>;
591
592 // m,1.
593 def : InstRW<[WriteMicrocoded], (instregex "RC(R|L)(8|16|32|64)m1")>;
594
595 // i.
596 def : InstRW<[WriteShift], (instregex "RC(R|L)(8|16|32|64)r(i|CL)")>;
597
598 // m,i.
599 def : InstRW<[WriteMicrocoded], (instregex "RC(R|L)(8|16|32|64)m(i|CL)")>;
600
601 // SHR SHL SAR.
602 // m,i.
603 def : InstRW<[WriteShiftLd], (instregex "S(A|H)(R|L)(8|16|32|64)m(i|1)")>;
604
605 // SHRD SHLD.
606 // r,r
607 def : InstRW<[WriteShift], (instregex "SH(R|L)D(16|32|64)rri8")>;
608
609 // m,r
610 def : InstRW<[WriteShiftLd], (instregex "SH(R|L)D(16|32|64)mri8")>;
611
612 // r,r,cl.
613 def : InstRW<[WriteMicrocoded], (instregex "SHLD(16|32|64)rrCL")>;
614
615 // r,r,cl.
616 def : InstRW<[WriteMicrocoded], (instregex "SHRD(16|32|64)rrCL")>;
617
618 // m,r,cl.
619 def : InstRW<[WriteMicrocoded], (instregex "SH(R|L)D(16|32|64)mrCL")>;
620
621 // SETcc.
622 // r.
623 def : InstRW<[WriteShift],
624              (instregex "SET(O|NO|B|AE|E|NE|BE|A|S|NS|P|NP|L|GE|LE|G)r")>;
625 // m.
626 def : InstRW<[WriteShift],
627              (instregex "SET(O|NO|B|AE|E|NE|BE|A|S|NS|P|NP|L|GE|LE|G)m")>;
628
629 // LZCNT TZCNT.
630 // r,r.
631 def : InstRW<[ZnWriteALULat2], (instregex "(LZCNT|TZCNT)(16|32|64)rr")>;
632 // r,m.
633 def : InstRW<[ZnWriteALULat2Ld, ReadAfterLd], (instregex "(LZCNT|TZCNT)(16|32|64)rm")>;
634
635 //-- Misc instructions --//
636 // CMPXCHG.
637 def ZnWriteCMPXCHG : SchedWriteRes<[ZnAGU, ZnALU]> {
638   let Latency = 8;
639   let NumMicroOps = 5;
640 }
641 def : InstRW<[ZnWriteCMPXCHG], (instregex "CMPXCHG(8|16|32|64)rm")>;
642
643 // CMPXCHG8B.
644 def ZnWriteCMPXCHG8B : SchedWriteRes<[ZnAGU, ZnALU]> {
645   let NumMicroOps = 18;
646 }
647 def : InstRW<[ZnWriteCMPXCHG8B], (instregex "CMPXCHG8B")>;
648
649 def : InstRW<[WriteMicrocoded], (instregex "CMPXCHG16B")>;
650
651 // LEAVE
652 def ZnWriteLEAVE : SchedWriteRes<[ZnALU, ZnAGU]> {
653   let Latency = 8;
654   let NumMicroOps = 2;
655 }
656 def : InstRW<[ZnWriteLEAVE], (instregex "LEAVE")>;
657
658 // PAUSE.
659 def : InstRW<[WriteMicrocoded], (instregex "PAUSE")>;
660
661 // RDTSC.
662 def : InstRW<[WriteMicrocoded], (instregex "RDTSC")>;
663
664 // RDPMC.
665 def : InstRW<[WriteMicrocoded], (instregex "RDPMC")>;
666
667 // RDRAND.
668 def : InstRW<[WriteMicrocoded], (instregex "RDRAND(16|32|64)r")>;
669
670 // XGETBV.
671 def : InstRW<[WriteMicrocoded], (instregex "XGETBV")>;
672
673 //-- String instructions --//
674 // CMPS.
675 def : InstRW<[WriteMicrocoded], (instregex "CMPS(B|L|Q|W)")>;
676
677 // LODSB/W.
678 def : InstRW<[WriteMicrocoded], (instregex "LODS(B|W)")>;
679
680 // LODSD/Q.
681 def : InstRW<[WriteMicrocoded], (instregex "LODS(L|Q)")>;
682
683 // MOVS.
684 def : InstRW<[WriteMicrocoded], (instregex "MOVS(B|L|Q|W)")>;
685
686 // SCAS.
687 def : InstRW<[WriteMicrocoded], (instregex "SCAS(B|W|L|Q)")>;
688
689 // STOS
690 def : InstRW<[WriteMicrocoded], (instregex "STOS(B|L|Q|W)")>;
691
692 // XADD.
693 def : InstRW<[WriteMicrocoded], (instregex "XADD(8|16|32|64)rm")>;
694
695 //=== Floating Point x87 Instructions ===//
696 //-- Move instructions --//
697
698 def ZnWriteFLDr : SchedWriteRes<[ZnFPU13]> ;
699
700 def ZnWriteSTr: SchedWriteRes<[ZnFPU23]> {
701   let Latency = 5;
702   let NumMicroOps = 2;
703 }
704
705 // LD_F.
706 // r.
707 def : InstRW<[ZnWriteFLDr], (instregex "LD_Frr")>;
708
709 // m.
710 def ZnWriteLD_F80m : SchedWriteRes<[ZnAGU, ZnFPU13]> {
711   let NumMicroOps = 2;
712 }
713 def : InstRW<[ZnWriteLD_F80m], (instregex "LD_F80m")>;
714
715 // FBLD.
716 def : InstRW<[WriteMicrocoded], (instregex "FBLDm")>;
717
718 // FST(P).
719 // r.
720 def : InstRW<[ZnWriteSTr], (instregex "ST_(F|FP)rr")>;
721
722 // m80.
723 def ZnWriteST_FP80m : SchedWriteRes<[ZnAGU, ZnFPU23]> {
724   let Latency = 5;
725 }
726 def : InstRW<[ZnWriteST_FP80m], (instregex "ST_FP80m")>;
727
728 // FBSTP.
729 // m80.
730 def : InstRW<[WriteMicrocoded], (instregex "FBSTPm")>;
731
732 def ZnWriteFXCH : SchedWriteRes<[ZnFPU]>;
733
734 // FXCHG.
735 def : InstRW<[ZnWriteFXCH], (instregex "XCH_F")>;
736
737 // FILD.
738 def ZnWriteFILD : SchedWriteRes<[ZnAGU, ZnFPU3]> {
739   let Latency = 11;
740   let NumMicroOps = 2;
741 }
742 def : InstRW<[ZnWriteFILD], (instregex "ILD_F(16|32|64)m")>;
743
744 // FIST(P) FISTTP.
745 def ZnWriteFIST : SchedWriteRes<[ZnAGU, ZnFPU23]> {
746   let Latency = 12;
747 }
748 def : InstRW<[ZnWriteFIST], (instregex "IS(T|TT)_(F|FP)(16|32|64)m")>;
749
750 def ZnWriteFPU13 : SchedWriteRes<[ZnAGU, ZnFPU13]> {
751   let Latency = 8;
752 }
753
754 def ZnWriteFPU3 : SchedWriteRes<[ZnAGU, ZnFPU3]> {
755   let Latency = 11;
756 }
757
758 // FLDZ.
759 def : InstRW<[ZnWriteFPU13], (instregex "LD_F0")>;
760
761 // FLD1.
762 def : InstRW<[ZnWriteFPU3], (instregex "LD_F1")>;
763
764 // FLDPI FLDL2E etc.
765 def : InstRW<[ZnWriteFPU3], (instregex "FLDPI", "FLDL2(T|E)" "FLDL(G|N)2")>;
766
767 def : InstRW<[WriteMicrocoded], (instregex "CMOV(B|BE|E|P|NB|NBE|NE|NP)_F")>;
768
769 // FNSTSW.
770 // AX.
771 def : InstRW<[WriteMicrocoded], (instregex "FNSTSW16r")>;
772
773 // m16.
774 def : InstRW<[WriteMicrocoded], (instregex "FNSTSWm")>;
775
776 // FLDCW.
777 def : InstRW<[WriteMicrocoded], (instregex "FLDCW16m")>;
778
779 // FNSTCW.
780 def : InstRW<[WriteMicrocoded], (instregex "FNSTCW16m")>;
781
782 // FINCSTP FDECSTP.
783 def : InstRW<[ZnWriteFPU3], (instregex "FINCSTP", "FDECSTP")>;
784
785 // FFREE.
786 def : InstRW<[ZnWriteFPU3], (instregex "FFREE")>;
787
788 // FNSAVE.
789 def : InstRW<[WriteMicrocoded], (instregex "FSAVEm")>;
790
791 // FRSTOR.
792 def : InstRW<[WriteMicrocoded], (instregex "FRSTORm")>;
793
794 //-- Arithmetic instructions --//
795
796 def ZnWriteFPU3Lat2 : SchedWriteRes<[ZnFPU3]> {
797   let Latency = 2;
798 }
799
800 def ZnWriteFPU3Lat2Ld : SchedWriteRes<[ZnAGU, ZnFPU3]> {
801   let Latency = 9;
802 }
803
804 def ZnWriteFPU3Lat1 : SchedWriteRes<[ZnFPU3]> ;
805
806 def ZnWriteFPU0Lat1 : SchedWriteRes<[ZnFPU0]> ;
807
808 def ZnWriteFPU0Lat1Ld : SchedWriteRes<[ZnAGU, ZnFPU0]> {
809   let Latency = 8;
810 }
811
812 // FABS.
813 def : InstRW<[ZnWriteFPU3Lat2], (instregex "ABS_F")>;
814
815 // FCHS.
816 def : InstRW<[ZnWriteFPU3Lat1], (instregex "CHS_F")>;
817
818 // FCOM(P) FUCOM(P).
819 // r.
820 def : InstRW<[ZnWriteFPU0Lat1], (instregex "COM_FST0r", "COMP_FST0r", "UCOM_Fr",
821                          "UCOM_FPr")>;
822 // m.
823 def : InstRW<[ZnWriteFPU0Lat1Ld], (instregex "FCOM(32|64)m", "FCOMP(32|64)m")>;
824
825 // FCOMPP FUCOMPP.
826 // r.
827 def : InstRW<[ZnWriteFPU0Lat1], (instregex "FCOMPP", "UCOM_FPPr")>;
828
829 def ZnWriteFPU02 : SchedWriteRes<[ZnAGU, ZnFPU02]>
830 {
831   let Latency = 9;
832 }
833
834 // FCOMI(P) FUCOMI(P).
835 // m.
836 def : InstRW<[ZnWriteFPU02], (instregex "COM_FIr", "COM_FIPr", "UCOM_FIr",
837                            "UCOM_FIPr")>;
838
839 def ZnWriteFPU03 : SchedWriteRes<[ZnAGU, ZnFPU03]>
840 {
841   let Latency = 12;
842   let NumMicroOps = 2;
843   let ResourceCycles = [1,3];
844 }
845
846 // FICOM(P).
847 def : InstRW<[ZnWriteFPU03], (instregex "FICOM(16|32)m", "FICOMP(16|32)m")>;
848
849 // FTST.
850 def : InstRW<[ZnWriteFPU0Lat1], (instregex "TST_F")>;
851
852 // FXAM.
853 def : InstRW<[ZnWriteFPU3Lat1], (instregex "FXAM")>;
854
855 // FPREM.
856 def : InstRW<[WriteMicrocoded], (instregex "FPREM")>;
857
858 // FPREM1.
859 def : InstRW<[WriteMicrocoded], (instregex "FPREM1")>;
860
861 // FRNDINT.
862 def : InstRW<[WriteMicrocoded], (instregex "FRNDINT")>;
863
864 // FSCALE.
865 def : InstRW<[WriteMicrocoded], (instregex "FSCALE")>;
866
867 // FXTRACT.
868 def : InstRW<[WriteMicrocoded], (instregex "FXTRACT")>;
869
870 // FNOP.
871 def : InstRW<[ZnWriteFPU0Lat1], (instregex "FNOP")>;
872
873 // WAIT.
874 def : InstRW<[ZnWriteFPU0Lat1], (instregex "WAIT")>;
875
876 // FNCLEX.
877 def : InstRW<[WriteMicrocoded], (instregex "FNCLEX")>;
878
879 // FNINIT.
880 def : InstRW<[WriteMicrocoded], (instregex "FNINIT")>;
881
882 //=== Integer MMX and XMM Instructions ===//
883 //-- Move instructions --//
884
885 // Moves from GPR to FPR incurs a penalty
886 def ZnWriteFPU2 : SchedWriteRes<[ZnFPU2]> {
887   let Latency = 3;
888 }
889
890 // Move to ALU doesn't incur penalty
891 def ZnWriteToALU2 : SchedWriteRes<[ZnFPU2]> {
892   let Latency = 2;
893 }
894
895 def ZnWriteFPU : SchedWriteRes<[ZnFPU]>;
896 def ZnWriteFPUY : SchedWriteRes<[ZnFPU]> {
897   let NumMicroOps = 2;
898   let Latency=2;
899 }
900
901 // MOVD.
902 // r32/64 <- (x)mm.
903 def : InstRW<[ZnWriteToALU2], (instregex "MMX_MOVD64grr", "MMX_MOVD64from64rr",
904                          "VMOVPDI2DIrr", "MOVPDI2DIrr")>;
905
906 // (x)mm <- r32/64.
907 def : InstRW<[ZnWriteFPU2], (instregex "MMX_MOVD64rr", "MMX_MOVD64to64rr",
908                          "VMOVDI2PDIrr", "MOVDI2PDIrr")>;
909
910 // MOVQ.
911 // r64 <- (x)mm.
912 def : InstRW<[ZnWriteToALU2], (instregex "VMOVPQIto64rr")>;
913
914 // (x)mm <- r64.
915 def : InstRW<[ZnWriteFPU2], (instregex "VMOV64toPQIrr", "VMOVZQI2PQIrr")>;
916
917 // (x)mm <- (x)mm.
918 def : InstRW<[ZnWriteFPU], (instregex "MMX_MOVQ64rr")>;
919
920 // (V)MOVDQA/U.
921 // x <- x.
922 def : InstRW<[ZnWriteFPU], (instregex "MOVDQ(A|U)rr", "VMOVDQ(A|U)rr",
923                            "MOVDQ(A|U)rr_REV", "VMOVDQ(A|U)rr_REV")>;
924
925 // y <- y.
926 def : InstRW<[ZnWriteFPUY], (instregex "VMOVDQ(A|U)Yrr", "VMOVDQ(A|U)Yrr_REV")>;
927
928 // MOVDQ2Q.
929 def : InstRW<[ZnWriteFPU], (instregex "MMX_MOVDQ2Qrr")>;
930
931 // MOVQ2DQ.
932 def : InstRW<[ZnWriteFPU], (instregex "MMX_MOVQ2DQrr")>;
933
934 // PACKSSWB/DW.
935 // mm <- mm.
936 def ZnWriteFPU12 : SchedWriteRes<[ZnFPU12]> ;
937 def ZnWriteFPU12Y : SchedWriteRes<[ZnFPU12]> {
938   let NumMicroOps = 2;
939 }
940 def ZnWriteFPU12m : SchedWriteRes<[ZnAGU, ZnFPU12]> ;
941
942 def : InstRW<[ZnWriteFPU12], (instregex "MMX_PACKSSDWirr",
943                                   "MMX_PACKSSWBirr", "MMX_PACKUSWBirr")>;
944 def : InstRW<[ZnWriteFPU12m], (instregex "MMX_PACKSSDWirm",
945                                   "MMX_PACKSSWBirm", "MMX_PACKUSWBirm")>;
946
947 // VPMOVSX/ZX BW BD BQ DW DQ.
948 // y <- x.
949 def : InstRW<[ZnWriteFPU12Y], (instregex "VPMOV(SX|ZX)(BW|BQ|DW|DQ)Yrr")>;
950
951 def ZnWriteFPU013 : SchedWriteRes<[ZnFPU013]> ;
952 def ZnWriteFPU013Y : SchedWriteRes<[ZnFPU013]> {
953   let Latency = 2;
954 }
955 def ZnWriteFPU013m : SchedWriteRes<[ZnAGU, ZnFPU013]> {
956   let Latency = 8;
957   let NumMicroOps = 2;
958 }
959 def ZnWriteFPU013Ld : SchedWriteRes<[ZnAGU, ZnFPU013]> {
960   let Latency = 8;
961   let NumMicroOps = 2;
962 }
963 def ZnWriteFPU013LdY : SchedWriteRes<[ZnAGU, ZnFPU013]> {
964   let Latency = 9;
965   let NumMicroOps = 2;
966 }
967
968 // PBLENDW.
969 // x,x,i / v,v,v,i
970 def : InstRW<[ZnWriteFPU013], (instregex "(V?)PBLENDWrri")>;
971 // ymm
972 def : InstRW<[ZnWriteFPU013Y], (instregex "(V?)PBLENDWYrri")>;
973
974 // x,m,i / v,v,m,i
975 def : InstRW<[ZnWriteFPU013Ld], (instregex "(V?)PBLENDWrmi")>;
976 // y,m,i
977 def : InstRW<[ZnWriteFPU013LdY], (instregex "(V?)PBLENDWYrmi")>;
978
979 def ZnWriteFPU01 : SchedWriteRes<[ZnFPU01]> ;
980 def ZnWriteFPU01Y : SchedWriteRes<[ZnFPU01]> {
981   let NumMicroOps = 2;
982 }
983
984 // VPBLENDD.
985 // v,v,v,i.
986 def : InstRW<[ZnWriteFPU01], (instregex "VPBLENDDrri")>;
987 // ymm
988 def : InstRW<[ZnWriteFPU01Y], (instregex "VPBLENDDYrri")>;
989
990 // v,v,m,i
991 def ZnWriteFPU01Op2 : SchedWriteRes<[ZnAGU, ZnFPU01]> {
992   let NumMicroOps = 2;
993   let Latency = 8;
994   let ResourceCycles = [1, 2];
995 }
996 def ZnWriteFPU01Op2Y : SchedWriteRes<[ZnAGU, ZnFPU01]> {
997   let NumMicroOps = 2;
998   let Latency = 9;
999   let ResourceCycles = [1, 3];
1000 }
1001 def : InstRW<[ZnWriteFPU01Op2], (instregex "VPBLENDDrmi")>;
1002 def : InstRW<[ZnWriteFPU01Op2Y], (instregex "VPBLENDDYrmi")>;
1003
1004 // MASKMOVQ.
1005 def : InstRW<[WriteMicrocoded], (instregex "MMX_MASKMOVQ(64)?")>;
1006
1007 // MASKMOVDQU.
1008 def : InstRW<[WriteMicrocoded], (instregex "(V?)MASKMOVDQU(64)?")>;
1009
1010 // VPMASKMOVQ.
1011 // ymm
1012 def : InstRW<[ZnWriteFPU01Op2],(instregex "VPMASKMOVQrm")>;
1013 def : InstRW<[ZnWriteFPU01Op2Y],(instregex "VPMASKMOVQYrm")>;
1014
1015 def : InstRW<[WriteMicrocoded],
1016                                (instregex "VPMASKMOVD(Y?)rm")>;
1017 // m, v,v.
1018 def : InstRW<[WriteMicrocoded], (instregex "VPMASKMOV(D|Q)(Y?)mr")>;
1019
1020 // PMOVMSKB.
1021 def ZnWritePMOVMSKB : SchedWriteRes<[ZnFPU2]> {
1022   let NumMicroOps = 2;
1023 }
1024 def ZnWritePMOVMSKBY : SchedWriteRes<[ZnFPU2]> {
1025   let Latency = 2;
1026 }
1027 def : InstRW<[ZnWritePMOVMSKB], (instregex "(V|MMX_)?PMOVMSKBrr")>;
1028 def : InstRW<[ZnWritePMOVMSKBY], (instregex "(V|MMX_)?PMOVMSKBYrr")>;
1029
1030 // PEXTR B/W/D/Q.
1031 // r32,x,i.
1032 def ZnWritePEXTRr : SchedWriteRes<[ZnFPU12, ZnFPU2]> {
1033   let Latency = 2;
1034   let ResourceCycles = [1, 2];
1035 }
1036 def : InstRW<[ZnWritePEXTRr], (instregex "PEXTR(B|W|D|Q)rr", "MMX_PEXTRWirri")>;
1037
1038 def ZnWritePEXTRm : SchedWriteRes<[ZnAGU, ZnFPU12, ZnFPU2]> {
1039   let Latency = 5;
1040   let NumMicroOps = 2;
1041   let ResourceCycles = [1, 2, 3];
1042 }
1043 // m8,x,i.
1044 def : InstRW<[ZnWritePEXTRm], (instregex "PEXTR(B|W|D|Q)mr")>;
1045
1046 // VPBROADCAST B/W.
1047 // x, m8/16.
1048 def ZnWriteVPBROADCAST128Ld : SchedWriteRes<[ZnAGU, ZnFPU12]> {
1049   let Latency = 8;
1050   let NumMicroOps = 2;
1051   let ResourceCycles = [1, 2];
1052 }
1053 def : InstRW<[ZnWriteVPBROADCAST128Ld],
1054                                      (instregex "VPBROADCAST(B|W)rm")>;
1055
1056 // y, m8/16
1057 def ZnWriteVPBROADCAST256Ld : SchedWriteRes<[ZnAGU, ZnFPU1]> {
1058   let Latency = 8;
1059   let NumMicroOps = 2;
1060   let ResourceCycles = [1, 2];
1061 }
1062 def : InstRW<[ZnWriteVPBROADCAST256Ld],
1063                                      (instregex "VPBROADCAST(B|W)Yrm")>;
1064
1065 // VPGATHER.
1066 def : InstRW<[WriteMicrocoded], (instregex "VPGATHER(Q|D)(Q|D)(Y?)rm")>;
1067
1068 //-- Arithmetic instructions --//
1069
1070 // HADD, HSUB PS/PD
1071 // PHADD|PHSUB (S) W/D.
1072 def : InstRW<[WriteMicrocoded], (instregex "MMX_PHADD(W?)r(r|m)64",
1073                                "MMX_PHADDSWr(r|m)64",
1074                                "MMX_PHSUB(W|D)r(r|m)64",
1075                                "MMX_PHSUBSWrr64",
1076                                "(V?)PH(ADD|SUB)(W|D)(Y?)r(r|m)",
1077                                "(V?)PH(ADD|SUB)SWr(r|m)(256)?")>;
1078
1079
1080 // PCMPGTQ.
1081 def ZnWritePCMPGTQr : SchedWriteRes<[ZnFPU03]>;
1082 def : InstRW<[ZnWritePCMPGTQr], (instregex "(V?)PCMPGTQ(Y?)rr")>;
1083
1084 // x <- x,m.
1085 def ZnWritePCMPGTQm : SchedWriteRes<[ZnAGU, ZnFPU03]> {
1086   let Latency = 8;
1087 }
1088 // ymm.
1089 def ZnWritePCMPGTQYm : SchedWriteRes<[ZnAGU, ZnFPU03]> {
1090   let Latency = 8;
1091   let NumMicroOps = 2;
1092   let ResourceCycles = [1,2];
1093 }
1094 def : InstRW<[ZnWritePCMPGTQm], (instregex "(V?)PCMPGTQrm")>;
1095 def : InstRW<[ZnWritePCMPGTQYm], (instregex "(V?)PCMPGTQYrm")>;
1096
1097 // PMULLD.
1098 // x,x.
1099 def ZnWritePMULLDr : SchedWriteRes<[ZnFPU0]> {
1100   let Latency = 4;
1101 }
1102 // ymm.
1103 def ZnWritePMULLDYr : SchedWriteRes<[ZnFPU0]> {
1104   let Latency = 5;
1105   let ResourceCycles = [2];
1106 }
1107 def : InstRW<[ZnWritePMULLDr], (instregex "(V?)PMULLDrr")>;
1108 def : InstRW<[ZnWritePMULLDYr], (instregex "(V?)PMULLDYrr")>;
1109
1110 // x,m.
1111 def ZnWritePMULLDm : SchedWriteRes<[ZnAGU, ZnFPU0]> {
1112   let Latency = 11;
1113   let NumMicroOps = 2;
1114 }
1115 // y,m.
1116 def ZnWritePMULLDYm : SchedWriteRes<[ZnAGU, ZnFPU0]> {
1117   let Latency = 12;
1118   let NumMicroOps = 2;
1119   let ResourceCycles = [1, 2];
1120 }
1121 def : InstRW<[ZnWritePMULLDm], (instregex "(V?)PMULLDrm")>;
1122 def : InstRW<[ZnWritePMULLDYm], (instregex "(V?)PMULLDYrm")>;
1123
1124 //-- Logic instructions --//
1125
1126 // PTEST.
1127 // v,v.
1128 def ZnWritePTESTr : SchedWriteRes<[ZnFPU12]> {
1129   let ResourceCycles = [2];
1130 }
1131 def : InstRW<[ZnWritePTESTr], (instregex "(V?)PTEST(Y?)rr")>;
1132
1133 // v,m.
1134 def ZnWritePTESTm : SchedWriteRes<[ZnAGU, ZnFPU12]> {
1135   let Latency = 8;
1136   let NumMicroOps = 2;
1137   let ResourceCycles = [1, 2];
1138 }
1139 def : InstRW<[ZnWritePTESTm], (instregex "(V?)PTEST(Y?)rm")>;
1140
1141 // PSLL,PSRL,PSRA W/D/Q.
1142 // x,x / v,v,x.
1143 def ZnWritePShift  : SchedWriteRes<[ZnFPU2]> ;
1144 def ZnWritePShiftY : SchedWriteRes<[ZnFPU2]> {
1145   let Latency = 2;
1146 }
1147 def ZnWritePShiftLd  : SchedWriteRes<[ZnAGU,ZnFPU2]> {
1148   let Latency = 8;
1149 }
1150 def ZnWritePShiftYLd : SchedWriteRes<[ZnAGU, ZnFPU2]> {
1151   let Latency = 9;
1152 }
1153 def : InstRW<[ZnWritePShift], (instregex "(V?)PS(LL|RL|RA)(W|D|Q)rr")>;
1154 def : InstRW<[ZnWritePShiftY], (instregex "(V?)PS(LL|RL|RA)(W|D|Q)Yrr")>;
1155
1156 def : InstRW<[ZnWritePShiftLd], (instregex "(V?)PS(LL|RL|RA)(W|D|Q)rm")>;
1157 def : InstRW<[ZnWritePShiftYLd], (instregex "(V?)PS(LL|RL|RA)(W|D|Q)Yrm")>;
1158
1159 // PSLL,PSRL DQ.
1160 def : InstRW<[ZnWritePShift], (instregex "(V?)PS(R|L)LDQri")>;
1161 def : InstRW<[ZnWritePShiftY], (instregex "(V?)PS(R|L)LDQYri")>;
1162
1163 //=== Floating Point XMM and YMM Instructions ===//
1164 //-- Move instructions --//
1165
1166 // MOVMSKP S/D.
1167 // r32 <- x,y.
1168 def ZnWriteMOVMSKPr : SchedWriteRes<[ZnFPU2]> ;
1169 def : InstRW<[ZnWriteMOVMSKPr], (instregex "(V?)MOVMSKP(S|D)(Y?)rr")>;
1170
1171 // VPERM2F128.
1172 def : InstRW<[WriteMicrocoded], (instregex "VPERM2F128rr")>;
1173 def : InstRW<[WriteMicrocoded], (instregex "VPERM2F128rm")>;
1174
1175 // BLENDVP S/D.
1176 def ZnWriteFPU01Lat3 : SchedWriteRes<[ZnFPU013]> {
1177   let Latency = 3;
1178 }
1179 def ZnWriteFPU01Lat3Ld : SchedWriteRes<[ZnAGU, ZnFPU013]> {
1180   let Latency = 11;
1181   let NumMicroOps = 2;
1182   let ResourceCycles = [1, 2];
1183 }
1184 def : InstRW<[ZnWriteFPU01Lat3], (instregex "BLENDVP(S|D)rr0")>;
1185 def : InstRW<[ZnWriteFPU01Lat3Ld, ReadAfterLd], (instregex "BLENDVP(S|D)rm0")>;
1186
1187 def ZnWriteBROADCAST : SchedWriteRes<[ZnAGU, ZnFPU13]> {
1188   let NumMicroOps = 2;
1189   let Latency = 8;
1190 }
1191 // VBROADCASTF128.
1192 def : InstRW<[ZnWriteBROADCAST], (instregex "VBROADCASTF128")>;
1193
1194 // EXTRACTPS.
1195 // r32,x,i.
1196 def ZnWriteEXTRACTPSr : SchedWriteRes<[ZnFPU12, ZnFPU2]> {
1197   let Latency = 2;
1198   let NumMicroOps = 2;
1199   let ResourceCycles = [1, 2];
1200 }
1201 def : InstRW<[ZnWriteEXTRACTPSr], (instregex "(V?)EXTRACTPSrr")>;
1202
1203 def ZnWriteEXTRACTPSm : SchedWriteRes<[ZnAGU,ZnFPU12, ZnFPU2]> {
1204   let Latency = 5;
1205   let NumMicroOps = 2;
1206   let ResourceCycles = [5, 1, 2];
1207 }
1208 // m32,x,i.
1209 def : InstRW<[ZnWriteEXTRACTPSm], (instregex "(V?)EXTRACTPSmr")>;
1210
1211 // VEXTRACTF128.
1212 // x,y,i.
1213 def : InstRW<[ZnWriteFPU013], (instregex "VEXTRACTF128rr")>;
1214
1215 // m128,y,i.
1216 def : InstRW<[ZnWriteFPU013m], (instregex "VEXTRACTF128mr")>;
1217
1218 def ZnWriteVINSERT128r: SchedWriteRes<[ZnFPU013]> {
1219   let Latency = 2;
1220   let ResourceCycles = [2];
1221 }
1222 def ZnWriteVINSERT128Ld: SchedWriteRes<[ZnAGU,ZnFPU013]> {
1223   let Latency = 9;
1224   let NumMicroOps = 2;
1225   let ResourceCycles = [1, 2];
1226 }
1227 // VINSERTF128.
1228 // y,y,x,i.
1229 def : InstRW<[ZnWriteVINSERT128r], (instregex "VINSERTF128rr")>;
1230 def : InstRW<[ZnWriteVINSERT128Ld], (instregex "VINSERTF128rm")>;
1231
1232 // VMASKMOVP S/D.
1233 // x,x,m.
1234 def ZnWriteVMASKMOVPLd : SchedWriteRes<[ZnAGU, ZnFPU01]> {
1235   let Latency = 8;
1236 }
1237 // y,y,m.
1238 def ZnWriteVMASKMOVPLdY : SchedWriteRes<[ZnAGU, ZnFPU01]> {
1239   let Latency = 8;
1240   let NumMicroOps = 2;
1241   let ResourceCycles = [1, 2];
1242 }
1243 def ZnWriteVMASKMOVPm : SchedWriteRes<[ZnAGU, ZnFPU01]> {
1244   let Latency = 4;
1245 }
1246 def : InstRW<[ZnWriteVMASKMOVPLd], (instregex "VMASKMOVP(S|D)rm")>;
1247 def : InstRW<[ZnWriteVMASKMOVPLdY], (instregex "VMASKMOVP(S|D)Yrm")>;
1248 def : InstRW<[ZnWriteVMASKMOVPm], (instregex "VMASKMOVP(S|D)mr")>;
1249
1250 // m256,y,y.
1251 def ZnWriteVMASKMOVPYmr : SchedWriteRes<[ZnAGU,ZnFPU01]> {
1252   let Latency = 5;
1253   let NumMicroOps = 2;
1254   let ResourceCycles = [1, 2];
1255 }
1256 def : InstRW<[ZnWriteVMASKMOVPYmr], (instregex "VMASKMOVP(S|D)Ymr")>;
1257
1258 // VGATHERDPS.
1259 // x.
1260 def : InstRW<[WriteMicrocoded], (instregex "VGATHERDPSrm")>;
1261 // y.
1262 def : InstRW<[WriteMicrocoded], (instregex "VGATHERDPSYrm")>;
1263
1264 // VGATHERQPS.
1265 // x.
1266 def : InstRW<[WriteMicrocoded], (instregex "VGATHERQPSrm")>;
1267
1268 // y.
1269 def : InstRW<[WriteMicrocoded], (instregex "VGATHERQPSYrm")>;
1270
1271 // VGATHERDPD.
1272 // x.
1273 def : InstRW<[WriteMicrocoded], (instregex "VGATHERDPDrm")>;
1274
1275 // y.
1276 def : InstRW<[WriteMicrocoded], (instregex "VGATHERDPDYrm")>;
1277
1278 // VGATHERQPD.
1279 // x.
1280 def : InstRW<[WriteMicrocoded], (instregex "VGATHERQPDrm")>;
1281
1282 // y.
1283 def : InstRW<[WriteMicrocoded], (instregex "VGATHERQPDYrm")>;
1284
1285 //-- Conversion instructions --//
1286 def ZnWriteCVTPD2PSr: SchedWriteRes<[ZnFPU3]> {
1287   let Latency = 4;
1288 }
1289 // CVTPD2PS.
1290 // x,x.
1291 def : InstRW<[ZnWriteCVTPD2PSr], (instregex "(V?)CVTPD2PSrr")>;
1292
1293 def ZnWriteCVTPD2PSLd: SchedWriteRes<[ZnAGU,ZnFPU03]> {
1294   let Latency = 11;
1295   let NumMicroOps = 2;
1296   let ResourceCycles = [1,2];
1297 }
1298 // x,m128.
1299 def : InstRW<[ZnWriteCVTPD2PSLd], (instregex "(V?)CVTPD2PS(X?)rm")>;
1300
1301 // x,y.
1302 def ZnWriteCVTPD2PSYr : SchedWriteRes<[ZnFPU3]> {
1303   let Latency = 5;
1304 }
1305 def : InstRW<[ZnWriteCVTPD2PSYr], (instregex "(V?)CVTPD2PSYrr")>;
1306
1307 // x,m256.
1308 def ZnWriteCVTPD2PSYLd : SchedWriteRes<[ZnAGU, ZnFPU3]> {
1309   let Latency = 11;
1310 }
1311 def : InstRW<[ZnWriteCVTPD2PSYLd], (instregex "(V?)CVTPD2PSYrm")>;
1312
1313 // CVTSD2SS.
1314 // x,x.
1315 // Same as WriteCVTPD2PSr
1316 def : InstRW<[ZnWriteCVTPD2PSr], (instregex "(Int_)?(V)?CVTSD2SSrr")>;
1317
1318 // x,m64.
1319 def : InstRW<[ZnWriteCVTPD2PSLd], (instregex "(Int_)?(V)?CVTSD2SSrm")>;
1320
1321 // CVTPS2PD.
1322 // x,x.
1323 def ZnWriteCVTPS2PDr : SchedWriteRes<[ZnFPU3]> {
1324   let Latency = 3;
1325 }
1326 def : InstRW<[ZnWriteCVTPS2PDr], (instregex "(V?)CVTPS2PDrr")>;
1327
1328 // x,m64.
1329 // y,m128.
1330 def ZnWriteCVTPS2PDLd : SchedWriteRes<[ZnAGU, ZnFPU3]> {
1331   let Latency = 10;
1332   let NumMicroOps = 2;
1333 }
1334 def : InstRW<[ZnWriteCVTPS2PDLd], (instregex "(V?)CVTPS2PD(Y?)rm")>;
1335
1336 // y,x.
1337 def ZnWriteVCVTPS2PDY : SchedWriteRes<[ZnFPU3]> {
1338   let Latency = 3;
1339 }
1340 def : InstRW<[ZnWriteVCVTPS2PDY], (instregex "VCVTPS2PDYrr")>;
1341
1342 // CVTSS2SD.
1343 // x,x.
1344 def ZnWriteCVTSS2SDr : SchedWriteRes<[ZnFPU3]> {
1345   let Latency = 4;
1346 }
1347 def : InstRW<[ZnWriteCVTSS2SDr], (instregex "(Int_)?(V?)CVTSS2SDrr")>;
1348
1349 // x,m32.
1350 def ZnWriteCVTSS2SDLd : SchedWriteRes<[ZnAGU, ZnFPU3]> {
1351   let Latency = 11;
1352   let NumMicroOps = 2;
1353   let ResourceCycles = [1, 2];
1354 }
1355 def : InstRW<[ZnWriteCVTSS2SDLd], (instregex "(Int_)?(V?)CVTSS2SDrm")>;
1356
1357 def ZnWriteCVTDQ2PDr: SchedWriteRes<[ZnFPU12,ZnFPU3]> {
1358   let Latency = 5;
1359 }
1360 // CVTDQ2PD.
1361 // x,x.
1362 def : InstRW<[ZnWriteCVTDQ2PDr], (instregex "(V)?CVTDQ2PDrr")>;
1363
1364 // Same as xmm
1365 // y,x.
1366 def : InstRW<[ZnWriteCVTDQ2PDr], (instregex "VCVTDQ2PDYrr")>;
1367
1368 def ZnWriteCVTPD2DQr: SchedWriteRes<[ZnFPU12, ZnFPU3]> {
1369   let Latency = 5;
1370 }
1371 // CVT(T)PD2DQ.
1372 // x,x.
1373 def : InstRW<[ZnWriteCVTDQ2PDr], (instregex "(V?)CVT(T?)PD2DQrr")>;
1374
1375 def ZnWriteCVTPD2DQLd: SchedWriteRes<[ZnAGU,ZnFPU12,ZnFPU3]> {
1376   let Latency = 12;
1377   let NumMicroOps = 2;
1378 }
1379 // x,m128.
1380 def : InstRW<[ZnWriteCVTPD2DQLd], (instregex "(V?)CVT(T?)PD2DQrm")>;
1381 // same as xmm handling
1382 // x,y.
1383 def : InstRW<[ZnWriteCVTPD2DQr], (instregex "VCVT(T?)PD2DQYrr")>;
1384 // x,m256.
1385 def : InstRW<[ZnWriteCVTPD2DQLd], (instregex "VCVT(T?)PD2DQYrm")>;
1386 def : InstRW<[ZnWriteCVTPD2DQLd], (instregex "VCVT(T?)PD2DQ(64)?rm")>;
1387
1388 def ZnWriteCVTPS2PIr: SchedWriteRes<[ZnFPU3]> {
1389   let Latency = 4;
1390 }
1391 // CVT(T)PS2PI.
1392 // mm,x.
1393 def : InstRW<[ZnWriteCVTPS2PIr], (instregex "MMX_CVT(T?)PS2PIirr")>;
1394
1395 // CVTPI2PD.
1396 // x,mm.
1397 def : InstRW<[ZnWriteCVTPS2PDr], (instregex "MMX_CVT(T?)PI2PDirr")>;
1398
1399 // CVT(T)PD2PI.
1400 // mm,x.
1401 def : InstRW<[ZnWriteCVTPS2PIr], (instregex "MMX_CVT(T?)PD2PIirr")>;
1402
1403 def ZnWriteCVSTSI2SSr: SchedWriteRes<[ZnFPU3]> {
1404   let Latency = 5;
1405 }
1406 // CVSTSI2SS.
1407 // x,r32.
1408 def : InstRW<[ZnWriteCVSTSI2SSr], (instregex "(Int_)?(V?)CVT(T?)SI2SS(64)?rr")>;
1409
1410 // same as CVTPD2DQr
1411 // CVT(T)SS2SI.
1412 // r32,x.
1413 def : InstRW<[ZnWriteCVTPD2DQr], (instregex "(Int_)?(V?)CVT(T?)SS2SI(64)?rr")>;
1414 // same as CVTPD2DQm
1415 // r32,m32.
1416 def : InstRW<[ZnWriteCVTPD2DQLd], (instregex "(Int_)?(V?)CVT(T?)SS2SI(64)?rm")>;
1417
1418 def ZnWriteCVSTSI2SDr: SchedWriteRes<[ZnFPU013, ZnFPU3]> {
1419   let Latency = 5;
1420 }
1421 // CVTSI2SD.
1422 // x,r32/64.
1423 def : InstRW<[ZnWriteCVSTSI2SDr], (instregex "(Int_)?(V?)CVTSI2SS(64)?rr")>;
1424
1425
1426 def ZnWriteCVSTSI2SIr: SchedWriteRes<[ZnFPU3, ZnFPU2]> {
1427   let Latency = 5;
1428 }
1429 def ZnWriteCVSTSI2SILd: SchedWriteRes<[ZnAGU, ZnFPU3, ZnFPU2]> {
1430   let Latency = 12;
1431 }
1432 // CVTSD2SI.
1433 // r32/64
1434 def : InstRW<[ZnWriteCVSTSI2SIr], (instregex "(Int_)?CVT(T?)SD2SI(64)?rr")>;
1435 // r32,m32.
1436 def : InstRW<[ZnWriteCVSTSI2SILd], (instregex "(Int_)?CVT(T?)SD2SI(64)?rm")>;
1437
1438
1439 def ZnWriteVCVSTSI2SIr: SchedWriteRes<[ZnFPU3]> {
1440   let Latency = 5;
1441 }
1442 def ZnWriteVCVSTSI2SILd: SchedWriteRes<[ZnFPU3, ZnAGU]> {
1443   let Latency = 12;
1444 }
1445 // VCVTSD2SI.
1446 // r32/64
1447 def : InstRW<[ZnWriteCVSTSI2SIr], (instregex "(Int_)?VCVT(T?)SD2SI(64)?rr")>;
1448 // r32,m32.
1449 def : InstRW<[ZnWriteCVSTSI2SILd], (instregex "(Int_)?VCVT(T?)SD2SI(64)?rm")>;
1450
1451 // VCVTPS2PH.
1452 // x,v,i.
1453 def : InstRW<[WriteMicrocoded], (instregex "VCVTPS2PH(Y?)rr")>;
1454 // m,v,i.
1455 def : InstRW<[WriteMicrocoded], (instregex "VCVTPS2PH(Y?)mr")>;
1456
1457 // VCVTPH2PS.
1458 // v,x.
1459 def : InstRW<[WriteMicrocoded], (instregex "VCVTPH2PS(Y?)rr")>;
1460 // v,m.
1461 def : InstRW<[WriteMicrocoded], (instregex "VCVTPH2PS(Y?)rm")>;
1462
1463 //-- SSE4A instructions --//
1464 // EXTRQ
1465 def ZnWriteEXTRQ: SchedWriteRes<[ZnFPU12, ZnFPU2]> {
1466   let Latency = 2;
1467 }
1468 def : InstRW<[ZnWriteEXTRQ], (instregex "EXTRQ")>;
1469
1470 // INSERTQ
1471 def ZnWriteINSERTQ: SchedWriteRes<[ZnFPU03,ZnFPU1]> {
1472   let Latency = 4;
1473 }
1474 def : InstRW<[ZnWriteINSERTQ], (instregex "INSERTQ")>;
1475
1476 // MOVNTSS/MOVNTSD
1477 def ZnWriteMOVNT: SchedWriteRes<[ZnAGU,ZnFPU2]> {
1478   let Latency = 8;
1479 }
1480 def : InstRW<[ZnWriteMOVNT], (instregex "MOVNTS(S|D)")>;
1481
1482 //-- SHA instructions --//
1483 // SHA256MSG2
1484 def : InstRW<[WriteMicrocoded], (instregex "SHA256MSG2(Y?)r(r|m)")>;
1485
1486 // SHA1MSG1, SHA256MSG1
1487 // x,x.
1488 def ZnWriteSHA1MSG1r : SchedWriteRes<[ZnFPU12]> {
1489   let Latency = 2;
1490   let ResourceCycles = [2];
1491 }
1492 def : InstRW<[ZnWriteSHA1MSG1r], (instregex "SHA(1|256)MSG1rr")>;
1493 // x,m.
1494 def ZnWriteSHA1MSG1Ld : SchedWriteRes<[ZnAGU, ZnFPU12]> {
1495   let Latency = 9;
1496   let ResourceCycles = [1,2];
1497 }
1498 def : InstRW<[ZnWriteSHA1MSG1Ld], (instregex "SHA(1|256)MSG1rm")>;
1499
1500 // SHA1MSG2
1501 // x,x.
1502 def ZnWriteSHA1MSG2r : SchedWriteRes<[ZnFPU12]> ;
1503 def : InstRW<[ZnWriteSHA1MSG2r], (instregex "SHA1MSG2rr")>;
1504 // x,m.
1505 def ZnWriteSHA1MSG2Ld : SchedWriteRes<[ZnAGU, ZnFPU12]> {
1506   let Latency = 8;
1507 }
1508 def : InstRW<[ZnWriteSHA1MSG2Ld], (instregex "SHA1MSG2rm")>;
1509
1510 // SHA1NEXTE
1511 // x,x.
1512 def ZnWriteSHA1NEXTEr : SchedWriteRes<[ZnFPU1]> ;
1513 def : InstRW<[ZnWriteSHA1NEXTEr], (instregex "SHA1NEXTErr")>;
1514 // x,m.
1515 def ZnWriteSHA1NEXTELd : SchedWriteRes<[ZnAGU, ZnFPU1]> {
1516   let Latency = 8;
1517 }
1518 def : InstRW<[ZnWriteSHA1NEXTELd], (instregex "SHA1NEXTErm")>;
1519
1520 // SHA1RNDS4
1521 // x,x.
1522 def ZnWriteSHA1RNDS4r : SchedWriteRes<[ZnFPU1]> {
1523   let Latency = 6;
1524 }
1525 def : InstRW<[ZnWriteSHA1RNDS4r], (instregex "SHA1RNDS4rr")>;
1526 // x,m.
1527 def ZnWriteSHA1RNDS4Ld : SchedWriteRes<[ZnAGU, ZnFPU1]> {
1528   let Latency = 13;
1529 }
1530 def : InstRW<[ZnWriteSHA1RNDS4Ld], (instregex "SHA1RNDS4rm")>;
1531
1532 // SHA256RNDS2
1533 // x,x.
1534 def ZnWriteSHA256RNDS2r : SchedWriteRes<[ZnFPU1]> {
1535   let Latency = 4;
1536 }
1537 def : InstRW<[ZnWriteSHA256RNDS2r], (instregex "SHA256RNDS2rr")>;
1538 // x,m.
1539 def ZnWriteSHA256RNDS2Ld : SchedWriteRes<[ZnAGU, ZnFPU1]> {
1540   let Latency = 11;
1541 }
1542 def : InstRW<[ZnWriteSHA256RNDS2Ld], (instregex "SHA256RNDS2rm")>;
1543
1544 //-- Arithmetic instructions --//
1545
1546 // HADD, HSUB PS/PD
1547 def : InstRW<[WriteMicrocoded], (instregex "(V?)H(ADD|SUB)P(S|D)(Y?)r(r|m)")>;
1548
1549 // MULL SS/SD PS/PD.
1550 // x,x / v,v,v.
1551 def ZnWriteMULr : SchedWriteRes<[ZnFPU01]> {
1552   let Latency = 3;
1553 }
1554 // ymm.
1555 def ZnWriteMULYr : SchedWriteRes<[ZnFPU01]> {
1556   let Latency = 4;
1557 }
1558 def : InstRW<[ZnWriteMULr], (instregex "(V?)MUL(P|S)(S|D)rr")>;
1559 def : InstRW<[ZnWriteMULYr], (instregex "(V?)MUL(P|S)(S|D)Yrr")>;
1560
1561 // x,m / v,v,m.
1562 def ZnWriteMULLd : SchedWriteRes<[ZnAGU, ZnFPU01]> {
1563   let Latency = 10;
1564   let NumMicroOps = 2;
1565 }
1566 def : InstRW<[ZnWriteMULLd], (instregex "(V?)MUL(P|S)(S|D)rm")>;
1567
1568 // ymm
1569 def ZnWriteMULYLd : SchedWriteRes<[ZnAGU, ZnFPU01]> {
1570   let Latency = 11;
1571   let NumMicroOps = 2;
1572 }
1573 def : InstRW<[ZnWriteMULYLd], (instregex "(V?)MUL(P|S)(S|D)Yrm")>;
1574
1575 // VDIVPS.
1576 // y,y,y.
1577 def ZnWriteVDIVPSYr : SchedWriteRes<[ZnFPU3]> {
1578   let Latency = 12;
1579   let ResourceCycles = [12];
1580 }
1581 def : InstRW<[ZnWriteVDIVPSYr], (instregex "VDIVPSYrr")>;
1582
1583 // y,y,m256.
1584 def ZnWriteVDIVPSYLd : SchedWriteRes<[ZnAGU, ZnFPU3]> {
1585   let Latency = 19;
1586   let NumMicroOps = 2;
1587   let ResourceCycles = [1, 19];
1588 }
1589 def : InstRW<[ZnWriteVDIVPSYLd], (instregex "VDIVPSYrm")>;
1590
1591 // VDIVPD.
1592 // y,y,y.
1593 def ZnWriteVDIVPDY : SchedWriteRes<[ZnFPU3]> {
1594   let Latency = 15;
1595   let ResourceCycles = [15];
1596 }
1597 def : InstRW<[ZnWriteVDIVPDY], (instregex "VDIVPDYrr")>;
1598
1599 // y,y,m256.
1600 def ZnWriteVDIVPDYLd : SchedWriteRes<[ZnAGU, ZnFPU3]> {
1601   let Latency = 22;
1602   let NumMicroOps = 2;
1603   let ResourceCycles = [1,22];
1604 }
1605 def : InstRW<[ZnWriteVDIVPDYLd], (instregex "VDIVPDYrm")>;
1606
1607 // VRCPPS.
1608 // y,y.
1609 def ZnWriteVRCPPSr : SchedWriteRes<[ZnFPU01]> {
1610   let Latency = 5;
1611 }
1612 def : InstRW<[ZnWriteVRCPPSr], (instregex "VRCPPSYr(_Int)?")>;
1613
1614 // y,m256.
1615 def ZnWriteVRCPPSLd : SchedWriteRes<[ZnAGU, ZnFPU01]> {
1616   let Latency = 12;
1617   let NumMicroOps = 3;
1618 }
1619 def : InstRW<[ZnWriteVRCPPSLd], (instregex "VRCPPSYm(_Int)?")>;
1620
1621 // ROUND SS/SD PS/PD.
1622 // v,v,i.
1623 def ZnWriteROUNDr : SchedWriteRes<[ZnFPU3]> {
1624   let Latency = 4;
1625 }
1626 def : InstRW<[ZnWriteROUNDr], (instregex "(V?)ROUND(Y?)(S|P)(S|D)r(_Int)?")>;
1627
1628 // VFMADD.
1629 // v,v,v.
1630 def ZnWriteFMADDr : SchedWriteRes<[ZnFPU03]> {
1631   let Latency = 5;
1632 }
1633 def : InstRW<[ZnWriteFMADDr],
1634     (instregex
1635     "VF(N?)M(ADD|SUB|ADDSUB|SUBADD)P(S|D)(213|132|231)(Y)?r",
1636     "VF(N?)M(ADD|SUB)(132|231|213)S(S|D)r",
1637     "VF(N?)M(ADD|SUB)S(S|D)4rr(_REV|_Int)?",
1638     "VF(N?)M(ADD|SUB)P(S|D)4rr(Y)?(_REV)?")>;
1639
1640 // v,v,m.
1641 def ZnWriteFMADDm : SchedWriteRes<[ZnAGU, ZnFPU03]> {
1642   let Latency = 12;
1643   let NumMicroOps = 2;
1644 }
1645 def : InstRW<[ZnWriteFMADDm],
1646     (instregex
1647     "VF(N?)M(ADD|SUB|ADDSUB|SUBADD)(213|132|231)P(S|D)(Y)?m",
1648     "VF(N?)M(ADD|SUB)(132|231|213)S(S|D)m",
1649     "VF(N?)M(ADD|SUB)S(S|D)4(rm|mr)(_Int)?",
1650     "VF(N?)M(ADD|SUB)P(S|D)4(rm|mr)(Y)?")>;
1651
1652 // v,m,i.
1653 def ZnWriteROUNDm : SchedWriteRes<[ZnAGU, ZnFPU3]> {
1654   let Latency = 11;
1655   let NumMicroOps = 2;
1656 }
1657 def : InstRW<[ZnWriteROUNDm], (instregex "(V?)ROUND(Y?)(S|P)(S|D)m(_Int)?")>;
1658
1659 // DPPS.
1660 // x,x,i / v,v,v,i.
1661 def : InstRW<[WriteMicrocoded], (instregex "(V?)DPPS(Y?)rri")>;
1662
1663 // x,m,i / v,v,m,i.
1664 def : InstRW<[WriteMicrocoded], (instregex "(V?)DPPS(Y?)rmi")>;
1665
1666 // DPPD.
1667 // x,x,i.
1668 def : InstRW<[WriteMicrocoded], (instregex "(V?)DPPDrri")>;
1669
1670 // x,m,i.
1671 def : InstRW<[WriteMicrocoded], (instregex "(V?)DPPDrmi")>;
1672
1673 // VSQRTPS.
1674 // y,y.
1675 def ZnWriteVSQRTPSYr : SchedWriteRes<[ZnFPU3]> {
1676   let Latency = 28;
1677   let ResourceCycles = [28];
1678 }
1679 def : InstRW<[ZnWriteVSQRTPSYr], (instregex "VSQRTPSYr")>;
1680
1681 // y,m256.
1682 def ZnWriteVSQRTPSYLd : SchedWriteRes<[ZnAGU, ZnFPU3]> {
1683   let Latency = 35;
1684   let ResourceCycles = [1,35];
1685   let NumMicroOps = 2;
1686 }
1687 def : InstRW<[ZnWriteVSQRTPSYLd], (instregex "VSQRTPSYm")>;
1688
1689 // VSQRTPD.
1690 // y,y.
1691 def ZnWriteVSQRTPDYr : SchedWriteRes<[ZnFPU3]> {
1692   let Latency = 40;
1693   let ResourceCycles = [40];
1694 }
1695 def : InstRW<[ZnWriteVSQRTPDYr], (instregex "VSQRTPDYr")>;
1696
1697 // y,m256.
1698 def ZnWriteVSQRTPDYLd : SchedWriteRes<[ZnAGU, ZnFPU3]> {
1699   let Latency = 47;
1700   let NumMicroOps = 2;
1701   let ResourceCycles = [1,47];
1702 }
1703 def : InstRW<[ZnWriteVSQRTPDYLd], (instregex "VSQRTPDYm")>;
1704
1705 // RSQRTSS
1706 // x,x.
1707 def ZnWriteRSQRTSSr : SchedWriteRes<[ZnFPU02]> {
1708   let Latency = 5;
1709 }
1710 def : InstRW<[ZnWriteRSQRTSSr], (instregex "(V?)RSQRTSS(Y?)r(_Int)?")>;
1711
1712 // RSQRTPS
1713 // x,x.
1714 def ZnWriteRSQRTPSr : SchedWriteRes<[ZnFPU01]> {
1715   let Latency = 5;
1716 }
1717 def : InstRW<[ZnWriteRSQRTPSr], (instregex "(V?)RSQRTPS(Y?)r(_Int)?")>;
1718
1719 // RSQRTSSm
1720 // x,m128.
1721 def ZnWriteRSQRTSSLd: SchedWriteRes<[ZnAGU, ZnFPU02]> {
1722   let Latency = 12;
1723   let NumMicroOps = 2;
1724   let ResourceCycles = [1,2];
1725 }
1726 def : InstRW<[ZnWriteRSQRTSSLd], (instregex "(V?)RSQRTSSm(_Int)?")>;
1727
1728 // RSQRTPSm
1729 def ZnWriteRSQRTPSLd : SchedWriteRes<[ZnAGU, ZnFPU01]> {
1730   let Latency = 12;
1731   let NumMicroOps = 2;
1732 }
1733 def : InstRW<[ZnWriteRSQRTPSLd], (instregex "(V?)RSQRTPSm(_Int)?")>;
1734
1735 // RSQRTPS 256.
1736 // y,y.
1737 def ZnWriteRSQRTPSYr : SchedWriteRes<[ZnFPU01]> {
1738   let Latency = 5;
1739   let NumMicroOps = 2;
1740   let ResourceCycles = [2];
1741 }
1742 def : InstRW<[ZnWriteRSQRTPSYr], (instregex "VRSQRTPSYr(_Int)?")>;
1743
1744 // y,m256.
1745 def ZnWriteRSQRTPSYLd : SchedWriteRes<[ZnAGU, ZnFPU01]> {
1746   let Latency = 12;
1747   let NumMicroOps = 2;
1748 }
1749 def : InstRW<[ZnWriteRSQRTPSYLd], (instregex "VRSQRTPSYm(_Int)?")>;
1750
1751 //-- Logic instructions --//
1752
1753 // AND, ANDN, OR, XOR PS/PD.
1754 // x,x / v,v,v.
1755 def : InstRW<[WriteVecLogic], (instregex "(V?)(AND|ANDN|OR|XOR)P(S|D)(Y?)rr")>;
1756 // x,m / v,v,m.
1757 def : InstRW<[WriteVecLogicLd],
1758                          (instregex "(V?)(AND|ANDN|OR|XOR)P(S|D)(Y?)rm")>;
1759
1760 //-- Other instructions --//
1761
1762 // VZEROUPPER.
1763 def : InstRW<[WriteMicrocoded], (instregex "VZEROUPPER")>;
1764
1765 // VZEROALL.
1766 def : InstRW<[WriteMicrocoded], (instregex "VZEROALL")>;
1767
1768 // LDMXCSR.
1769 def : InstRW<[WriteMicrocoded], (instregex "(V)?LDMXCSR")>;
1770
1771 // STMXCSR.
1772 def : InstRW<[WriteMicrocoded], (instregex "(V)?STMXCSR")>;
1773
1774 } // SchedModel