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 = 8; }
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>;
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>;
233defm : Zn2WriteResPair<WriteBZHI,  [Zn2ALU], 1>;
234
235// IDIV
236defm : Zn2WriteResPair<WriteDiv8,   [Zn2ALU2, Zn2Divider], 15, [1,15], 1>;
237defm : Zn2WriteResPair<WriteDiv16,  [Zn2ALU2, Zn2Divider], 17, [1,17], 2>;
238defm : Zn2WriteResPair<WriteDiv32,  [Zn2ALU2, Zn2Divider], 25, [1,25], 2>;
239defm : Zn2WriteResPair<WriteDiv64,  [Zn2ALU2, Zn2Divider], 41, [1,41], 2>;
240defm : Zn2WriteResPair<WriteIDiv8,  [Zn2ALU2, Zn2Divider], 15, [1,15], 1>;
241defm : Zn2WriteResPair<WriteIDiv16, [Zn2ALU2, Zn2Divider], 17, [1,17], 2>;
242defm : Zn2WriteResPair<WriteIDiv32, [Zn2ALU2, Zn2Divider], 25, [1,25], 2>;
243defm : Zn2WriteResPair<WriteIDiv64, [Zn2ALU2, Zn2Divider], 41, [1,41], 2>;
244
245// IMULH
246def Zn2WriteIMulH : WriteRes<WriteIMulH, [Zn2Multiplier]>{
247  let Latency = 3;
248  let NumMicroOps = 0;
249}
250def  : WriteRes<WriteIMulHLd, [Zn2Multiplier]>{
251  let Latency = !add(Zn2WriteIMulH.Latency, Znver2Model.LoadLatency);
252  let NumMicroOps = Zn2WriteIMulH.NumMicroOps;
253}
254
255// Floating point operations
256defm : X86WriteRes<WriteFLoad,         [Zn2AGU], 8, [1], 1>;
257defm : X86WriteRes<WriteFLoadX,        [Zn2AGU], 8, [1], 1>;
258defm : X86WriteRes<WriteFLoadY,        [Zn2AGU], 8, [1], 1>;
259defm : X86WriteRes<WriteFMaskedLoad,   [Zn2AGU,Zn2FPU01], 8, [1,1], 1>;
260defm : X86WriteRes<WriteFMaskedLoadY,  [Zn2AGU,Zn2FPU01], 8, [1,1], 2>;
261
262defm : X86WriteRes<WriteFStore,        [Zn2AGU], 1, [1], 1>;
263defm : X86WriteRes<WriteFStoreX,       [Zn2AGU], 1, [1], 1>;
264defm : X86WriteRes<WriteFStoreY,       [Zn2AGU], 1, [1], 1>;
265defm : X86WriteRes<WriteFStoreNT,      [Zn2AGU,Zn2FPU2], 8, [1,1], 1>;
266defm : X86WriteRes<WriteFStoreNTX,     [Zn2AGU], 1, [1], 1>;
267defm : X86WriteRes<WriteFStoreNTY,     [Zn2AGU], 1, [1], 1>;
268defm : X86WriteRes<WriteFMaskedStore32,  [Zn2AGU,Zn2FPU01], 4, [1,1], 1>;
269defm : X86WriteRes<WriteFMaskedStore32Y, [Zn2AGU,Zn2FPU01], 5, [1,2], 2>;
270defm : X86WriteRes<WriteFMaskedStore64,  [Zn2AGU,Zn2FPU01], 4, [1,1], 1>;
271defm : X86WriteRes<WriteFMaskedStore64Y, [Zn2AGU,Zn2FPU01], 5, [1,2], 2>;
272
273defm : X86WriteRes<WriteFMove,         [Zn2FPU], 1, [1], 1>;
274defm : X86WriteRes<WriteFMoveX,        [Zn2FPU], 1, [1], 1>;
275defm : X86WriteRes<WriteFMoveY,        [Zn2FPU], 1, [1], 1>;
276defm : X86WriteResUnsupported<WriteFMoveZ>;
277
278defm : Zn2WriteResFpuPair<WriteFAdd,      [Zn2FPU23], 3>;
279defm : Zn2WriteResFpuPair<WriteFAddX,     [Zn2FPU23], 3>;
280defm : Zn2WriteResFpuPair<WriteFAddY,     [Zn2FPU23], 3>;
281defm : X86WriteResPairUnsupported<WriteFAddZ>;
282defm : Zn2WriteResFpuPair<WriteFAdd64,    [Zn2FPU23], 3>;
283defm : Zn2WriteResFpuPair<WriteFAdd64X,   [Zn2FPU23], 3>;
284defm : Zn2WriteResFpuPair<WriteFAdd64Y,   [Zn2FPU23], 3>;
285defm : X86WriteResPairUnsupported<WriteFAdd64Z>;
286defm : Zn2WriteResFpuPair<WriteFCmp,      [Zn2FPU01], 1>;
287defm : Zn2WriteResFpuPair<WriteFCmpX,     [Zn2FPU01], 1>;
288defm : Zn2WriteResFpuPair<WriteFCmpY,     [Zn2FPU01], 1>;
289defm : X86WriteResPairUnsupported<WriteFCmpZ>;
290defm : Zn2WriteResFpuPair<WriteFCmp64,    [Zn2FPU01], 1>;
291defm : Zn2WriteResFpuPair<WriteFCmp64X,   [Zn2FPU01], 1>;
292defm : Zn2WriteResFpuPair<WriteFCmp64Y,   [Zn2FPU01], 1>;
293defm : X86WriteResPairUnsupported<WriteFCmp64Z>;
294defm : Zn2WriteResFpuPair<WriteFCom,      [Zn2FPU01,Zn2FPU2], 3, [1,1], 2>;
295defm : Zn2WriteResFpuPair<WriteFComX,     [Zn2FPU01,Zn2FPU2], 3, [1,1], 2>;
296defm : Zn2WriteResFpuPair<WriteFBlend,    [Zn2FPU01], 1>;
297defm : Zn2WriteResFpuPair<WriteFBlendY,   [Zn2FPU01], 1>;
298defm : X86WriteResPairUnsupported<WriteFBlendZ>;
299defm : Zn2WriteResFpuPair<WriteFVarBlend, [Zn2FPU01], 1>;
300defm : Zn2WriteResFpuPair<WriteFVarBlendY,[Zn2FPU01], 1>;
301defm : X86WriteResPairUnsupported<WriteFVarBlendZ>;
302defm : Zn2WriteResFpuPair<WriteVarBlend,  [Zn2FPU0],  1>;
303defm : Zn2WriteResFpuPair<WriteVarBlendY, [Zn2FPU0],  1>;
304defm : X86WriteResPairUnsupported<WriteVarBlendZ>;
305defm : Zn2WriteResFpuPair<WriteCvtSS2I,   [Zn2FPU3],  5>;
306defm : Zn2WriteResFpuPair<WriteCvtPS2I,   [Zn2FPU3],  5>;
307defm : Zn2WriteResFpuPair<WriteCvtPS2IY,  [Zn2FPU3],  5>;
308defm : X86WriteResPairUnsupported<WriteCvtPS2IZ>;
309defm : Zn2WriteResFpuPair<WriteCvtSD2I,   [Zn2FPU3],  5>;
310defm : Zn2WriteResFpuPair<WriteCvtPD2I,   [Zn2FPU3],  5>;
311defm : Zn2WriteResFpuPair<WriteCvtPD2IY,  [Zn2FPU3],  5>;
312defm : X86WriteResPairUnsupported<WriteCvtPD2IZ>;
313defm : Zn2WriteResFpuPair<WriteCvtI2SS,   [Zn2FPU3],  5>;
314defm : Zn2WriteResFpuPair<WriteCvtI2PS,   [Zn2FPU3],  5>;
315defm : Zn2WriteResFpuPair<WriteCvtI2PSY,  [Zn2FPU3],  5>;
316defm : X86WriteResPairUnsupported<WriteCvtI2PSZ>;
317defm : Zn2WriteResFpuPair<WriteCvtI2SD,   [Zn2FPU3],  5>;
318defm : Zn2WriteResFpuPair<WriteCvtI2PD,   [Zn2FPU3],  5>;
319defm : Zn2WriteResFpuPair<WriteCvtI2PDY,  [Zn2FPU3],  5>;
320defm : X86WriteResPairUnsupported<WriteCvtI2PDZ>;
321defm : Zn2WriteResFpuPair<WriteFDiv,      [Zn2FPU3], 15>;
322defm : Zn2WriteResFpuPair<WriteFDivX,     [Zn2FPU3], 15>;
323defm : X86WriteResPairUnsupported<WriteFDivZ>;
324defm : Zn2WriteResFpuPair<WriteFDiv64,    [Zn2FPU3], 15>;
325defm : Zn2WriteResFpuPair<WriteFDiv64X,   [Zn2FPU3], 15>;
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, [1], 1, 7, 1>;
344defm : Zn2WriteResFpuPair<WriteFMulX,     [Zn2FPU01], 3, [1], 1, 7, 1>;
345defm : Zn2WriteResFpuPair<WriteFMulY,     [Zn2FPU01], 3, [1], 1, 7, 1>;
346defm : X86WriteResPairUnsupported<WriteFMulZ>;
347defm : Zn2WriteResFpuPair<WriteFMul64,    [Zn2FPU01], 3, [1], 1, 7, 1>;
348defm : Zn2WriteResFpuPair<WriteFMul64X,   [Zn2FPU01], 3, [1], 1, 7, 1>;
349defm : Zn2WriteResFpuPair<WriteFMul64Y,   [Zn2FPU01], 3, [1], 1, 7, 1>;
350defm : X86WriteResPairUnsupported<WriteFMul64Z>;
351defm : Zn2WriteResFpuPair<WriteFMA,       [Zn2FPU03], 5>;
352defm : Zn2WriteResFpuPair<WriteFMAX,      [Zn2FPU03], 5>;
353defm : Zn2WriteResFpuPair<WriteFMAY,      [Zn2FPU03], 5>;
354defm : X86WriteResPairUnsupported<WriteFMAZ>;
355defm : Zn2WriteResFpuPair<WriteFRcp,      [Zn2FPU01], 5>;
356defm : Zn2WriteResFpuPair<WriteFRcpX,     [Zn2FPU01], 5>;
357defm : Zn2WriteResFpuPair<WriteFRcpY,     [Zn2FPU01], 5, [1], 1, 7, 2>;
358defm : X86WriteResPairUnsupported<WriteFRcpZ>;
359defm : Zn2WriteResFpuPair<WriteFRsqrtX,   [Zn2FPU01], 5, [1], 1, 7, 1>;
360defm : X86WriteResPairUnsupported<WriteFRsqrtZ>;
361defm : Zn2WriteResFpuPair<WriteFSqrt,     [Zn2FPU3], 20, [20]>;
362defm : Zn2WriteResFpuPair<WriteFSqrtX,    [Zn2FPU3], 20, [20]>;
363defm : Zn2WriteResFpuPair<WriteFSqrtY,    [Zn2FPU3], 28, [28], 1, 7, 1>;
364defm : X86WriteResPairUnsupported<WriteFSqrtZ>;
365defm : Zn2WriteResFpuPair<WriteFSqrt64,   [Zn2FPU3], 20, [20]>;
366defm : Zn2WriteResFpuPair<WriteFSqrt64X,  [Zn2FPU3], 20, [20]>;
367defm : Zn2WriteResFpuPair<WriteFSqrt64Y,  [Zn2FPU3], 20, [20], 1, 7, 1>;
368defm : X86WriteResPairUnsupported<WriteFSqrt64Z>;
369defm : Zn2WriteResFpuPair<WriteFSqrt80,   [Zn2FPU3], 20, [20]>;
370
371// Vector integer operations which uses FPU units
372defm : X86WriteRes<WriteVecLoad,         [Zn2AGU], 8, [1], 1>;
373defm : X86WriteRes<WriteVecLoadX,        [Zn2AGU], 8, [1], 1>;
374defm : X86WriteRes<WriteVecLoadY,        [Zn2AGU], 8, [1], 1>;
375defm : X86WriteRes<WriteVecLoadNT,       [Zn2AGU], 8, [1], 1>;
376defm : X86WriteRes<WriteVecLoadNTY,      [Zn2AGU], 8, [1], 1>;
377defm : X86WriteRes<WriteVecMaskedLoad,   [Zn2AGU,Zn2FPU01], 8, [1,2], 2>;
378defm : X86WriteRes<WriteVecMaskedLoadY,  [Zn2AGU,Zn2FPU01], 8, [1,2], 2>;
379defm : X86WriteRes<WriteVecStore,        [Zn2AGU], 1, [1], 1>;
380defm : X86WriteRes<WriteVecStoreX,       [Zn2AGU], 1, [1], 1>;
381defm : X86WriteRes<WriteVecStoreY,       [Zn2AGU], 1, [1], 1>;
382defm : X86WriteRes<WriteVecStoreNT,      [Zn2AGU], 1, [1], 1>;
383defm : X86WriteRes<WriteVecStoreNTY,     [Zn2AGU], 1, [1], 1>;
384defm : X86WriteRes<WriteVecMaskedStore32,  [Zn2AGU,Zn2FPU01], 4, [1,1], 1>;
385defm : X86WriteRes<WriteVecMaskedStore32Y, [Zn2AGU,Zn2FPU01], 5, [1,2], 2>;
386defm : X86WriteRes<WriteVecMaskedStore64,  [Zn2AGU,Zn2FPU01], 4, [1,1], 1>;
387defm : X86WriteRes<WriteVecMaskedStore64Y, [Zn2AGU,Zn2FPU01], 5, [1,2], 2>;
388defm : X86WriteRes<WriteVecMove,         [Zn2FPU], 1, [1], 1>;
389defm : X86WriteRes<WriteVecMoveX,        [Zn2FPU], 1, [1], 1>;
390defm : X86WriteRes<WriteVecMoveY,        [Zn2FPU], 2, [1], 2>;
391defm : X86WriteResUnsupported<WriteVecMoveZ>;
392defm : X86WriteRes<WriteVecMoveToGpr,    [Zn2FPU2], 2, [1], 1>;
393defm : X86WriteRes<WriteVecMoveFromGpr,  [Zn2FPU2], 3, [1], 1>;
394defm : X86WriteRes<WriteEMMS,            [Zn2FPU], 2, [1], 1>;
395
396defm : Zn2WriteResFpuPair<WriteVecShift,   [Zn2FPU2],  1>;
397defm : Zn2WriteResFpuPair<WriteVecShiftX,  [Zn2FPU2],  1>;
398defm : Zn2WriteResFpuPair<WriteVecShiftY,  [Zn2FPU2],  1>;
399defm : X86WriteResPairUnsupported<WriteVecShiftZ>;
400defm : Zn2WriteResFpuPair<WriteVecShiftImm,  [Zn2FPU2], 1>;
401defm : Zn2WriteResFpuPair<WriteVecShiftImmX, [Zn2FPU2], 1>;
402defm : Zn2WriteResFpuPair<WriteVecShiftImmY, [Zn2FPU2], 1>;
403defm : X86WriteResPairUnsupported<WriteVecShiftImmZ>;
404defm : Zn2WriteResFpuPair<WriteVarVecShift,  [Zn2FPU1], 3, [2], 1>;
405defm : Zn2WriteResFpuPair<WriteVarVecShiftY, [Zn2FPU1], 3, [2], 1>;
406defm : X86WriteResPairUnsupported<WriteVarVecShiftZ>;
407defm : Zn2WriteResFpuPair<WriteVecLogic,   [Zn2FPU],   1>;
408defm : Zn2WriteResFpuPair<WriteVecLogicX,  [Zn2FPU],   1>;
409defm : Zn2WriteResFpuPair<WriteVecLogicY,  [Zn2FPU],   1>;
410defm : X86WriteResPairUnsupported<WriteVecLogicZ>;
411defm : Zn2WriteResFpuPair<WriteVecTest,    [Zn2FPU12], 3, [2], 1, 7, 1>;
412defm : Zn2WriteResFpuPair<WriteVecTestY,   [Zn2FPU12], 3, [2], 1, 7, 1>;
413defm : X86WriteResPairUnsupported<WriteVecTestZ>;
414defm : Zn2WriteResFpuPair<WriteVecALU,     [Zn2FPU],   1>;
415defm : Zn2WriteResFpuPair<WriteVecALUX,    [Zn2FPU],   1>;
416defm : Zn2WriteResFpuPair<WriteVecALUY,    [Zn2FPU],   1>;
417defm : X86WriteResPairUnsupported<WriteVecALUZ>;
418defm : Zn2WriteResFpuPair<WriteVecIMul,    [Zn2FPU0],  4>;
419defm : Zn2WriteResFpuPair<WriteVecIMulX,   [Zn2FPU0],  4>;
420defm : Zn2WriteResFpuPair<WriteVecIMulY,   [Zn2FPU0],  4>;
421defm : X86WriteResPairUnsupported<WriteVecIMulZ>;
422defm : Zn2WriteResFpuPair<WritePMULLD,     [Zn2FPU0],  4, [1], 1, 7, 1>;
423defm : Zn2WriteResFpuPair<WritePMULLDY,    [Zn2FPU0],  4, [1], 1, 7, 1>;
424defm : X86WriteResPairUnsupported<WritePMULLDZ>;
425defm : Zn2WriteResFpuPair<WriteShuffle,    [Zn2FPU],   1>;
426defm : Zn2WriteResFpuPair<WriteShuffleX,   [Zn2FPU],   1>;
427defm : Zn2WriteResFpuPair<WriteShuffleY,   [Zn2FPU],   1>;
428defm : X86WriteResPairUnsupported<WriteShuffleZ>;
429defm : Zn2WriteResFpuPair<WriteVarShuffle, [Zn2FPU],   1>;
430defm : Zn2WriteResFpuPair<WriteVarShuffleX,[Zn2FPU],   1>;
431defm : Zn2WriteResFpuPair<WriteVarShuffleY,[Zn2FPU],   1>;
432defm : X86WriteResPairUnsupported<WriteVarShuffleZ>;
433defm : Zn2WriteResFpuPair<WriteBlend,      [Zn2FPU01], 1>;
434defm : Zn2WriteResFpuPair<WriteBlendY,     [Zn2FPU01], 1>;
435defm : X86WriteResPairUnsupported<WriteBlendZ>;
436defm : Zn2WriteResFpuPair<WriteShuffle256, [Zn2FPU],   2>;
437defm : Zn2WriteResFpuPair<WriteVPMOV256,   [Zn2FPU12],  4, [1], 2, 4>;
438defm : Zn2WriteResFpuPair<WriteVarShuffle256, [Zn2FPU],   2>;
439defm : Zn2WriteResFpuPair<WritePSADBW,     [Zn2FPU0],  3>;
440defm : Zn2WriteResFpuPair<WritePSADBWX,    [Zn2FPU0],  3>;
441defm : Zn2WriteResFpuPair<WritePSADBWY,    [Zn2FPU0],  3>;
442defm : X86WriteResPairUnsupported<WritePSADBWZ>;
443defm : Zn2WriteResFpuPair<WritePHMINPOS,   [Zn2FPU0],  4>;
444
445// Vector insert/extract operations.
446defm : Zn2WriteResFpuPair<WriteVecInsert,   [Zn2FPU],   1>;
447
448def : WriteRes<WriteVecExtract, [Zn2FPU12, Zn2FPU2]> {
449  let Latency = 2;
450  let ResourceCycles = [1, 2];
451}
452def : WriteRes<WriteVecExtractSt, [Zn2AGU, Zn2FPU12, Zn2FPU2]> {
453  let Latency = 5;
454  let NumMicroOps = 2;
455  let ResourceCycles = [1, 2, 3];
456}
457
458// MOVMSK Instructions.
459def : WriteRes<WriteFMOVMSK, [Zn2FPU2]>;
460def : WriteRes<WriteMMXMOVMSK, [Zn2FPU2]>;
461def : WriteRes<WriteVecMOVMSK, [Zn2FPU2]>;
462
463def : WriteRes<WriteVecMOVMSKY, [Zn2FPU2]> {
464  let NumMicroOps = 2;
465  let Latency = 2;
466  let ResourceCycles = [2];
467}
468
469// AES Instructions.
470defm : Zn2WriteResFpuPair<WriteAESDecEnc, [Zn2FPU01], 4>;
471defm : Zn2WriteResFpuPair<WriteAESIMC,    [Zn2FPU01], 4>;
472defm : Zn2WriteResFpuPair<WriteAESKeyGen, [Zn2FPU01], 4>;
473
474def : WriteRes<WriteFence,  [Zn2AGU]>;
475def : WriteRes<WriteNop, []>;
476
477// Following instructions with latency=100 are microcoded.
478// We set long latency so as to block the entire pipeline.
479defm : Zn2WriteResFpuPair<WriteFShuffle256, [Zn2FPU], 100>;
480defm : Zn2WriteResFpuPair<WriteFVarShuffle256, [Zn2FPU], 100>;
481
482// Microcoded Instructions
483def Zn2WriteMicrocoded : SchedWriteRes<[]> {
484  let Latency = 100;
485}
486
487def : SchedAlias<WriteMicrocoded, Zn2WriteMicrocoded>;
488def : SchedAlias<WriteFCMOV, Zn2WriteMicrocoded>;
489def : SchedAlias<WriteSystem, Zn2WriteMicrocoded>;
490def : SchedAlias<WriteMPSAD, Zn2WriteMicrocoded>;
491def : SchedAlias<WriteMPSADY, Zn2WriteMicrocoded>;
492def : SchedAlias<WriteMPSADLd, Zn2WriteMicrocoded>;
493def : SchedAlias<WriteMPSADYLd, Zn2WriteMicrocoded>;
494def : SchedAlias<WriteCLMul, Zn2WriteMicrocoded>;
495def : SchedAlias<WriteCLMulLd, Zn2WriteMicrocoded>;
496def : SchedAlias<WritePCmpIStrM, Zn2WriteMicrocoded>;
497def : SchedAlias<WritePCmpIStrMLd, Zn2WriteMicrocoded>;
498def : SchedAlias<WritePCmpEStrI, Zn2WriteMicrocoded>;
499def : SchedAlias<WritePCmpEStrILd, Zn2WriteMicrocoded>;
500def : SchedAlias<WritePCmpEStrM, Zn2WriteMicrocoded>;
501def : SchedAlias<WritePCmpEStrMLd, Zn2WriteMicrocoded>;
502def : SchedAlias<WritePCmpIStrI, Zn2WriteMicrocoded>;
503def : SchedAlias<WritePCmpIStrILd, Zn2WriteMicrocoded>;
504def : SchedAlias<WriteLDMXCSR, Zn2WriteMicrocoded>;
505def : SchedAlias<WriteSTMXCSR, Zn2WriteMicrocoded>;
506
507//=== Regex based InstRW ===//
508// Notation:
509// - r: register.
510// - m = memory.
511// - i = immediate
512// - mm: 64 bit mmx register.
513// - x = 128 bit xmm register.
514// - (x)mm = mmx or xmm register.
515// - y = 256 bit ymm register.
516// - v = any vector register.
517
518//=== Integer Instructions ===//
519//-- Move instructions --//
520// MOV.
521// r16,m.
522def : InstRW<[WriteALULd, ReadAfterLd], (instregex "MOV16rm")>;
523
524// MOVSX, MOVZX.
525// r,m.
526def : InstRW<[WriteLoad], (instregex "MOV(S|Z)X32rm(8|16)")>;
527
528// XCHG.
529// r,r.
530def Zn2WriteXCHG : SchedWriteRes<[Zn2ALU]> {
531  let NumMicroOps = 2;
532}
533
534def : InstRW<[Zn2WriteXCHG], (instregex "^XCHG(8|16|32|64)rr", "^XCHG(16|32|64)ar")>;
535
536// r,m.
537def Zn2WriteXCHGrm : SchedWriteRes<[Zn2AGU, Zn2ALU]> {
538  let Latency = 5;
539  let NumMicroOps = 2;
540}
541def : InstRW<[Zn2WriteXCHGrm, ReadAfterLd], (instregex "^XCHG(8|16|32|64)rm")>;
542
543def : InstRW<[WriteMicrocoded], (instrs XLAT)>;
544
545// POP16.
546// r.
547def Zn2WritePop16r : SchedWriteRes<[Zn2AGU]>{
548  let Latency = 5;
549  let NumMicroOps = 2;
550}
551def : InstRW<[Zn2WritePop16r], (instregex "POP16rmm")>;
552def : InstRW<[WriteMicrocoded], (instregex "POPF(16|32)")>;
553def : InstRW<[WriteMicrocoded], (instregex "POPA(16|32)")>;
554
555
556// PUSH.
557// r. Has default values.
558// m.
559def Zn2WritePUSH : SchedWriteRes<[Zn2AGU]>{
560  let Latency = 4;
561}
562def : InstRW<[Zn2WritePUSH], (instregex "PUSH(16|32)rmm")>;
563
564//PUSHF
565def : InstRW<[WriteMicrocoded], (instregex "PUSHF(16|32)")>;
566
567// PUSHA.
568def Zn2WritePushA : SchedWriteRes<[Zn2AGU]> {
569  let Latency = 8;
570}
571def : InstRW<[Zn2WritePushA], (instregex "PUSHA(16|32)")>;
572
573//LAHF
574def : InstRW<[WriteMicrocoded], (instrs LAHF)>;
575
576// MOVBE.
577// r,m.
578def Zn2WriteMOVBE : SchedWriteRes<[Zn2AGU, Zn2ALU]> {
579  let Latency = 5;
580}
581def : InstRW<[Zn2WriteMOVBE, ReadAfterLd], (instregex "MOVBE(16|32|64)rm")>;
582
583// m16,r16.
584def : InstRW<[Zn2WriteMOVBE], (instregex "MOVBE(16|32|64)mr")>;
585
586//-- Arithmetic instructions --//
587
588// ADD SUB.
589// m,r/i.
590def : InstRW<[WriteALULd], (instregex "(ADD|SUB)(8|16|32|64)m(r|i)",
591                          "(ADD|SUB)(8|16|32|64)mi8",
592                          "(ADD|SUB)64mi32")>;
593
594// ADC SBB.
595// m,r/i.
596def : InstRW<[WriteALULd],
597             (instregex "(ADC|SBB)(8|16|32|64)m(r|i)",
598              "(ADC|SBB)(16|32|64)mi8",
599              "(ADC|SBB)64mi32")>;
600
601// INC DEC NOT NEG.
602// m.
603def : InstRW<[WriteALULd],
604             (instregex "(INC|DEC|NOT|NEG)(8|16|32|64)m")>;
605
606// MUL IMUL.
607// r16.
608def Zn2WriteMul16 : SchedWriteRes<[Zn2ALU1, Zn2Multiplier]> {
609  let Latency = 3;
610}
611def Zn2WriteMul16Imm : SchedWriteRes<[Zn2ALU1, Zn2Multiplier]> {
612  let Latency = 4;
613}
614def : SchedAlias<WriteIMul16, Zn2WriteMul16>;
615def : SchedAlias<WriteIMul16Imm, Zn2WriteMul16Imm>;
616def : SchedAlias<WriteIMul16Reg, Zn2WriteMul16>;
617
618// m16.
619def Zn2WriteMul16Ld : SchedWriteRes<[Zn2AGU, Zn2ALU1, Zn2Multiplier]> {
620  let Latency = 7;
621}
622def : SchedAlias<WriteIMul16Ld, Zn2WriteMul16Ld>;
623def : SchedAlias<WriteIMul16ImmLd, Zn2WriteMul16Ld>;
624def : SchedAlias<WriteIMul16RegLd, Zn2WriteMul16Ld>;
625
626// r32.
627def Zn2WriteMul32 : SchedWriteRes<[Zn2ALU1, Zn2Multiplier]> {
628  let Latency = 3;
629}
630def : SchedAlias<WriteIMul32, Zn2WriteMul32>;
631def : SchedAlias<WriteIMul32Imm, Zn2WriteMul32>;
632def : SchedAlias<WriteIMul32Reg, Zn2WriteMul32>;
633
634// m32.
635def Zn2WriteMul32Ld : SchedWriteRes<[Zn2AGU, Zn2ALU1, Zn2Multiplier]> {
636  let Latency = 7;
637}
638def : SchedAlias<WriteIMul32Ld, Zn2WriteMul32Ld>;
639def : SchedAlias<WriteIMul32ImmLd, Zn2WriteMul32Ld>;
640def : SchedAlias<WriteIMul32RegLd, Zn2WriteMul32Ld>;
641
642// r64.
643def Zn2WriteMul64 : SchedWriteRes<[Zn2ALU1, Zn2Multiplier]> {
644  let Latency = 4;
645  let NumMicroOps = 2;
646}
647def : SchedAlias<WriteIMul64, Zn2WriteMul64>;
648def : SchedAlias<WriteIMul64Imm, Zn2WriteMul64>;
649def : SchedAlias<WriteIMul64Reg, Zn2WriteMul64>;
650
651// m64.
652def Zn2WriteMul64Ld : SchedWriteRes<[Zn2AGU, Zn2ALU1, Zn2Multiplier]> {
653  let Latency = 8;
654  let NumMicroOps = 2;
655}
656def : SchedAlias<WriteIMul64Ld, Zn2WriteMul64Ld>;
657def : SchedAlias<WriteIMul64ImmLd, Zn2WriteMul64Ld>;
658def : SchedAlias<WriteIMul64RegLd, Zn2WriteMul64Ld>;
659
660// MULX.
661// Numbers are based on the AMD SOG for Family 17h - Instruction Latencies.
662defm : Zn2WriteResPair<WriteMULX32, [Zn2ALU1, Zn2Multiplier], 3, [1, 1], 1, 4, 0>;
663defm : Zn2WriteResPair<WriteMULX64, [Zn2ALU1, Zn2Multiplier], 3, [1, 1], 1, 4, 0>;
664
665//-- Control transfer instructions --//
666
667// J(E|R)CXZ.
668def Zn2WriteJCXZ : SchedWriteRes<[Zn2ALU03]>;
669def : InstRW<[Zn2WriteJCXZ], (instrs JCXZ, JECXZ, JRCXZ)>;
670
671// INTO
672def : InstRW<[WriteMicrocoded], (instrs INTO)>;
673
674// LOOP.
675def Zn2WriteLOOP : SchedWriteRes<[Zn2ALU03]>;
676def : InstRW<[Zn2WriteLOOP], (instrs LOOP)>;
677
678// LOOP(N)E, LOOP(N)Z
679def Zn2WriteLOOPE : SchedWriteRes<[Zn2ALU03]>;
680def : InstRW<[Zn2WriteLOOPE], (instrs LOOPE, LOOPNE)>;
681
682// CALL.
683// r.
684def Zn2WriteCALLr : SchedWriteRes<[Zn2AGU, Zn2ALU03]>;
685def : InstRW<[Zn2WriteCALLr], (instregex "CALL(16|32)r")>;
686
687def : InstRW<[WriteMicrocoded], (instregex "CALL(16|32)m")>;
688
689// RET.
690def Zn2WriteRET : SchedWriteRes<[Zn2ALU03]> {
691  let NumMicroOps = 2;
692}
693def : InstRW<[Zn2WriteRET], (instregex "RET(16|32|64)", "LRET(16|32|64)",
694                            "IRET(16|32|64)")>;
695
696//-- Logic instructions --//
697
698// AND OR XOR.
699// m,r/i.
700def : InstRW<[WriteALULd],
701             (instregex "(AND|OR|XOR)(8|16|32|64)m(r|i)",
702              "(AND|OR|XOR)(8|16|32|64)mi8", "(AND|OR|XOR)64mi32")>;
703
704// Define ALU latency variants
705def Zn2WriteALULat2 : SchedWriteRes<[Zn2ALU]> {
706  let Latency = 2;
707}
708def Zn2WriteALULat2Ld : SchedWriteRes<[Zn2AGU, Zn2ALU]> {
709  let Latency = 6;
710}
711
712// BT.
713// m,i.
714def : InstRW<[WriteShiftLd], (instregex "BT(16|32|64)mi8")>;
715
716// BTR BTS BTC.
717// r,r,i.
718def Zn2WriteBTRSC : SchedWriteRes<[Zn2ALU]> {
719  let Latency = 2;
720  let NumMicroOps = 2;
721}
722def : InstRW<[Zn2WriteBTRSC], (instregex "BT(R|S|C)(16|32|64)r(r|i8)")>;
723
724// m,r,i.
725def Zn2WriteBTRSCm : SchedWriteRes<[Zn2AGU, Zn2ALU]> {
726  let Latency = 6;
727  let NumMicroOps = 2;
728}
729// m,r,i.
730def : SchedAlias<WriteBitTestSetImmRMW, Zn2WriteBTRSCm>;
731def : SchedAlias<WriteBitTestSetRegRMW, Zn2WriteBTRSCm>;
732
733// BLSI BLSMSK BLSR.
734// r,r.
735def : SchedAlias<WriteBLS, Zn2WriteALULat2>;
736// r,m.
737def : SchedAlias<WriteBLSLd, Zn2WriteALULat2Ld>;
738
739// CLD STD.
740def : InstRW<[WriteALU], (instrs STD, CLD)>;
741
742// PDEP PEXT.
743// r,r,r.
744def : InstRW<[WriteMicrocoded], (instregex "PDEP(32|64)rr", "PEXT(32|64)rr")>;
745// r,r,m.
746def : InstRW<[WriteMicrocoded], (instregex "PDEP(32|64)rm", "PEXT(32|64)rm")>;
747
748// RCR RCL.
749// m,i.
750def : InstRW<[WriteMicrocoded], (instregex "RC(R|L)(8|16|32|64)m(1|i|CL)")>;
751
752// SHR SHL SAR.
753// m,i.
754def : InstRW<[WriteShiftLd], (instregex "S(A|H)(R|L)(8|16|32|64)m(i|1)")>;
755
756// SHRD SHLD.
757// m,r
758def : InstRW<[WriteShiftLd], (instregex "SH(R|L)D(16|32|64)mri8")>;
759
760// r,r,cl.
761def : InstRW<[WriteMicrocoded], (instregex "SH(R|L)D(16|32|64)rrCL")>;
762
763// m,r,cl.
764def : InstRW<[WriteMicrocoded], (instregex "SH(R|L)D(16|32|64)mrCL")>;
765
766//-- Misc instructions --//
767// CMPXCHG8B.
768def Zn2WriteCMPXCHG8B : SchedWriteRes<[Zn2AGU, Zn2ALU]> {
769  let NumMicroOps = 18;
770}
771def : InstRW<[Zn2WriteCMPXCHG8B], (instrs CMPXCHG8B)>;
772
773def : InstRW<[WriteMicrocoded], (instrs CMPXCHG16B)>;
774
775// LEAVE
776def Zn2WriteLEAVE : SchedWriteRes<[Zn2ALU, Zn2AGU]> {
777  let Latency = 8;
778  let NumMicroOps = 2;
779}
780def : InstRW<[Zn2WriteLEAVE], (instregex "LEAVE")>;
781
782// PAUSE.
783def : InstRW<[WriteMicrocoded], (instrs PAUSE)>;
784
785// RDTSC.
786def : InstRW<[WriteMicrocoded], (instregex "RDTSC")>;
787
788// RDPMC.
789def : InstRW<[WriteMicrocoded], (instrs RDPMC)>;
790
791// RDRAND.
792def : InstRW<[WriteMicrocoded], (instregex "RDRAND(16|32|64)r")>;
793
794// XGETBV.
795def : InstRW<[WriteMicrocoded], (instregex "XGETBV")>;
796
797//-- String instructions --//
798// CMPS.
799def : InstRW<[WriteMicrocoded], (instregex "CMPS(B|L|Q|W)")>;
800
801// LODSB/W.
802def : InstRW<[WriteMicrocoded], (instregex "LODS(B|W)")>;
803
804// LODSD/Q.
805def : InstRW<[WriteMicrocoded], (instregex "LODS(L|Q)")>;
806
807// MOVS.
808def : InstRW<[WriteMicrocoded], (instregex "MOVS(B|L|Q|W)")>;
809
810// SCAS.
811def : InstRW<[WriteMicrocoded], (instregex "SCAS(B|W|L|Q)")>;
812
813// STOS
814def : InstRW<[WriteMicrocoded], (instregex "STOS(B|L|Q|W)")>;
815
816// XADD.
817def Zn2XADD : SchedWriteRes<[Zn2ALU]>;
818def : InstRW<[Zn2XADD], (instregex "XADD(8|16|32|64)rr")>;
819def : InstRW<[WriteMicrocoded], (instregex "XADD(8|16|32|64)rm")>;
820
821//=== Floating Point x87 Instructions ===//
822//-- Move instructions --//
823
824def Zn2WriteFLDr : SchedWriteRes<[Zn2FPU13]> ;
825
826def Zn2WriteSTr: SchedWriteRes<[Zn2FPU23]> {
827  let Latency = 5;
828  let NumMicroOps = 2;
829}
830
831// LD_F.
832// r.
833def : InstRW<[Zn2WriteFLDr], (instregex "LD_Frr")>;
834
835// m.
836def Zn2WriteLD_F80m : SchedWriteRes<[Zn2AGU, Zn2FPU13]> {
837  let NumMicroOps = 2;
838}
839def : InstRW<[Zn2WriteLD_F80m], (instregex "LD_F80m")>;
840
841// FBLD.
842def : InstRW<[WriteMicrocoded], (instregex "FBLDm")>;
843
844// FST(P).
845// r.
846def : InstRW<[Zn2WriteSTr], (instregex "ST_(F|FP)rr")>;
847
848// m80.
849def Zn2WriteST_FP80m : SchedWriteRes<[Zn2AGU, Zn2FPU23]> {
850  let Latency = 5;
851}
852def : InstRW<[Zn2WriteST_FP80m], (instregex "ST_FP80m")>;
853
854// FBSTP.
855// m80.
856def : InstRW<[WriteMicrocoded], (instregex "FBSTPm")>;
857
858def Zn2WriteFXCH : SchedWriteRes<[Zn2FPU]>;
859
860// FXCHG.
861def : InstRW<[Zn2WriteFXCH], (instrs XCH_F)>;
862
863// FILD.
864def Zn2WriteFILD : SchedWriteRes<[Zn2AGU, Zn2FPU3]> {
865  let Latency = 11;
866  let NumMicroOps = 2;
867}
868def : InstRW<[Zn2WriteFILD], (instregex "ILD_F(16|32|64)m")>;
869
870// FIST(P) FISTTP.
871def Zn2WriteFIST : SchedWriteRes<[Zn2AGU, Zn2FPU23]> {
872  let Latency = 12;
873}
874def : InstRW<[Zn2WriteFIST], (instregex "IS(T|TT)_(F|FP)(16|32|64)m")>;
875
876def Zn2WriteFPU13 : SchedWriteRes<[Zn2AGU, Zn2FPU13]> {
877  let Latency = 8;
878}
879
880def Zn2WriteFPU3 : SchedWriteRes<[Zn2AGU, Zn2FPU3]> {
881  let Latency = 11;
882}
883
884// FLDZ.
885def : SchedAlias<WriteFLD0, Zn2WriteFPU13>;
886
887// FLD1.
888def : SchedAlias<WriteFLD1, Zn2WriteFPU3>;
889
890// FLDPI FLDL2E etc.
891def : SchedAlias<WriteFLDC, Zn2WriteFPU3>;
892
893// FNSTSW.
894// AX.
895def : InstRW<[WriteMicrocoded], (instrs FNSTSW16r)>;
896
897// m16.
898def : InstRW<[WriteMicrocoded], (instrs FNSTSWm)>;
899
900// FLDCW.
901def : InstRW<[WriteMicrocoded], (instrs FLDCW16m)>;
902
903// FNSTCW.
904def : InstRW<[WriteMicrocoded], (instrs FNSTCW16m)>;
905
906// FINCSTP FDECSTP.
907def : InstRW<[Zn2WriteFPU3], (instrs FINCSTP, FDECSTP)>;
908
909// FFREE.
910def : InstRW<[Zn2WriteFPU3], (instregex "FFREE")>;
911
912// FNSAVE.
913def : InstRW<[WriteMicrocoded], (instregex "FSAVEm")>;
914
915// FRSTOR.
916def : InstRW<[WriteMicrocoded], (instregex "FRSTORm")>;
917
918//-- Arithmetic instructions --//
919
920def Zn2WriteFPU3Lat1 : SchedWriteRes<[Zn2FPU3]> ;
921
922def Zn2WriteFPU0Lat1 : SchedWriteRes<[Zn2FPU0]> ;
923
924def Zn2WriteFPU0Lat1Ld : SchedWriteRes<[Zn2AGU, Zn2FPU0]> {
925  let Latency = 8;
926}
927
928// FCHS.
929def : InstRW<[Zn2WriteFPU3Lat1], (instregex "CHS_F")>;
930
931// FCOM(P) FUCOM(P).
932// r.
933def : InstRW<[Zn2WriteFPU0Lat1], (instregex "COM(P?)_FST0r", "UCOM_F(P?)r")>;
934// m.
935def : InstRW<[Zn2WriteFPU0Lat1Ld], (instregex "FCOM(P?)(32|64)m")>;
936
937// FCOMPP FUCOMPP.
938// r.
939def : InstRW<[Zn2WriteFPU0Lat1], (instrs FCOMPP, UCOM_FPPr)>;
940
941def Zn2WriteFPU02 : SchedWriteRes<[Zn2AGU, Zn2FPU02]>
942{
943  let Latency = 9;
944}
945
946// FCOMI(P) FUCOMI(P).
947// m.
948def : InstRW<[Zn2WriteFPU02], (instrs COM_FIPr, COM_FIr, UCOM_FIPr, UCOM_FIr)>;
949
950def Zn2WriteFPU03 : SchedWriteRes<[Zn2AGU, Zn2FPU03]>
951{
952  let Latency = 12;
953  let NumMicroOps = 2;
954  let ResourceCycles = [1,3];
955}
956
957// FICOM(P).
958def : InstRW<[Zn2WriteFPU03], (instregex "FICOM(P?)(16|32)m")>;
959
960// FTST.
961def : InstRW<[Zn2WriteFPU0Lat1], (instregex "TST_F")>;
962
963// FXAM.
964def : InstRW<[Zn2WriteFPU3Lat1], (instrs XAM_F)>;
965
966// FPREM.
967def : InstRW<[WriteMicrocoded], (instrs FPREM)>;
968
969// FPREM1.
970def : InstRW<[WriteMicrocoded], (instrs FPREM1)>;
971
972// FRNDINT.
973def : InstRW<[WriteMicrocoded], (instrs FRNDINT)>;
974
975// FSCALE.
976def : InstRW<[WriteMicrocoded], (instrs FSCALE)>;
977
978// FXTRACT.
979def : InstRW<[WriteMicrocoded], (instrs FXTRACT)>;
980
981// FNOP.
982def : InstRW<[Zn2WriteFPU0Lat1], (instrs FNOP)>;
983
984// WAIT.
985def : InstRW<[Zn2WriteFPU0Lat1], (instrs WAIT)>;
986
987// FNCLEX.
988def : InstRW<[WriteMicrocoded], (instrs FNCLEX)>;
989
990// FNINIT.
991def : InstRW<[WriteMicrocoded], (instrs FNINIT)>;
992
993//=== Integer MMX and XMM Instructions ===//
994
995// PACKSSWB/DW.
996// mm <- mm.
997def Zn2WriteFPU12 : SchedWriteRes<[Zn2FPU12]> ;
998def Zn2WriteFPU12Y : SchedWriteRes<[Zn2FPU12]> {
999  let Latency = 4;
1000  let NumMicroOps = 2;
1001}
1002def Zn2WriteFPU12m : SchedWriteRes<[Zn2AGU, Zn2FPU12]> ;
1003def Zn2WriteFPU12Ym : SchedWriteRes<[Zn2AGU, Zn2FPU12]> {
1004  let Latency = 8;
1005  let NumMicroOps = 2;
1006}
1007
1008def : InstRW<[Zn2WriteFPU12], (instrs MMX_PACKSSDWrr,
1009                                     MMX_PACKSSWBrr,
1010                                     MMX_PACKUSWBrr)>;
1011def : InstRW<[Zn2WriteFPU12m], (instrs MMX_PACKSSDWrm,
1012                                      MMX_PACKSSWBrm,
1013                                      MMX_PACKUSWBrm)>;
1014
1015def Zn2WriteFPU013 : SchedWriteRes<[Zn2FPU013]> ;
1016def Zn2WriteFPU013Y : SchedWriteRes<[Zn2FPU013]> ;
1017def Zn2WriteFPU013m : SchedWriteRes<[Zn2AGU, Zn2FPU013]> {
1018  let Latency = 8;
1019  let NumMicroOps = 2;
1020}
1021def Zn2WriteFPU013Ld : SchedWriteRes<[Zn2AGU, Zn2FPU013]> {
1022  let Latency = 8;
1023  let NumMicroOps = 2;
1024}
1025def Zn2WriteFPU013LdY : SchedWriteRes<[Zn2AGU, Zn2FPU013]> {
1026  let Latency = 8;
1027  let NumMicroOps = 2;
1028}
1029
1030// PBLENDW.
1031// x,x,i / v,v,v,i
1032def : InstRW<[Zn2WriteFPU013], (instregex "(V?)PBLENDWrri")>;
1033// ymm
1034def : InstRW<[Zn2WriteFPU013Y], (instrs VPBLENDWYrri)>;
1035
1036// x,m,i / v,v,m,i
1037def : InstRW<[Zn2WriteFPU013Ld], (instregex "(V?)PBLENDWrmi")>;
1038// y,m,i
1039def : InstRW<[Zn2WriteFPU013LdY], (instrs VPBLENDWYrmi)>;
1040
1041def Zn2WriteFPU01 : SchedWriteRes<[Zn2FPU01]> ;
1042def Zn2WriteFPU01Y : SchedWriteRes<[Zn2FPU01]> {
1043  let NumMicroOps = 2;
1044}
1045
1046// VPBLENDD.
1047// v,v,v,i.
1048def : InstRW<[Zn2WriteFPU01], (instrs VPBLENDDrri)>;
1049// ymm
1050def : InstRW<[Zn2WriteFPU01Y], (instrs VPBLENDDYrri)>;
1051
1052// v,v,m,i
1053def Zn2WriteFPU01Op2 : SchedWriteRes<[Zn2AGU, Zn2FPU01]> {
1054  let NumMicroOps = 2;
1055  let Latency = 8;
1056  let ResourceCycles = [1, 2];
1057}
1058def Zn2WriteFPU01Op2Y : SchedWriteRes<[Zn2AGU, Zn2FPU01]> {
1059  let NumMicroOps = 2;
1060  let Latency = 9;
1061  let ResourceCycles = [1, 3];
1062}
1063def : InstRW<[Zn2WriteFPU01Op2], (instrs VPBLENDDrmi)>;
1064def : InstRW<[Zn2WriteFPU01Op2Y], (instrs VPBLENDDYrmi)>;
1065
1066// MASKMOVQ.
1067def : InstRW<[WriteMicrocoded], (instregex "MMX_MASKMOVQ(64)?")>;
1068
1069// MASKMOVDQU.
1070def : InstRW<[WriteMicrocoded], (instregex "(V?)MASKMOVDQU(64)?")>;
1071
1072// VPMASKMOVD.
1073// ymm
1074def : InstRW<[WriteMicrocoded],
1075                               (instregex "VPMASKMOVD(Y?)rm")>;
1076// m, v,v.
1077def : InstRW<[WriteMicrocoded], (instregex "VPMASKMOV(D|Q)(Y?)mr")>;
1078
1079// VPBROADCAST B/W.
1080// x, m8/16.
1081def Zn2WriteVPBROADCAST128Ld : SchedWriteRes<[Zn2AGU, Zn2FPU12]> {
1082  let Latency = 8;
1083  let NumMicroOps = 2;
1084  let ResourceCycles = [1, 2];
1085}
1086def : InstRW<[Zn2WriteVPBROADCAST128Ld],
1087                                     (instregex "VPBROADCAST(B|W)rm")>;
1088
1089// y, m8/16
1090def Zn2WriteVPBROADCAST256Ld : SchedWriteRes<[Zn2AGU, Zn2FPU1]> {
1091  let Latency = 8;
1092  let NumMicroOps = 2;
1093  let ResourceCycles = [1, 2];
1094}
1095def : InstRW<[Zn2WriteVPBROADCAST256Ld],
1096                                     (instregex "VPBROADCAST(B|W)Yrm")>;
1097
1098// VPGATHER.
1099def : InstRW<[WriteMicrocoded], (instregex "VPGATHER(Q|D)(Q|D)(Y?)rm")>;
1100
1101//-- Arithmetic instructions --//
1102
1103// HADD, HSUB PS/PD
1104// PHADD|PHSUB (S) W/D.
1105defm : Zn2WriteResFpuPair<WriteFHAdd, [], 7>;
1106defm : Zn2WriteResFpuPair<WriteFHAddY, [], 7>;
1107defm : Zn2WriteResFpuPair<WritePHAdd, [], 3>;
1108defm : Zn2WriteResFpuPair<WritePHAddX, [], 3>;
1109defm : Zn2WriteResFpuPair<WritePHAddY, [], 3>;
1110
1111// PCMPGTQ.
1112def Zn2WritePCMPGTQr : SchedWriteRes<[Zn2FPU03]>;
1113def : InstRW<[Zn2WritePCMPGTQr], (instregex "(V?)PCMPGTQ(Y?)rr")>;
1114
1115// x <- x,m.
1116def Zn2WritePCMPGTQm : SchedWriteRes<[Zn2AGU, Zn2FPU03]> {
1117  let Latency = 8;
1118}
1119// ymm.
1120def Zn2WritePCMPGTQYm : SchedWriteRes<[Zn2AGU, Zn2FPU03]> {
1121  let Latency = 8;
1122}
1123def : InstRW<[Zn2WritePCMPGTQm], (instregex "(V?)PCMPGTQrm")>;
1124def : InstRW<[Zn2WritePCMPGTQYm], (instrs VPCMPGTQYrm)>;
1125
1126//-- Logic instructions --//
1127
1128// PSLL,PSRL,PSRA W/D/Q.
1129// x,x / v,v,x.
1130def Zn2WritePShift  : SchedWriteRes<[Zn2FPU2]> {
1131  let Latency = 3;
1132}
1133def Zn2WritePShiftY : SchedWriteRes<[Zn2FPU2]> {
1134  let Latency = 3;
1135}
1136
1137// PSLL,PSRL DQ.
1138def : InstRW<[Zn2WritePShift], (instregex "(V?)PS(R|L)LDQri")>;
1139def : InstRW<[Zn2WritePShiftY], (instregex "(V?)PS(R|L)LDQYri")>;
1140
1141//=== Floating Point XMM and YMM Instructions ===//
1142//-- Move instructions --//
1143
1144// VPERM2F128.
1145def : InstRW<[WriteMicrocoded], (instrs VPERM2F128rr)>;
1146def : InstRW<[WriteMicrocoded], (instrs VPERM2F128rm)>;
1147
1148def Zn2WriteBROADCAST : SchedWriteRes<[Zn2AGU, Zn2FPU13]> {
1149  let NumMicroOps = 2;
1150  let Latency = 8;
1151}
1152// VBROADCASTF128.
1153def : InstRW<[Zn2WriteBROADCAST], (instrs VBROADCASTF128)>;
1154
1155// EXTRACTPS.
1156// r32,x,i.
1157def Zn2WriteEXTRACTPSr : SchedWriteRes<[Zn2FPU12, Zn2FPU2]> {
1158  let Latency = 2;
1159  let ResourceCycles = [1, 2];
1160}
1161def : InstRW<[Zn2WriteEXTRACTPSr], (instregex "(V?)EXTRACTPSrr")>;
1162
1163def Zn2WriteEXTRACTPSm : SchedWriteRes<[Zn2AGU,Zn2FPU12, Zn2FPU2]> {
1164  let Latency = 5;
1165  let NumMicroOps = 2;
1166  let ResourceCycles = [5, 1, 2];
1167}
1168// m32,x,i.
1169def : InstRW<[Zn2WriteEXTRACTPSm], (instregex "(V?)EXTRACTPSmr")>;
1170
1171// VEXTRACTF128.
1172// x,y,i.
1173def : InstRW<[Zn2WriteFPU013], (instrs VEXTRACTF128rr)>;
1174
1175// m128,y,i.
1176def : InstRW<[Zn2WriteFPU013m], (instrs VEXTRACTF128mr)>;
1177
1178def Zn2WriteVINSERT128r: SchedWriteRes<[Zn2FPU013]> {
1179  let Latency = 2;
1180//  let ResourceCycles = [2];
1181}
1182def Zn2WriteVINSERT128Ld: SchedWriteRes<[Zn2AGU,Zn2FPU013]> {
1183  let Latency = 9;
1184  let NumMicroOps = 2;
1185}
1186// VINSERTF128.
1187// y,y,x,i.
1188def : InstRW<[Zn2WriteVINSERT128r], (instrs VINSERTF128rr)>;
1189def : InstRW<[Zn2WriteVINSERT128Ld], (instrs VINSERTF128rm)>;
1190
1191// VGATHER.
1192def : InstRW<[WriteMicrocoded], (instregex "VGATHER(Q|D)(PD|PS)(Y?)rm")>;
1193
1194//-- Conversion instructions --//
1195def Zn2WriteCVTPD2PSr: SchedWriteRes<[Zn2FPU3]> {
1196  let Latency = 3;
1197}
1198def Zn2WriteCVTPD2PSYr: SchedWriteRes<[Zn2FPU3]> {
1199  let Latency = 3;
1200}
1201
1202// CVTPD2PS.
1203// x,x.
1204def : SchedAlias<WriteCvtPD2PS,  Zn2WriteCVTPD2PSr>;
1205// y,y.
1206def : SchedAlias<WriteCvtPD2PSY, Zn2WriteCVTPD2PSYr>;
1207// z,z.
1208defm : X86WriteResUnsupported<WriteCvtPD2PSZ>;
1209
1210def Zn2WriteCVTPD2PSLd: SchedWriteRes<[Zn2AGU,Zn2FPU03]> {
1211  let Latency = 10;
1212  let NumMicroOps = 2;
1213}
1214// x,m128.
1215def : SchedAlias<WriteCvtPD2PSLd, Zn2WriteCVTPD2PSLd>;
1216
1217// x,m256.
1218def Zn2WriteCVTPD2PSYLd : SchedWriteRes<[Zn2AGU, Zn2FPU3]> {
1219  let Latency = 10;
1220}
1221def : SchedAlias<WriteCvtPD2PSYLd, Zn2WriteCVTPD2PSYLd>;
1222// z,m512
1223defm : X86WriteResUnsupported<WriteCvtPD2PSZLd>;
1224
1225// CVTSD2SS.
1226// x,x.
1227// Same as WriteCVTPD2PSr
1228def : SchedAlias<WriteCvtSD2SS, Zn2WriteCVTPD2PSr>;
1229
1230// x,m64.
1231def : SchedAlias<WriteCvtSD2SSLd, Zn2WriteCVTPD2PSLd>;
1232
1233// CVTPS2PD.
1234// x,x.
1235def Zn2WriteCVTPS2PDr : SchedWriteRes<[Zn2FPU3]> {
1236  let Latency = 3;
1237}
1238def : SchedAlias<WriteCvtPS2PD, Zn2WriteCVTPS2PDr>;
1239
1240// x,m64.
1241// y,m128.
1242def Zn2WriteCVTPS2PDLd : SchedWriteRes<[Zn2AGU, Zn2FPU3]> {
1243  let Latency = 10;
1244  let NumMicroOps = 2;
1245}
1246def : SchedAlias<WriteCvtPS2PDLd, Zn2WriteCVTPS2PDLd>;
1247def : SchedAlias<WriteCvtPS2PDYLd, Zn2WriteCVTPS2PDLd>;
1248defm : X86WriteResUnsupported<WriteCvtPS2PDZLd>;
1249
1250// y,x.
1251def Zn2WriteVCVTPS2PDY : SchedWriteRes<[Zn2FPU3]> {
1252  let Latency = 3;
1253}
1254def : SchedAlias<WriteCvtPS2PDY, Zn2WriteVCVTPS2PDY>;
1255defm : X86WriteResUnsupported<WriteCvtPS2PDZ>;
1256
1257// CVTSS2SD.
1258// x,x.
1259def Zn2WriteCVTSS2SDr : SchedWriteRes<[Zn2FPU3]> {
1260  let Latency = 3;
1261}
1262def : SchedAlias<WriteCvtSS2SD, Zn2WriteCVTSS2SDr>;
1263
1264// x,m32.
1265def Zn2WriteCVTSS2SDLd : SchedWriteRes<[Zn2AGU, Zn2FPU3]> {
1266  let Latency = 10;
1267  let NumMicroOps = 2;
1268  let ResourceCycles = [1, 2];
1269}
1270def : SchedAlias<WriteCvtSS2SDLd, Zn2WriteCVTSS2SDLd>;
1271
1272def Zn2WriteCVTDQ2PDr: SchedWriteRes<[Zn2FPU12,Zn2FPU3]> {
1273  let Latency = 3;
1274}
1275// CVTDQ2PD.
1276// x,x.
1277def : InstRW<[Zn2WriteCVTDQ2PDr], (instregex "(V)?CVTDQ2P(D|S)rr")>;
1278
1279// Same as xmm
1280// y,x.
1281def : InstRW<[Zn2WriteCVTDQ2PDr], (instrs VCVTDQ2PDYrr)>;
1282def : InstRW<[Zn2WriteCVTDQ2PDr], (instrs VCVTDQ2PSYrr)>;
1283
1284def Zn2WriteCVTPD2DQr: SchedWriteRes<[Zn2FPU12, Zn2FPU3]> {
1285  let Latency = 3;
1286}
1287// CVT(T)P(D|S)2DQ.
1288// x,x.
1289def : InstRW<[Zn2WriteCVTPD2DQr], (instregex "(V?)CVT(T?)P(D|S)2DQrr")>;
1290
1291def Zn2WriteCVTPD2DQLd: SchedWriteRes<[Zn2AGU,Zn2FPU12,Zn2FPU3]> {
1292  let Latency = 10;
1293  let NumMicroOps = 2;
1294}
1295// x,m128.
1296def : InstRW<[Zn2WriteCVTPD2DQLd], (instregex "(V?)CVT(T?)PD2DQrm")>;
1297// same as xmm handling
1298// x,y.
1299def : InstRW<[Zn2WriteCVTPD2DQr], (instregex "VCVT(T?)PD2DQYrr")>;
1300// x,m256.
1301def : InstRW<[Zn2WriteCVTPD2DQLd], (instregex "VCVT(T?)PD2DQYrm")>;
1302
1303def Zn2WriteCVTPS2PIr: SchedWriteRes<[Zn2FPU3]> {
1304  let Latency = 4;
1305}
1306// CVT(T)PS2PI.
1307// mm,x.
1308def : InstRW<[Zn2WriteCVTPS2PIr], (instregex "MMX_CVT(T?)PS2PIrr")>;
1309
1310// CVTPI2PD.
1311// x,mm.
1312def : InstRW<[Zn2WriteCVTPS2PDr], (instrs MMX_CVTPI2PDrr)>;
1313
1314// CVT(T)PD2PI.
1315// mm,x.
1316def : InstRW<[Zn2WriteCVTPS2PIr], (instregex "MMX_CVT(T?)PD2PIrr")>;
1317
1318def Zn2WriteCVSTSI2SSr: SchedWriteRes<[Zn2FPU3]> {
1319  let Latency = 3;
1320}
1321
1322// same as CVTPD2DQr
1323// CVT(T)SS2SI.
1324// r32,x.
1325def : InstRW<[Zn2WriteCVTPD2DQr], (instregex "(V?)CVT(T?)SS2SI(64)?rr")>;
1326// same as CVTPD2DQm
1327// r32,m32.
1328def : InstRW<[Zn2WriteCVTPD2DQLd], (instregex "(V?)CVT(T?)SS2SI(64)?rm")>;
1329
1330def Zn2WriteCVSTSI2SDr: SchedWriteRes<[Zn2FPU013, Zn2FPU3]> {
1331  let Latency = 3;
1332}
1333// CVTSI2SD.
1334// x,r32/64.
1335def : InstRW<[Zn2WriteCVSTSI2SDr], (instregex "(V?)CVTSI(64)?2SDrr")>;
1336
1337
1338def Zn2WriteCVSTSI2SIr: SchedWriteRes<[Zn2FPU3, Zn2FPU2]> {
1339  let Latency = 4;
1340}
1341def Zn2WriteCVSTSI2SILd: SchedWriteRes<[Zn2AGU, Zn2FPU3, Zn2FPU2]> {
1342  let Latency = 11;
1343}
1344// CVTSD2SI.
1345// r32/64
1346def : InstRW<[Zn2WriteCVSTSI2SIr], (instregex "(V?)CVT(T?)SD2SI(64)?rr")>;
1347// r32,m32.
1348def : InstRW<[Zn2WriteCVSTSI2SILd], (instregex "(V?)CVT(T?)SD2SI(64)?rm")>;
1349
1350// VCVTPS2PH.
1351// x,v,i.
1352def : SchedAlias<WriteCvtPS2PH,    Zn2WriteMicrocoded>;
1353def : SchedAlias<WriteCvtPS2PHY,   Zn2WriteMicrocoded>;
1354defm : X86WriteResUnsupported<WriteCvtPS2PHZ>;
1355// m,v,i.
1356def : SchedAlias<WriteCvtPS2PHSt,  Zn2WriteMicrocoded>;
1357def : SchedAlias<WriteCvtPS2PHYSt, Zn2WriteMicrocoded>;
1358defm : X86WriteResUnsupported<WriteCvtPS2PHZSt>;
1359
1360// VCVTPH2PS.
1361// v,x.
1362def : SchedAlias<WriteCvtPH2PS,    Zn2WriteMicrocoded>;
1363def : SchedAlias<WriteCvtPH2PSY,   Zn2WriteMicrocoded>;
1364defm : X86WriteResUnsupported<WriteCvtPH2PSZ>;
1365// v,m.
1366def : SchedAlias<WriteCvtPH2PSLd,  Zn2WriteMicrocoded>;
1367def : SchedAlias<WriteCvtPH2PSYLd, Zn2WriteMicrocoded>;
1368defm : X86WriteResUnsupported<WriteCvtPH2PSZLd>;
1369
1370//-- SSE4A instructions --//
1371// EXTRQ
1372def Zn2WriteEXTRQ: SchedWriteRes<[Zn2FPU12, Zn2FPU2]> {
1373  let Latency = 3;
1374}
1375def : InstRW<[Zn2WriteEXTRQ], (instregex "EXTRQ")>;
1376
1377// INSERTQ
1378def Zn2WriteINSERTQ: SchedWriteRes<[Zn2FPU03,Zn2FPU1]> {
1379  let Latency = 4;
1380}
1381def : InstRW<[Zn2WriteINSERTQ], (instregex "INSERTQ")>;
1382
1383//-- SHA instructions --//
1384// SHA256MSG2
1385def : InstRW<[WriteMicrocoded], (instregex "SHA256MSG2(Y?)r(r|m)")>;
1386
1387// SHA1MSG1, SHA256MSG1
1388// x,x.
1389def Zn2WriteSHA1MSG1r : SchedWriteRes<[Zn2FPU12]> {
1390  let Latency = 2;
1391}
1392def : InstRW<[Zn2WriteSHA1MSG1r], (instregex "SHA(1|256)MSG1rr")>;
1393// x,m.
1394def Zn2WriteSHA1MSG1Ld : SchedWriteRes<[Zn2AGU, Zn2FPU12]> {
1395  let Latency = 9;
1396}
1397def : InstRW<[Zn2WriteSHA1MSG1Ld], (instregex "SHA(1|256)MSG1rm")>;
1398
1399// SHA1MSG2
1400// x,x.
1401def Zn2WriteSHA1MSG2r : SchedWriteRes<[Zn2FPU12]> ;
1402def : InstRW<[Zn2WriteSHA1MSG2r], (instregex "SHA1MSG2rr")>;
1403// x,m.
1404def Zn2WriteSHA1MSG2Ld : SchedWriteRes<[Zn2AGU, Zn2FPU12]> {
1405  let Latency = 8;
1406}
1407def : InstRW<[Zn2WriteSHA1MSG2Ld], (instregex "SHA1MSG2rm")>;
1408
1409// SHA1NEXTE
1410// x,x.
1411def Zn2WriteSHA1NEXTEr : SchedWriteRes<[Zn2FPU1]> ;
1412def : InstRW<[Zn2WriteSHA1NEXTEr], (instregex "SHA1NEXTErr")>;
1413// x,m.
1414def Zn2WriteSHA1NEXTELd : SchedWriteRes<[Zn2AGU, Zn2FPU1]> {
1415  let Latency = 8;
1416}
1417def : InstRW<[Zn2WriteSHA1NEXTELd], (instregex "SHA1NEXTErm")>;
1418
1419// SHA1RNDS4
1420// x,x.
1421def Zn2WriteSHA1RNDS4r : SchedWriteRes<[Zn2FPU1]> {
1422  let Latency = 6;
1423}
1424def : InstRW<[Zn2WriteSHA1RNDS4r], (instregex "SHA1RNDS4rr")>;
1425// x,m.
1426def Zn2WriteSHA1RNDS4Ld : SchedWriteRes<[Zn2AGU, Zn2FPU1]> {
1427  let Latency = 13;
1428}
1429def : InstRW<[Zn2WriteSHA1RNDS4Ld], (instregex "SHA1RNDS4rm")>;
1430
1431// SHA256RNDS2
1432// x,x.
1433def Zn2WriteSHA256RNDS2r : SchedWriteRes<[Zn2FPU1]> {
1434  let Latency = 4;
1435}
1436def : InstRW<[Zn2WriteSHA256RNDS2r], (instregex "SHA256RNDS2rr")>;
1437// x,m.
1438def Zn2WriteSHA256RNDS2Ld : SchedWriteRes<[Zn2AGU, Zn2FPU1]> {
1439  let Latency = 11;
1440}
1441def : InstRW<[Zn2WriteSHA256RNDS2Ld], (instregex "SHA256RNDS2rm")>;
1442
1443//-- Arithmetic instructions --//
1444
1445// VDIVPS.
1446// TODO - convert to Zn2WriteResFpuPair
1447// y,y,y.
1448def Zn2WriteVDIVPSYr : SchedWriteRes<[Zn2FPU3]> {
1449  let Latency = 10;
1450  let ResourceCycles = [10];
1451}
1452def : SchedAlias<WriteFDivY,   Zn2WriteVDIVPSYr>;
1453
1454// y,y,m256.
1455def Zn2WriteVDIVPSYLd : SchedWriteRes<[Zn2AGU, Zn2FPU3]> {
1456  let Latency = 17;
1457  let NumMicroOps = 2;
1458  let ResourceCycles = [1, 17];
1459}
1460def : SchedAlias<WriteFDivYLd,  Zn2WriteVDIVPSYLd>;
1461
1462// VDIVPD.
1463// TODO - convert to Zn2WriteResFpuPair
1464// y,y,y.
1465def Zn2WriteVDIVPDY : SchedWriteRes<[Zn2FPU3]> {
1466  let Latency = 13;
1467  let ResourceCycles = [13];
1468}
1469def : SchedAlias<WriteFDiv64Y, Zn2WriteVDIVPDY>;
1470
1471// y,y,m256.
1472def Zn2WriteVDIVPDYLd : SchedWriteRes<[Zn2AGU, Zn2FPU3]> {
1473  let Latency = 20;
1474  let NumMicroOps = 2;
1475  let ResourceCycles = [1,20];
1476}
1477def : SchedAlias<WriteFDiv64YLd, Zn2WriteVDIVPDYLd>;
1478
1479// DPPS.
1480// x,x,i / v,v,v,i.
1481defm : Zn2WriteResPair<WriteDPPS, [], 15>;
1482def : SchedAlias<WriteDPPSY,  Zn2WriteMicrocoded>;
1483
1484// x,m,i / v,v,m,i.
1485def : SchedAlias<WriteDPPSYLd,Zn2WriteMicrocoded>;
1486
1487// DPPD.
1488// x,x,i.
1489def : SchedAlias<WriteDPPD,   Zn2WriteMicrocoded>;
1490
1491// x,m,i.
1492def : SchedAlias<WriteDPPDLd, Zn2WriteMicrocoded>;
1493
1494// RSQRTSS
1495// TODO - convert to Zn2WriteResFpuPair
1496// x,x.
1497def Zn2WriteRSQRTSSr : SchedWriteRes<[Zn2FPU02]> {
1498  let Latency = 5;
1499}
1500def : SchedAlias<WriteFRsqrt, Zn2WriteRSQRTSSr>;
1501
1502// x,m128.
1503def Zn2WriteRSQRTSSLd: SchedWriteRes<[Zn2AGU, Zn2FPU02]> {
1504  let Latency = 12;
1505  let NumMicroOps = 2;
1506  let ResourceCycles = [1,2];
1507}
1508def : SchedAlias<WriteFRsqrtLd, Zn2WriteRSQRTSSLd>;
1509
1510// RSQRTPS
1511// TODO - convert to Zn2WriteResFpuPair
1512// y,y.
1513def Zn2WriteRSQRTPSYr : SchedWriteRes<[Zn2FPU01]> {
1514  let Latency = 5;
1515  let NumMicroOps = 2;
1516  let ResourceCycles = [2];
1517}
1518def : SchedAlias<WriteFRsqrtY, Zn2WriteRSQRTPSYr>;
1519
1520// y,m256.
1521def Zn2WriteRSQRTPSYLd : SchedWriteRes<[Zn2AGU, Zn2FPU01]> {
1522  let Latency = 12;
1523  let NumMicroOps = 2;
1524}
1525def : SchedAlias<WriteFRsqrtYLd, Zn2WriteRSQRTPSYLd>;
1526
1527//-- Other instructions --//
1528
1529// VZEROUPPER.
1530def : InstRW<[WriteALU], (instrs VZEROUPPER)>;
1531
1532// VZEROALL.
1533def : InstRW<[WriteMicrocoded], (instrs VZEROALL)>;
1534
1535///////////////////////////////////////////////////////////////////////////////
1536// Dependency breaking instructions.
1537///////////////////////////////////////////////////////////////////////////////
1538
1539def : IsZeroIdiomFunction<[
1540  // GPR Zero-idioms.
1541  DepBreakingClass<[
1542    SUB32rr, SUB64rr,
1543    XOR32rr, XOR64rr
1544  ], ZeroIdiomPredicate>,
1545
1546  // MMX Zero-idioms.
1547  DepBreakingClass<[
1548    MMX_PXORrr, MMX_PANDNrr, MMX_PSUBBrr,
1549    MMX_PSUBDrr, MMX_PSUBQrr, MMX_PSUBWrr,
1550    MMX_PSUBSBrr, MMX_PSUBSWrr, MMX_PSUBUSBrr, MMX_PSUBUSWrr,
1551    MMX_PCMPGTBrr, MMX_PCMPGTDrr, MMX_PCMPGTWrr
1552  ], ZeroIdiomPredicate>,
1553
1554  // SSE Zero-idioms.
1555  DepBreakingClass<[
1556    // fp variants.
1557    XORPSrr, XORPDrr, ANDNPSrr, ANDNPDrr,
1558
1559    // int variants.
1560    PXORrr, PANDNrr,
1561    PSUBBrr, PSUBWrr, PSUBDrr, PSUBQrr,
1562    PCMPGTBrr, PCMPGTDrr, PCMPGTQrr, PCMPGTWrr
1563  ], ZeroIdiomPredicate>,
1564
1565  // AVX XMM Zero-idioms.
1566  DepBreakingClass<[
1567    // fp variants.
1568    VXORPSrr, VXORPDrr, VANDNPSrr, VANDNPDrr,
1569
1570    // int variants.
1571    VPXORrr, VPANDNrr,
1572    VPSUBBrr, VPSUBWrr, VPSUBDrr, VPSUBQrr,
1573    VPCMPGTBrr, VPCMPGTWrr, VPCMPGTDrr, VPCMPGTQrr
1574  ], ZeroIdiomPredicate>,
1575
1576  // AVX YMM Zero-idioms.
1577  DepBreakingClass<[
1578    // fp variants
1579    VXORPSYrr, VXORPDYrr, VANDNPSYrr, VANDNPDYrr,
1580
1581    // int variants
1582    VPXORYrr, VPANDNYrr,
1583    VPSUBBYrr, VPSUBWYrr, VPSUBDYrr, VPSUBQYrr,
1584    VPCMPGTBYrr, VPCMPGTWYrr, VPCMPGTDYrr, VPCMPGTQYrr
1585  ], ZeroIdiomPredicate>
1586]>;
1587
1588def : IsDepBreakingFunction<[
1589  // GPR
1590  DepBreakingClass<[ SBB32rr, SBB64rr ], ZeroIdiomPredicate>,
1591  DepBreakingClass<[ CMP32rr, CMP64rr ], CheckSameRegOperand<0, 1> >,
1592
1593  // MMX
1594  DepBreakingClass<[
1595    MMX_PCMPEQBrr, MMX_PCMPEQWrr, MMX_PCMPEQDrr
1596  ], ZeroIdiomPredicate>,
1597
1598  // SSE
1599  DepBreakingClass<[
1600    PCMPEQBrr, PCMPEQWrr, PCMPEQDrr, PCMPEQQrr
1601  ], ZeroIdiomPredicate>,
1602
1603  // AVX XMM
1604  DepBreakingClass<[
1605    VPCMPEQBrr, VPCMPEQWrr, VPCMPEQDrr, VPCMPEQQrr
1606  ], ZeroIdiomPredicate>,
1607
1608  // AVX YMM
1609  DepBreakingClass<[
1610    VPCMPEQBYrr, VPCMPEQWYrr, VPCMPEQDYrr, VPCMPEQQYrr
1611  ], ZeroIdiomPredicate>,
1612]>;
1613
1614} // SchedModel
1615