1//=- X86ScheduleZnver2.td - X86 Znver2 Scheduling -------------*- tablegen -*-=//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the machine model for Znver2 to support instruction
10// scheduling and other instruction cost heuristics.
11//
12//===----------------------------------------------------------------------===//
13
14def Znver2Model : SchedMachineModel {
15  // Zen can decode 4 instructions per cycle.
16  let IssueWidth = 4;
17  // Based on the reorder buffer we define MicroOpBufferSize
18  let MicroOpBufferSize = 224;
19  let LoadLatency = 4;
20  let MispredictPenalty = 17;
21  let HighLatency = 25;
22  let PostRAScheduler = 1;
23
24  // FIXME: This variable is required for incomplete model.
25  // We haven't catered all instructions.
26  // So, we reset the value of this variable so as to
27  // say that the model is incomplete.
28  let CompleteModel = 0;
29}
30
31let SchedModel = Znver2Model in {
32
33// Zen can issue micro-ops to 10 different units in one cycle.
34// These are
35//  * Four integer ALU units (ZALU0, ZALU1, ZALU2, ZALU3)
36//  * Three AGU units (ZAGU0, ZAGU1, ZAGU2)
37//  * Four FPU units (ZFPU0, ZFPU1, ZFPU2, ZFPU3)
38// AGUs feed load store queues @two loads and 1 store per cycle.
39
40// Four ALU units are defined below
41def Zn2ALU0 : ProcResource<1>;
42def Zn2ALU1 : ProcResource<1>;
43def Zn2ALU2 : ProcResource<1>;
44def Zn2ALU3 : ProcResource<1>;
45
46// Three AGU units are defined below
47def Zn2AGU0 : ProcResource<1>;
48def Zn2AGU1 : ProcResource<1>;
49def Zn2AGU2 : ProcResource<1>;
50
51// Four FPU units are defined below
52def Zn2FPU0 : ProcResource<1>;
53def Zn2FPU1 : ProcResource<1>;
54def Zn2FPU2 : ProcResource<1>;
55def Zn2FPU3 : ProcResource<1>;
56
57// FPU grouping
58def Zn2FPU013  : ProcResGroup<[Zn2FPU0, Zn2FPU1, Zn2FPU3]>;
59def Zn2FPU01   : ProcResGroup<[Zn2FPU0, Zn2FPU1]>;
60def Zn2FPU12   : ProcResGroup<[Zn2FPU1, Zn2FPU2]>;
61def Zn2FPU13   : ProcResGroup<[Zn2FPU1, Zn2FPU3]>;
62def Zn2FPU23   : ProcResGroup<[Zn2FPU2, Zn2FPU3]>;
63def Zn2FPU02   : ProcResGroup<[Zn2FPU0, Zn2FPU2]>;
64def Zn2FPU03   : ProcResGroup<[Zn2FPU0, Zn2FPU3]>;
65
66// Below are the grouping of the units.
67// Micro-ops to be issued to multiple units are tackled this way.
68
69// ALU grouping
70// Zn2ALU03 - 0,3 grouping
71def Zn2ALU03: ProcResGroup<[Zn2ALU0, Zn2ALU3]>;
72
73// 64 Entry (16x4 entries) Int Scheduler
74def Zn2ALU : ProcResGroup<[Zn2ALU0, Zn2ALU1, Zn2ALU2, Zn2ALU3]> {
75  let BufferSize=64;
76}
77
78// 28 Entry (14x2) AGU group. AGUs can't be used for all ALU operations
79// but are relevant for some instructions
80def Zn2AGU : ProcResGroup<[Zn2AGU0, Zn2AGU1, Zn2AGU2]> {
81  let BufferSize=28;
82}
83
84// Integer Multiplication issued on ALU1.
85def Zn2Multiplier : ProcResource<1>;
86
87// Integer division issued on ALU2.
88def Zn2Divider : ProcResource<1>;
89
90// 4 Cycles load-to use Latency is captured
91def : ReadAdvance<ReadAfterLd, 4>;
92
93// 7 Cycles vector load-to use Latency is captured
94def : ReadAdvance<ReadAfterVecLd, 7>;
95def : ReadAdvance<ReadAfterVecXLd, 7>;
96def : ReadAdvance<ReadAfterVecYLd, 7>;
97
98def : ReadAdvance<ReadInt2Fpu, 0>;
99
100// The Integer PRF for Zen is 168 entries, and it holds the architectural and
101// speculative version of the 64-bit integer registers.
102// Reference: "Software Optimization Guide for AMD Family 17h Processors"
103def Zn2IntegerPRF : RegisterFile<168, [GR64, CCR]>;
104
105// 36 Entry (9x4 entries) floating-point Scheduler
106def Zn2FPU     : ProcResGroup<[Zn2FPU0, Zn2FPU1, Zn2FPU2, Zn2FPU3]> {
107  let BufferSize=36;
108}
109
110// The Zen FP Retire Queue renames SIMD and FP uOps onto a pool of 160 128-bit
111// registers. Operations on 256-bit data types are cracked into two COPs.
112// Reference: "Software Optimization Guide for AMD Family 17h Processors"
113def Zn2FpuPRF: RegisterFile<160, [VR64, VR128, VR256], [1, 1, 2]>;
114
115// The unit can track up to 192 macro ops in-flight.
116// The retire unit handles in-order commit of up to 8 macro ops per cycle.
117// Reference: "Software Optimization Guide for AMD Family 17h Processors"
118// To be noted, the retire unit is shared between integer and FP ops.
119// In SMT mode it is 96 entry per thread. But, we do not use the conservative
120// value here because there is currently no way to fully mode the SMT mode,
121// so there is no point in trying.
122def Zn2RCU : RetireControlUnit<192, 8>;
123
124// (a folded load is an instruction that loads and does some operation)
125// Ex: ADDPD xmm,[mem]-> This instruction has two micro-ops
126// Instructions with folded loads are usually micro-fused, so they only appear
127// as two micro-ops.
128//      a. load and
129//      b. addpd
130// This multiclass is for folded loads for integer units.
131multiclass Zn2WriteResPair<X86FoldableSchedWrite SchedRW,
132                          list<ProcResourceKind> ExePorts,
133                          int Lat, list<int> Res = [], int UOps = 1,
134                          int LoadLat = 4, int LoadUOps = 1> {
135  // Register variant takes 1-cycle on Execution Port.
136  def : WriteRes<SchedRW, ExePorts> {
137    let Latency = Lat;
138    let ResourceCycles = Res;
139    let NumMicroOps = UOps;
140  }
141
142  // Memory variant also uses a cycle on Zn2AGU
143  // adds LoadLat cycles to the latency (default = 4).
144  def : WriteRes<SchedRW.Folded, !listconcat([Zn2AGU], ExePorts)> {
145    let Latency = !add(Lat, LoadLat);
146    let ResourceCycles = !if(!empty(Res), [], !listconcat([1], Res));
147    let NumMicroOps = !add(UOps, LoadUOps);
148  }
149}
150
151// This multiclass is for folded loads for floating point units.
152multiclass Zn2WriteResFpuPair<X86FoldableSchedWrite SchedRW,
153                          list<ProcResourceKind> ExePorts,
154                          int Lat, list<int> Res = [], int UOps = 1,
155                          int LoadLat = 7, int LoadUOps = 0> {
156  // Register variant takes 1-cycle on Execution Port.
157  def : WriteRes<SchedRW, ExePorts> {
158    let Latency = Lat;
159    let ResourceCycles = Res;
160    let NumMicroOps = UOps;
161  }
162
163  // Memory variant also uses a cycle on Zn2AGU
164  // adds LoadLat cycles to the latency (default = 7).
165  def : WriteRes<SchedRW.Folded, !listconcat([Zn2AGU], ExePorts)> {
166    let Latency = !add(Lat, LoadLat);
167    let ResourceCycles = !if(!empty(Res), [], !listconcat([1], Res));
168    let NumMicroOps = !add(UOps, LoadUOps);
169  }
170}
171
172// WriteRMW is set for instructions with Memory write
173// operation in codegen
174def : WriteRes<WriteRMW, [Zn2AGU]>;
175
176def : WriteRes<WriteStore,   [Zn2AGU]>;
177def : WriteRes<WriteStoreNT, [Zn2AGU]>;
178def : WriteRes<WriteMove,    [Zn2ALU]>;
179def : WriteRes<WriteLoad,    [Zn2AGU]> { let Latency = 4; }
180
181// Model the effect of clobbering the read-write mask operand of the GATHER operation.
182// Does not cost anything by itself, only has latency, matching that of the WriteLoad,
183def : WriteRes<WriteVecMaskedGatherWriteback, []> { let Latency = 8; let NumMicroOps = 0; }
184
185def : WriteRes<WriteZero,  []>;
186def : WriteRes<WriteLEA, [Zn2ALU]>;
187defm : Zn2WriteResPair<WriteALU,   [Zn2ALU], 1>;
188defm : Zn2WriteResPair<WriteADC,   [Zn2ALU], 1>;
189
190defm : Zn2WriteResPair<WriteIMul8,     [Zn2ALU1, Zn2Multiplier], 4>;
191
192defm : X86WriteRes<WriteBSWAP32, [Zn2ALU], 1, [4], 1>;
193defm : X86WriteRes<WriteBSWAP64, [Zn2ALU], 1, [4], 1>;
194defm : X86WriteRes<WriteCMPXCHG, [Zn2ALU], 3, [1], 1>;
195defm : X86WriteRes<WriteCMPXCHGRMW,[Zn2ALU,Zn2AGU], 8, [1,1], 5>;
196defm : X86WriteRes<WriteXCHG, [Zn2ALU], 1, [2], 2>;
197
198defm : Zn2WriteResPair<WriteShift,    [Zn2ALU], 1>;
199defm : Zn2WriteResPair<WriteShiftCL,  [Zn2ALU], 1>;
200defm : Zn2WriteResPair<WriteRotate,   [Zn2ALU], 1>;
201defm : Zn2WriteResPair<WriteRotateCL, [Zn2ALU], 1>;
202
203defm : X86WriteRes<WriteSHDrri, [Zn2ALU], 1, [1], 1>;
204defm : X86WriteResUnsupported<WriteSHDrrcl>;
205defm : X86WriteResUnsupported<WriteSHDmri>;
206defm : X86WriteResUnsupported<WriteSHDmrcl>;
207
208defm : Zn2WriteResPair<WriteJump,  [Zn2ALU], 1>;
209defm : Zn2WriteResFpuPair<WriteCRC32, [Zn2FPU0], 3>;
210
211defm : Zn2WriteResPair<WriteCMOV,   [Zn2ALU], 1>;
212def  : WriteRes<WriteSETCC,  [Zn2ALU]>;
213def  : WriteRes<WriteSETCCStore,  [Zn2ALU, Zn2AGU]>;
214defm : X86WriteRes<WriteLAHFSAHF, [Zn2ALU], 2, [1], 2>;
215
216defm : X86WriteRes<WriteBitTest,         [Zn2ALU], 1, [1], 1>;
217defm : X86WriteRes<WriteBitTestImmLd,    [Zn2ALU,Zn2AGU], 5, [1,1], 2>;
218defm : X86WriteRes<WriteBitTestRegLd,    [Zn2ALU,Zn2AGU], 5, [1,1], 2>;
219defm : X86WriteRes<WriteBitTestSet,      [Zn2ALU], 2, [1], 2>;
220
221// Bit counts.
222defm : Zn2WriteResPair<WriteBSF, [Zn2ALU], 3, [12], 6, 4, 2>;
223defm : Zn2WriteResPair<WriteBSR, [Zn2ALU], 4, [16], 6, 4, 2>;
224defm : Zn2WriteResPair<WriteLZCNT,          [Zn2ALU], 1>;
225defm : Zn2WriteResPair<WriteTZCNT,          [Zn2ALU], 2, [2], 2, 4, 0>;
226defm : Zn2WriteResPair<WritePOPCNT,         [Zn2ALU], 1>;
227
228// Treat misc copies as a move.
229def : InstRW<[WriteMove], (instrs COPY)>;
230
231// BMI1 BEXTR, BMI2 BZHI
232defm : Zn2WriteResPair<WriteBEXTR, [Zn2ALU], 1, [1], 1, 4, 1>;
233defm : Zn2WriteResPair<WriteBLS,   [Zn2ALU], 2, [2], 2, 4, 1>;
234defm : Zn2WriteResPair<WriteBZHI,  [Zn2ALU], 1>;
235
236// IDIV
237defm : Zn2WriteResPair<WriteDiv8,   [Zn2ALU2, Zn2Divider], 15, [1,15], 1>;
238defm : Zn2WriteResPair<WriteDiv16,  [Zn2ALU2, Zn2Divider], 17, [1,17], 2>;
239defm : Zn2WriteResPair<WriteDiv32,  [Zn2ALU2, Zn2Divider], 25, [1,25], 2>;
240defm : Zn2WriteResPair<WriteDiv64,  [Zn2ALU2, Zn2Divider], 41, [1,41], 2>;
241defm : Zn2WriteResPair<WriteIDiv8,  [Zn2ALU2, Zn2Divider], 15, [1,15], 1>;
242defm : Zn2WriteResPair<WriteIDiv16, [Zn2ALU2, Zn2Divider], 17, [1,17], 2>;
243defm : Zn2WriteResPair<WriteIDiv32, [Zn2ALU2, Zn2Divider], 25, [1,25], 2>;
244defm : Zn2WriteResPair<WriteIDiv64, [Zn2ALU2, Zn2Divider], 41, [1,41], 2>;
245
246// IMULH
247def Zn2WriteIMulH : WriteRes<WriteIMulH, [Zn2Multiplier]>{
248  let Latency = 3;
249  let NumMicroOps = 0;
250}
251def  : WriteRes<WriteIMulHLd, [Zn2Multiplier]>{
252  let Latency = !add(Zn2WriteIMulH.Latency, Znver2Model.LoadLatency);
253  let NumMicroOps = Zn2WriteIMulH.NumMicroOps;
254}
255
256// Floating point operations
257defm : X86WriteRes<WriteFLoad,         [Zn2AGU], 8, [1], 1>;
258defm : X86WriteRes<WriteFLoadX,        [Zn2AGU], 8, [1], 1>;
259defm : X86WriteRes<WriteFLoadY,        [Zn2AGU], 8, [1], 1>;
260defm : X86WriteRes<WriteFMaskedLoad,   [Zn2AGU,Zn2FPU01], 8, [1,1], 1>;
261defm : X86WriteRes<WriteFMaskedLoadY,  [Zn2AGU,Zn2FPU01], 8, [1,1], 2>;
262
263defm : X86WriteRes<WriteFStore,        [Zn2AGU], 1, [1], 1>;
264defm : X86WriteRes<WriteFStoreX,       [Zn2AGU], 1, [1], 1>;
265defm : X86WriteRes<WriteFStoreY,       [Zn2AGU], 1, [1], 1>;
266defm : X86WriteRes<WriteFStoreNT,      [Zn2AGU,Zn2FPU2], 8, [1,1], 1>;
267defm : X86WriteRes<WriteFStoreNTX,     [Zn2AGU], 1, [1], 1>;
268defm : X86WriteRes<WriteFStoreNTY,     [Zn2AGU], 1, [1], 1>;
269defm : X86WriteRes<WriteFMaskedStore32,  [Zn2AGU,Zn2FPU01], 4, [1,1], 1>;
270defm : X86WriteRes<WriteFMaskedStore32Y, [Zn2AGU,Zn2FPU01], 5, [1,2], 2>;
271defm : X86WriteRes<WriteFMaskedStore64,  [Zn2AGU,Zn2FPU01], 4, [1,1], 1>;
272defm : X86WriteRes<WriteFMaskedStore64Y, [Zn2AGU,Zn2FPU01], 5, [1,2], 2>;
273
274defm : X86WriteRes<WriteFMove,         [Zn2FPU], 1, [1], 1>;
275defm : X86WriteRes<WriteFMoveX,        [Zn2FPU], 1, [1], 1>;
276defm : X86WriteRes<WriteFMoveY,        [Zn2FPU], 1, [1], 1>;
277defm : X86WriteResUnsupported<WriteFMoveZ>;
278
279defm : Zn2WriteResFpuPair<WriteFAdd,      [Zn2FPU23], 3>;
280defm : Zn2WriteResFpuPair<WriteFAddX,     [Zn2FPU23], 3>;
281defm : Zn2WriteResFpuPair<WriteFAddY,     [Zn2FPU23], 3>;
282defm : X86WriteResPairUnsupported<WriteFAddZ>;
283defm : Zn2WriteResFpuPair<WriteFAdd64,    [Zn2FPU23], 3>;
284defm : Zn2WriteResFpuPair<WriteFAdd64X,   [Zn2FPU23], 3>;
285defm : Zn2WriteResFpuPair<WriteFAdd64Y,   [Zn2FPU23], 3>;
286defm : X86WriteResPairUnsupported<WriteFAdd64Z>;
287defm : Zn2WriteResFpuPair<WriteFCmp,      [Zn2FPU01], 1>;
288defm : Zn2WriteResFpuPair<WriteFCmpX,     [Zn2FPU01], 1>;
289defm : Zn2WriteResFpuPair<WriteFCmpY,     [Zn2FPU01], 1>;
290defm : X86WriteResPairUnsupported<WriteFCmpZ>;
291defm : Zn2WriteResFpuPair<WriteFCmp64,    [Zn2FPU01], 1>;
292defm : Zn2WriteResFpuPair<WriteFCmp64X,   [Zn2FPU01], 1>;
293defm : Zn2WriteResFpuPair<WriteFCmp64Y,   [Zn2FPU01], 1>;
294defm : X86WriteResPairUnsupported<WriteFCmp64Z>;
295defm : Zn2WriteResFpuPair<WriteFCom,      [Zn2FPU01,Zn2FPU2], 3, [1,1], 2>;
296defm : Zn2WriteResFpuPair<WriteFComX,     [Zn2FPU01,Zn2FPU2], 3, [1,1], 2>;
297defm : Zn2WriteResFpuPair<WriteFBlend,    [Zn2FPU01], 1>;
298defm : Zn2WriteResFpuPair<WriteFBlendY,   [Zn2FPU01], 1>;
299defm : X86WriteResPairUnsupported<WriteFBlendZ>;
300defm : Zn2WriteResFpuPair<WriteFVarBlend, [Zn2FPU01], 1>;
301defm : Zn2WriteResFpuPair<WriteFVarBlendY,[Zn2FPU01], 1>;
302defm : X86WriteResPairUnsupported<WriteFVarBlendZ>;
303defm : Zn2WriteResFpuPair<WriteCvtSS2I,   [Zn2FPU3],  5>;
304defm : Zn2WriteResFpuPair<WriteCvtPS2I,   [Zn2FPU3],  5>;
305defm : Zn2WriteResFpuPair<WriteCvtPS2IY,  [Zn2FPU3],  5>;
306defm : X86WriteResPairUnsupported<WriteCvtPS2IZ>;
307defm : Zn2WriteResFpuPair<WriteCvtSD2I,   [Zn2FPU3],  5>;
308defm : Zn2WriteResFpuPair<WriteCvtPD2I,   [Zn2FPU3],  5>;
309defm : Zn2WriteResFpuPair<WriteCvtPD2IY,  [Zn2FPU3],  5>;
310defm : X86WriteResPairUnsupported<WriteCvtPD2IZ>;
311defm : Zn2WriteResFpuPair<WriteCvtI2SS,   [Zn2FPU3],  5>;
312defm : Zn2WriteResFpuPair<WriteCvtI2PS,   [Zn2FPU3],  5>;
313defm : Zn2WriteResFpuPair<WriteCvtI2PSY,  [Zn2FPU3],  5>;
314defm : X86WriteResPairUnsupported<WriteCvtI2PSZ>;
315defm : Zn2WriteResFpuPair<WriteCvtI2SD,   [Zn2FPU3],  5>;
316defm : Zn2WriteResFpuPair<WriteCvtI2PD,   [Zn2FPU3],  5>;
317defm : Zn2WriteResFpuPair<WriteCvtI2PDY,  [Zn2FPU3],  5>;
318defm : X86WriteResPairUnsupported<WriteCvtI2PDZ>;
319defm : Zn2WriteResFpuPair<WriteFDiv,      [Zn2FPU3], 10, [5]>;
320defm : Zn2WriteResFpuPair<WriteFDivX,     [Zn2FPU3], 10, [5]>;
321defm : Zn2WriteResFpuPair<WriteFDivY,     [Zn2FPU3], 10, [5]>;
322defm : X86WriteResPairUnsupported<WriteFDivZ>;
323defm : Zn2WriteResFpuPair<WriteFDiv64,    [Zn2FPU3], 13, [6]>;
324defm : Zn2WriteResFpuPair<WriteFDiv64X,   [Zn2FPU3], 13, [6]>;
325defm : Zn2WriteResFpuPair<WriteFDiv64Y,   [Zn2FPU3], 13, [6]>;
326defm : X86WriteResPairUnsupported<WriteFDiv64Z>;
327defm : Zn2WriteResFpuPair<WriteFSign,     [Zn2FPU3],  2>;
328defm : Zn2WriteResFpuPair<WriteFRnd,      [Zn2FPU3],  3, [1], 1, 7, 0>;
329defm : Zn2WriteResFpuPair<WriteFRndY,     [Zn2FPU3],  3, [1], 1, 7, 0>;
330defm : X86WriteResPairUnsupported<WriteFRndZ>;
331defm : Zn2WriteResFpuPair<WriteFLogic,    [Zn2FPU],   1>;
332defm : Zn2WriteResFpuPair<WriteFLogicY,   [Zn2FPU],   1>;
333defm : X86WriteResPairUnsupported<WriteFLogicZ>;
334defm : Zn2WriteResFpuPair<WriteFTest,     [Zn2FPU12], 3, [2], 1, 7, 1>;
335defm : Zn2WriteResFpuPair<WriteFTestY,    [Zn2FPU12], 3, [2], 1, 7, 1>;
336defm : X86WriteResPairUnsupported<WriteFTestZ>;
337defm : Zn2WriteResFpuPair<WriteFShuffle,  [Zn2FPU12], 1>;
338defm : Zn2WriteResFpuPair<WriteFShuffleY, [Zn2FPU12], 1>;
339defm : X86WriteResPairUnsupported<WriteFShuffleZ>;
340defm : Zn2WriteResFpuPair<WriteFVarShuffle, [Zn2FPU12], 3>;
341defm : Zn2WriteResFpuPair<WriteFVarShuffleY,[Zn2FPU12], 3>;
342defm : X86WriteResPairUnsupported<WriteFVarShuffleZ>;
343defm : Zn2WriteResFpuPair<WriteFMul,      [Zn2FPU01], 3>;
344defm : Zn2WriteResFpuPair<WriteFMulX,     [Zn2FPU01], 3>;
345defm : Zn2WriteResFpuPair<WriteFMulY,     [Zn2FPU01], 3>;
346defm : X86WriteResPairUnsupported<WriteFMulZ>;
347defm : Zn2WriteResFpuPair<WriteFMul64,    [Zn2FPU01], 3>;
348defm : Zn2WriteResFpuPair<WriteFMul64X,   [Zn2FPU01], 3>;
349defm : Zn2WriteResFpuPair<WriteFMul64Y,   [Zn2FPU01], 3>;
350defm : X86WriteResPairUnsupported<WriteFMul64Z>;
351defm : Zn2WriteResFpuPair<WriteFMA,       [Zn2FPU01], 5>;
352defm : Zn2WriteResFpuPair<WriteFMAX,      [Zn2FPU01], 5>;
353defm : Zn2WriteResFpuPair<WriteFMAY,      [Zn2FPU01], 5>;
354defm : X86WriteResPairUnsupported<WriteFMAZ>;
355defm : Zn2WriteResFpuPair<WriteFRcp,      [Zn2FPU01], 5>;
356defm : Zn2WriteResFpuPair<WriteFRcpX,     [Zn2FPU01], 5>;
357defm : Zn2WriteResFpuPair<WriteFRcpY,     [Zn2FPU01], 5>;
358defm : X86WriteResPairUnsupported<WriteFRcpZ>;
359defm : Zn2WriteResFpuPair<WriteFRsqrt,    [Zn2FPU01], 5>;
360defm : Zn2WriteResFpuPair<WriteFRsqrtX,   [Zn2FPU01], 5>;
361defm : Zn2WriteResFpuPair<WriteFRsqrtY,   [Zn2FPU01], 5>;
362defm : X86WriteResPairUnsupported<WriteFRsqrtZ>;
363defm : Zn2WriteResFpuPair<WriteFSqrt,     [Zn2FPU3], 14, [7]>;
364defm : Zn2WriteResFpuPair<WriteFSqrtX,    [Zn2FPU3], 14, [7]>;
365defm : Zn2WriteResFpuPair<WriteFSqrtY,    [Zn2FPU3], 14, [7]>;
366defm : X86WriteResPairUnsupported<WriteFSqrtZ>;
367defm : Zn2WriteResFpuPair<WriteFSqrt64,   [Zn2FPU3], 20, [10]>;
368defm : Zn2WriteResFpuPair<WriteFSqrt64X,  [Zn2FPU3], 20, [10]>;
369defm : Zn2WriteResFpuPair<WriteFSqrt64Y,  [Zn2FPU3], 20, [10]>;
370defm : X86WriteResPairUnsupported<WriteFSqrt64Z>;
371defm : Zn2WriteResFpuPair<WriteFSqrt80,   [Zn2FPU3], 20, [20]>;
372defm : Zn2WriteResFpuPair<WriteFShuffle256, [Zn2FPU12], 2>;
373defm : Zn2WriteResFpuPair<WriteFVarShuffle256, [Zn2FPU12], 2>;
374
375// Vector integer operations which uses FPU units
376defm : X86WriteRes<WriteVecLoad,         [Zn2AGU], 8, [1], 1>;
377defm : X86WriteRes<WriteVecLoadX,        [Zn2AGU], 8, [1], 1>;
378defm : X86WriteRes<WriteVecLoadY,        [Zn2AGU], 8, [1], 1>;
379defm : X86WriteRes<WriteVecLoadNT,       [Zn2AGU], 8, [1], 1>;
380defm : X86WriteRes<WriteVecLoadNTY,      [Zn2AGU], 8, [1], 1>;
381defm : X86WriteRes<WriteVecMaskedLoad,   [Zn2AGU,Zn2FPU01], 8, [1,2], 2>;
382defm : X86WriteRes<WriteVecMaskedLoadY,  [Zn2AGU,Zn2FPU01], 8, [1,2], 2>;
383defm : X86WriteRes<WriteVecStore,        [Zn2AGU], 1, [1], 1>;
384defm : X86WriteRes<WriteVecStoreX,       [Zn2AGU], 1, [1], 1>;
385defm : X86WriteRes<WriteVecStoreY,       [Zn2AGU], 1, [1], 1>;
386defm : X86WriteRes<WriteVecStoreNT,      [Zn2AGU], 1, [1], 1>;
387defm : X86WriteRes<WriteVecStoreNTY,     [Zn2AGU], 1, [1], 1>;
388defm : X86WriteRes<WriteVecMaskedStore32,  [Zn2AGU,Zn2FPU01], 4, [1,1], 1>;
389defm : X86WriteRes<WriteVecMaskedStore32Y, [Zn2AGU,Zn2FPU01], 5, [1,2], 2>;
390defm : X86WriteRes<WriteVecMaskedStore64,  [Zn2AGU,Zn2FPU01], 4, [1,1], 1>;
391defm : X86WriteRes<WriteVecMaskedStore64Y, [Zn2AGU,Zn2FPU01], 5, [1,2], 2>;
392defm : X86WriteRes<WriteVecMove,         [Zn2FPU], 1, [1], 1>;
393defm : X86WriteRes<WriteVecMoveX,        [Zn2FPU], 1, [1], 1>;
394defm : X86WriteRes<WriteVecMoveY,        [Zn2FPU], 2, [1], 2>;
395defm : X86WriteResUnsupported<WriteVecMoveZ>;
396defm : X86WriteRes<WriteVecMoveToGpr,    [Zn2FPU2], 2, [1], 1>;
397defm : X86WriteRes<WriteVecMoveFromGpr,  [Zn2FPU2], 3, [1], 1>;
398defm : X86WriteRes<WriteEMMS,            [Zn2FPU], 2, [1], 1>;
399
400defm : Zn2WriteResFpuPair<WriteVecShift,   [Zn2FPU2],  1>;
401defm : Zn2WriteResFpuPair<WriteVecShiftX,  [Zn2FPU2],  1>;
402defm : Zn2WriteResFpuPair<WriteVecShiftY,  [Zn2FPU2],  1>;
403defm : X86WriteResPairUnsupported<WriteVecShiftZ>;
404defm : Zn2WriteResFpuPair<WriteVecShiftImm,  [Zn2FPU2], 1>;
405defm : Zn2WriteResFpuPair<WriteVecShiftImmX, [Zn2FPU2], 1>;
406defm : Zn2WriteResFpuPair<WriteVecShiftImmY, [Zn2FPU2], 1>;
407defm : X86WriteResPairUnsupported<WriteVecShiftImmZ>;
408defm : Zn2WriteResFpuPair<WriteVarVecShift,  [Zn2FPU1], 3, [2], 1>;
409defm : Zn2WriteResFpuPair<WriteVarVecShiftY, [Zn2FPU1], 3, [2], 1>;
410defm : X86WriteResPairUnsupported<WriteVarVecShiftZ>;
411defm : Zn2WriteResFpuPair<WriteVecLogic,   [Zn2FPU],   1>;
412defm : Zn2WriteResFpuPair<WriteVecLogicX,  [Zn2FPU],   1>;
413defm : Zn2WriteResFpuPair<WriteVecLogicY,  [Zn2FPU],   1>;
414defm : X86WriteResPairUnsupported<WriteVecLogicZ>;
415defm : Zn2WriteResFpuPair<WriteVecTest,    [Zn2FPU12], 3, [2], 1, 7, 1>;
416defm : Zn2WriteResFpuPair<WriteVecTestY,   [Zn2FPU12], 3, [2], 1, 7, 1>;
417defm : X86WriteResPairUnsupported<WriteVecTestZ>;
418defm : Zn2WriteResFpuPair<WriteVecALU,     [Zn2FPU013],   1>;
419defm : Zn2WriteResFpuPair<WriteVecALUX,    [Zn2FPU013],   1>;
420defm : Zn2WriteResFpuPair<WriteVecALUY,    [Zn2FPU013],   1>;
421defm : X86WriteResPairUnsupported<WriteVecALUZ>;
422defm : Zn2WriteResFpuPair<WriteVecIMul,    [Zn2FPU0],  4>;
423defm : Zn2WriteResFpuPair<WriteVecIMulX,   [Zn2FPU0],  4>;
424defm : Zn2WriteResFpuPair<WriteVecIMulY,   [Zn2FPU0],  4>;
425defm : X86WriteResPairUnsupported<WriteVecIMulZ>;
426defm : Zn2WriteResFpuPair<WritePMULLD,     [Zn2FPU0],  4, [2]>;
427defm : Zn2WriteResFpuPair<WritePMULLDY,    [Zn2FPU0],  4, [2]>;
428defm : X86WriteResPairUnsupported<WritePMULLDZ>;
429defm : Zn2WriteResFpuPair<WriteShuffle,    [Zn2FPU12],   1>;
430defm : Zn2WriteResFpuPair<WriteShuffleX,   [Zn2FPU12],   1>;
431defm : Zn2WriteResFpuPair<WriteShuffleY,   [Zn2FPU12],   1>;
432defm : X86WriteResPairUnsupported<WriteShuffleZ>;
433defm : Zn2WriteResFpuPair<WriteVarShuffle, [Zn2FPU12],   1>;
434defm : Zn2WriteResFpuPair<WriteVarShuffleX,[Zn2FPU12],   1>;
435defm : Zn2WriteResFpuPair<WriteVarShuffleY,[Zn2FPU12],   1>;
436defm : X86WriteResPairUnsupported<WriteVarShuffleZ>;
437defm : Zn2WriteResFpuPair<WriteBlend,      [Zn2FPU013], 1>;
438defm : Zn2WriteResFpuPair<WriteBlendY,     [Zn2FPU013], 1>;
439defm : X86WriteResPairUnsupported<WriteBlendZ>;
440defm : Zn2WriteResFpuPair<WriteVarBlend,   [Zn2FPU0],  1>;
441defm : Zn2WriteResFpuPair<WriteVarBlendY,  [Zn2FPU0],  1>;
442defm : X86WriteResPairUnsupported<WriteVarBlendZ>;
443defm : Zn2WriteResFpuPair<WriteShuffle256, [Zn2FPU12],   2>;
444defm : Zn2WriteResFpuPair<WriteVPMOV256,   [Zn2FPU12],  4, [1], 2, 4>;
445defm : Zn2WriteResFpuPair<WriteVarShuffle256, [Zn2FPU12],   2>;
446defm : Zn2WriteResFpuPair<WritePSADBW,     [Zn2FPU0],  3>;
447defm : Zn2WriteResFpuPair<WritePSADBWX,    [Zn2FPU0],  3>;
448defm : Zn2WriteResFpuPair<WritePSADBWY,    [Zn2FPU0],  3>;
449defm : X86WriteResPairUnsupported<WritePSADBWZ>;
450defm : Zn2WriteResFpuPair<WritePHMINPOS,   [Zn2FPU0],  4>;
451
452// Vector insert/extract operations.
453defm : Zn2WriteResFpuPair<WriteVecInsert,   [Zn2FPU],   1>;
454
455def : WriteRes<WriteVecExtract, [Zn2FPU12, Zn2FPU2]> {
456  let Latency = 2;
457  let ResourceCycles = [1, 2];
458}
459def : WriteRes<WriteVecExtractSt, [Zn2AGU, Zn2FPU12, Zn2FPU2]> {
460  let Latency = 5;
461  let NumMicroOps = 2;
462  let ResourceCycles = [1, 2, 3];
463}
464
465// MOVMSK Instructions.
466def : WriteRes<WriteFMOVMSK, [Zn2FPU2]>;
467def : WriteRes<WriteMMXMOVMSK, [Zn2FPU2]>;
468def : WriteRes<WriteVecMOVMSK, [Zn2FPU2]>;
469
470def : WriteRes<WriteVecMOVMSKY, [Zn2FPU2]> {
471  let NumMicroOps = 2;
472  let Latency = 2;
473  let ResourceCycles = [2];
474}
475
476// AES Instructions.
477defm : Zn2WriteResFpuPair<WriteAESDecEnc, [Zn2FPU01], 4>;
478defm : Zn2WriteResFpuPair<WriteAESIMC,    [Zn2FPU01], 4>;
479defm : Zn2WriteResFpuPair<WriteAESKeyGen, [Zn2FPU01], 4>;
480
481def : WriteRes<WriteFence,  [Zn2AGU]>;
482def : WriteRes<WriteNop, []>;
483
484// Microcoded Instructions
485def Zn2WriteMicrocoded : SchedWriteRes<[]> {
486  let Latency = 100;
487}
488
489def : SchedAlias<WriteMicrocoded, Zn2WriteMicrocoded>;
490def : SchedAlias<WriteFCMOV, Zn2WriteMicrocoded>;
491def : SchedAlias<WriteSystem, Zn2WriteMicrocoded>;
492def : SchedAlias<WriteMPSAD, Zn2WriteMicrocoded>;
493def : SchedAlias<WriteMPSADY, Zn2WriteMicrocoded>;
494def : SchedAlias<WriteMPSADLd, Zn2WriteMicrocoded>;
495def : SchedAlias<WriteMPSADYLd, Zn2WriteMicrocoded>;
496def : SchedAlias<WriteCLMul, Zn2WriteMicrocoded>;
497def : SchedAlias<WriteCLMulLd, Zn2WriteMicrocoded>;
498def : SchedAlias<WritePCmpIStrM, Zn2WriteMicrocoded>;
499def : SchedAlias<WritePCmpIStrMLd, Zn2WriteMicrocoded>;
500def : SchedAlias<WritePCmpEStrI, Zn2WriteMicrocoded>;
501def : SchedAlias<WritePCmpEStrILd, Zn2WriteMicrocoded>;
502def : SchedAlias<WritePCmpEStrM, Zn2WriteMicrocoded>;
503def : SchedAlias<WritePCmpEStrMLd, Zn2WriteMicrocoded>;
504def : SchedAlias<WritePCmpIStrI, Zn2WriteMicrocoded>;
505def : SchedAlias<WritePCmpIStrILd, Zn2WriteMicrocoded>;
506def : SchedAlias<WriteLDMXCSR, Zn2WriteMicrocoded>;
507def : SchedAlias<WriteSTMXCSR, Zn2WriteMicrocoded>;
508
509//=== Regex based InstRW ===//
510// Notation:
511// - r: register.
512// - m = memory.
513// - i = immediate
514// - mm: 64 bit mmx register.
515// - x = 128 bit xmm register.
516// - (x)mm = mmx or xmm register.
517// - y = 256 bit ymm register.
518// - v = any vector register.
519
520//=== Integer Instructions ===//
521//-- Move instructions --//
522// MOV.
523// r16,m.
524def : InstRW<[WriteALULd, ReadAfterLd], (instrs MOV16rm)>;
525
526// XCHG.
527// r,r.
528def Zn2WriteXCHG : SchedWriteRes<[Zn2ALU]> {
529  let NumMicroOps = 2;
530}
531
532def : InstRW<[Zn2WriteXCHG], (instregex "^XCHG(8|16|32|64)rr", "^XCHG(16|32|64)ar")>;
533
534// r,m.
535def Zn2WriteXCHGrm : SchedWriteRes<[Zn2AGU, Zn2ALU]> {
536  let Latency = 5;
537  let NumMicroOps = 2;
538}
539def : InstRW<[Zn2WriteXCHGrm, ReadAfterLd], (instregex "^XCHG(8|16|32|64)rm")>;
540
541def : InstRW<[WriteMicrocoded], (instrs XLAT)>;
542
543// POP16.
544// r.
545def Zn2WritePop16r : SchedWriteRes<[Zn2AGU]>{
546  let Latency = 5;
547  let NumMicroOps = 2;
548}
549def : InstRW<[Zn2WritePop16r], (instrs POP16rmm)>;
550def : InstRW<[WriteMicrocoded], (instregex "POPF(16|32)")>;
551def : InstRW<[WriteMicrocoded], (instregex "POPA(16|32)")>;
552
553
554// PUSH.
555// r. Has default values.
556// m.
557def Zn2WritePUSH : SchedWriteRes<[Zn2AGU]>{
558  let Latency = 4;
559}
560def : InstRW<[Zn2WritePUSH], (instregex "PUSH(16|32)rmm")>;
561
562// PUSHF
563def : InstRW<[WriteMicrocoded], (instregex "PUSHF(16|32)")>;
564
565// PUSHA.
566def Zn2WritePushA : SchedWriteRes<[Zn2AGU]> {
567  let Latency = 8;
568}
569def : InstRW<[Zn2WritePushA], (instregex "PUSHA(16|32)")>;
570
571//LAHF
572def : InstRW<[WriteMicrocoded], (instrs LAHF)>;
573
574// MOVBE.
575// r,m.
576def Zn2WriteMOVBE : SchedWriteRes<[Zn2AGU, Zn2ALU]> {
577  let Latency = 5;
578}
579def : InstRW<[Zn2WriteMOVBE, ReadAfterLd], (instregex "MOVBE(16|32|64)rm")>;
580
581// m16,r16.
582def : InstRW<[Zn2WriteMOVBE], (instregex "MOVBE(16|32|64)mr")>;
583
584//-- Arithmetic instructions --//
585
586// ADD SUB.
587// m,r/i.
588def : InstRW<[WriteALULd], (instregex "(ADD|SUB)(8|16|32|64)m(r|i)",
589                          "(ADD|SUB)(8|16|32|64)mi8",
590                          "(ADD|SUB)64mi32")>;
591
592// ADC SBB.
593// m,r/i.
594def : InstRW<[WriteALULd],
595             (instregex "(ADC|SBB)(8|16|32|64)m(r|i)",
596              "(ADC|SBB)(16|32|64)mi8",
597              "(ADC|SBB)64mi32")>;
598
599// INC DEC NOT NEG.
600// m.
601def : InstRW<[WriteALULd],
602             (instregex "(INC|DEC|NOT|NEG)(8|16|32|64)m")>;
603
604// MUL IMUL.
605// r16.
606def Zn2WriteMul16 : SchedWriteRes<[Zn2ALU1, Zn2Multiplier]> {
607  let Latency = 3;
608}
609def Zn2WriteMul16Imm : SchedWriteRes<[Zn2ALU1, Zn2Multiplier]> {
610  let Latency = 4;
611}
612def : SchedAlias<WriteIMul16, Zn2WriteMul16>;
613def : SchedAlias<WriteIMul16Imm, Zn2WriteMul16Imm>;
614def : SchedAlias<WriteIMul16Reg, Zn2WriteMul16>;
615
616// m16.
617def Zn2WriteMul16Ld : SchedWriteRes<[Zn2AGU, Zn2ALU1, Zn2Multiplier]> {
618  let Latency = 7;
619}
620def : SchedAlias<WriteIMul16Ld, Zn2WriteMul16Ld>;
621def : SchedAlias<WriteIMul16ImmLd, Zn2WriteMul16Ld>;
622def : SchedAlias<WriteIMul16RegLd, Zn2WriteMul16Ld>;
623
624// r32.
625def Zn2WriteMul32 : SchedWriteRes<[Zn2ALU1, Zn2Multiplier]> {
626  let Latency = 3;
627}
628def : SchedAlias<WriteIMul32, Zn2WriteMul32>;
629def : SchedAlias<WriteIMul32Imm, Zn2WriteMul32>;
630def : SchedAlias<WriteIMul32Reg, Zn2WriteMul32>;
631
632// m32.
633def Zn2WriteMul32Ld : SchedWriteRes<[Zn2AGU, Zn2ALU1, Zn2Multiplier]> {
634  let Latency = 7;
635}
636def : SchedAlias<WriteIMul32Ld, Zn2WriteMul32Ld>;
637def : SchedAlias<WriteIMul32ImmLd, Zn2WriteMul32Ld>;
638def : SchedAlias<WriteIMul32RegLd, Zn2WriteMul32Ld>;
639
640// r64.
641def Zn2WriteMul64 : SchedWriteRes<[Zn2ALU1, Zn2Multiplier]> {
642  let Latency = 4;
643  let NumMicroOps = 2;
644}
645def : SchedAlias<WriteIMul64, Zn2WriteMul64>;
646def : SchedAlias<WriteIMul64Imm, Zn2WriteMul64>;
647def : SchedAlias<WriteIMul64Reg, Zn2WriteMul64>;
648
649// m64.
650def Zn2WriteMul64Ld : SchedWriteRes<[Zn2AGU, Zn2ALU1, Zn2Multiplier]> {
651  let Latency = 8;
652  let NumMicroOps = 2;
653}
654def : SchedAlias<WriteIMul64Ld, Zn2WriteMul64Ld>;
655def : SchedAlias<WriteIMul64ImmLd, Zn2WriteMul64Ld>;
656def : SchedAlias<WriteIMul64RegLd, Zn2WriteMul64Ld>;
657
658// MULX.
659// Numbers are based on the AMD SOG for Family 17h - Instruction Latencies.
660defm : Zn2WriteResPair<WriteMULX32, [Zn2ALU1, Zn2Multiplier], 3, [1, 1], 1, 4, 0>;
661defm : Zn2WriteResPair<WriteMULX64, [Zn2ALU1, Zn2Multiplier], 3, [1, 1], 1, 4, 0>;
662
663//-- Control transfer instructions --//
664
665// J(E|R)CXZ.
666def Zn2WriteJCXZ : SchedWriteRes<[Zn2ALU03]>;
667def : InstRW<[Zn2WriteJCXZ], (instrs JCXZ, JECXZ, JRCXZ)>;
668
669// LOOP.
670def Zn2WriteLOOP : SchedWriteRes<[Zn2ALU03]>;
671def : InstRW<[Zn2WriteLOOP], (instrs LOOP)>;
672
673// LOOP(N)E, LOOP(N)Z
674def Zn2WriteLOOPE : SchedWriteRes<[Zn2ALU03]>;
675def : InstRW<[Zn2WriteLOOPE], (instrs LOOPE, LOOPNE)>;
676
677// CALL.
678// r.
679def Zn2WriteCALLr : SchedWriteRes<[Zn2AGU, Zn2ALU03]>;
680def : InstRW<[Zn2WriteCALLr], (instregex "CALL(16|32)r")>;
681
682def : InstRW<[WriteMicrocoded], (instregex "CALL(16|32)m")>;
683
684// RET.
685def Zn2WriteRET : SchedWriteRes<[Zn2ALU03]> {
686  let NumMicroOps = 2;
687}
688def : InstRW<[Zn2WriteRET], (instregex "RET(16|32|64)", "LRET(16|32|64)",
689                            "IRET(16|32|64)")>;
690
691//-- Logic instructions --//
692
693// AND OR XOR.
694// m,r/i.
695def : InstRW<[WriteALULd],
696             (instregex "(AND|OR|XOR)(8|16|32|64)m(r|i)",
697              "(AND|OR|XOR)(8|16|32|64)mi8", "(AND|OR|XOR)64mi32")>;
698
699// Define ALU latency variants
700def Zn2WriteALULat2 : SchedWriteRes<[Zn2ALU]> {
701  let Latency = 2;
702}
703def Zn2WriteALULat2Ld : SchedWriteRes<[Zn2AGU, Zn2ALU]> {
704  let Latency = 6;
705}
706
707// BTR BTS BTC.
708// m,r,i.
709def Zn2WriteBTRSCm : SchedWriteRes<[Zn2AGU, Zn2ALU]> {
710  let Latency = 6;
711  let NumMicroOps = 2;
712}
713// m,r,i.
714def : SchedAlias<WriteBitTestSetImmRMW, Zn2WriteBTRSCm>;
715def : SchedAlias<WriteBitTestSetRegRMW, Zn2WriteBTRSCm>;
716
717// PDEP PEXT.
718// r,r,r.
719def : InstRW<[WriteMicrocoded], (instregex "PDEP(32|64)rr", "PEXT(32|64)rr")>;
720// r,r,m.
721def : InstRW<[WriteMicrocoded], (instregex "PDEP(32|64)rm", "PEXT(32|64)rm")>;
722
723// RCR RCL.
724// m,i.
725def : InstRW<[WriteMicrocoded], (instregex "RC(R|L)(8|16|32|64)m(1|i|CL)")>;
726
727// SHR SHL SAR.
728// m,i.
729def : InstRW<[WriteShiftLd], (instregex "S(A|H)(R|L)(8|16|32|64)m(i|1)")>;
730
731// SHRD SHLD.
732// m,r
733def : InstRW<[WriteShiftLd], (instregex "SH(R|L)D(16|32|64)mri8")>;
734
735// r,r,cl.
736def : InstRW<[WriteMicrocoded], (instregex "SH(R|L)D(16|32|64)rrCL")>;
737
738// m,r,cl.
739def : InstRW<[WriteMicrocoded], (instregex "SH(R|L)D(16|32|64)mrCL")>;
740
741//-- Misc instructions --//
742// CMPXCHG8B.
743def Zn2WriteCMPXCHG8B : SchedWriteRes<[Zn2AGU, Zn2ALU]> {
744  let NumMicroOps = 18;
745}
746def : InstRW<[Zn2WriteCMPXCHG8B], (instrs CMPXCHG8B)>;
747
748def : InstRW<[WriteMicrocoded], (instrs CMPXCHG16B)>;
749
750// LEAVE
751def Zn2WriteLEAVE : SchedWriteRes<[Zn2ALU, Zn2AGU]> {
752  let Latency = 8;
753  let NumMicroOps = 2;
754}
755def : InstRW<[Zn2WriteLEAVE], (instregex "LEAVE")>;
756
757// PAUSE.
758def : InstRW<[WriteMicrocoded], (instrs PAUSE)>;
759
760// XADD.
761def Zn2XADD : SchedWriteRes<[Zn2ALU]>;
762def : InstRW<[Zn2XADD], (instregex "XADD(8|16|32|64)rr")>;
763def : InstRW<[WriteMicrocoded], (instregex "XADD(8|16|32|64)rm")>;
764
765//=== Floating Point x87 Instructions ===//
766//-- Move instructions --//
767
768def Zn2WriteFLDr : SchedWriteRes<[Zn2FPU13]> ;
769
770def Zn2WriteSTr: SchedWriteRes<[Zn2FPU23]> {
771  let Latency = 5;
772  let NumMicroOps = 2;
773}
774
775// LD_F.
776// r.
777def : InstRW<[Zn2WriteFLDr], (instrs LD_Frr)>;
778
779// m.
780def Zn2WriteLD_F80m : SchedWriteRes<[Zn2AGU, Zn2FPU13]> {
781  let NumMicroOps = 2;
782}
783def : InstRW<[Zn2WriteLD_F80m], (instrs LD_F80m)>;
784
785// FST(P).
786// r.
787def : InstRW<[Zn2WriteSTr], (instregex "ST_(F|FP)rr")>;
788
789// m80.
790def Zn2WriteST_FP80m : SchedWriteRes<[Zn2AGU, Zn2FPU23]> {
791  let Latency = 5;
792}
793def : InstRW<[Zn2WriteST_FP80m], (instrs ST_FP80m)>;
794
795def Zn2WriteFXCH : SchedWriteRes<[Zn2FPU]>;
796
797// FXCHG.
798def : InstRW<[Zn2WriteFXCH], (instrs XCH_F)>;
799
800// FILD.
801def Zn2WriteFILD : SchedWriteRes<[Zn2AGU, Zn2FPU3]> {
802  let Latency = 11;
803  let NumMicroOps = 2;
804}
805def : InstRW<[Zn2WriteFILD], (instregex "ILD_F(16|32|64)m")>;
806
807// FIST(P) FISTTP.
808def Zn2WriteFIST : SchedWriteRes<[Zn2AGU, Zn2FPU23]> {
809  let Latency = 12;
810}
811def : InstRW<[Zn2WriteFIST], (instregex "IS(T|TT)_(F|FP)(16|32|64)m")>;
812
813def Zn2WriteFPU13 : SchedWriteRes<[Zn2AGU, Zn2FPU13]> {
814  let Latency = 8;
815}
816
817def Zn2WriteFPU3 : SchedWriteRes<[Zn2AGU, Zn2FPU3]> {
818  let Latency = 11;
819}
820
821// FLDZ.
822def : SchedAlias<WriteFLD0, Zn2WriteFPU13>;
823
824// FLD1.
825def : SchedAlias<WriteFLD1, Zn2WriteFPU3>;
826
827// FLDPI FLDL2E etc.
828def : SchedAlias<WriteFLDC, Zn2WriteFPU3>;
829
830// FNSTSW.
831// AX.
832def : InstRW<[WriteMicrocoded], (instrs FNSTSW16r)>;
833
834// FLDCW.
835def : InstRW<[WriteMicrocoded], (instrs FLDCW16m)>;
836
837// FNSTCW.
838def : InstRW<[WriteMicrocoded], (instrs FNSTCW16m)>;
839
840// FINCSTP FDECSTP.
841def : InstRW<[Zn2WriteFPU3], (instrs FINCSTP, FDECSTP)>;
842
843// FFREE.
844def : InstRW<[Zn2WriteFPU3], (instregex "FFREE")>;
845
846//-- Arithmetic instructions --//
847
848def Zn2WriteFPU3Lat1 : SchedWriteRes<[Zn2FPU3]> ;
849
850def Zn2WriteFPU0Lat1 : SchedWriteRes<[Zn2FPU0]> ;
851
852def Zn2WriteFPU0Lat1Ld : SchedWriteRes<[Zn2AGU, Zn2FPU0]> {
853  let Latency = 8;
854}
855
856// FCHS.
857def : InstRW<[Zn2WriteFPU3Lat1], (instregex "CHS_F")>;
858
859// FCOM(P) FUCOM(P).
860// r.
861def : InstRW<[Zn2WriteFPU0Lat1], (instregex "COM(P?)_FST0r", "UCOM_F(P?)r")>;
862// m.
863def : InstRW<[Zn2WriteFPU0Lat1Ld], (instregex "FCOM(P?)(32|64)m")>;
864
865// FCOMPP FUCOMPP.
866// r.
867def : InstRW<[Zn2WriteFPU0Lat1], (instrs FCOMPP, UCOM_FPPr)>;
868
869def Zn2WriteFPU02 : SchedWriteRes<[Zn2AGU, Zn2FPU02]>
870{
871  let Latency = 9;
872}
873
874// FCOMI(P) FUCOMI(P).
875// m.
876def : InstRW<[Zn2WriteFPU02], (instrs COM_FIPr, COM_FIr, UCOM_FIPr, UCOM_FIr)>;
877
878def Zn2WriteFPU03 : SchedWriteRes<[Zn2AGU, Zn2FPU03]>
879{
880  let Latency = 12;
881  let NumMicroOps = 2;
882  let ResourceCycles = [1,3];
883}
884
885// FICOM(P).
886def : InstRW<[Zn2WriteFPU03], (instregex "FICOM(P?)(16|32)m")>;
887
888// FTST.
889def : InstRW<[Zn2WriteFPU0Lat1], (instregex "TST_F")>;
890
891// FXAM.
892def : InstRW<[Zn2WriteFPU3Lat1], (instrs XAM_F)>;
893
894// FNOP.
895def : InstRW<[Zn2WriteFPU0Lat1], (instrs FNOP)>;
896
897// WAIT.
898def : InstRW<[Zn2WriteFPU0Lat1], (instrs WAIT)>;
899
900//=== Integer MMX and XMM Instructions ===//
901
902def Zn2WriteFPU013 : SchedWriteRes<[Zn2FPU013]> ;
903def Zn2WriteFPU013m : SchedWriteRes<[Zn2AGU, Zn2FPU013]> {
904  let Latency = 8;
905  let NumMicroOps = 2;
906}
907
908def Zn2WriteFPU01 : SchedWriteRes<[Zn2FPU01]> ;
909def Zn2WriteFPU01Y : SchedWriteRes<[Zn2FPU01]> {
910  let NumMicroOps = 2;
911}
912
913// VPBLENDD.
914// v,v,v,i.
915def : InstRW<[Zn2WriteFPU01], (instrs VPBLENDDrri)>;
916// ymm
917def : InstRW<[Zn2WriteFPU01Y], (instrs VPBLENDDYrri)>;
918
919// v,v,m,i
920def Zn2WriteFPU01Op2 : SchedWriteRes<[Zn2AGU, Zn2FPU01]> {
921  let NumMicroOps = 2;
922  let Latency = 8;
923  let ResourceCycles = [1, 2];
924}
925def Zn2WriteFPU01Op2Y : SchedWriteRes<[Zn2AGU, Zn2FPU01]> {
926  let NumMicroOps = 2;
927  let Latency = 9;
928  let ResourceCycles = [1, 3];
929}
930def : InstRW<[Zn2WriteFPU01Op2], (instrs VPBLENDDrmi)>;
931def : InstRW<[Zn2WriteFPU01Op2Y], (instrs VPBLENDDYrmi)>;
932
933// MASKMOVQ.
934def : InstRW<[WriteMicrocoded], (instregex "MMX_MASKMOVQ(64)?")>;
935
936// MASKMOVDQU.
937def : InstRW<[WriteMicrocoded], (instregex "(V?)MASKMOVDQU(64)?")>;
938
939// VPMASKMOVD.
940// ymm
941def : InstRW<[WriteMicrocoded],
942                               (instregex "VPMASKMOVD(Y?)rm")>;
943// m, v,v.
944def : InstRW<[WriteMicrocoded], (instregex "VPMASKMOV(D|Q)(Y?)mr")>;
945
946// VPBROADCAST B/W.
947// x, m8/16.
948def Zn2WriteVPBROADCAST128Ld : SchedWriteRes<[Zn2AGU, Zn2FPU12]> {
949  let Latency = 8;
950  let NumMicroOps = 2;
951  let ResourceCycles = [1, 2];
952}
953def : InstRW<[Zn2WriteVPBROADCAST128Ld],
954                                     (instregex "VPBROADCAST(B|W)rm")>;
955
956// y, m8/16
957def Zn2WriteVPBROADCAST256Ld : SchedWriteRes<[Zn2AGU, Zn2FPU1]> {
958  let Latency = 8;
959  let NumMicroOps = 2;
960  let ResourceCycles = [1, 2];
961}
962def : InstRW<[Zn2WriteVPBROADCAST256Ld],
963                                     (instregex "VPBROADCAST(B|W)Yrm")>;
964
965// VPGATHER.
966def : InstRW<[WriteMicrocoded], (instregex "VPGATHER(Q|D)(Q|D)(Y?)rm")>;
967
968//-- Arithmetic instructions --//
969
970// HADD, HSUB PS/PD
971// PHADD|PHSUB (S) W/D.
972defm : Zn2WriteResFpuPair<WriteFHAdd, [], 7>;
973defm : Zn2WriteResFpuPair<WriteFHAddY, [], 7>;
974defm : Zn2WriteResFpuPair<WritePHAdd, [], 3>;
975defm : Zn2WriteResFpuPair<WritePHAddX, [], 3>;
976defm : Zn2WriteResFpuPair<WritePHAddY, [], 3>;
977
978// PCMPGTQ.
979def Zn2WritePCMPGTQr : SchedWriteRes<[Zn2FPU03]>;
980def : InstRW<[Zn2WritePCMPGTQr], (instregex "(V?)PCMPGTQ(Y?)rr")>;
981
982// x <- x,m.
983def Zn2WritePCMPGTQm : SchedWriteRes<[Zn2AGU, Zn2FPU03]> {
984  let Latency = 8;
985}
986// ymm.
987def Zn2WritePCMPGTQYm : SchedWriteRes<[Zn2AGU, Zn2FPU03]> {
988  let Latency = 8;
989}
990def : InstRW<[Zn2WritePCMPGTQm], (instregex "(V?)PCMPGTQrm")>;
991def : InstRW<[Zn2WritePCMPGTQYm], (instrs VPCMPGTQYrm)>;
992
993//=== Floating Point XMM and YMM Instructions ===//
994//-- Move instructions --//
995
996// VPERM2F128 / VPERM2I128.
997def : InstRW<[WriteMicrocoded], (instrs VPERM2F128rr,
998                                        VPERM2I128rr)>;
999def : InstRW<[WriteMicrocoded], (instrs VPERM2F128rm,
1000                                        VPERM2I128rm)>;
1001
1002def Zn2WriteBROADCAST : SchedWriteRes<[Zn2AGU, Zn2FPU13]> {
1003  let NumMicroOps = 2;
1004  let Latency = 8;
1005}
1006// VBROADCASTF128 / VBROADCASTI128.
1007def : InstRW<[Zn2WriteBROADCAST], (instrs VBROADCASTF128,
1008                                          VBROADCASTI128)>;
1009
1010// EXTRACTPS.
1011// r32,x,i.
1012def Zn2WriteEXTRACTPSr : SchedWriteRes<[Zn2FPU12, Zn2FPU2]> {
1013  let Latency = 2;
1014  let NumMicroOps = 2;
1015  let ResourceCycles = [1, 2];
1016}
1017def : InstRW<[Zn2WriteEXTRACTPSr], (instregex "(V?)EXTRACTPSrr")>;
1018
1019def Zn2WriteEXTRACTPSm : SchedWriteRes<[Zn2AGU,Zn2FPU12, Zn2FPU2]> {
1020  let Latency = 5;
1021  let NumMicroOps = 2;
1022  let ResourceCycles = [5, 1, 2];
1023}
1024// m32,x,i.
1025def : InstRW<[Zn2WriteEXTRACTPSm], (instregex "(V?)EXTRACTPSmr")>;
1026
1027// VEXTRACTF128 / VEXTRACTI128.
1028// x,y,i.
1029def : InstRW<[Zn2WriteFPU013], (instrs VEXTRACTF128rr,
1030                                       VEXTRACTI128rr)>;
1031
1032// m128,y,i.
1033def : InstRW<[Zn2WriteFPU013m], (instrs VEXTRACTF128mr,
1034                                        VEXTRACTI128mr)>;
1035
1036def Zn2WriteVINSERT128r: SchedWriteRes<[Zn2FPU013]> {
1037  let Latency = 2;
1038//  let ResourceCycles = [2];
1039}
1040def Zn2WriteVINSERT128Ld: SchedWriteRes<[Zn2AGU,Zn2FPU013]> {
1041  let Latency = 9;
1042  let NumMicroOps = 2;
1043}
1044// VINSERTF128 / VINSERTI128.
1045// y,y,x,i.
1046def : InstRW<[Zn2WriteVINSERT128r], (instrs VINSERTF128rr,
1047                                            VINSERTI128rr)>;
1048def : InstRW<[Zn2WriteVINSERT128Ld], (instrs VINSERTF128rm,
1049                                             VINSERTI128rm)>;
1050
1051// VGATHER.
1052def : InstRW<[WriteMicrocoded], (instregex "VGATHER(Q|D)(PD|PS)(Y?)rm")>;
1053
1054//-- Conversion instructions --//
1055def Zn2WriteCVTPD2PSr: SchedWriteRes<[Zn2FPU3]> {
1056  let Latency = 3;
1057}
1058def Zn2WriteCVTPD2PSYr: SchedWriteRes<[Zn2FPU3]> {
1059  let Latency = 3;
1060}
1061
1062// CVTPD2PS.
1063// x,x.
1064def : SchedAlias<WriteCvtPD2PS,  Zn2WriteCVTPD2PSr>;
1065// y,y.
1066def : SchedAlias<WriteCvtPD2PSY, Zn2WriteCVTPD2PSYr>;
1067// z,z.
1068defm : X86WriteResUnsupported<WriteCvtPD2PSZ>;
1069
1070def Zn2WriteCVTPD2PSLd: SchedWriteRes<[Zn2AGU,Zn2FPU3]> {
1071  let Latency = 10;
1072}
1073// x,m128.
1074def : SchedAlias<WriteCvtPD2PSLd, Zn2WriteCVTPD2PSLd>;
1075
1076// x,m256.
1077def Zn2WriteCVTPD2PSYLd : SchedWriteRes<[Zn2AGU, Zn2FPU3]> {
1078  let Latency = 10;
1079}
1080def : SchedAlias<WriteCvtPD2PSYLd, Zn2WriteCVTPD2PSYLd>;
1081// z,m512
1082defm : X86WriteResUnsupported<WriteCvtPD2PSZLd>;
1083
1084// CVTSD2SS.
1085// x,x.
1086// Same as WriteCVTPD2PSr
1087def : SchedAlias<WriteCvtSD2SS, Zn2WriteCVTPD2PSr>;
1088
1089// x,m64.
1090def : SchedAlias<WriteCvtSD2SSLd, Zn2WriteCVTPD2PSLd>;
1091
1092// CVTPS2PD.
1093// x,x.
1094def Zn2WriteCVTPS2PDr : SchedWriteRes<[Zn2FPU3]> {
1095  let Latency = 3;
1096}
1097def : SchedAlias<WriteCvtPS2PD, Zn2WriteCVTPS2PDr>;
1098
1099// x,m64.
1100// y,m128.
1101def Zn2WriteCVTPS2PDLd : SchedWriteRes<[Zn2AGU, Zn2FPU3]> {
1102  let Latency = 10;
1103  let NumMicroOps = 2;
1104}
1105def : SchedAlias<WriteCvtPS2PDLd, Zn2WriteCVTPS2PDLd>;
1106def : SchedAlias<WriteCvtPS2PDYLd, Zn2WriteCVTPS2PDLd>;
1107defm : X86WriteResUnsupported<WriteCvtPS2PDZLd>;
1108
1109// y,x.
1110def Zn2WriteVCVTPS2PDY : SchedWriteRes<[Zn2FPU3]> {
1111  let Latency = 3;
1112}
1113def : SchedAlias<WriteCvtPS2PDY, Zn2WriteVCVTPS2PDY>;
1114defm : X86WriteResUnsupported<WriteCvtPS2PDZ>;
1115
1116// CVTSS2SD.
1117// x,x.
1118def Zn2WriteCVTSS2SDr : SchedWriteRes<[Zn2FPU3]> {
1119  let Latency = 3;
1120}
1121def : SchedAlias<WriteCvtSS2SD, Zn2WriteCVTSS2SDr>;
1122
1123// x,m32.
1124def Zn2WriteCVTSS2SDLd : SchedWriteRes<[Zn2AGU, Zn2FPU3]> {
1125  let Latency = 10;
1126  let NumMicroOps = 2;
1127  let ResourceCycles = [1, 2];
1128}
1129def : SchedAlias<WriteCvtSS2SDLd, Zn2WriteCVTSS2SDLd>;
1130
1131def Zn2WriteCVTDQ2PDr: SchedWriteRes<[Zn2FPU12,Zn2FPU3]> {
1132  let Latency = 3;
1133}
1134// CVTDQ2PD.
1135// x,x.
1136def : InstRW<[Zn2WriteCVTDQ2PDr], (instregex "(V)?CVTDQ2P(D|S)rr")>;
1137
1138// Same as xmm
1139// y,x.
1140def : InstRW<[Zn2WriteCVTDQ2PDr], (instrs VCVTDQ2PDYrr)>;
1141def : InstRW<[Zn2WriteCVTDQ2PDr], (instrs VCVTDQ2PSYrr)>;
1142
1143def Zn2WriteCVTPD2DQr: SchedWriteRes<[Zn2FPU12, Zn2FPU3]> {
1144  let Latency = 3;
1145}
1146// CVT(T)P(D|S)2DQ.
1147// x,x.
1148def : InstRW<[Zn2WriteCVTPD2DQr], (instregex "(V?)CVT(T?)P(D|S)2DQrr")>;
1149
1150def Zn2WriteCVTPD2DQLd: SchedWriteRes<[Zn2AGU,Zn2FPU12,Zn2FPU3]> {
1151  let Latency = 10;
1152  let NumMicroOps = 2;
1153}
1154// x,m128.
1155def : InstRW<[Zn2WriteCVTPD2DQLd], (instregex "(V?)CVT(T?)PD2DQrm")>;
1156// same as xmm handling
1157// x,y.
1158def : InstRW<[Zn2WriteCVTPD2DQr], (instregex "VCVT(T?)PD2DQYrr")>;
1159// x,m256.
1160def : InstRW<[Zn2WriteCVTPD2DQLd], (instregex "VCVT(T?)PD2DQYrm")>;
1161
1162def Zn2WriteCVTPS2PIr: SchedWriteRes<[Zn2FPU3]> {
1163  let Latency = 4;
1164}
1165// CVT(T)PS2PI.
1166// mm,x.
1167def : InstRW<[Zn2WriteCVTPS2PIr], (instregex "MMX_CVT(T?)PS2PIrr")>;
1168
1169// CVTPI2PD.
1170// x,mm.
1171def : InstRW<[Zn2WriteCVTPS2PDr], (instrs MMX_CVTPI2PDrr)>;
1172
1173// CVT(T)PD2PI.
1174// mm,x.
1175def : InstRW<[Zn2WriteCVTPS2PIr], (instregex "MMX_CVT(T?)PD2PIrr")>;
1176
1177def Zn2WriteCVSTSI2SSr: SchedWriteRes<[Zn2FPU3]> {
1178  let Latency = 3;
1179}
1180
1181// same as CVTPD2DQr
1182// CVT(T)SS2SI.
1183// r32,x.
1184def : InstRW<[Zn2WriteCVTPD2DQr], (instregex "(V?)CVT(T?)SS2SI(64)?rr")>;
1185// same as CVTPD2DQm
1186// r32,m32.
1187def : InstRW<[Zn2WriteCVTPD2DQLd], (instregex "(V?)CVT(T?)SS2SI(64)?rm")>;
1188
1189def Zn2WriteCVSTSI2SDr: SchedWriteRes<[Zn2FPU013, Zn2FPU3]> {
1190  let Latency = 3;
1191}
1192// CVTSI2SD.
1193// x,r32/64.
1194def : InstRW<[Zn2WriteCVSTSI2SDr], (instregex "(V?)CVTSI(64)?2SDrr")>;
1195
1196
1197def Zn2WriteCVSTSI2SIr: SchedWriteRes<[Zn2FPU3, Zn2FPU2]> {
1198  let Latency = 4;
1199}
1200def Zn2WriteCVSTSI2SILd: SchedWriteRes<[Zn2AGU, Zn2FPU3, Zn2FPU2]> {
1201  let Latency = 11;
1202}
1203// CVTSD2SI.
1204// r32/64
1205def : InstRW<[Zn2WriteCVSTSI2SIr], (instregex "(V?)CVT(T?)SD2SI(64)?rr")>;
1206// r32,m32.
1207def : InstRW<[Zn2WriteCVSTSI2SILd], (instregex "(V?)CVT(T?)SD2SI(64)?rm")>;
1208
1209// VCVTPS2PH.
1210// x,v,i.
1211def : SchedAlias<WriteCvtPS2PH,    Zn2WriteMicrocoded>;
1212def : SchedAlias<WriteCvtPS2PHY,   Zn2WriteMicrocoded>;
1213defm : X86WriteResUnsupported<WriteCvtPS2PHZ>;
1214// m,v,i.
1215def : SchedAlias<WriteCvtPS2PHSt,  Zn2WriteMicrocoded>;
1216def : SchedAlias<WriteCvtPS2PHYSt, Zn2WriteMicrocoded>;
1217defm : X86WriteResUnsupported<WriteCvtPS2PHZSt>;
1218
1219// VCVTPH2PS.
1220// v,x.
1221def : SchedAlias<WriteCvtPH2PS,    Zn2WriteMicrocoded>;
1222def : SchedAlias<WriteCvtPH2PSY,   Zn2WriteMicrocoded>;
1223defm : X86WriteResUnsupported<WriteCvtPH2PSZ>;
1224// v,m.
1225def : SchedAlias<WriteCvtPH2PSLd,  Zn2WriteMicrocoded>;
1226def : SchedAlias<WriteCvtPH2PSYLd, Zn2WriteMicrocoded>;
1227defm : X86WriteResUnsupported<WriteCvtPH2PSZLd>;
1228
1229//-- SSE4A instructions --//
1230// EXTRQ
1231def Zn2WriteEXTRQ: SchedWriteRes<[Zn2FPU12, Zn2FPU2]> {
1232  let Latency = 3;
1233}
1234def : InstRW<[Zn2WriteEXTRQ], (instregex "EXTRQ")>;
1235
1236// INSERTQ
1237def Zn2WriteINSERTQ: SchedWriteRes<[Zn2FPU03,Zn2FPU1]> {
1238  let Latency = 4;
1239}
1240def : InstRW<[Zn2WriteINSERTQ], (instregex "INSERTQ")>;
1241
1242//-- SHA instructions --//
1243// SHA256MSG2
1244def : InstRW<[WriteMicrocoded], (instregex "SHA256MSG2(Y?)r(r|m)")>;
1245
1246// SHA1MSG1, SHA256MSG1
1247// x,x.
1248def Zn2WriteSHA1MSG1r : SchedWriteRes<[Zn2FPU12]> {
1249  let Latency = 2;
1250}
1251def : InstRW<[Zn2WriteSHA1MSG1r], (instregex "SHA(1|256)MSG1rr")>;
1252// x,m.
1253def Zn2WriteSHA1MSG1Ld : SchedWriteRes<[Zn2AGU, Zn2FPU12]> {
1254  let Latency = 9;
1255}
1256def : InstRW<[Zn2WriteSHA1MSG1Ld], (instregex "SHA(1|256)MSG1rm")>;
1257
1258// SHA1MSG2
1259// x,x.
1260def Zn2WriteSHA1MSG2r : SchedWriteRes<[Zn2FPU12]> ;
1261def : InstRW<[Zn2WriteSHA1MSG2r], (instrs SHA1MSG2rr)>;
1262// x,m.
1263def Zn2WriteSHA1MSG2Ld : SchedWriteRes<[Zn2AGU, Zn2FPU12]> {
1264  let Latency = 8;
1265}
1266def : InstRW<[Zn2WriteSHA1MSG2Ld], (instrs SHA1MSG2rm)>;
1267
1268// SHA1NEXTE
1269// x,x.
1270def Zn2WriteSHA1NEXTEr : SchedWriteRes<[Zn2FPU1]> ;
1271def : InstRW<[Zn2WriteSHA1NEXTEr], (instrs SHA1NEXTErr)>;
1272// x,m.
1273def Zn2WriteSHA1NEXTELd : SchedWriteRes<[Zn2AGU, Zn2FPU1]> {
1274  let Latency = 8;
1275}
1276def : InstRW<[Zn2WriteSHA1NEXTELd], (instrs SHA1NEXTErm)>;
1277
1278// SHA1RNDS4
1279// x,x.
1280def Zn2WriteSHA1RNDS4r : SchedWriteRes<[Zn2FPU1]> {
1281  let Latency = 6;
1282}
1283def : InstRW<[Zn2WriteSHA1RNDS4r], (instrs SHA1RNDS4rri)>;
1284// x,m.
1285def Zn2WriteSHA1RNDS4Ld : SchedWriteRes<[Zn2AGU, Zn2FPU1]> {
1286  let Latency = 13;
1287}
1288def : InstRW<[Zn2WriteSHA1RNDS4Ld], (instrs SHA1RNDS4rmi)>;
1289
1290// SHA256RNDS2
1291// x,x.
1292def Zn2WriteSHA256RNDS2r : SchedWriteRes<[Zn2FPU1]> {
1293  let Latency = 4;
1294}
1295def : InstRW<[Zn2WriteSHA256RNDS2r], (instrs SHA256RNDS2rr)>;
1296// x,m.
1297def Zn2WriteSHA256RNDS2Ld : SchedWriteRes<[Zn2AGU, Zn2FPU1]> {
1298  let Latency = 11;
1299}
1300def : InstRW<[Zn2WriteSHA256RNDS2Ld], (instrs SHA256RNDS2rm)>;
1301
1302//-- Arithmetic instructions --//
1303
1304// DPPS.
1305// x,x,i / v,v,v,i.
1306defm : Zn2WriteResPair<WriteDPPS, [], 15>;
1307def : SchedAlias<WriteDPPSY,  Zn2WriteMicrocoded>;
1308
1309// x,m,i / v,v,m,i.
1310def : SchedAlias<WriteDPPSYLd,Zn2WriteMicrocoded>;
1311
1312// DPPD.
1313// x,x,i.
1314def : SchedAlias<WriteDPPD,   Zn2WriteMicrocoded>;
1315
1316// x,m,i.
1317def : SchedAlias<WriteDPPDLd, Zn2WriteMicrocoded>;
1318
1319//-- Other instructions --//
1320
1321// VZEROUPPER.
1322def : InstRW<[WriteALU], (instrs VZEROUPPER)>;
1323
1324// VZEROALL.
1325def : InstRW<[WriteMicrocoded], (instrs VZEROALL)>;
1326
1327///////////////////////////////////////////////////////////////////////////////
1328// Dependency breaking instructions.
1329///////////////////////////////////////////////////////////////////////////////
1330
1331def : IsZeroIdiomFunction<[
1332  // GPR Zero-idioms.
1333  DepBreakingClass<[
1334    SUB32rr, SUB64rr,
1335    XOR32rr, XOR64rr
1336  ], ZeroIdiomPredicate>,
1337
1338  // MMX Zero-idioms.
1339  DepBreakingClass<[
1340    MMX_PXORrr, MMX_PANDNrr, MMX_PSUBBrr,
1341    MMX_PSUBDrr, MMX_PSUBQrr, MMX_PSUBWrr,
1342    MMX_PSUBSBrr, MMX_PSUBSWrr, MMX_PSUBUSBrr, MMX_PSUBUSWrr,
1343    MMX_PCMPGTBrr, MMX_PCMPGTDrr, MMX_PCMPGTWrr
1344  ], ZeroIdiomPredicate>,
1345
1346  // SSE Zero-idioms.
1347  DepBreakingClass<[
1348    // fp variants.
1349    XORPSrr, XORPDrr, ANDNPSrr, ANDNPDrr,
1350
1351    // int variants.
1352    PXORrr, PANDNrr,
1353    PSUBBrr, PSUBWrr, PSUBDrr, PSUBQrr,
1354    PCMPGTBrr, PCMPGTDrr, PCMPGTQrr, PCMPGTWrr
1355  ], ZeroIdiomPredicate>,
1356
1357  // AVX XMM Zero-idioms.
1358  DepBreakingClass<[
1359    // fp variants.
1360    VXORPSrr, VXORPDrr, VANDNPSrr, VANDNPDrr,
1361
1362    // int variants.
1363    VPXORrr, VPANDNrr,
1364    VPSUBBrr, VPSUBWrr, VPSUBDrr, VPSUBQrr,
1365    VPCMPGTBrr, VPCMPGTWrr, VPCMPGTDrr, VPCMPGTQrr
1366  ], ZeroIdiomPredicate>,
1367
1368  // AVX YMM Zero-idioms.
1369  DepBreakingClass<[
1370    // fp variants
1371    VXORPSYrr, VXORPDYrr, VANDNPSYrr, VANDNPDYrr,
1372
1373    // int variants
1374    VPXORYrr, VPANDNYrr,
1375    VPSUBBYrr, VPSUBWYrr, VPSUBDYrr, VPSUBQYrr,
1376    VPCMPGTBYrr, VPCMPGTWYrr, VPCMPGTDYrr, VPCMPGTQYrr
1377  ], ZeroIdiomPredicate>
1378]>;
1379
1380def : IsDepBreakingFunction<[
1381  // GPR
1382  DepBreakingClass<[ SBB32rr, SBB64rr ], ZeroIdiomPredicate>,
1383  DepBreakingClass<[ CMP32rr, CMP64rr ], CheckSameRegOperand<0, 1> >,
1384
1385  // MMX
1386  DepBreakingClass<[
1387    MMX_PCMPEQBrr, MMX_PCMPEQWrr, MMX_PCMPEQDrr
1388  ], ZeroIdiomPredicate>,
1389
1390  // SSE
1391  DepBreakingClass<[
1392    PCMPEQBrr, PCMPEQWrr, PCMPEQDrr, PCMPEQQrr
1393  ], ZeroIdiomPredicate>,
1394
1395  // AVX XMM
1396  DepBreakingClass<[
1397    VPCMPEQBrr, VPCMPEQWrr, VPCMPEQDrr, VPCMPEQQrr
1398  ], ZeroIdiomPredicate>,
1399
1400  // AVX YMM
1401  DepBreakingClass<[
1402    VPCMPEQBYrr, VPCMPEQWYrr, VPCMPEQDYrr, VPCMPEQQYrr
1403  ], ZeroIdiomPredicate>,
1404]>;
1405
1406} // SchedModel
1407