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