Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / lib / Target / X86 / X86ScheduleBtVer2.td
blob7931a956b52516a58c72a1d6d1c30d709f8f3420
1 //=- X86ScheduleBtVer2.td - X86 BtVer2 (Jaguar) 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 AMD btver2 (Jaguar) to support
10 // instruction scheduling and other instruction cost heuristics. Based off AMD Software
11 // Optimization Guide for AMD Family 16h Processors & Instruction Latency appendix.
13 //===----------------------------------------------------------------------===//
15 def BtVer2Model : SchedMachineModel {
16   // All x86 instructions are modeled as a single micro-op, and btver2 can
17   // decode 2 instructions per cycle.
18   let IssueWidth = 2;
19   let MicroOpBufferSize = 64; // Retire Control Unit
20   let LoadLatency = 5; // FPU latency (worse case cf Integer 3 cycle latency)
21   let HighLatency = 25;
22   let MispredictPenalty = 14; // Minimum branch misdirection penalty
23   let PostRAScheduler = 1;
25   // FIXME: SSE4/AVX is unimplemented. This flag is set to allow
26   // the scheduler to assign a default model to unrecognized opcodes.
27   let CompleteModel = 0;
30 let SchedModel = BtVer2Model in {
32 // Jaguar can issue up to 6 micro-ops in one cycle
33 def JALU0 : ProcResource<1>; // Integer Pipe0: integer ALU0 (also handle FP->INT jam)
34 def JALU1 : ProcResource<1>; // Integer Pipe1: integer ALU1/MUL/DIV
35 def JLAGU : ProcResource<1>; // Integer Pipe2: LAGU
36 def JSAGU : ProcResource<1>; // Integer Pipe3: SAGU (also handles 3-operand LEA)
37 def JFPU0 : ProcResource<1>; // Vector/FPU Pipe0: VALU0/VIMUL/FPA
38 def JFPU1 : ProcResource<1>; // Vector/FPU Pipe1: VALU1/STC/FPM
40 // The Integer PRF for Jaguar is 64 entries, and it holds the architectural and
41 // speculative version of the 64-bit integer registers.
42 // Reference: www.realworldtech.com/jaguar/4/
44 // The processor always keeps the different parts of an integer register
45 // together. An instruction that writes to a part of a register will therefore
46 // have a false dependence on any previous write to the same register or any
47 // part of it.
48 // Reference: Section 21.10 "AMD Bobcat and Jaguar pipeline: Partial register
49 // access" - Agner Fog's "microarchitecture.pdf".
50 def JIntegerPRF : RegisterFile<64, [GR64, CCR], [1, 1], [1, 0],
51                                0,  // Max moves that can be eliminated per cycle.
52                                1>; // Restrict move elimination to zero regs.
54 // The Jaguar FP Retire Queue renames SIMD and FP uOps onto a pool of 72 SSE
55 // registers. Operations on 256-bit data types are cracked into two COPs.
56 // Reference: www.realworldtech.com/jaguar/4/
58 // The PRF in the floating point unit can eliminate a move from a MMX or SSE
59 // register that is know to be zero (i.e. it has been zeroed using a zero-idiom
60 // dependency breaking instruction, or via VZEROALL).
61 // Reference: Section 21.8 "AMD Bobcat and Jaguar pipeline: Dependency-breaking
62 // instructions" - Agner Fog's "microarchitecture.pdf"
63 def JFpuPRF: RegisterFile<72, [VR64, VR128, VR256], [1, 1, 2], [1, 1, 0],
64                           0,  // Max moves that can be eliminated per cycle.
65                           1>; // Restrict move elimination to zero regs.
67 // The retire control unit (RCU) can track up to 64 macro-ops in-flight. It can
68 // retire up to two macro-ops per cycle.
69 // Reference: "Software Optimization Guide for AMD Family 16h Processors"
70 def JRCU : RetireControlUnit<64, 2>;
72 // Integer Pipe Scheduler
73 def JALU01 : ProcResGroup<[JALU0, JALU1]> {
74   let BufferSize=20;
77 // AGU Pipe Scheduler
78 def JLSAGU : ProcResGroup<[JLAGU, JSAGU]> {
79   let BufferSize=12;
82 // Fpu Pipe Scheduler
83 def JFPU01 : ProcResGroup<[JFPU0, JFPU1]> {
84   let BufferSize=18;
87 // Functional units
88 def JDiv    : ProcResource<1>; // integer division
89 def JMul    : ProcResource<1>; // integer multiplication
90 def JVALU0  : ProcResource<1>; // vector integer
91 def JVALU1  : ProcResource<1>; // vector integer
92 def JVIMUL  : ProcResource<1>; // vector integer multiplication
93 def JSTC    : ProcResource<1>; // vector store/convert
94 def JFPM    : ProcResource<1>; // FP multiplication
95 def JFPA    : ProcResource<1>; // FP addition
97 // Functional unit groups
98 def JFPX  : ProcResGroup<[JFPA, JFPM]>;
99 def JVALU : ProcResGroup<[JVALU0, JVALU1]>;
101 // Integer loads are 3 cycles, so ReadAfterLd registers needn't be available until 3
102 // cycles after the memory operand.
103 def : ReadAdvance<ReadAfterLd, 3>;
105 // Vector loads are 5 cycles, so ReadAfterVec*Ld registers needn't be available until 5
106 // cycles after the memory operand.
107 def : ReadAdvance<ReadAfterVecLd, 5>;
108 def : ReadAdvance<ReadAfterVecXLd, 5>;
109 def : ReadAdvance<ReadAfterVecYLd, 5>;
111 /// "Additional 6 cycle transfer operation which moves a floating point
112 /// operation input value from the integer unit to the floating point unit.
113 /// Reference: AMDfam16h SOG (Appendix A "Instruction Latencies", Section A.2).
114 def : ReadAdvance<ReadInt2Fpu, -6>;
116 // Many SchedWrites are defined in pairs with and without a folded load.
117 // Instructions with folded loads are usually micro-fused, so they only appear
118 // as two micro-ops when dispatched by the schedulers.
119 // This multiclass defines the resource usage for variants with and without
120 // folded loads.
121 multiclass JWriteResIntPair<X86FoldableSchedWrite SchedRW,
122                             list<ProcResourceKind> ExePorts,
123                             int Lat, list<int> Res = [], int UOps = 1,
124                             int LoadUOps = 0> {
125   // Register variant is using a single cycle on ExePort.
126   def : WriteRes<SchedRW, ExePorts> {
127     let Latency = Lat;
128     let ResourceCycles = Res;
129     let NumMicroOps = UOps;
130   }
132   // Memory variant also uses a cycle on JLAGU and adds 3 cycles to the
133   // latency.
134   def : WriteRes<SchedRW.Folded, !listconcat([JLAGU], ExePorts)> {
135     let Latency = !add(Lat, 3);
136     let ResourceCycles = !if(!empty(Res), [], !listconcat([1], Res));
137     let NumMicroOps = !add(UOps, LoadUOps);
138   }
141 multiclass JWriteResFpuPair<X86FoldableSchedWrite SchedRW,
142                             list<ProcResourceKind> ExePorts,
143                             int Lat, list<int> Res = [], int UOps = 1,
144                             int LoadUOps = 0> {
145   // Register variant is using a single cycle on ExePort.
146   def : WriteRes<SchedRW, ExePorts> {
147     let Latency = Lat;
148     let ResourceCycles = Res;
149     let NumMicroOps = UOps;
150   }
152   // Memory variant also uses a cycle on JLAGU and adds 5 cycles to the
153   // latency.
154   def : WriteRes<SchedRW.Folded, !listconcat([JLAGU], ExePorts)> {
155     let Latency = !add(Lat, 5);
156     let ResourceCycles = !if(!empty(Res), [], !listconcat([1], Res));
157     let NumMicroOps = !add(UOps, LoadUOps);
158   }
161 multiclass JWriteResYMMPair<X86FoldableSchedWrite SchedRW,
162                             list<ProcResourceKind> ExePorts,
163                             int Lat, list<int> Res = [2], int UOps = 2,
164                             int LoadUOps = 0> {
165   // Register variant is using a single cycle on ExePort.
166   def : WriteRes<SchedRW, ExePorts> {
167     let Latency = Lat;
168     let ResourceCycles = Res;
169     let NumMicroOps = UOps;
170   }
172   // Memory variant also uses 2 cycles on JLAGU and adds 5 cycles to the
173   // latency.
174   def : WriteRes<SchedRW.Folded, !listconcat([JLAGU], ExePorts)> {
175     let Latency = !add(Lat, 5);
176     let ResourceCycles = !listconcat([2], Res);
177     let NumMicroOps = !add(UOps, LoadUOps);
178   }
181 // Instructions that have local forwarding disabled have an extra +1cy latency.
183 // A folded store needs a cycle on the SAGU for the store data,
184 // most RMW instructions don't need an extra uop.
185 defm : X86WriteRes<WriteRMW, [JSAGU], 1, [1], 0>;
187 ////////////////////////////////////////////////////////////////////////////////
188 // Arithmetic.
189 ////////////////////////////////////////////////////////////////////////////////
191 defm : JWriteResIntPair<WriteALU,    [JALU01], 1>;
192 defm : JWriteResIntPair<WriteADC,    [JALU01], 1, [2]>;
194 defm : X86WriteRes<WriteBSWAP32, [JALU01], 1, [1], 1>;
195 defm : X86WriteRes<WriteBSWAP64, [JALU01], 1, [1], 1>;
196 defm : X86WriteRes<WriteCMPXCHG,[JALU01], 1, [1], 1>;
197 defm : X86WriteRes<WriteCMPXCHGRMW,[JALU01, JSAGU, JLAGU], 4, [1, 1, 1], 2>;
198 defm : X86WriteRes<WriteXCHG,        [JALU01], 1, [1], 1>;
200 defm : JWriteResIntPair<WriteIMul8,     [JALU1, JMul], 3, [1, 1], 2>;
201 defm : JWriteResIntPair<WriteIMul16,    [JALU1, JMul], 3, [1, 1], 2>;
202 defm : JWriteResIntPair<WriteIMul16Imm, [JALU1, JMul], 3, [1, 1], 2>;
203 defm : JWriteResIntPair<WriteIMul16Reg, [JALU1, JMul], 3, [1, 1], 2>;
204 defm : JWriteResIntPair<WriteIMul32,    [JALU1, JMul], 3, [1, 1], 2>;
205 defm : JWriteResIntPair<WriteIMul32Imm, [JALU1, JMul], 3, [1, 1], 2>;
206 defm : JWriteResIntPair<WriteIMul32Reg, [JALU1, JMul], 3, [1, 1], 2>;
207 defm : JWriteResIntPair<WriteIMul64,    [JALU1, JMul], 6, [1, 4], 2>;
208 defm : JWriteResIntPair<WriteIMul64Imm, [JALU1, JMul], 6, [1, 4], 2>;
209 defm : JWriteResIntPair<WriteIMul64Reg, [JALU1, JMul], 6, [1, 4], 2>;
210 defm : X86WriteRes<WriteIMulH,          [JALU1], 6, [4], 1>;
212 defm : JWriteResIntPair<WriteDiv8,   [JALU1, JDiv], 12, [1, 12], 1>;
213 defm : JWriteResIntPair<WriteDiv16,  [JALU1, JDiv], 17, [1, 17], 2>;
214 defm : JWriteResIntPair<WriteDiv32,  [JALU1, JDiv], 25, [1, 25], 2>;
215 defm : JWriteResIntPair<WriteDiv64,  [JALU1, JDiv], 41, [1, 41], 2>;
216 defm : JWriteResIntPair<WriteIDiv8,  [JALU1, JDiv], 12, [1, 12], 1>;
217 defm : JWriteResIntPair<WriteIDiv16, [JALU1, JDiv], 17, [1, 17], 2>;
218 defm : JWriteResIntPair<WriteIDiv32, [JALU1, JDiv], 25, [1, 25], 2>;
219 defm : JWriteResIntPair<WriteIDiv64, [JALU1, JDiv], 41, [1, 41], 2>;
221 defm : JWriteResIntPair<WriteCRC32,  [JALU01], 3, [4], 3>;
223 defm : JWriteResIntPair<WriteCMOV,  [JALU01], 1>; // Conditional move.
224 defm : JWriteResIntPair<WriteCMOV2, [JALU01], 1>; // Conditional (CF + ZF flag) move.
225 defm : X86WriteRes<WriteFCMOV, [JFPU0, JFPA], 3, [1,1], 1>; // x87 conditional move.
226 def  : WriteRes<WriteSETCC, [JALU01]>; // Setcc.
227 def  : WriteRes<WriteSETCCStore, [JALU01,JSAGU]>;
228 def  : WriteRes<WriteLAHFSAHF, [JALU01]>;
230 defm : X86WriteRes<WriteBitTest,         [JALU01], 1, [1], 1>;
231 defm : X86WriteRes<WriteBitTestImmLd,    [JALU01,JLAGU], 4, [1,1], 1>;
232 defm : X86WriteRes<WriteBitTestRegLd,    [JALU01,JLAGU], 4, [1,1], 5>;
233 defm : X86WriteRes<WriteBitTestSet,      [JALU01], 1, [1], 2>;
234 defm : X86WriteRes<WriteBitTestSetImmLd, [JALU01,JLAGU], 4, [1,1], 4>;
235 defm : X86WriteRes<WriteBitTestSetRegLd, [JALU01,JLAGU], 4, [1,1], 8>;
237 // This is for simple LEAs with one or two input operands.
238 def : WriteRes<WriteLEA, [JALU01]>;
240 // Bit counts.
241 defm : JWriteResIntPair<WriteBSF, [JALU01], 4, [8], 7>;
242 defm : JWriteResIntPair<WriteBSR, [JALU01], 5, [8], 8>;
243 defm : JWriteResIntPair<WritePOPCNT,         [JALU01], 1>;
244 defm : JWriteResIntPair<WriteLZCNT,          [JALU01], 1>;
245 defm : JWriteResIntPair<WriteTZCNT,          [JALU01], 2, [2], 2>;
247 // BMI1 BEXTR/BLS, BMI2 BZHI
248 defm : JWriteResIntPair<WriteBEXTR, [JALU01], 1>;
249 defm : JWriteResIntPair<WriteBLS,   [JALU01], 2, [2], 2>;
250 defm : X86WriteResPairUnsupported<WriteBZHI>;
252 ////////////////////////////////////////////////////////////////////////////////
253 // Integer shifts and rotates.
254 ////////////////////////////////////////////////////////////////////////////////
256 defm : JWriteResIntPair<WriteShift,    [JALU01], 1>;
257 defm : JWriteResIntPair<WriteShiftCL,  [JALU01], 1>;
258 defm : JWriteResIntPair<WriteRotate,   [JALU01], 1>;
259 defm : JWriteResIntPair<WriteRotateCL, [JALU01], 1>;
261 // SHLD/SHRD.
262 defm : X86WriteRes<WriteSHDrri, [JALU01], 3, [6], 6>;
263 defm : X86WriteRes<WriteSHDrrcl,[JALU01], 4, [8], 7>;
264 defm : X86WriteRes<WriteSHDmri, [JLAGU, JALU01], 9, [1, 22], 8>;
265 defm : X86WriteRes<WriteSHDmrcl,[JLAGU, JALU01], 9, [1, 22], 8>;
267 ////////////////////////////////////////////////////////////////////////////////
268 // Loads, stores, and moves, not folded with other operations.
269 ////////////////////////////////////////////////////////////////////////////////
271 def : WriteRes<WriteLoad,    [JLAGU]> { let Latency = 3; }
272 def : WriteRes<WriteStore,   [JSAGU]>;
273 def : WriteRes<WriteStoreNT, [JSAGU]>;
274 def : WriteRes<WriteMove,    [JALU01]>;
276 // Load/store MXCSR.
277 def : WriteRes<WriteLDMXCSR, [JLAGU]> { let Latency = 3; }
278 def : WriteRes<WriteSTMXCSR, [JSAGU]>;
280 // Treat misc copies as a move.
281 def : InstRW<[WriteMove], (instrs COPY)>;
283 ////////////////////////////////////////////////////////////////////////////////
284 // Idioms that clear a register, like xorps %xmm0, %xmm0.
285 // These can often bypass execution ports completely.
286 ////////////////////////////////////////////////////////////////////////////////
288 def : WriteRes<WriteZero,  []>;
290 ////////////////////////////////////////////////////////////////////////////////
291 // Branches don't produce values, so they have no latency, but they still
292 // consume resources. Indirect branches can fold loads.
293 ////////////////////////////////////////////////////////////////////////////////
295 defm : JWriteResIntPair<WriteJump,  [JALU01], 1>;
297 ////////////////////////////////////////////////////////////////////////////////
298 // Special case scheduling classes.
299 ////////////////////////////////////////////////////////////////////////////////
301 def : WriteRes<WriteSystem,     [JALU01]> { let Latency = 100; }
302 def : WriteRes<WriteMicrocoded, [JALU01]> { let Latency = 100; }
303 def : WriteRes<WriteFence,  [JSAGU]>;
305 // Nops don't have dependencies, so there's no actual latency, but we set this
306 // to '1' to tell the scheduler that the nop uses an ALU slot for a cycle.
307 def : WriteRes<WriteNop, [JALU01]> { let Latency = 1; }
309 ////////////////////////////////////////////////////////////////////////////////
310 // Floating point. This covers both scalar and vector operations.
311 ////////////////////////////////////////////////////////////////////////////////
313 defm : X86WriteRes<WriteFLD0,          [JFPU1, JSTC], 3, [1,1], 1>;
314 defm : X86WriteRes<WriteFLD1,          [JFPU1, JSTC], 3, [1,1], 1>;
315 defm : X86WriteRes<WriteFLDC,          [JFPU1, JSTC], 3, [1,1], 1>;
316 defm : X86WriteRes<WriteFLoad,         [JLAGU, JFPU01, JFPX], 5, [1, 1, 1], 1>;
317 defm : X86WriteRes<WriteFLoadX,        [JLAGU, JFPU01, JFPX], 5, [1, 1, 1], 1>;
318 defm : X86WriteRes<WriteFLoadY,        [JLAGU, JFPU01, JFPX], 5, [1, 1, 1], 1>;
319 defm : X86WriteRes<WriteFMaskedLoad,   [JLAGU, JFPU01, JFPX], 6, [1, 2, 2], 1>;
320 defm : X86WriteRes<WriteFMaskedLoadY,  [JLAGU, JFPU01, JFPX], 6, [2, 4, 4], 2>;
322 defm : X86WriteRes<WriteFStore,        [JSAGU, JFPU1,  JSTC], 2, [1, 1, 1], 1>;
323 defm : X86WriteRes<WriteFStoreX,       [JSAGU, JFPU1,  JSTC], 1, [1, 1, 1], 1>;
324 defm : X86WriteRes<WriteFStoreY,       [JSAGU, JFPU1,  JSTC], 1, [1, 1, 1], 1>;
325 defm : X86WriteRes<WriteFStoreNT,      [JSAGU, JFPU1,  JSTC], 3, [1, 1, 1], 1>;
326 defm : X86WriteRes<WriteFStoreNTX,     [JSAGU, JFPU1,  JSTC], 3, [1, 1, 1], 1>;
327 defm : X86WriteRes<WriteFStoreNTY,     [JSAGU, JFPU1,  JSTC], 3, [2, 2, 2], 1>;
328 defm : X86WriteRes<WriteFMaskedStore,  [JSAGU, JFPU01, JFPX], 6, [1, 1, 4], 1>;
329 defm : X86WriteRes<WriteFMaskedStoreY, [JSAGU, JFPU01, JFPX], 6, [2, 2, 4], 2>;
331 defm : X86WriteRes<WriteFMove,         [JFPU01, JFPX], 1, [1, 1], 1>;
332 defm : X86WriteRes<WriteFMoveX,        [JFPU01, JFPX], 1, [1, 1], 1>;
333 defm : X86WriteRes<WriteFMoveY,        [JFPU01, JFPX], 1, [2, 2], 2>;
335 defm : X86WriteRes<WriteEMMS,          [JFPU01, JFPX], 2, [1, 1], 1>;
337 defm : JWriteResFpuPair<WriteFAdd,         [JFPU0, JFPA],  3>;
338 defm : JWriteResFpuPair<WriteFAddX,        [JFPU0, JFPA],  3>;
339 defm : JWriteResYMMPair<WriteFAddY,        [JFPU0, JFPA],  3, [2,2], 2>;
340 defm : X86WriteResPairUnsupported<WriteFAddZ>;
341 defm : JWriteResFpuPair<WriteFAdd64,       [JFPU0, JFPA],  3>;
342 defm : JWriteResFpuPair<WriteFAdd64X,      [JFPU0, JFPA],  3>;
343 defm : JWriteResYMMPair<WriteFAdd64Y,      [JFPU0, JFPA],  3, [2,2], 2>;
344 defm : X86WriteResPairUnsupported<WriteFAdd64Z>;
345 defm : JWriteResFpuPair<WriteFCmp,         [JFPU0, JFPA],  2>;
346 defm : JWriteResFpuPair<WriteFCmpX,        [JFPU0, JFPA],  2>;
347 defm : JWriteResYMMPair<WriteFCmpY,        [JFPU0, JFPA],  2, [2,2], 2>;
348 defm : X86WriteResPairUnsupported<WriteFCmpZ>;
349 defm : JWriteResFpuPair<WriteFCmp64,       [JFPU0, JFPA],  2>;
350 defm : JWriteResFpuPair<WriteFCmp64X,      [JFPU0, JFPA],  2>;
351 defm : JWriteResYMMPair<WriteFCmp64Y,      [JFPU0, JFPA],  2, [2,2], 2>;
352 defm : X86WriteResPairUnsupported<WriteFCmp64Z>;
353 defm : JWriteResFpuPair<WriteFCom,  [JFPU0, JFPA, JALU0],  3>;
354 defm : JWriteResFpuPair<WriteFMul,         [JFPU1, JFPM],  2>;
355 defm : JWriteResFpuPair<WriteFMulX,        [JFPU1, JFPM],  2>;
356 defm : JWriteResYMMPair<WriteFMulY,        [JFPU1, JFPM],  2, [2,2], 2>;
357 defm : X86WriteResPairUnsupported<WriteFMulZ>;
358 defm : JWriteResFpuPair<WriteFMul64,       [JFPU1, JFPM],  4, [1,2]>;
359 defm : JWriteResFpuPair<WriteFMul64X,      [JFPU1, JFPM],  4, [1,2]>;
360 defm : JWriteResYMMPair<WriteFMul64Y,      [JFPU1, JFPM],  4, [2,4], 2>;
361 defm : X86WriteResPairUnsupported<WriteFMul64Z>;
362 defm : X86WriteResPairUnsupported<WriteFMA>;
363 defm : X86WriteResPairUnsupported<WriteFMAX>;
364 defm : X86WriteResPairUnsupported<WriteFMAY>;
365 defm : X86WriteResPairUnsupported<WriteFMAZ>;
366 defm : JWriteResFpuPair<WriteDPPD,   [JFPU1, JFPM, JFPA],  9, [1, 3, 3],  3>;
367 defm : JWriteResFpuPair<WriteDPPS,   [JFPU1, JFPM, JFPA], 11, [1, 3, 3],  5>;
368 defm : JWriteResYMMPair<WriteDPPSY,  [JFPU1, JFPM, JFPA], 12, [2, 6, 6], 10>;
369 defm : X86WriteResPairUnsupported<WriteDPPSZ>;
370 defm : JWriteResFpuPair<WriteFRcp,         [JFPU1, JFPM],  2>;
371 defm : JWriteResFpuPair<WriteFRcpX,        [JFPU1, JFPM],  2>;
372 defm : JWriteResYMMPair<WriteFRcpY,        [JFPU1, JFPM],  2, [2,2], 2>;
373 defm : X86WriteResPairUnsupported<WriteFRcpZ>;
374 defm : JWriteResFpuPair<WriteFRsqrt,       [JFPU1, JFPM],  2>;
375 defm : JWriteResFpuPair<WriteFRsqrtX,      [JFPU1, JFPM],  2>;
376 defm : JWriteResYMMPair<WriteFRsqrtY,      [JFPU1, JFPM],  2, [2,2], 2>;
377 defm : X86WriteResPairUnsupported<WriteFRsqrtZ>;
378 defm : JWriteResFpuPair<WriteFDiv,         [JFPU1, JFPM], 19, [1, 19]>;
379 defm : JWriteResFpuPair<WriteFDivX,        [JFPU1, JFPM], 19, [1, 19]>;
380 defm : JWriteResYMMPair<WriteFDivY,        [JFPU1, JFPM], 38, [2, 38], 2>;
381 defm : X86WriteResPairUnsupported<WriteFDivZ>;
382 defm : JWriteResFpuPair<WriteFDiv64,       [JFPU1, JFPM], 19, [1, 19]>;
383 defm : JWriteResFpuPair<WriteFDiv64X,      [JFPU1, JFPM], 19, [1, 19]>;
384 defm : JWriteResYMMPair<WriteFDiv64Y,      [JFPU1, JFPM], 38, [2, 38], 2>;
385 defm : X86WriteResPairUnsupported<WriteFDiv64Z>;
386 defm : JWriteResFpuPair<WriteFSqrt,        [JFPU1, JFPM], 21, [1, 21]>;
387 defm : JWriteResFpuPair<WriteFSqrtX,       [JFPU1, JFPM], 21, [1, 21]>;
388 defm : JWriteResYMMPair<WriteFSqrtY,       [JFPU1, JFPM], 42, [2, 42], 2>;
389 defm : X86WriteResPairUnsupported<WriteFSqrtZ>;
390 defm : JWriteResFpuPair<WriteFSqrt64,      [JFPU1, JFPM], 27, [1, 27]>;
391 defm : JWriteResFpuPair<WriteFSqrt64X,     [JFPU1, JFPM], 27, [1, 27]>;
392 defm : JWriteResYMMPair<WriteFSqrt64Y,     [JFPU1, JFPM], 54, [2, 54], 2>;
393 defm : X86WriteResPairUnsupported<WriteFSqrt64Z>;
394 defm : JWriteResFpuPair<WriteFSqrt80,      [JFPU1, JFPM], 35, [1, 35]>;
395 defm : JWriteResFpuPair<WriteFSign,        [JFPU1, JFPM],  2>;
396 defm : JWriteResFpuPair<WriteFRnd,         [JFPU1, JSTC],  3>;
397 defm : JWriteResYMMPair<WriteFRndY,        [JFPU1, JSTC],  3, [2,2], 2>;
398 defm : X86WriteResPairUnsupported<WriteFRndZ>;
399 defm : JWriteResFpuPair<WriteFLogic,      [JFPU01, JFPX],  1>;
400 defm : JWriteResYMMPair<WriteFLogicY,     [JFPU01, JFPX],  1, [2, 2], 2>;
401 defm : X86WriteResPairUnsupported<WriteFLogicZ>;
402 defm : JWriteResFpuPair<WriteFTest,       [JFPU0, JFPA, JALU0], 3>;
403 defm : JWriteResYMMPair<WriteFTestY ,     [JFPU01, JFPX, JFPA, JALU0], 4, [2, 2, 2, 1], 3>;
404 defm : X86WriteResPairUnsupported<WriteFTestZ>;
405 defm : JWriteResFpuPair<WriteFShuffle,    [JFPU01, JFPX],  1>;
406 defm : JWriteResYMMPair<WriteFShuffleY,   [JFPU01, JFPX],  1, [2, 2], 2>;
407 defm : X86WriteResPairUnsupported<WriteFShuffleZ>;
408 defm : JWriteResFpuPair<WriteFVarShuffle, [JFPU01, JFPX],  3, [1, 4], 3>; // +1cy latency.
409 defm : JWriteResYMMPair<WriteFVarShuffleY,[JFPU01, JFPX],  4, [2, 6], 6>; // +1cy latency.
410 defm : X86WriteResPairUnsupported<WriteFVarShuffleZ>;
411 defm : JWriteResFpuPair<WriteFBlend,      [JFPU01, JFPX],  1>;
412 defm : JWriteResYMMPair<WriteFBlendY,     [JFPU01, JFPX],  1, [2, 2], 2>;
413 defm : X86WriteResPairUnsupported<WriteFBlendZ>;
414 defm : JWriteResFpuPair<WriteFVarBlend,   [JFPU01, JFPX],  2, [4, 4], 3>;
415 defm : JWriteResYMMPair<WriteFVarBlendY,  [JFPU01, JFPX],  3, [6, 6], 6>;
416 defm : X86WriteResPairUnsupported<WriteFVarBlendZ>;
417 defm : JWriteResFpuPair<WriteFShuffle256, [JFPU01, JFPX],  1, [2, 2], 2>;
418 defm : X86WriteResPairUnsupported<WriteFVarShuffle256>;
420 ////////////////////////////////////////////////////////////////////////////////
421 // Conversions.
422 ////////////////////////////////////////////////////////////////////////////////
424 defm : JWriteResFpuPair<WriteCvtSS2I,      [JFPU1, JSTC, JFPU0, JFPA, JALU0], 7, [1,1,1,1,1], 2>;
425 defm : JWriteResFpuPair<WriteCvtPS2I,      [JFPU1, JSTC], 3, [1,1], 1>;
426 defm : JWriteResYMMPair<WriteCvtPS2IY,     [JFPU1, JSTC], 3, [2,2], 2>;
427 defm : X86WriteResPairUnsupported<WriteCvtPS2IZ>;
428 defm : JWriteResFpuPair<WriteCvtSD2I,      [JFPU1, JSTC, JFPU0, JFPA, JALU0], 7, [1,1,1,1,1], 2>;
429 defm : JWriteResFpuPair<WriteCvtPD2I,      [JFPU1, JSTC], 3, [1,1], 1>;
430 defm : JWriteResYMMPair<WriteCvtPD2IY,     [JFPU1, JSTC, JFPX], 6, [2,2,4], 3>;
431 defm : X86WriteResPairUnsupported<WriteCvtPD2IZ>;
433 defm : X86WriteRes<WriteCvtI2SS,           [JFPU1, JSTC], 4, [1,1], 2>;
434 defm : X86WriteRes<WriteCvtI2SSLd,         [JLAGU, JFPU1, JSTC], 9, [1,1,1], 1>;
435 defm : JWriteResFpuPair<WriteCvtI2PS,      [JFPU1, JSTC], 3, [1,1], 1>;
436 defm : JWriteResYMMPair<WriteCvtI2PSY,     [JFPU1, JSTC], 3, [2,2], 2>;
437 defm : X86WriteResPairUnsupported<WriteCvtI2PSZ>;
438 defm : X86WriteRes<WriteCvtI2SD,           [JFPU1, JSTC], 4, [1,1], 2>;
439 defm : X86WriteRes<WriteCvtI2SDLd,         [JLAGU, JFPU1, JSTC], 9, [1,1,1], 1>;
440 defm : JWriteResFpuPair<WriteCvtI2PD,      [JFPU1, JSTC], 3, [1,1], 1>;
441 defm : JWriteResYMMPair<WriteCvtI2PDY,     [JFPU1, JSTC], 3, [2,2], 2>;
442 defm : X86WriteResPairUnsupported<WriteCvtI2PDZ>;
444 defm : JWriteResFpuPair<WriteCvtSS2SD,      [JFPU1, JSTC], 7, [1,2], 2>;
445 defm : JWriteResFpuPair<WriteCvtPS2PD,      [JFPU1, JSTC], 2, [1,1], 1>;
446 defm : JWriteResYMMPair<WriteCvtPS2PDY,     [JFPU1, JSTC], 2, [2,2], 2>;
447 defm : X86WriteResPairUnsupported<WriteCvtPS2PDZ>;
449 defm : JWriteResFpuPair<WriteCvtSD2SS,    [JFPU1, JSTC], 7, [1,2], 2>;
450 defm : JWriteResFpuPair<WriteCvtPD2PS,    [JFPU1, JSTC], 3, [1,1], 1>;
451 defm : JWriteResYMMPair<WriteCvtPD2PSY,   [JFPU1, JSTC, JFPX], 6, [2,2,4], 3>;
452 defm : X86WriteResPairUnsupported<WriteCvtPD2PSZ>;
454 defm : JWriteResFpuPair<WriteCvtPH2PS,     [JFPU1, JSTC], 3, [1,1], 1>;
455 defm : JWriteResYMMPair<WriteCvtPH2PSY,    [JFPU1, JSTC], 3, [2,2], 2>;
456 defm : X86WriteResPairUnsupported<WriteCvtPH2PSZ>;
458 defm : X86WriteRes<WriteCvtPS2PH,                 [JFPU1, JSTC], 3, [1,1], 1>;
459 defm : X86WriteRes<WriteCvtPS2PHY,          [JFPU1, JSTC, JFPX], 6, [2,2,2], 3>;
460 defm : X86WriteResUnsupported<WriteCvtPS2PHZ>;
461 defm : X86WriteRes<WriteCvtPS2PHSt,        [JFPU1, JSTC, JSAGU], 4, [1,1,1], 1>;
462 defm : X86WriteRes<WriteCvtPS2PHYSt, [JFPU1, JSTC, JFPX, JSAGU], 7, [2,2,2,1], 3>;
463 defm : X86WriteResUnsupported<WriteCvtPS2PHZSt>;
465 ////////////////////////////////////////////////////////////////////////////////
466 // Vector integer operations.
467 ////////////////////////////////////////////////////////////////////////////////
469 defm : X86WriteRes<WriteVecLoad,          [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
470 defm : X86WriteRes<WriteVecLoadX,         [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
471 defm : X86WriteRes<WriteVecLoadY,         [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
472 defm : X86WriteRes<WriteVecLoadNT,        [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
473 defm : X86WriteRes<WriteVecLoadNTY,       [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
474 defm : X86WriteRes<WriteVecMaskedLoad,    [JLAGU, JFPU01, JVALU], 6, [1, 2, 2], 1>;
475 defm : X86WriteRes<WriteVecMaskedLoadY,   [JLAGU, JFPU01, JVALU], 6, [2, 4, 4], 2>;
477 defm : X86WriteRes<WriteVecStore,         [JSAGU, JFPU1,   JSTC], 2, [1, 1, 1], 1>;
478 defm : X86WriteRes<WriteVecStoreX,        [JSAGU, JFPU1,   JSTC], 1, [1, 1, 1], 1>;
479 defm : X86WriteRes<WriteVecStoreY,        [JSAGU, JFPU1,   JSTC], 1, [1, 1, 1], 1>;
480 defm : X86WriteRes<WriteVecStoreNT,       [JSAGU, JFPU1,   JSTC], 2, [1, 1, 1], 1>;
481 defm : X86WriteRes<WriteVecStoreNTY,      [JSAGU, JFPU1,   JSTC], 2, [2, 2, 2], 1>;
482 defm : X86WriteRes<WriteVecMaskedStore,   [JSAGU, JFPU01, JVALU], 6, [1, 1, 4], 1>;
483 defm : X86WriteRes<WriteVecMaskedStoreY,  [JSAGU, JFPU01, JVALU], 6, [2, 2, 4], 2>;
485 defm : X86WriteRes<WriteVecMove,          [JFPU01, JVALU], 1, [1, 1], 1>;
486 defm : X86WriteRes<WriteVecMoveX,         [JFPU01, JVALU], 1, [1, 1], 1>;
487 defm : X86WriteRes<WriteVecMoveY,         [JFPU01, JVALU], 1, [2, 2], 2>;
488 defm : X86WriteRes<WriteVecMoveToGpr,     [JFPU0, JFPA, JALU0], 4, [1, 1, 1], 1>;
489 defm : X86WriteRes<WriteVecMoveFromGpr,   [JFPU01, JFPX], 8, [1, 1], 2>;
491 defm : JWriteResFpuPair<WriteVecALU,      [JFPU01, JVALU], 1>;
492 defm : JWriteResFpuPair<WriteVecALUX,     [JFPU01, JVALU], 1>;
493 defm : X86WriteResPairUnsupported<WriteVecALUY>;
494 defm : X86WriteResPairUnsupported<WriteVecALUZ>;
495 defm : JWriteResFpuPair<WriteVecShift,    [JFPU01, JVALU], 1>;
496 defm : JWriteResFpuPair<WriteVecShiftX,   [JFPU01, JVALU], 2>; // +1cy latency.
497 defm : X86WriteResPairUnsupported<WriteVecShiftY>;
498 defm : X86WriteResPairUnsupported<WriteVecShiftZ>;
499 defm : JWriteResFpuPair<WriteVecShiftImm, [JFPU01, JVALU], 1>;
500 defm : JWriteResFpuPair<WriteVecShiftImmX,[JFPU01, JVALU], 2>; // +1cy latency.
501 defm : X86WriteResPairUnsupported<WriteVecShiftImmY>;
502 defm : X86WriteResPairUnsupported<WriteVecShiftImmZ>;
503 defm : X86WriteResPairUnsupported<WriteVarVecShift>;
504 defm : X86WriteResPairUnsupported<WriteVarVecShiftY>;
505 defm : X86WriteResPairUnsupported<WriteVarVecShiftZ>;
506 defm : JWriteResFpuPair<WriteVecIMul,     [JFPU0, JVIMUL], 2>;
507 defm : JWriteResFpuPair<WriteVecIMulX,    [JFPU0, JVIMUL], 2>;
508 defm : X86WriteResPairUnsupported<WriteVecIMulY>;
509 defm : X86WriteResPairUnsupported<WriteVecIMulZ>;
510 defm : JWriteResFpuPair<WritePMULLD,      [JFPU0, JFPU01, JVIMUL, JVALU], 4, [2, 1, 2, 1], 3>;
511 defm : X86WriteResPairUnsupported<WritePMULLDY>;
512 defm : X86WriteResPairUnsupported<WritePMULLDZ>;
513 defm : JWriteResFpuPair<WriteMPSAD,       [JFPU0, JVIMUL], 3, [1, 2], 3>;
514 defm : X86WriteResPairUnsupported<WriteMPSADY>;
515 defm : X86WriteResPairUnsupported<WriteMPSADZ>;
516 defm : JWriteResFpuPair<WritePSADBW,      [JFPU01, JVALU], 2>;
517 defm : JWriteResFpuPair<WritePSADBWX,     [JFPU01, JVALU], 2>;
518 defm : X86WriteResPairUnsupported<WritePSADBWY>;
519 defm : X86WriteResPairUnsupported<WritePSADBWZ>;
520 defm : JWriteResFpuPair<WritePHMINPOS,    [JFPU01, JVALU], 2>;
521 defm : JWriteResFpuPair<WriteShuffle,     [JFPU01, JVALU], 1>;
522 defm : JWriteResFpuPair<WriteShuffleX,    [JFPU01, JVALU], 1>;
523 defm : X86WriteResPairUnsupported<WriteShuffleY>;
524 defm : X86WriteResPairUnsupported<WriteShuffleZ>;
525 defm : JWriteResFpuPair<WriteVarShuffle,  [JFPU01, JVALU], 2, [1, 1], 1>;
526 defm : JWriteResFpuPair<WriteVarShuffleX, [JFPU01, JVALU], 2, [1, 4], 3>;
527 defm : X86WriteResPairUnsupported<WriteVarShuffleY>;
528 defm : X86WriteResPairUnsupported<WriteVarShuffleZ>;
529 defm : JWriteResFpuPair<WriteBlend,       [JFPU01, JVALU], 1>;
530 defm : X86WriteResPairUnsupported<WriteBlendY>;
531 defm : X86WriteResPairUnsupported<WriteBlendZ>;
532 defm : JWriteResFpuPair<WriteVarBlend,    [JFPU01, JVALU], 2, [4, 4], 3>;
533 defm : X86WriteResPairUnsupported<WriteVarBlendY>;
534 defm : X86WriteResPairUnsupported<WriteVarBlendZ>;
535 defm : JWriteResFpuPair<WriteVecLogic,    [JFPU01, JVALU], 1>;
536 defm : JWriteResFpuPair<WriteVecLogicX,   [JFPU01, JVALU], 1>;
537 defm : X86WriteResPairUnsupported<WriteVecLogicY>;
538 defm : X86WriteResPairUnsupported<WriteVecLogicZ>;
539 defm : JWriteResFpuPair<WriteVecTest,     [JFPU0, JFPA, JALU0], 3>;
540 defm : JWriteResYMMPair<WriteVecTestY,    [JFPU01, JFPX, JFPA, JALU0], 4, [2, 2, 2, 1], 3>;
541 defm : X86WriteResPairUnsupported<WriteVecTestZ>;
542 defm : X86WriteResPairUnsupported<WriteShuffle256>;
543 defm : X86WriteResPairUnsupported<WriteVarShuffle256>;
545 ////////////////////////////////////////////////////////////////////////////////
546 // Vector insert/extract operations.
547 ////////////////////////////////////////////////////////////////////////////////
549 defm : X86WriteRes<WriteVecInsert,      [JFPU01, JVALU], 1, [1,1], 2>;
550 defm : X86WriteRes<WriteVecInsertLd,    [JFPU01, JVALU, JLAGU], 4, [1,1,1], 1>;
551 defm : X86WriteRes<WriteVecExtract,     [JFPU0, JFPA, JALU0], 3, [1,1,1], 1>;
552 defm : X86WriteRes<WriteVecExtractSt,   [JFPU1, JSTC, JSAGU], 3, [1,1,1], 1>;
554 ////////////////////////////////////////////////////////////////////////////////
555 // SSE42 String instructions.
556 ////////////////////////////////////////////////////////////////////////////////
558 defm : JWriteResFpuPair<WritePCmpIStrI, [JFPU1, JVALU1, JFPU0, JFPA, JALU0], 7, [2, 2, 1, 1, 1], 3>;
559 defm : JWriteResFpuPair<WritePCmpIStrM, [JFPU1, JVALU1, JFPU0, JFPA, JALU0], 8, [2, 2, 1, 1, 1], 3>;
560 defm : JWriteResFpuPair<WritePCmpEStrI, [JFPU1, JSAGU, JLAGU, JVALU, JVALU1, JFPA, JALU0], 14, [1, 2, 2, 6, 4, 1, 1], 9>;
561 defm : JWriteResFpuPair<WritePCmpEStrM, [JFPU1, JSAGU, JLAGU, JVALU, JVALU1, JFPA, JALU0], 14, [1, 2, 2, 6, 4, 1, 1], 9>;
563 ////////////////////////////////////////////////////////////////////////////////
564 // MOVMSK Instructions.
565 ////////////////////////////////////////////////////////////////////////////////
567 def  : WriteRes<WriteFMOVMSK,    [JFPU0, JFPA, JALU0]> { let Latency = 3; }
568 def  : WriteRes<WriteVecMOVMSK,  [JFPU0, JFPA, JALU0]> { let Latency = 3; }
569 defm : X86WriteResUnsupported<WriteVecMOVMSKY>;
570 def  : WriteRes<WriteMMXMOVMSK,  [JFPU0, JFPA, JALU0]> { let Latency = 3; }
572 ////////////////////////////////////////////////////////////////////////////////
573 // AES Instructions.
574 ////////////////////////////////////////////////////////////////////////////////
576 defm : JWriteResFpuPair<WriteAESIMC,      [JFPU0, JVIMUL], 2>;
577 defm : JWriteResFpuPair<WriteAESKeyGen,   [JFPU0, JVIMUL], 2>;
578 defm : JWriteResFpuPair<WriteAESDecEnc,   [JFPU01, JVALU, JFPU0, JVIMUL], 3, [1,1,1,1], 2>;
580 ////////////////////////////////////////////////////////////////////////////////
581 // Horizontal add/sub  instructions.
582 ////////////////////////////////////////////////////////////////////////////////
584 defm : JWriteResFpuPair<WriteFHAdd,         [JFPU0, JFPA], 4>;            // +1cy latency.
585 defm : JWriteResYMMPair<WriteFHAddY,        [JFPU0, JFPA], 4, [2,2], 2>;  // +1cy latency.
586 defm : JWriteResFpuPair<WritePHAdd,         [JFPU01, JVALU], 1>;
587 defm : JWriteResFpuPair<WritePHAddX,        [JFPU01, JVALU], 2>;          // +1cy latency.
588 defm : X86WriteResPairUnsupported<WritePHAddY>;
590 ////////////////////////////////////////////////////////////////////////////////
591 // Carry-less multiplication instructions.
592 ////////////////////////////////////////////////////////////////////////////////
594 defm : JWriteResFpuPair<WriteCLMul,       [JFPU0, JVIMUL], 2>;
596 ////////////////////////////////////////////////////////////////////////////////
597 // SSE4A instructions.
598 ////////////////////////////////////////////////////////////////////////////////
600 def JWriteINSERTQ: SchedWriteRes<[JFPU01, JVALU]> {
601   let Latency = 2;
602   let ResourceCycles = [1, 4];
604 def : InstRW<[JWriteINSERTQ], (instrs INSERTQ, INSERTQI)>;
606 ////////////////////////////////////////////////////////////////////////////////
607 // AVX instructions.
608 ////////////////////////////////////////////////////////////////////////////////
610 def JWriteVecExtractF128: SchedWriteRes<[JFPU01, JFPX]>;
611 def : InstRW<[JWriteVecExtractF128], (instrs VEXTRACTF128rr)>;
613 def JWriteVBROADCASTYLd: SchedWriteRes<[JLAGU, JFPU01, JFPX]> {
614   let Latency = 6;
615   let ResourceCycles = [1, 2, 4];
616   let NumMicroOps = 2;
618 def : InstRW<[JWriteVBROADCASTYLd], (instrs VBROADCASTSDYrm,
619                                             VBROADCASTSSYrm,
620                                             VBROADCASTF128)>;
622 def JWriteJVZEROALL: SchedWriteRes<[]> {
623   let Latency = 90;
624   let NumMicroOps = 73;
626 def : InstRW<[JWriteJVZEROALL], (instrs VZEROALL)>;
628 def JWriteJVZEROUPPER: SchedWriteRes<[]> {
629   let Latency = 46;
630   let NumMicroOps = 37;
632 def : InstRW<[JWriteJVZEROUPPER], (instrs VZEROUPPER)>;
634 ///////////////////////////////////////////////////////////////////////////////
635 //  SchedWriteVariant definitions.
636 ///////////////////////////////////////////////////////////////////////////////
638 def JWriteZeroLatency : SchedWriteRes<[]> {
639   let Latency = 0;
642 def JWriteZeroIdiomYmm : SchedWriteRes<[JFPU01, JFPX]> {
643   let NumMicroOps = 2;
646 // Certain instructions that use the same register for both source
647 // operands do not have a real dependency on the previous contents of the
648 // register, and thus, do not have to wait before completing. They can be
649 // optimized out at register renaming stage.
650 // Reference: Section 10.8 of the "Software Optimization Guide for AMD Family
651 // 15h Processors".
652 // Reference: Agner's Fog "The microarchitecture of Intel, AMD and VIA CPUs",
653 // Section 21.8 [Dependency-breaking instructions].
655 def JWriteZeroIdiom : SchedWriteVariant<[
656     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
657     SchedVar<NoSchedPred,                          [WriteALU]>
659 def : InstRW<[JWriteZeroIdiom], (instrs SUB32rr, SUB64rr,
660                                         XOR32rr, XOR64rr)>;
662 def JWriteFZeroIdiom : SchedWriteVariant<[
663     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
664     SchedVar<NoSchedPred,                          [WriteFLogic]>
666 def : InstRW<[JWriteFZeroIdiom], (instrs XORPSrr, VXORPSrr, XORPDrr, VXORPDrr,
667                                          ANDNPSrr, VANDNPSrr,
668                                          ANDNPDrr, VANDNPDrr)>;
670 def JWriteFZeroIdiomY : SchedWriteVariant<[
671     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroIdiomYmm]>,
672     SchedVar<NoSchedPred,                          [WriteFLogicY]>
674 def : InstRW<[JWriteFZeroIdiomY], (instrs VXORPSYrr, VXORPDYrr,
675                                           VANDNPSYrr, VANDNPDYrr)>;
677 def JWriteVZeroIdiomLogic : SchedWriteVariant<[
678     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
679     SchedVar<NoSchedPred,                          [WriteVecLogic]>
681 def : InstRW<[JWriteVZeroIdiomLogic], (instrs MMX_PXORirr, MMX_PANDNirr)>;
683 def JWriteVZeroIdiomLogicX : SchedWriteVariant<[
684     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
685     SchedVar<NoSchedPred,                          [WriteVecLogicX]>
687 def : InstRW<[JWriteVZeroIdiomLogicX], (instrs PXORrr, VPXORrr,
688                                                PANDNrr, VPANDNrr)>;
690 def JWriteVZeroIdiomALU : SchedWriteVariant<[
691     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
692     SchedVar<NoSchedPred,                          [WriteVecALU]>
694 def : InstRW<[JWriteVZeroIdiomALU], (instrs MMX_PSUBBirr, MMX_PSUBDirr,
695                                             MMX_PSUBQirr, MMX_PSUBWirr,
696                                             MMX_PSUBSBirr, MMX_PSUBSWirr,
697                                             MMX_PSUBUSBirr, MMX_PSUBUSWirr,
698                                             MMX_PCMPGTBirr, MMX_PCMPGTDirr,
699                                             MMX_PCMPGTWirr)>;
701 def JWriteVZeroIdiomALUX : SchedWriteVariant<[
702     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
703     SchedVar<NoSchedPred,                          [WriteVecALUX]>
705 def : InstRW<[JWriteVZeroIdiomALUX], (instrs PSUBBrr, VPSUBBrr,
706                                              PSUBDrr, VPSUBDrr,
707                                              PSUBQrr, VPSUBQrr,
708                                              PSUBWrr, VPSUBWrr,
709                                              PSUBSBrr, VPSUBSBrr,
710                                              PSUBSWrr, VPSUBSWrr,
711                                              PSUBUSBrr, VPSUBUSBrr,
712                                              PSUBUSWrr, VPSUBUSWrr,
713                                              PCMPGTBrr, VPCMPGTBrr,
714                                              PCMPGTDrr, VPCMPGTDrr,
715                                              PCMPGTQrr, VPCMPGTQrr,
716                                              PCMPGTWrr, VPCMPGTWrr)>;
718 def JWriteVPERM2F128 : SchedWriteVariant<[
719   SchedVar<MCSchedPredicate<ZeroIdiomVPERMPredicate>, [JWriteZeroIdiomYmm]>,
720   SchedVar<NoSchedPred,                               [WriteFShuffle256]>
722 def : InstRW<[JWriteVPERM2F128], (instrs VPERM2F128rr)>;
724 // This write is used for slow LEA instructions.
725 def JWrite3OpsLEA : SchedWriteRes<[JALU1, JSAGU]> {
726   let Latency = 2;
729 // On Jaguar, a slow LEA is either a 3Ops LEA (base, index, offset), or an LEA
730 // with a `Scale` value different than 1.
731 def JSlowLEAPredicate : MCSchedPredicate<
732   CheckAny<[
733     // A 3-operand LEA (base, index, offset).
734     IsThreeOperandsLEAFn,
735     // An LEA with a "Scale" different than 1.
736     CheckAll<[
737       CheckIsImmOperand<2>,
738       CheckNot<CheckImmOperand<2, 1>>
739     ]>
740   ]>
743 def JWriteLEA : SchedWriteVariant<[
744     SchedVar<JSlowLEAPredicate, [JWrite3OpsLEA]>,
745     SchedVar<NoSchedPred,       [WriteLEA]>
748 def : InstRW<[JWriteLEA], (instrs LEA32r, LEA64r, LEA64_32r)>;
750 def JSlowLEA16r : SchedWriteRes<[JALU01]> {
751   let Latency = 3;
752   let ResourceCycles = [4];
755 def : InstRW<[JSlowLEA16r], (instrs LEA16r)>;
757 ///////////////////////////////////////////////////////////////////////////////
758 // Dependency breaking instructions.
759 ///////////////////////////////////////////////////////////////////////////////
761 def : IsZeroIdiomFunction<[
762   // GPR Zero-idioms.
763   DepBreakingClass<[ SUB32rr, SUB64rr, XOR32rr, XOR64rr ], ZeroIdiomPredicate>,
765   // MMX Zero-idioms.
766   DepBreakingClass<[
767     MMX_PXORirr, MMX_PANDNirr, MMX_PSUBBirr,
768     MMX_PSUBDirr, MMX_PSUBQirr, MMX_PSUBWirr,
769     MMX_PSUBSBirr, MMX_PSUBSWirr, MMX_PSUBUSBirr, MMX_PSUBUSWirr,
770     MMX_PCMPGTBirr, MMX_PCMPGTDirr, MMX_PCMPGTWirr
771   ], ZeroIdiomPredicate>,
773   // SSE Zero-idioms.
774   DepBreakingClass<[
775     // fp variants.
776     XORPSrr, XORPDrr, ANDNPSrr, ANDNPDrr,
778     // int variants.
779     PXORrr, PANDNrr,
780     PSUBBrr, PSUBWrr, PSUBDrr, PSUBQrr,
781     PSUBSBrr, PSUBSWrr, PSUBUSBrr, PSUBUSWrr,
782     PCMPGTBrr, PCMPGTDrr, PCMPGTQrr, PCMPGTWrr
783   ], ZeroIdiomPredicate>,
785   // AVX Zero-idioms.
786   DepBreakingClass<[
787     // xmm fp variants.
788     VXORPSrr, VXORPDrr, VANDNPSrr, VANDNPDrr,
790     // xmm int variants.
791     VPXORrr, VPANDNrr,
792     VPSUBBrr, VPSUBWrr, VPSUBDrr, VPSUBQrr,
793     VPSUBSBrr, VPSUBSWrr, VPSUBUSBrr, VPSUBUSWrr,
794     VPCMPGTBrr, VPCMPGTWrr, VPCMPGTDrr, VPCMPGTQrr,
796     // ymm variants.
797     VXORPSYrr, VXORPDYrr, VANDNPSYrr, VANDNPDYrr
798   ], ZeroIdiomPredicate>,
800   DepBreakingClass<[ VPERM2F128rr ], ZeroIdiomVPERMPredicate>
803 def : IsDepBreakingFunction<[
804   // GPR
805   DepBreakingClass<[ SBB32rr, SBB64rr ], ZeroIdiomPredicate>,
806   DepBreakingClass<[ CMP32rr, CMP64rr ], CheckSameRegOperand<0, 1> >,
808   // MMX
809   DepBreakingClass<[
810     MMX_PCMPEQBirr, MMX_PCMPEQDirr, MMX_PCMPEQWirr
811   ], ZeroIdiomPredicate>,
813   // SSE
814   DepBreakingClass<[ 
815     PCMPEQBrr, PCMPEQWrr, PCMPEQDrr, PCMPEQQrr
816   ], ZeroIdiomPredicate>,
818   // AVX
819   DepBreakingClass<[
820     VPCMPEQBrr, VPCMPEQWrr, VPCMPEQDrr, VPCMPEQQrr
821   ], ZeroIdiomPredicate>
824 def : IsOptimizableRegisterMove<[
825   InstructionEquivalenceClass<[
826     // GPR variants.
827     MOV32rr, MOV64rr,
829     // MMX variants.
830     MMX_MOVQ64rr,
832     // SSE variants.
833     MOVAPSrr, MOVUPSrr,
834     MOVAPDrr, MOVUPDrr,
835     MOVDQArr, MOVDQUrr,
837     // AVX variants.
838     VMOVAPSrr, VMOVUPSrr,
839     VMOVAPDrr, VMOVUPDrr,
840     VMOVDQArr, VMOVDQUrr
841   ], TruePred >
844 } // SchedModel