• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1//=- X86ScheduleBtVer2.td - X86 BtVer2 (Jaguar) Scheduling ---*- tablegen -*-=//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the machine model for AMD btver2 (Jaguar) to support
11// instruction scheduling and other instruction cost heuristics. Based off AMD Software
12// Optimization Guide for AMD Family 16h Processors & Instruction Latency appendix.
13//
14//===----------------------------------------------------------------------===//
15
16def BtVer2Model : SchedMachineModel {
17  // All x86 instructions are modeled as a single micro-op, and btver2 can
18  // decode 2 instructions per cycle.
19  let IssueWidth = 2;
20  let MicroOpBufferSize = 64; // Retire Control Unit
21  let LoadLatency = 5; // FPU latency (worse case cf Integer 3 cycle latency)
22  let HighLatency = 25;
23  let MispredictPenalty = 14; // Minimum branch misdirection penalty
24  let PostRAScheduler = 1;
25
26  // FIXME: SSE4/AVX is unimplemented. This flag is set to allow
27  // the scheduler to assign a default model to unrecognized opcodes.
28  let CompleteModel = 0;
29}
30
31let SchedModel = BtVer2Model in {
32
33// Jaguar can issue up to 6 micro-ops in one cycle
34def JALU0 : ProcResource<1>; // Integer Pipe0: integer ALU0 (also handle FP->INT jam)
35def JALU1 : ProcResource<1>; // Integer Pipe1: integer ALU1/MUL/DIV
36def JLAGU : ProcResource<1>; // Integer Pipe2: LAGU
37def JSAGU : ProcResource<1>; // Integer Pipe3: SAGU (also handles 3-operand LEA)
38def JFPU0 : ProcResource<1>; // Vector/FPU Pipe0: VALU0/VIMUL/FPA
39def JFPU1 : ProcResource<1>; // Vector/FPU Pipe1: VALU1/STC/FPM
40
41// The Integer PRF for Jaguar is 64 entries, and it holds the architectural and
42// speculative version of the 64-bit integer registers.
43// Reference: www.realworldtech.com/jaguar/4/
44//
45// The processor always keeps the different parts of an integer register
46// together. An instruction that writes to a part of a register will therefore
47// have a false dependence on any previous write to the same register or any
48// part of it.
49// Reference: Section 21.10 "AMD Bobcat and Jaguar pipeline: Partial register
50// access" - Agner Fog's "microarchitecture.pdf".
51def JIntegerPRF : RegisterFile<64, [GR64, CCR]>;
52
53// The Jaguar FP Retire Queue renames SIMD and FP uOps onto a pool of 72 SSE
54// registers. Operations on 256-bit data types are cracked into two COPs.
55// Reference: www.realworldtech.com/jaguar/4/
56def JFpuPRF: RegisterFile<72, [VR64, VR128, VR256], [1, 1, 2]>;
57
58// The retire control unit (RCU) can track up to 64 macro-ops in-flight. It can
59// retire up to two macro-ops per cycle.
60// Reference: "Software Optimization Guide for AMD Family 16h Processors"
61def JRCU : RetireControlUnit<64, 2>;
62
63// Integer Pipe Scheduler
64def JALU01 : ProcResGroup<[JALU0, JALU1]> {
65  let BufferSize=20;
66}
67
68// AGU Pipe Scheduler
69def JLSAGU : ProcResGroup<[JLAGU, JSAGU]> {
70  let BufferSize=12;
71}
72
73// Fpu Pipe Scheduler
74def JFPU01 : ProcResGroup<[JFPU0, JFPU1]> {
75  let BufferSize=18;
76}
77
78// Functional units
79def JDiv    : ProcResource<1>; // integer division
80def JMul    : ProcResource<1>; // integer multiplication
81def JVALU0  : ProcResource<1>; // vector integer
82def JVALU1  : ProcResource<1>; // vector integer
83def JVIMUL  : ProcResource<1>; // vector integer multiplication
84def JSTC    : ProcResource<1>; // vector store/convert
85def JFPM    : ProcResource<1>; // FP multiplication
86def JFPA    : ProcResource<1>; // FP addition
87
88// Functional unit groups
89def JFPX  : ProcResGroup<[JFPA, JFPM]>;
90def JVALU : ProcResGroup<[JVALU0, JVALU1]>;
91
92// Integer loads are 3 cycles, so ReadAfterLd registers needn't be available until 3
93// cycles after the memory operand.
94def : ReadAdvance<ReadAfterLd, 3>;
95
96// Many SchedWrites are defined in pairs with and without a folded load.
97// Instructions with folded loads are usually micro-fused, so they only appear
98// as two micro-ops when dispatched by the schedulers.
99// This multiclass defines the resource usage for variants with and without
100// folded loads.
101multiclass JWriteResIntPair<X86FoldableSchedWrite SchedRW,
102                            list<ProcResourceKind> ExePorts,
103                            int Lat, list<int> Res = [], int UOps = 1> {
104  // Register variant is using a single cycle on ExePort.
105  def : WriteRes<SchedRW, ExePorts> {
106    let Latency = Lat;
107    let ResourceCycles = Res;
108    let NumMicroOps = UOps;
109  }
110
111  // Memory variant also uses a cycle on JLAGU and adds 3 cycles to the
112  // latency.
113  def : WriteRes<SchedRW.Folded, !listconcat([JLAGU], ExePorts)> {
114    let Latency = !add(Lat, 3);
115    let ResourceCycles = !if(!empty(Res), [], !listconcat([1], Res));
116    let NumMicroOps = UOps;
117  }
118}
119
120multiclass JWriteResFpuPair<X86FoldableSchedWrite SchedRW,
121                            list<ProcResourceKind> ExePorts,
122                            int Lat, list<int> Res = [], int UOps = 1> {
123  // Register variant is using a single cycle on ExePort.
124  def : WriteRes<SchedRW, ExePorts> {
125    let Latency = Lat;
126    let ResourceCycles = Res;
127    let NumMicroOps = UOps;
128  }
129
130  // Memory variant also uses a cycle on JLAGU and adds 5 cycles to the
131  // latency.
132  def : WriteRes<SchedRW.Folded, !listconcat([JLAGU], ExePorts)> {
133    let Latency = !add(Lat, 5);
134    let ResourceCycles = !if(!empty(Res), [], !listconcat([1], Res));
135    let NumMicroOps = UOps;
136  }
137}
138
139multiclass JWriteResYMMPair<X86FoldableSchedWrite SchedRW,
140                            list<ProcResourceKind> ExePorts,
141                            int Lat, list<int> Res = [2], int UOps = 2> {
142  // Register variant is using a single cycle on ExePort.
143  def : WriteRes<SchedRW, ExePorts> {
144    let Latency = Lat;
145    let ResourceCycles = Res;
146    let NumMicroOps = UOps;
147  }
148
149  // Memory variant also uses 2 cycles on JLAGU and adds 5 cycles to the
150  // latency.
151  def : WriteRes<SchedRW.Folded, !listconcat([JLAGU], ExePorts)> {
152    let Latency = !add(Lat, 5);
153    let ResourceCycles = !listconcat([2], Res);
154    let NumMicroOps = UOps;
155  }
156}
157
158// A folded store needs a cycle on the SAGU for the store data.
159def : WriteRes<WriteRMW, [JSAGU]>;
160
161////////////////////////////////////////////////////////////////////////////////
162// Arithmetic.
163////////////////////////////////////////////////////////////////////////////////
164
165defm : JWriteResIntPair<WriteALU,    [JALU01], 1>;
166defm : JWriteResIntPair<WriteADC,    [JALU01], 1, [2]>;
167defm : JWriteResIntPair<WriteIMul,   [JALU1, JMul], 3, [1, 1], 2>; // i8/i16/i32 multiplication
168defm : JWriteResIntPair<WriteIMul64, [JALU1, JMul], 6, [1, 4], 2>; // i64 multiplication
169defm : X86WriteRes<WriteIMulH,       [JALU1], 6, [4], 1>;
170
171defm : X86WriteRes<WriteBSWAP32, [JALU01], 1, [1], 1>;
172defm : X86WriteRes<WriteBSWAP64, [JALU01], 1, [1], 1>;
173
174defm : JWriteResIntPair<WriteDiv8,   [JALU1, JDiv], 12, [1, 12], 1>;
175defm : JWriteResIntPair<WriteDiv16,  [JALU1, JDiv], 17, [1, 17], 2>;
176defm : JWriteResIntPair<WriteDiv32,  [JALU1, JDiv], 25, [1, 25], 2>;
177defm : JWriteResIntPair<WriteDiv64,  [JALU1, JDiv], 41, [1, 41], 2>;
178defm : JWriteResIntPair<WriteIDiv8,  [JALU1, JDiv], 12, [1, 12], 1>;
179defm : JWriteResIntPair<WriteIDiv16, [JALU1, JDiv], 17, [1, 17], 2>;
180defm : JWriteResIntPair<WriteIDiv32, [JALU1, JDiv], 25, [1, 25], 2>;
181defm : JWriteResIntPair<WriteIDiv64, [JALU1, JDiv], 41, [1, 41], 2>;
182
183defm : JWriteResIntPair<WriteCRC32,  [JALU01], 3, [4], 3>;
184
185defm : JWriteResIntPair<WriteCMOV,  [JALU01], 1>; // Conditional move.
186defm : JWriteResIntPair<WriteCMOV2, [JALU01], 1>; // Conditional (CF + ZF flag) move.
187defm : X86WriteRes<WriteFCMOV, [JFPU0, JFPA], 3, [1,1], 1>; // x87 conditional move.
188def  : WriteRes<WriteSETCC, [JALU01]>; // Setcc.
189def  : WriteRes<WriteSETCCStore, [JALU01,JSAGU]>;
190def  : WriteRes<WriteLAHFSAHF, [JALU01]>;
191def  : WriteRes<WriteBitTest,[JALU01]>;
192
193// This is for simple LEAs with one or two input operands.
194def : WriteRes<WriteLEA, [JALU01]>;
195
196// Bit counts.
197defm : JWriteResIntPair<WriteBSF, [JALU01], 5, [4], 8>;
198defm : JWriteResIntPair<WriteBSR, [JALU01], 5, [4], 8>;
199defm : JWriteResIntPair<WritePOPCNT,         [JALU01], 1>;
200defm : JWriteResIntPair<WriteLZCNT,          [JALU01], 1>;
201defm : JWriteResIntPair<WriteTZCNT,          [JALU01], 2, [2]>;
202
203// BMI1 BEXTR, BMI2 BZHI
204defm : JWriteResIntPair<WriteBEXTR, [JALU01], 1>;
205defm : X86WriteResPairUnsupported<WriteBZHI>;
206
207////////////////////////////////////////////////////////////////////////////////
208// Integer shifts and rotates.
209////////////////////////////////////////////////////////////////////////////////
210
211defm : JWriteResIntPair<WriteShift, [JALU01], 1>;
212
213// SHLD/SHRD.
214defm : X86WriteRes<WriteSHDrri, [JALU01], 3, [6], 6>;
215defm : X86WriteRes<WriteSHDrrcl,[JALU01], 4, [8], 7>;
216defm : X86WriteRes<WriteSHDmri, [JLAGU, JALU01], 9, [1, 22], 8>;
217defm : X86WriteRes<WriteSHDmrcl,[JLAGU, JALU01], 9, [1, 22], 8>;
218
219////////////////////////////////////////////////////////////////////////////////
220// Loads, stores, and moves, not folded with other operations.
221////////////////////////////////////////////////////////////////////////////////
222
223def : WriteRes<WriteLoad,    [JLAGU]> { let Latency = 5; }
224def : WriteRes<WriteStore,   [JSAGU]>;
225def : WriteRes<WriteStoreNT, [JSAGU]>;
226def : WriteRes<WriteMove,    [JALU01]>;
227
228// Load/store MXCSR.
229// FIXME: These are copy and pasted from WriteLoad/Store.
230def : WriteRes<WriteLDMXCSR, [JLAGU]> { let Latency = 5; }
231def : WriteRes<WriteSTMXCSR, [JSAGU]>;
232
233// Treat misc copies as a move.
234def : InstRW<[WriteMove], (instrs COPY)>;
235
236////////////////////////////////////////////////////////////////////////////////
237// Idioms that clear a register, like xorps %xmm0, %xmm0.
238// These can often bypass execution ports completely.
239////////////////////////////////////////////////////////////////////////////////
240
241def : WriteRes<WriteZero,  []>;
242
243////////////////////////////////////////////////////////////////////////////////
244// Branches don't produce values, so they have no latency, but they still
245// consume resources. Indirect branches can fold loads.
246////////////////////////////////////////////////////////////////////////////////
247
248defm : JWriteResIntPair<WriteJump,  [JALU01], 1>;
249
250////////////////////////////////////////////////////////////////////////////////
251// Special case scheduling classes.
252////////////////////////////////////////////////////////////////////////////////
253
254def : WriteRes<WriteSystem,     [JALU01]> { let Latency = 100; }
255def : WriteRes<WriteMicrocoded, [JALU01]> { let Latency = 100; }
256def : WriteRes<WriteFence,  [JSAGU]>;
257
258// Nops don't have dependencies, so there's no actual latency, but we set this
259// to '1' to tell the scheduler that the nop uses an ALU slot for a cycle.
260def : WriteRes<WriteNop, [JALU01]> { let Latency = 1; }
261
262////////////////////////////////////////////////////////////////////////////////
263// Floating point. This covers both scalar and vector operations.
264////////////////////////////////////////////////////////////////////////////////
265
266defm : X86WriteRes<WriteFLD0,          [JFPU1, JSTC], 3, [1,1], 1>;
267defm : X86WriteRes<WriteFLD1,          [JFPU1, JSTC], 3, [1,1], 1>;
268defm : X86WriteRes<WriteFLDC,          [JFPU1, JSTC], 3, [1,1], 1>;
269defm : X86WriteRes<WriteFLoad,         [JLAGU, JFPU01, JFPX], 5, [1, 1, 1], 1>;
270defm : X86WriteRes<WriteFLoadX,        [JLAGU, JFPU01, JFPX], 5, [1, 1, 1], 1>;
271defm : X86WriteRes<WriteFLoadY,        [JLAGU, JFPU01, JFPX], 5, [1, 1, 1], 1>;
272defm : X86WriteRes<WriteFMaskedLoad,   [JLAGU, JFPU01, JFPX], 6, [1, 1, 2], 1>;
273defm : X86WriteRes<WriteFMaskedLoadY,  [JLAGU, JFPU01, JFPX], 6, [2, 2, 4], 2>;
274
275defm : X86WriteRes<WriteFStore,        [JSAGU, JFPU1,  JSTC], 2, [1, 1, 1], 1>;
276defm : X86WriteRes<WriteFStoreX,       [JSAGU, JFPU1,  JSTC], 1, [1, 1, 1], 1>;
277defm : X86WriteRes<WriteFStoreY,       [JSAGU, JFPU1,  JSTC], 1, [1, 1, 1], 1>;
278defm : X86WriteRes<WriteFStoreNT,      [JSAGU, JFPU1,  JSTC], 3, [1, 1, 1], 1>;
279defm : X86WriteRes<WriteFStoreNTX,     [JSAGU, JFPU1,  JSTC], 3, [1, 1, 1], 1>;
280defm : X86WriteRes<WriteFStoreNTY,     [JSAGU, JFPU1,  JSTC], 3, [2, 2, 2], 1>;
281defm : X86WriteRes<WriteFMaskedStore,  [JSAGU, JFPU01, JFPX], 6, [1, 1, 4], 1>;
282defm : X86WriteRes<WriteFMaskedStoreY, [JSAGU, JFPU01, JFPX], 6, [2, 2, 4], 2>;
283
284defm : X86WriteRes<WriteFMove,         [JFPU01, JFPX], 1, [1, 1], 1>;
285defm : X86WriteRes<WriteFMoveX,        [JFPU01, JFPX], 1, [1, 1], 1>;
286defm : X86WriteRes<WriteFMoveY,        [JFPU01, JFPX], 1, [2, 2], 2>;
287
288defm : X86WriteRes<WriteEMMS,          [JFPU01, JFPX], 2, [1, 1], 1>;
289
290defm : JWriteResFpuPair<WriteFAdd,         [JFPU0, JFPA],  3>;
291defm : JWriteResFpuPair<WriteFAddX,        [JFPU0, JFPA],  3>;
292defm : JWriteResYMMPair<WriteFAddY,        [JFPU0, JFPA],  3, [2,2], 2>;
293defm : X86WriteResPairUnsupported<WriteFAddZ>;
294defm : JWriteResFpuPair<WriteFAdd64,       [JFPU0, JFPA],  3>;
295defm : JWriteResFpuPair<WriteFAdd64X,      [JFPU0, JFPA],  3>;
296defm : JWriteResYMMPair<WriteFAdd64Y,      [JFPU0, JFPA],  3, [2,2], 2>;
297defm : X86WriteResPairUnsupported<WriteFAdd64Z>;
298defm : JWriteResFpuPair<WriteFCmp,         [JFPU0, JFPA],  2>;
299defm : JWriteResFpuPair<WriteFCmpX,        [JFPU0, JFPA],  2>;
300defm : JWriteResYMMPair<WriteFCmpY,        [JFPU0, JFPA],  2, [2,2], 2>;
301defm : X86WriteResPairUnsupported<WriteFCmpZ>;
302defm : JWriteResFpuPair<WriteFCmp64,       [JFPU0, JFPA],  2>;
303defm : JWriteResFpuPair<WriteFCmp64X,      [JFPU0, JFPA],  2>;
304defm : JWriteResYMMPair<WriteFCmp64Y,      [JFPU0, JFPA],  2, [2,2], 2>;
305defm : X86WriteResPairUnsupported<WriteFCmp64Z>;
306defm : JWriteResFpuPair<WriteFCom,  [JFPU0, JFPA, JALU0],  3>;
307defm : JWriteResFpuPair<WriteFMul,         [JFPU1, JFPM],  2>;
308defm : JWriteResFpuPair<WriteFMulX,        [JFPU1, JFPM],  2>;
309defm : JWriteResYMMPair<WriteFMulY,        [JFPU1, JFPM],  2, [2,2], 2>;
310defm : X86WriteResPairUnsupported<WriteFMulZ>;
311defm : JWriteResFpuPair<WriteFMul64,       [JFPU1, JFPM],  4, [1,2]>;
312defm : JWriteResFpuPair<WriteFMul64X,      [JFPU1, JFPM],  4, [1,2]>;
313defm : JWriteResYMMPair<WriteFMul64Y,      [JFPU1, JFPM],  4, [2,4], 2>;
314defm : X86WriteResPairUnsupported<WriteFMul64Z>;
315defm : X86WriteResPairUnsupported<WriteFMA>;
316defm : X86WriteResPairUnsupported<WriteFMAX>;
317defm : X86WriteResPairUnsupported<WriteFMAY>;
318defm : X86WriteResPairUnsupported<WriteFMAZ>;
319defm : JWriteResFpuPair<WriteDPPD,   [JFPU1, JFPM, JFPA],  9, [1, 3, 3],  3>;
320defm : JWriteResFpuPair<WriteDPPS,   [JFPU1, JFPM, JFPA], 11, [1, 3, 3],  5>;
321defm : JWriteResYMMPair<WriteDPPSY,  [JFPU1, JFPM, JFPA], 12, [2, 6, 6], 10>;
322defm : X86WriteResPairUnsupported<WriteDPPSZ>;
323defm : JWriteResFpuPair<WriteFRcp,         [JFPU1, JFPM],  2>;
324defm : JWriteResFpuPair<WriteFRcpX,        [JFPU1, JFPM],  2>;
325defm : JWriteResYMMPair<WriteFRcpY,        [JFPU1, JFPM],  2, [2,2], 2>;
326defm : X86WriteResPairUnsupported<WriteFRcpZ>;
327defm : JWriteResFpuPair<WriteFRsqrt,       [JFPU1, JFPM],  2>;
328defm : JWriteResFpuPair<WriteFRsqrtX,      [JFPU1, JFPM],  2>;
329defm : JWriteResYMMPair<WriteFRsqrtY,      [JFPU1, JFPM],  2, [2,2], 2>;
330defm : X86WriteResPairUnsupported<WriteFRsqrtZ>;
331defm : JWriteResFpuPair<WriteFDiv,         [JFPU1, JFPM], 19, [1, 19]>;
332defm : JWriteResFpuPair<WriteFDivX,        [JFPU1, JFPM], 19, [1, 19]>;
333defm : JWriteResYMMPair<WriteFDivY,        [JFPU1, JFPM], 38, [2, 38], 2>;
334defm : X86WriteResPairUnsupported<WriteFDivZ>;
335defm : JWriteResFpuPair<WriteFDiv64,       [JFPU1, JFPM], 19, [1, 19]>;
336defm : JWriteResFpuPair<WriteFDiv64X,      [JFPU1, JFPM], 19, [1, 19]>;
337defm : JWriteResYMMPair<WriteFDiv64Y,      [JFPU1, JFPM], 38, [2, 38], 2>;
338defm : X86WriteResPairUnsupported<WriteFDiv64Z>;
339defm : JWriteResFpuPair<WriteFSqrt,        [JFPU1, JFPM], 21, [1, 21]>;
340defm : JWriteResFpuPair<WriteFSqrtX,       [JFPU1, JFPM], 21, [1, 21]>;
341defm : JWriteResYMMPair<WriteFSqrtY,       [JFPU1, JFPM], 42, [2, 42], 2>;
342defm : X86WriteResPairUnsupported<WriteFSqrtZ>;
343defm : JWriteResFpuPair<WriteFSqrt64,      [JFPU1, JFPM], 27, [1, 27]>;
344defm : JWriteResFpuPair<WriteFSqrt64X,     [JFPU1, JFPM], 27, [1, 27]>;
345defm : JWriteResYMMPair<WriteFSqrt64Y,     [JFPU1, JFPM], 54, [2, 54], 2>;
346defm : X86WriteResPairUnsupported<WriteFSqrt64Z>;
347defm : JWriteResFpuPair<WriteFSqrt80,      [JFPU1, JFPM], 35, [1, 35]>;
348defm : JWriteResFpuPair<WriteFSign,        [JFPU1, JFPM],  2>;
349defm : JWriteResFpuPair<WriteFRnd,         [JFPU1, JSTC],  3>;
350defm : JWriteResYMMPair<WriteFRndY,        [JFPU1, JSTC],  3, [2,2], 2>;
351defm : X86WriteResPairUnsupported<WriteFRndZ>;
352defm : JWriteResFpuPair<WriteFLogic,      [JFPU01, JFPX],  1>;
353defm : JWriteResYMMPair<WriteFLogicY,     [JFPU01, JFPX],  1, [2, 2], 2>;
354defm : X86WriteResPairUnsupported<WriteFLogicZ>;
355defm : JWriteResFpuPair<WriteFTest,       [JFPU0, JFPA, JALU0], 3>;
356defm : JWriteResYMMPair<WriteFTestY ,     [JFPU01, JFPX, JFPA, JALU0], 4, [2, 2, 2, 1], 3>;
357defm : X86WriteResPairUnsupported<WriteFTestZ>;
358defm : JWriteResFpuPair<WriteFShuffle,    [JFPU01, JFPX],  1>;
359defm : JWriteResYMMPair<WriteFShuffleY,   [JFPU01, JFPX],  1, [2, 2], 2>;
360defm : X86WriteResPairUnsupported<WriteFShuffleZ>;
361defm : JWriteResFpuPair<WriteFVarShuffle, [JFPU01, JFPX],  2, [1, 4], 3>;
362defm : JWriteResYMMPair<WriteFVarShuffleY,[JFPU01, JFPX],  3, [2, 6], 6>;
363defm : X86WriteResPairUnsupported<WriteFVarShuffleZ>;
364defm : JWriteResFpuPair<WriteFBlend,      [JFPU01, JFPX],  1>;
365defm : JWriteResYMMPair<WriteFBlendY,     [JFPU01, JFPX],  1, [2, 2], 2>;
366defm : X86WriteResPairUnsupported<WriteFBlendZ>;
367defm : JWriteResFpuPair<WriteFVarBlend,   [JFPU01, JFPX],  2, [1, 4], 3>;
368defm : JWriteResYMMPair<WriteFVarBlendY,  [JFPU01, JFPX],  3, [2, 6], 6>;
369defm : X86WriteResPairUnsupported<WriteFVarBlendZ>;
370defm : JWriteResFpuPair<WriteFShuffle256, [JFPU01, JFPX],  1>;
371defm : X86WriteResPairUnsupported<WriteFVarShuffle256>;
372
373////////////////////////////////////////////////////////////////////////////////
374// Conversions.
375////////////////////////////////////////////////////////////////////////////////
376
377defm : JWriteResFpuPair<WriteCvtSS2I,      [JFPU1, JSTC, JFPA, JALU0], 7, [1,1,1,1], 2>;
378defm : JWriteResFpuPair<WriteCvtPS2I,      [JFPU1, JSTC], 3, [1,1], 1>;
379defm : JWriteResYMMPair<WriteCvtPS2IY,     [JFPU1, JSTC], 3, [2,2], 2>;
380defm : X86WriteResPairUnsupported<WriteCvtPS2IZ>;
381defm : JWriteResFpuPair<WriteCvtSD2I,      [JFPU1, JSTC, JFPA, JALU0], 7, [1,1,1,1], 2>;
382defm : JWriteResFpuPair<WriteCvtPD2I,      [JFPU1, JSTC], 3, [1,1], 1>;
383defm : JWriteResYMMPair<WriteCvtPD2IY,     [JFPU1, JSTC, JFPX], 6, [2,2,4], 3>;
384defm : X86WriteResPairUnsupported<WriteCvtPD2IZ>;
385
386// FIXME: f+3 ST, LD+STC latency
387defm : JWriteResFpuPair<WriteCvtI2SS,      [JFPU1, JSTC], 9, [1,1], 2>;
388defm : JWriteResFpuPair<WriteCvtI2PS,      [JFPU1, JSTC], 3, [1,1], 1>;
389defm : JWriteResYMMPair<WriteCvtI2PSY,     [JFPU1, JSTC], 3, [2,2], 2>;
390defm : X86WriteResPairUnsupported<WriteCvtI2PSZ>;
391defm : JWriteResFpuPair<WriteCvtI2SD,      [JFPU1, JSTC], 9, [1,1], 2>;
392defm : JWriteResFpuPair<WriteCvtI2PD,      [JFPU1, JSTC], 3, [1,1], 1>;
393defm : JWriteResYMMPair<WriteCvtI2PDY,     [JFPU1, JSTC], 3, [2,2], 2>;
394defm : X86WriteResPairUnsupported<WriteCvtI2PDZ>;
395
396defm : JWriteResFpuPair<WriteCvtSS2SD,      [JFPU1, JSTC], 7, [1,2], 2>;
397defm : JWriteResFpuPair<WriteCvtPS2PD,      [JFPU1, JSTC], 2, [1,1], 1>;
398defm : JWriteResYMMPair<WriteCvtPS2PDY,     [JFPU1, JSTC], 2, [2,2], 2>;
399defm : X86WriteResPairUnsupported<WriteCvtPS2PDZ>;
400
401defm : JWriteResFpuPair<WriteCvtSD2SS,    [JFPU1, JSTC], 7, [1,2], 2>;
402defm : JWriteResFpuPair<WriteCvtPD2PS,    [JFPU1, JSTC], 3, [1,1], 1>;
403defm : JWriteResYMMPair<WriteCvtPD2PSY,   [JFPU1, JSTC, JFPX], 6, [2,2,4], 3>;
404defm : X86WriteResPairUnsupported<WriteCvtPD2PSZ>;
405
406defm : JWriteResFpuPair<WriteCvtPH2PS,     [JFPU1, JSTC], 3, [1,1], 1>;
407defm : JWriteResYMMPair<WriteCvtPH2PSY,    [JFPU1, JSTC], 3, [2,2], 2>;
408defm : X86WriteResPairUnsupported<WriteCvtPH2PSZ>;
409
410defm : X86WriteRes<WriteCvtPS2PH,                 [JFPU1, JSTC], 3, [1,1], 1>;
411defm : X86WriteRes<WriteCvtPS2PHY,          [JFPU1, JSTC, JFPX], 6, [2,2,2], 3>;
412defm : X86WriteResUnsupported<WriteCvtPS2PHZ>;
413defm : X86WriteRes<WriteCvtPS2PHSt,        [JFPU1, JSTC, JSAGU], 4, [1,1,1], 1>;
414defm : X86WriteRes<WriteCvtPS2PHYSt, [JFPU1, JSTC, JFPX, JSAGU], 7, [2,2,2,1], 3>;
415defm : X86WriteResUnsupported<WriteCvtPS2PHZSt>;
416
417////////////////////////////////////////////////////////////////////////////////
418// Vector integer operations.
419////////////////////////////////////////////////////////////////////////////////
420
421defm : X86WriteRes<WriteVecLoad,          [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
422defm : X86WriteRes<WriteVecLoadX,         [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
423defm : X86WriteRes<WriteVecLoadY,         [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
424defm : X86WriteRes<WriteVecLoadNT,        [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
425defm : X86WriteRes<WriteVecLoadNTY,       [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
426defm : X86WriteRes<WriteVecMaskedLoad,    [JLAGU, JFPU01, JVALU], 6, [1, 1, 2], 1>;
427defm : X86WriteRes<WriteVecMaskedLoadY,   [JLAGU, JFPU01, JVALU], 6, [2, 2, 4], 2>;
428
429defm : X86WriteRes<WriteVecStore,         [JSAGU, JFPU1,   JSTC], 2, [1, 1, 1], 1>;
430defm : X86WriteRes<WriteVecStoreX,        [JSAGU, JFPU1,   JSTC], 1, [1, 1, 1], 1>;
431defm : X86WriteRes<WriteVecStoreY,        [JSAGU, JFPU1,   JSTC], 1, [1, 1, 1], 1>;
432defm : X86WriteRes<WriteVecStoreNT,       [JSAGU, JFPU1,   JSTC], 2, [1, 1, 1], 1>;
433defm : X86WriteRes<WriteVecStoreNTY,      [JSAGU, JFPU1,   JSTC], 2, [2, 2, 2], 1>;
434defm : X86WriteRes<WriteVecMaskedStore,   [JSAGU, JFPU01, JVALU], 6, [1, 1, 4], 1>;
435defm : X86WriteRes<WriteVecMaskedStoreY,  [JSAGU, JFPU01, JVALU], 6, [2, 2, 4], 2>;
436
437defm : X86WriteRes<WriteVecMove,          [JFPU01, JVALU], 1, [1, 1], 1>;
438defm : X86WriteRes<WriteVecMoveX,         [JFPU01, JVALU], 1, [1, 1], 1>;
439defm : X86WriteRes<WriteVecMoveY,         [JFPU01, JVALU], 1, [2, 2], 2>;
440defm : X86WriteRes<WriteVecMoveToGpr,     [JFPU0, JFPA, JALU0], 4, [1, 1, 1], 1>;
441defm : X86WriteRes<WriteVecMoveFromGpr,   [JFPU01, JFPX], 8, [1, 1], 2>;
442
443defm : JWriteResFpuPair<WriteVecALU,      [JFPU01, JVALU], 1>;
444defm : JWriteResFpuPair<WriteVecALUX,     [JFPU01, JVALU], 1>;
445defm : X86WriteResPairUnsupported<WriteVecALUY>;
446defm : X86WriteResPairUnsupported<WriteVecALUZ>;
447defm : JWriteResFpuPair<WriteVecShift,    [JFPU01, JVALU], 1>;
448defm : JWriteResFpuPair<WriteVecShiftX,   [JFPU01, JVALU], 1>;
449defm : X86WriteResPairUnsupported<WriteVecShiftY>;
450defm : X86WriteResPairUnsupported<WriteVecShiftZ>;
451defm : JWriteResFpuPair<WriteVecShiftImm, [JFPU01, JVALU], 1>;
452defm : JWriteResFpuPair<WriteVecShiftImmX,[JFPU01, JVALU], 1>;
453defm : X86WriteResPairUnsupported<WriteVecShiftImmY>;
454defm : X86WriteResPairUnsupported<WriteVecShiftImmZ>;
455defm : X86WriteResPairUnsupported<WriteVarVecShift>;
456defm : X86WriteResPairUnsupported<WriteVarVecShiftY>;
457defm : X86WriteResPairUnsupported<WriteVarVecShiftZ>;
458defm : JWriteResFpuPair<WriteVecIMul,     [JFPU0, JVIMUL], 2>;
459defm : JWriteResFpuPair<WriteVecIMulX,    [JFPU0, JVIMUL], 2>;
460defm : X86WriteResPairUnsupported<WriteVecIMulY>;
461defm : X86WriteResPairUnsupported<WriteVecIMulZ>;
462defm : JWriteResFpuPair<WritePMULLD,      [JFPU0, JFPU01, JVIMUL, JVALU], 4, [2, 1, 2, 1], 3>;
463defm : X86WriteResPairUnsupported<WritePMULLDY>;
464defm : X86WriteResPairUnsupported<WritePMULLDZ>;
465defm : JWriteResFpuPair<WriteMPSAD,       [JFPU0, JVIMUL], 3, [1, 2]>;
466defm : X86WriteResPairUnsupported<WriteMPSADY>;
467defm : X86WriteResPairUnsupported<WriteMPSADZ>;
468defm : JWriteResFpuPair<WritePSADBW,      [JFPU01, JVALU], 2>;
469defm : JWriteResFpuPair<WritePSADBWX,     [JFPU01, JVALU], 2>;
470defm : X86WriteResPairUnsupported<WritePSADBWY>;
471defm : X86WriteResPairUnsupported<WritePSADBWZ>;
472defm : JWriteResFpuPair<WritePHMINPOS,    [JFPU0,  JVALU], 2>;
473defm : JWriteResFpuPair<WriteShuffle,     [JFPU01, JVALU], 1>;
474defm : JWriteResFpuPair<WriteShuffleX,    [JFPU01, JVALU], 1>;
475defm : X86WriteResPairUnsupported<WriteShuffleY>;
476defm : X86WriteResPairUnsupported<WriteShuffleZ>;
477defm : JWriteResFpuPair<WriteVarShuffle,  [JFPU01, JVALU], 2, [1, 4], 3>;
478defm : JWriteResFpuPair<WriteVarShuffleX, [JFPU01, JVALU], 2, [1, 4], 3>;
479defm : X86WriteResPairUnsupported<WriteVarShuffleY>;
480defm : X86WriteResPairUnsupported<WriteVarShuffleZ>;
481defm : JWriteResFpuPair<WriteBlend,       [JFPU01, JVALU], 1>;
482defm : X86WriteResPairUnsupported<WriteBlendY>;
483defm : X86WriteResPairUnsupported<WriteBlendZ>;
484defm : JWriteResFpuPair<WriteVarBlend,    [JFPU01, JVALU], 2, [1, 4], 3>;
485defm : X86WriteResPairUnsupported<WriteVarBlendY>;
486defm : X86WriteResPairUnsupported<WriteVarBlendZ>;
487defm : JWriteResFpuPair<WriteVecLogic,    [JFPU01, JVALU], 1>;
488defm : JWriteResFpuPair<WriteVecLogicX,   [JFPU01, JVALU], 1>;
489defm : X86WriteResPairUnsupported<WriteVecLogicY>;
490defm : X86WriteResPairUnsupported<WriteVecLogicZ>;
491defm : JWriteResFpuPair<WriteVecTest,     [JFPU0, JFPA, JALU0], 3>;
492defm : JWriteResYMMPair<WriteVecTestY,    [JFPU01, JFPX, JFPA, JALU0], 4, [2, 2, 2, 1], 3>;
493defm : X86WriteResPairUnsupported<WriteVecTestZ>;
494defm : X86WriteResPairUnsupported<WriteShuffle256>;
495defm : X86WriteResPairUnsupported<WriteVarShuffle256>;
496
497////////////////////////////////////////////////////////////////////////////////
498// Vector insert/extract operations.
499////////////////////////////////////////////////////////////////////////////////
500
501defm : X86WriteRes<WriteVecInsert,      [JFPU01, JVALU], 7, [1,1], 2>;
502defm : X86WriteRes<WriteVecInsertLd,    [JFPU01, JVALU, JLAGU], 4, [1,1,1], 1>;
503defm : X86WriteRes<WriteVecExtract,     [JFPU0, JFPA, JALU0], 3, [1,1,1], 1>;
504defm : X86WriteRes<WriteVecExtractSt,   [JFPU1, JSTC, JSAGU], 3, [1,1,1], 1>;
505
506////////////////////////////////////////////////////////////////////////////////
507// SSE42 String instructions.
508////////////////////////////////////////////////////////////////////////////////
509
510defm : JWriteResFpuPair<WritePCmpIStrI, [JFPU1, JVALU1, JFPA, JALU0], 7, [1, 2, 1, 1], 3>;
511defm : JWriteResFpuPair<WritePCmpIStrM, [JFPU1, JVALU1, JFPA, JALU0], 8, [1, 2, 1, 1], 3>;
512defm : JWriteResFpuPair<WritePCmpEStrI, [JFPU1, JSAGU, JLAGU, JVALU, JVALU1, JFPA, JALU0], 14, [1, 2, 2, 6, 4, 1, 1], 9>;
513defm : JWriteResFpuPair<WritePCmpEStrM, [JFPU1, JSAGU, JLAGU, JVALU, JVALU1, JFPA, JALU0], 14, [1, 2, 2, 6, 4, 1, 1], 9>;
514
515////////////////////////////////////////////////////////////////////////////////
516// MOVMSK Instructions.
517////////////////////////////////////////////////////////////////////////////////
518
519def  : WriteRes<WriteFMOVMSK,    [JFPU0, JFPA, JALU0]> { let Latency = 3; }
520def  : WriteRes<WriteVecMOVMSK,  [JFPU0, JFPA, JALU0]> { let Latency = 3; }
521defm : X86WriteResUnsupported<WriteVecMOVMSKY>;
522def  : WriteRes<WriteMMXMOVMSK,  [JFPU0, JFPA, JALU0]> { let Latency = 3; }
523
524////////////////////////////////////////////////////////////////////////////////
525// AES Instructions.
526////////////////////////////////////////////////////////////////////////////////
527
528defm : JWriteResFpuPair<WriteAESIMC,      [JFPU0, JVIMUL], 2>;
529defm : JWriteResFpuPair<WriteAESKeyGen,   [JFPU0, JVIMUL], 2>;
530defm : JWriteResFpuPair<WriteAESDecEnc,   [JFPU0, JVIMUL], 3, [1, 1], 2>;
531
532////////////////////////////////////////////////////////////////////////////////
533// Horizontal add/sub  instructions.
534////////////////////////////////////////////////////////////////////////////////
535
536defm : JWriteResFpuPair<WriteFHAdd,         [JFPU0, JFPA], 3>;
537defm : JWriteResYMMPair<WriteFHAddY,        [JFPU0, JFPA], 3, [2,2], 2>;
538defm : JWriteResFpuPair<WritePHAdd,       [JFPU01, JVALU], 1>;
539defm : JWriteResFpuPair<WritePHAddX,      [JFPU01, JVALU], 1>;
540defm : X86WriteResPairUnsupported<WritePHAddY>;
541
542////////////////////////////////////////////////////////////////////////////////
543// Carry-less multiplication instructions.
544////////////////////////////////////////////////////////////////////////////////
545
546defm : JWriteResFpuPair<WriteCLMul,       [JFPU0, JVIMUL], 2>;
547
548////////////////////////////////////////////////////////////////////////////////
549// SSE4A instructions.
550////////////////////////////////////////////////////////////////////////////////
551
552def JWriteINSERTQ: SchedWriteRes<[JFPU01, JVALU]> {
553  let Latency = 2;
554  let ResourceCycles = [1, 4];
555}
556def : InstRW<[JWriteINSERTQ], (instrs INSERTQ, INSERTQI)>;
557
558////////////////////////////////////////////////////////////////////////////////
559// AVX instructions.
560////////////////////////////////////////////////////////////////////////////////
561
562def JWriteVBROADCASTYLd: SchedWriteRes<[JLAGU, JFPU01, JFPX]> {
563  let Latency = 6;
564  let ResourceCycles = [1, 2, 4];
565  let NumMicroOps = 2;
566}
567def : InstRW<[JWriteVBROADCASTYLd, ReadAfterLd], (instrs VBROADCASTSDYrm,
568                                                         VBROADCASTSSYrm)>;
569
570def JWriteJVZEROALL: SchedWriteRes<[]> {
571  let Latency = 90;
572  let NumMicroOps = 73;
573}
574def : InstRW<[JWriteJVZEROALL], (instrs VZEROALL)>;
575
576def JWriteJVZEROUPPER: SchedWriteRes<[]> {
577  let Latency = 46;
578  let NumMicroOps = 37;
579}
580def : InstRW<[JWriteJVZEROUPPER], (instrs VZEROUPPER)>;
581
582///////////////////////////////////////////////////////////////////////////////
583//  SchedWriteVariant definitions.
584///////////////////////////////////////////////////////////////////////////////
585
586def JWriteZeroLatency : SchedWriteRes<[]> {
587  let Latency = 0;
588}
589
590// Certain instructions that use the same register for both source
591// operands do not have a real dependency on the previous contents of the
592// register, and thus, do not have to wait before completing. They can be
593// optimized out at register renaming stage.
594// Reference: Section 10.8 of the "Software Optimization Guide for AMD Family
595// 15h Processors".
596// Reference: Agner's Fog "The microarchitecture of Intel, AMD and VIA CPUs",
597// Section 21.8 [Dependency-breaking instructions].
598
599def JWriteZeroIdiom : SchedWriteVariant<[
600    SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
601    SchedVar<MCSchedPredicate<TruePred>,           [WriteALU]>
602]>;
603def : InstRW<[JWriteZeroIdiom], (instrs SUB32rr, SUB64rr,
604                                        XOR32rr, XOR64rr)>;
605
606def JWriteFZeroIdiom : SchedWriteVariant<[
607    SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
608    SchedVar<MCSchedPredicate<TruePred>,           [WriteFLogic]>
609]>;
610def : InstRW<[JWriteFZeroIdiom], (instrs XORPSrr, VXORPSrr, XORPDrr, VXORPDrr,
611                                         ANDNPSrr, VANDNPSrr,
612                                         ANDNPDrr, VANDNPDrr)>;
613
614def JWriteVZeroIdiomLogic : SchedWriteVariant<[
615    SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
616    SchedVar<MCSchedPredicate<TruePred>,           [WriteVecLogic]>
617]>;
618def : InstRW<[JWriteVZeroIdiomLogic], (instrs MMX_PXORirr, MMX_PANDNirr)>;
619
620def JWriteVZeroIdiomLogicX : SchedWriteVariant<[
621    SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
622    SchedVar<MCSchedPredicate<TruePred>,           [WriteVecLogicX]>
623]>;
624def : InstRW<[JWriteVZeroIdiomLogicX], (instrs PXORrr, VPXORrr,
625                                               PANDNrr, VPANDNrr)>;
626
627def JWriteVZeroIdiomALU : SchedWriteVariant<[
628    SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
629    SchedVar<MCSchedPredicate<TruePred>,           [WriteVecALU]>
630]>;
631def : InstRW<[JWriteVZeroIdiomALU], (instrs MMX_PSUBBirr, MMX_PSUBDirr,
632                                            MMX_PSUBQirr, MMX_PSUBWirr,
633                                            MMX_PCMPGTBirr, MMX_PCMPGTDirr,
634                                            MMX_PCMPGTWirr)>;
635
636def JWriteVZeroIdiomALUX : SchedWriteVariant<[
637    SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
638    SchedVar<MCSchedPredicate<TruePred>,           [WriteVecALUX]>
639]>;
640def : InstRW<[JWriteVZeroIdiomALUX], (instrs PSUBBrr, VPSUBBrr,
641                                             PSUBDrr, VPSUBDrr,
642                                             PSUBQrr, VPSUBQrr,
643                                             PSUBWrr, VPSUBWrr,
644                                             PCMPGTBrr, VPCMPGTBrr,
645                                             PCMPGTDrr, VPCMPGTDrr,
646                                             PCMPGTQrr, VPCMPGTQrr,
647                                             PCMPGTWrr, VPCMPGTWrr)>;
648
649// This write is used for slow LEA instructions.
650def JWrite3OpsLEA : SchedWriteRes<[JALU1, JSAGU]> {
651  let Latency = 2;
652}
653
654// On Jaguar, a slow LEA is either a 3Ops LEA (base, index, offset), or an LEA
655// with a `Scale` value different than 1.
656def JSlowLEAPredicate : MCSchedPredicate<
657  CheckAny<[
658    // A 3-operand LEA (base, index, offset).
659    IsThreeOperandsLEAFn,
660    // An LEA with a "Scale" different than 1.
661    CheckAll<[
662      CheckIsImmOperand<2>,
663      CheckNot<CheckImmOperand<2, 1>>
664    ]>
665  ]>
666>;
667
668def JWriteLEA : SchedWriteVariant<[
669    SchedVar<JSlowLEAPredicate,          [JWrite3OpsLEA]>,
670    SchedVar<MCSchedPredicate<TruePred>, [WriteLEA]>
671]>;
672
673def : InstRW<[JWriteLEA], (instrs LEA32r, LEA64r, LEA64_32r)>;
674
675def JSlowLEA16r : SchedWriteRes<[JALU01]> {
676  let Latency = 3;
677  let ResourceCycles = [4];
678}
679
680def : InstRW<[JSlowLEA16r], (instrs LEA16r)>;
681
682} // SchedModel
683