[PowerPC] Do not emit record-form rotates when record-form andi/andis suffices
[llvm-core.git] / lib / Target / X86 / X86ScheduleBtVer2.td
blob9b1a45467e21a5943457f3c0c9e27045ff1b075a
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.
14 //===----------------------------------------------------------------------===//
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;
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;
31 let SchedModel = BtVer2Model in {
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
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/
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]>;
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/
56 def JFpuPRF: RegisterFile<72, [VR64, VR128, VR256], [1, 1, 2]>;
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"
61 def JRCU : RetireControlUnit<64, 2>;
63 // Integer Pipe Scheduler
64 def JALU01 : ProcResGroup<[JALU0, JALU1]> {
65   let BufferSize=20;
68 // AGU Pipe Scheduler
69 def JLSAGU : ProcResGroup<[JLAGU, JSAGU]> {
70   let BufferSize=12;
73 // Fpu Pipe Scheduler
74 def JFPU01 : ProcResGroup<[JFPU0, JFPU1]> {
75   let BufferSize=18;
78 // Functional units
79 def JDiv    : ProcResource<1>; // integer division
80 def JMul    : ProcResource<1>; // integer multiplication
81 def JVALU0  : ProcResource<1>; // vector integer
82 def JVALU1  : ProcResource<1>; // vector integer
83 def JVIMUL  : ProcResource<1>; // vector integer multiplication
84 def JSTC    : ProcResource<1>; // vector store/convert
85 def JFPM    : ProcResource<1>; // FP multiplication
86 def JFPA    : ProcResource<1>; // FP addition
88 // Functional unit groups
89 def JFPX  : ProcResGroup<[JFPA, JFPM]>;
90 def JVALU : ProcResGroup<[JVALU0, JVALU1]>;
92 // Integer loads are 3 cycles, so ReadAfterLd registers needn't be available until 3
93 // cycles after the memory operand.
94 def : ReadAdvance<ReadAfterLd, 3>;
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.
101 multiclass 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   }
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   }
120 multiclass 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   }
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   }
139 multiclass 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   }
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   }
158 // A folded store needs a cycle on the SAGU for the store data.
159 def : WriteRes<WriteRMW, [JSAGU]>;
161 ////////////////////////////////////////////////////////////////////////////////
162 // Arithmetic.
163 ////////////////////////////////////////////////////////////////////////////////
165 defm : JWriteResIntPair<WriteALU,    [JALU01], 1>;
166 defm : JWriteResIntPair<WriteADC,    [JALU01], 1, [2]>;
167 defm : JWriteResIntPair<WriteIMul,   [JALU1, JMul], 3, [1, 1], 2>; // i8/i16/i32 multiplication
168 defm : JWriteResIntPair<WriteIMul64, [JALU1, JMul], 6, [1, 4], 2>; // i64 multiplication
169 defm : X86WriteRes<WriteIMulH,       [JALU1], 6, [4], 1>;
171 defm : X86WriteRes<WriteBSWAP32, [JALU01], 1, [1], 1>;
172 defm : X86WriteRes<WriteBSWAP64, [JALU01], 1, [1], 1>;
173 defm : X86WriteRes<WriteCMPXCHG,[JALU01], 1, [1], 1>;
174 defm : X86WriteRes<WriteCMPXCHGRMW,[JALU01, JSAGU, JLAGU], 4, [1, 1, 1], 2>;
175 defm : X86WriteRes<WriteXCHG,        [JALU01], 1, [1], 1>;
177 defm : JWriteResIntPair<WriteDiv8,   [JALU1, JDiv], 12, [1, 12], 1>;
178 defm : JWriteResIntPair<WriteDiv16,  [JALU1, JDiv], 17, [1, 17], 2>;
179 defm : JWriteResIntPair<WriteDiv32,  [JALU1, JDiv], 25, [1, 25], 2>;
180 defm : JWriteResIntPair<WriteDiv64,  [JALU1, JDiv], 41, [1, 41], 2>;
181 defm : JWriteResIntPair<WriteIDiv8,  [JALU1, JDiv], 12, [1, 12], 1>;
182 defm : JWriteResIntPair<WriteIDiv16, [JALU1, JDiv], 17, [1, 17], 2>;
183 defm : JWriteResIntPair<WriteIDiv32, [JALU1, JDiv], 25, [1, 25], 2>;
184 defm : JWriteResIntPair<WriteIDiv64, [JALU1, JDiv], 41, [1, 41], 2>;
186 defm : JWriteResIntPair<WriteCRC32,  [JALU01], 3, [4], 3>;
188 defm : JWriteResIntPair<WriteCMOV,  [JALU01], 1>; // Conditional move.
189 defm : JWriteResIntPair<WriteCMOV2, [JALU01], 1>; // Conditional (CF + ZF flag) move.
190 defm : X86WriteRes<WriteFCMOV, [JFPU0, JFPA], 3, [1,1], 1>; // x87 conditional move.
191 def  : WriteRes<WriteSETCC, [JALU01]>; // Setcc.
192 def  : WriteRes<WriteSETCCStore, [JALU01,JSAGU]>;
193 def  : WriteRes<WriteLAHFSAHF, [JALU01]>;
194 def  : WriteRes<WriteBitTest,[JALU01]>;
196 // This is for simple LEAs with one or two input operands.
197 def : WriteRes<WriteLEA, [JALU01]>;
199 // Bit counts.
200 defm : JWriteResIntPair<WriteBSF, [JALU01], 5, [4], 8>;
201 defm : JWriteResIntPair<WriteBSR, [JALU01], 5, [4], 8>;
202 defm : JWriteResIntPair<WritePOPCNT,         [JALU01], 1>;
203 defm : JWriteResIntPair<WriteLZCNT,          [JALU01], 1>;
204 defm : JWriteResIntPair<WriteTZCNT,          [JALU01], 2, [2]>;
206 // BMI1 BEXTR/BLS, BMI2 BZHI
207 defm : JWriteResIntPair<WriteBEXTR, [JALU01], 1>;
208 defm : JWriteResIntPair<WriteBLS,   [JALU01], 2, [2]>;
209 defm : X86WriteResPairUnsupported<WriteBZHI>;
211 ////////////////////////////////////////////////////////////////////////////////
212 // Integer shifts and rotates.
213 ////////////////////////////////////////////////////////////////////////////////
215 defm : JWriteResIntPair<WriteShift, [JALU01], 1>;
217 // SHLD/SHRD.
218 defm : X86WriteRes<WriteSHDrri, [JALU01], 3, [6], 6>;
219 defm : X86WriteRes<WriteSHDrrcl,[JALU01], 4, [8], 7>;
220 defm : X86WriteRes<WriteSHDmri, [JLAGU, JALU01], 9, [1, 22], 8>;
221 defm : X86WriteRes<WriteSHDmrcl,[JLAGU, JALU01], 9, [1, 22], 8>;
223 ////////////////////////////////////////////////////////////////////////////////
224 // Loads, stores, and moves, not folded with other operations.
225 ////////////////////////////////////////////////////////////////////////////////
227 def : WriteRes<WriteLoad,    [JLAGU]> { let Latency = 5; }
228 def : WriteRes<WriteStore,   [JSAGU]>;
229 def : WriteRes<WriteStoreNT, [JSAGU]>;
230 def : WriteRes<WriteMove,    [JALU01]>;
232 // Load/store MXCSR.
233 // FIXME: These are copy and pasted from WriteLoad/Store.
234 def : WriteRes<WriteLDMXCSR, [JLAGU]> { let Latency = 5; }
235 def : WriteRes<WriteSTMXCSR, [JSAGU]>;
237 // Treat misc copies as a move.
238 def : InstRW<[WriteMove], (instrs COPY)>;
240 ////////////////////////////////////////////////////////////////////////////////
241 // Idioms that clear a register, like xorps %xmm0, %xmm0.
242 // These can often bypass execution ports completely.
243 ////////////////////////////////////////////////////////////////////////////////
245 def : WriteRes<WriteZero,  []>;
247 ////////////////////////////////////////////////////////////////////////////////
248 // Branches don't produce values, so they have no latency, but they still
249 // consume resources. Indirect branches can fold loads.
250 ////////////////////////////////////////////////////////////////////////////////
252 defm : JWriteResIntPair<WriteJump,  [JALU01], 1>;
254 ////////////////////////////////////////////////////////////////////////////////
255 // Special case scheduling classes.
256 ////////////////////////////////////////////////////////////////////////////////
258 def : WriteRes<WriteSystem,     [JALU01]> { let Latency = 100; }
259 def : WriteRes<WriteMicrocoded, [JALU01]> { let Latency = 100; }
260 def : WriteRes<WriteFence,  [JSAGU]>;
262 // Nops don't have dependencies, so there's no actual latency, but we set this
263 // to '1' to tell the scheduler that the nop uses an ALU slot for a cycle.
264 def : WriteRes<WriteNop, [JALU01]> { let Latency = 1; }
266 ////////////////////////////////////////////////////////////////////////////////
267 // Floating point. This covers both scalar and vector operations.
268 ////////////////////////////////////////////////////////////////////////////////
270 defm : X86WriteRes<WriteFLD0,          [JFPU1, JSTC], 3, [1,1], 1>;
271 defm : X86WriteRes<WriteFLD1,          [JFPU1, JSTC], 3, [1,1], 1>;
272 defm : X86WriteRes<WriteFLDC,          [JFPU1, JSTC], 3, [1,1], 1>;
273 defm : X86WriteRes<WriteFLoad,         [JLAGU, JFPU01, JFPX], 5, [1, 1, 1], 1>;
274 defm : X86WriteRes<WriteFLoadX,        [JLAGU, JFPU01, JFPX], 5, [1, 1, 1], 1>;
275 defm : X86WriteRes<WriteFLoadY,        [JLAGU, JFPU01, JFPX], 5, [1, 1, 1], 1>;
276 defm : X86WriteRes<WriteFMaskedLoad,   [JLAGU, JFPU01, JFPX], 6, [1, 1, 2], 1>;
277 defm : X86WriteRes<WriteFMaskedLoadY,  [JLAGU, JFPU01, JFPX], 6, [2, 2, 4], 2>;
279 defm : X86WriteRes<WriteFStore,        [JSAGU, JFPU1,  JSTC], 2, [1, 1, 1], 1>;
280 defm : X86WriteRes<WriteFStoreX,       [JSAGU, JFPU1,  JSTC], 1, [1, 1, 1], 1>;
281 defm : X86WriteRes<WriteFStoreY,       [JSAGU, JFPU1,  JSTC], 1, [1, 1, 1], 1>;
282 defm : X86WriteRes<WriteFStoreNT,      [JSAGU, JFPU1,  JSTC], 3, [1, 1, 1], 1>;
283 defm : X86WriteRes<WriteFStoreNTX,     [JSAGU, JFPU1,  JSTC], 3, [1, 1, 1], 1>;
284 defm : X86WriteRes<WriteFStoreNTY,     [JSAGU, JFPU1,  JSTC], 3, [2, 2, 2], 1>;
285 defm : X86WriteRes<WriteFMaskedStore,  [JSAGU, JFPU01, JFPX], 6, [1, 1, 4], 1>;
286 defm : X86WriteRes<WriteFMaskedStoreY, [JSAGU, JFPU01, JFPX], 6, [2, 2, 4], 2>;
288 defm : X86WriteRes<WriteFMove,         [JFPU01, JFPX], 1, [1, 1], 1>;
289 defm : X86WriteRes<WriteFMoveX,        [JFPU01, JFPX], 1, [1, 1], 1>;
290 defm : X86WriteRes<WriteFMoveY,        [JFPU01, JFPX], 1, [2, 2], 2>;
292 defm : X86WriteRes<WriteEMMS,          [JFPU01, JFPX], 2, [1, 1], 1>;
294 defm : JWriteResFpuPair<WriteFAdd,         [JFPU0, JFPA],  3>;
295 defm : JWriteResFpuPair<WriteFAddX,        [JFPU0, JFPA],  3>;
296 defm : JWriteResYMMPair<WriteFAddY,        [JFPU0, JFPA],  3, [2,2], 2>;
297 defm : X86WriteResPairUnsupported<WriteFAddZ>;
298 defm : JWriteResFpuPair<WriteFAdd64,       [JFPU0, JFPA],  3>;
299 defm : JWriteResFpuPair<WriteFAdd64X,      [JFPU0, JFPA],  3>;
300 defm : JWriteResYMMPair<WriteFAdd64Y,      [JFPU0, JFPA],  3, [2,2], 2>;
301 defm : X86WriteResPairUnsupported<WriteFAdd64Z>;
302 defm : JWriteResFpuPair<WriteFCmp,         [JFPU0, JFPA],  2>;
303 defm : JWriteResFpuPair<WriteFCmpX,        [JFPU0, JFPA],  2>;
304 defm : JWriteResYMMPair<WriteFCmpY,        [JFPU0, JFPA],  2, [2,2], 2>;
305 defm : X86WriteResPairUnsupported<WriteFCmpZ>;
306 defm : JWriteResFpuPair<WriteFCmp64,       [JFPU0, JFPA],  2>;
307 defm : JWriteResFpuPair<WriteFCmp64X,      [JFPU0, JFPA],  2>;
308 defm : JWriteResYMMPair<WriteFCmp64Y,      [JFPU0, JFPA],  2, [2,2], 2>;
309 defm : X86WriteResPairUnsupported<WriteFCmp64Z>;
310 defm : JWriteResFpuPair<WriteFCom,  [JFPU0, JFPA, JALU0],  3>;
311 defm : JWriteResFpuPair<WriteFMul,         [JFPU1, JFPM],  2>;
312 defm : JWriteResFpuPair<WriteFMulX,        [JFPU1, JFPM],  2>;
313 defm : JWriteResYMMPair<WriteFMulY,        [JFPU1, JFPM],  2, [2,2], 2>;
314 defm : X86WriteResPairUnsupported<WriteFMulZ>;
315 defm : JWriteResFpuPair<WriteFMul64,       [JFPU1, JFPM],  4, [1,2]>;
316 defm : JWriteResFpuPair<WriteFMul64X,      [JFPU1, JFPM],  4, [1,2]>;
317 defm : JWriteResYMMPair<WriteFMul64Y,      [JFPU1, JFPM],  4, [2,4], 2>;
318 defm : X86WriteResPairUnsupported<WriteFMul64Z>;
319 defm : X86WriteResPairUnsupported<WriteFMA>;
320 defm : X86WriteResPairUnsupported<WriteFMAX>;
321 defm : X86WriteResPairUnsupported<WriteFMAY>;
322 defm : X86WriteResPairUnsupported<WriteFMAZ>;
323 defm : JWriteResFpuPair<WriteDPPD,   [JFPU1, JFPM, JFPA],  9, [1, 3, 3],  3>;
324 defm : JWriteResFpuPair<WriteDPPS,   [JFPU1, JFPM, JFPA], 11, [1, 3, 3],  5>;
325 defm : JWriteResYMMPair<WriteDPPSY,  [JFPU1, JFPM, JFPA], 12, [2, 6, 6], 10>;
326 defm : X86WriteResPairUnsupported<WriteDPPSZ>;
327 defm : JWriteResFpuPair<WriteFRcp,         [JFPU1, JFPM],  2>;
328 defm : JWriteResFpuPair<WriteFRcpX,        [JFPU1, JFPM],  2>;
329 defm : JWriteResYMMPair<WriteFRcpY,        [JFPU1, JFPM],  2, [2,2], 2>;
330 defm : X86WriteResPairUnsupported<WriteFRcpZ>;
331 defm : JWriteResFpuPair<WriteFRsqrt,       [JFPU1, JFPM],  2>;
332 defm : JWriteResFpuPair<WriteFRsqrtX,      [JFPU1, JFPM],  2>;
333 defm : JWriteResYMMPair<WriteFRsqrtY,      [JFPU1, JFPM],  2, [2,2], 2>;
334 defm : X86WriteResPairUnsupported<WriteFRsqrtZ>;
335 defm : JWriteResFpuPair<WriteFDiv,         [JFPU1, JFPM], 19, [1, 19]>;
336 defm : JWriteResFpuPair<WriteFDivX,        [JFPU1, JFPM], 19, [1, 19]>;
337 defm : JWriteResYMMPair<WriteFDivY,        [JFPU1, JFPM], 38, [2, 38], 2>;
338 defm : X86WriteResPairUnsupported<WriteFDivZ>;
339 defm : JWriteResFpuPair<WriteFDiv64,       [JFPU1, JFPM], 19, [1, 19]>;
340 defm : JWriteResFpuPair<WriteFDiv64X,      [JFPU1, JFPM], 19, [1, 19]>;
341 defm : JWriteResYMMPair<WriteFDiv64Y,      [JFPU1, JFPM], 38, [2, 38], 2>;
342 defm : X86WriteResPairUnsupported<WriteFDiv64Z>;
343 defm : JWriteResFpuPair<WriteFSqrt,        [JFPU1, JFPM], 21, [1, 21]>;
344 defm : JWriteResFpuPair<WriteFSqrtX,       [JFPU1, JFPM], 21, [1, 21]>;
345 defm : JWriteResYMMPair<WriteFSqrtY,       [JFPU1, JFPM], 42, [2, 42], 2>;
346 defm : X86WriteResPairUnsupported<WriteFSqrtZ>;
347 defm : JWriteResFpuPair<WriteFSqrt64,      [JFPU1, JFPM], 27, [1, 27]>;
348 defm : JWriteResFpuPair<WriteFSqrt64X,     [JFPU1, JFPM], 27, [1, 27]>;
349 defm : JWriteResYMMPair<WriteFSqrt64Y,     [JFPU1, JFPM], 54, [2, 54], 2>;
350 defm : X86WriteResPairUnsupported<WriteFSqrt64Z>;
351 defm : JWriteResFpuPair<WriteFSqrt80,      [JFPU1, JFPM], 35, [1, 35]>;
352 defm : JWriteResFpuPair<WriteFSign,        [JFPU1, JFPM],  2>;
353 defm : JWriteResFpuPair<WriteFRnd,         [JFPU1, JSTC],  3>;
354 defm : JWriteResYMMPair<WriteFRndY,        [JFPU1, JSTC],  3, [2,2], 2>;
355 defm : X86WriteResPairUnsupported<WriteFRndZ>;
356 defm : JWriteResFpuPair<WriteFLogic,      [JFPU01, JFPX],  1>;
357 defm : JWriteResYMMPair<WriteFLogicY,     [JFPU01, JFPX],  1, [2, 2], 2>;
358 defm : X86WriteResPairUnsupported<WriteFLogicZ>;
359 defm : JWriteResFpuPair<WriteFTest,       [JFPU0, JFPA, JALU0], 3>;
360 defm : JWriteResYMMPair<WriteFTestY ,     [JFPU01, JFPX, JFPA, JALU0], 4, [2, 2, 2, 1], 3>;
361 defm : X86WriteResPairUnsupported<WriteFTestZ>;
362 defm : JWriteResFpuPair<WriteFShuffle,    [JFPU01, JFPX],  1>;
363 defm : JWriteResYMMPair<WriteFShuffleY,   [JFPU01, JFPX],  1, [2, 2], 2>;
364 defm : X86WriteResPairUnsupported<WriteFShuffleZ>;
365 defm : JWriteResFpuPair<WriteFVarShuffle, [JFPU01, JFPX],  2, [1, 4], 3>;
366 defm : JWriteResYMMPair<WriteFVarShuffleY,[JFPU01, JFPX],  3, [2, 6], 6>;
367 defm : X86WriteResPairUnsupported<WriteFVarShuffleZ>;
368 defm : JWriteResFpuPair<WriteFBlend,      [JFPU01, JFPX],  1>;
369 defm : JWriteResYMMPair<WriteFBlendY,     [JFPU01, JFPX],  1, [2, 2], 2>;
370 defm : X86WriteResPairUnsupported<WriteFBlendZ>;
371 defm : JWriteResFpuPair<WriteFVarBlend,   [JFPU01, JFPX],  2, [1, 4], 3>;
372 defm : JWriteResYMMPair<WriteFVarBlendY,  [JFPU01, JFPX],  3, [2, 6], 6>;
373 defm : X86WriteResPairUnsupported<WriteFVarBlendZ>;
374 defm : JWriteResFpuPair<WriteFShuffle256, [JFPU01, JFPX],  1, [2, 2], 2>;
375 defm : X86WriteResPairUnsupported<WriteFVarShuffle256>;
377 ////////////////////////////////////////////////////////////////////////////////
378 // Conversions.
379 ////////////////////////////////////////////////////////////////////////////////
381 defm : JWriteResFpuPair<WriteCvtSS2I,      [JFPU1, JSTC, JFPA, JALU0], 7, [1,1,1,1], 2>;
382 defm : JWriteResFpuPair<WriteCvtPS2I,      [JFPU1, JSTC], 3, [1,1], 1>;
383 defm : JWriteResYMMPair<WriteCvtPS2IY,     [JFPU1, JSTC], 3, [2,2], 2>;
384 defm : X86WriteResPairUnsupported<WriteCvtPS2IZ>;
385 defm : JWriteResFpuPair<WriteCvtSD2I,      [JFPU1, JSTC, JFPA, JALU0], 7, [1,1,1,1], 2>;
386 defm : JWriteResFpuPair<WriteCvtPD2I,      [JFPU1, JSTC], 3, [1,1], 1>;
387 defm : JWriteResYMMPair<WriteCvtPD2IY,     [JFPU1, JSTC, JFPX], 6, [2,2,4], 3>;
388 defm : X86WriteResPairUnsupported<WriteCvtPD2IZ>;
390 // FIXME: f+3 ST, LD+STC latency
391 defm : JWriteResFpuPair<WriteCvtI2SS,      [JFPU1, JSTC], 9, [1,1], 2>;
392 defm : JWriteResFpuPair<WriteCvtI2PS,      [JFPU1, JSTC], 3, [1,1], 1>;
393 defm : JWriteResYMMPair<WriteCvtI2PSY,     [JFPU1, JSTC], 3, [2,2], 2>;
394 defm : X86WriteResPairUnsupported<WriteCvtI2PSZ>;
395 defm : JWriteResFpuPair<WriteCvtI2SD,      [JFPU1, JSTC], 9, [1,1], 2>;
396 defm : JWriteResFpuPair<WriteCvtI2PD,      [JFPU1, JSTC], 3, [1,1], 1>;
397 defm : JWriteResYMMPair<WriteCvtI2PDY,     [JFPU1, JSTC], 3, [2,2], 2>;
398 defm : X86WriteResPairUnsupported<WriteCvtI2PDZ>;
400 defm : JWriteResFpuPair<WriteCvtSS2SD,      [JFPU1, JSTC], 7, [1,2], 2>;
401 defm : JWriteResFpuPair<WriteCvtPS2PD,      [JFPU1, JSTC], 2, [1,1], 1>;
402 defm : JWriteResYMMPair<WriteCvtPS2PDY,     [JFPU1, JSTC], 2, [2,2], 2>;
403 defm : X86WriteResPairUnsupported<WriteCvtPS2PDZ>;
405 defm : JWriteResFpuPair<WriteCvtSD2SS,    [JFPU1, JSTC], 7, [1,2], 2>;
406 defm : JWriteResFpuPair<WriteCvtPD2PS,    [JFPU1, JSTC], 3, [1,1], 1>;
407 defm : JWriteResYMMPair<WriteCvtPD2PSY,   [JFPU1, JSTC, JFPX], 6, [2,2,4], 3>;
408 defm : X86WriteResPairUnsupported<WriteCvtPD2PSZ>;
410 defm : JWriteResFpuPair<WriteCvtPH2PS,     [JFPU1, JSTC], 3, [1,1], 1>;
411 defm : JWriteResYMMPair<WriteCvtPH2PSY,    [JFPU1, JSTC], 3, [2,2], 2>;
412 defm : X86WriteResPairUnsupported<WriteCvtPH2PSZ>;
414 defm : X86WriteRes<WriteCvtPS2PH,                 [JFPU1, JSTC], 3, [1,1], 1>;
415 defm : X86WriteRes<WriteCvtPS2PHY,          [JFPU1, JSTC, JFPX], 6, [2,2,2], 3>;
416 defm : X86WriteResUnsupported<WriteCvtPS2PHZ>;
417 defm : X86WriteRes<WriteCvtPS2PHSt,        [JFPU1, JSTC, JSAGU], 4, [1,1,1], 1>;
418 defm : X86WriteRes<WriteCvtPS2PHYSt, [JFPU1, JSTC, JFPX, JSAGU], 7, [2,2,2,1], 3>;
419 defm : X86WriteResUnsupported<WriteCvtPS2PHZSt>;
421 ////////////////////////////////////////////////////////////////////////////////
422 // Vector integer operations.
423 ////////////////////////////////////////////////////////////////////////////////
425 defm : X86WriteRes<WriteVecLoad,          [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
426 defm : X86WriteRes<WriteVecLoadX,         [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
427 defm : X86WriteRes<WriteVecLoadY,         [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
428 defm : X86WriteRes<WriteVecLoadNT,        [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
429 defm : X86WriteRes<WriteVecLoadNTY,       [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
430 defm : X86WriteRes<WriteVecMaskedLoad,    [JLAGU, JFPU01, JVALU], 6, [1, 1, 2], 1>;
431 defm : X86WriteRes<WriteVecMaskedLoadY,   [JLAGU, JFPU01, JVALU], 6, [2, 2, 4], 2>;
433 defm : X86WriteRes<WriteVecStore,         [JSAGU, JFPU1,   JSTC], 2, [1, 1, 1], 1>;
434 defm : X86WriteRes<WriteVecStoreX,        [JSAGU, JFPU1,   JSTC], 1, [1, 1, 1], 1>;
435 defm : X86WriteRes<WriteVecStoreY,        [JSAGU, JFPU1,   JSTC], 1, [1, 1, 1], 1>;
436 defm : X86WriteRes<WriteVecStoreNT,       [JSAGU, JFPU1,   JSTC], 2, [1, 1, 1], 1>;
437 defm : X86WriteRes<WriteVecStoreNTY,      [JSAGU, JFPU1,   JSTC], 2, [2, 2, 2], 1>;
438 defm : X86WriteRes<WriteVecMaskedStore,   [JSAGU, JFPU01, JVALU], 6, [1, 1, 4], 1>;
439 defm : X86WriteRes<WriteVecMaskedStoreY,  [JSAGU, JFPU01, JVALU], 6, [2, 2, 4], 2>;
441 defm : X86WriteRes<WriteVecMove,          [JFPU01, JVALU], 1, [1, 1], 1>;
442 defm : X86WriteRes<WriteVecMoveX,         [JFPU01, JVALU], 1, [1, 1], 1>;
443 defm : X86WriteRes<WriteVecMoveY,         [JFPU01, JVALU], 1, [2, 2], 2>;
444 defm : X86WriteRes<WriteVecMoveToGpr,     [JFPU0, JFPA, JALU0], 4, [1, 1, 1], 1>;
445 defm : X86WriteRes<WriteVecMoveFromGpr,   [JFPU01, JFPX], 8, [1, 1], 2>;
447 defm : JWriteResFpuPair<WriteVecALU,      [JFPU01, JVALU], 1>;
448 defm : JWriteResFpuPair<WriteVecALUX,     [JFPU01, JVALU], 1>;
449 defm : X86WriteResPairUnsupported<WriteVecALUY>;
450 defm : X86WriteResPairUnsupported<WriteVecALUZ>;
451 defm : JWriteResFpuPair<WriteVecShift,    [JFPU01, JVALU], 1>;
452 defm : JWriteResFpuPair<WriteVecShiftX,   [JFPU01, JVALU], 1>;
453 defm : X86WriteResPairUnsupported<WriteVecShiftY>;
454 defm : X86WriteResPairUnsupported<WriteVecShiftZ>;
455 defm : JWriteResFpuPair<WriteVecShiftImm, [JFPU01, JVALU], 1>;
456 defm : JWriteResFpuPair<WriteVecShiftImmX,[JFPU01, JVALU], 1>;
457 defm : X86WriteResPairUnsupported<WriteVecShiftImmY>;
458 defm : X86WriteResPairUnsupported<WriteVecShiftImmZ>;
459 defm : X86WriteResPairUnsupported<WriteVarVecShift>;
460 defm : X86WriteResPairUnsupported<WriteVarVecShiftY>;
461 defm : X86WriteResPairUnsupported<WriteVarVecShiftZ>;
462 defm : JWriteResFpuPair<WriteVecIMul,     [JFPU0, JVIMUL], 2>;
463 defm : JWriteResFpuPair<WriteVecIMulX,    [JFPU0, JVIMUL], 2>;
464 defm : X86WriteResPairUnsupported<WriteVecIMulY>;
465 defm : X86WriteResPairUnsupported<WriteVecIMulZ>;
466 defm : JWriteResFpuPair<WritePMULLD,      [JFPU0, JFPU01, JVIMUL, JVALU], 4, [2, 1, 2, 1], 3>;
467 defm : X86WriteResPairUnsupported<WritePMULLDY>;
468 defm : X86WriteResPairUnsupported<WritePMULLDZ>;
469 defm : JWriteResFpuPair<WriteMPSAD,       [JFPU0, JVIMUL], 3, [1, 2]>;
470 defm : X86WriteResPairUnsupported<WriteMPSADY>;
471 defm : X86WriteResPairUnsupported<WriteMPSADZ>;
472 defm : JWriteResFpuPair<WritePSADBW,      [JFPU01, JVALU], 2>;
473 defm : JWriteResFpuPair<WritePSADBWX,     [JFPU01, JVALU], 2>;
474 defm : X86WriteResPairUnsupported<WritePSADBWY>;
475 defm : X86WriteResPairUnsupported<WritePSADBWZ>;
476 defm : JWriteResFpuPair<WritePHMINPOS,    [JFPU0,  JVALU], 2>;
477 defm : JWriteResFpuPair<WriteShuffle,     [JFPU01, JVALU], 1>;
478 defm : JWriteResFpuPair<WriteShuffleX,    [JFPU01, JVALU], 1>;
479 defm : X86WriteResPairUnsupported<WriteShuffleY>;
480 defm : X86WriteResPairUnsupported<WriteShuffleZ>;
481 defm : JWriteResFpuPair<WriteVarShuffle,  [JFPU01, JVALU], 2, [1, 4], 3>;
482 defm : JWriteResFpuPair<WriteVarShuffleX, [JFPU01, JVALU], 2, [1, 4], 3>;
483 defm : X86WriteResPairUnsupported<WriteVarShuffleY>;
484 defm : X86WriteResPairUnsupported<WriteVarShuffleZ>;
485 defm : JWriteResFpuPair<WriteBlend,       [JFPU01, JVALU], 1>;
486 defm : X86WriteResPairUnsupported<WriteBlendY>;
487 defm : X86WriteResPairUnsupported<WriteBlendZ>;
488 defm : JWriteResFpuPair<WriteVarBlend,    [JFPU01, JVALU], 2, [1, 4], 3>;
489 defm : X86WriteResPairUnsupported<WriteVarBlendY>;
490 defm : X86WriteResPairUnsupported<WriteVarBlendZ>;
491 defm : JWriteResFpuPair<WriteVecLogic,    [JFPU01, JVALU], 1>;
492 defm : JWriteResFpuPair<WriteVecLogicX,   [JFPU01, JVALU], 1>;
493 defm : X86WriteResPairUnsupported<WriteVecLogicY>;
494 defm : X86WriteResPairUnsupported<WriteVecLogicZ>;
495 defm : JWriteResFpuPair<WriteVecTest,     [JFPU0, JFPA, JALU0], 3>;
496 defm : JWriteResYMMPair<WriteVecTestY,    [JFPU01, JFPX, JFPA, JALU0], 4, [2, 2, 2, 1], 3>;
497 defm : X86WriteResPairUnsupported<WriteVecTestZ>;
498 defm : X86WriteResPairUnsupported<WriteShuffle256>;
499 defm : X86WriteResPairUnsupported<WriteVarShuffle256>;
501 ////////////////////////////////////////////////////////////////////////////////
502 // Vector insert/extract operations.
503 ////////////////////////////////////////////////////////////////////////////////
505 defm : X86WriteRes<WriteVecInsert,      [JFPU01, JVALU], 7, [1,1], 2>;
506 defm : X86WriteRes<WriteVecInsertLd,    [JFPU01, JVALU, JLAGU], 4, [1,1,1], 1>;
507 defm : X86WriteRes<WriteVecExtract,     [JFPU0, JFPA, JALU0], 3, [1,1,1], 1>;
508 defm : X86WriteRes<WriteVecExtractSt,   [JFPU1, JSTC, JSAGU], 3, [1,1,1], 1>;
510 ////////////////////////////////////////////////////////////////////////////////
511 // SSE42 String instructions.
512 ////////////////////////////////////////////////////////////////////////////////
514 defm : JWriteResFpuPair<WritePCmpIStrI, [JFPU1, JVALU1, JFPA, JALU0], 7, [1, 2, 1, 1], 3>;
515 defm : JWriteResFpuPair<WritePCmpIStrM, [JFPU1, JVALU1, JFPA, JALU0], 8, [1, 2, 1, 1], 3>;
516 defm : JWriteResFpuPair<WritePCmpEStrI, [JFPU1, JSAGU, JLAGU, JVALU, JVALU1, JFPA, JALU0], 14, [1, 2, 2, 6, 4, 1, 1], 9>;
517 defm : JWriteResFpuPair<WritePCmpEStrM, [JFPU1, JSAGU, JLAGU, JVALU, JVALU1, JFPA, JALU0], 14, [1, 2, 2, 6, 4, 1, 1], 9>;
519 ////////////////////////////////////////////////////////////////////////////////
520 // MOVMSK Instructions.
521 ////////////////////////////////////////////////////////////////////////////////
523 def  : WriteRes<WriteFMOVMSK,    [JFPU0, JFPA, JALU0]> { let Latency = 3; }
524 def  : WriteRes<WriteVecMOVMSK,  [JFPU0, JFPA, JALU0]> { let Latency = 3; }
525 defm : X86WriteResUnsupported<WriteVecMOVMSKY>;
526 def  : WriteRes<WriteMMXMOVMSK,  [JFPU0, JFPA, JALU0]> { let Latency = 3; }
528 ////////////////////////////////////////////////////////////////////////////////
529 // AES Instructions.
530 ////////////////////////////////////////////////////////////////////////////////
532 defm : JWriteResFpuPair<WriteAESIMC,      [JFPU0, JVIMUL], 2>;
533 defm : JWriteResFpuPair<WriteAESKeyGen,   [JFPU0, JVIMUL], 2>;
534 defm : JWriteResFpuPair<WriteAESDecEnc,   [JFPU0, JVIMUL], 3, [1, 1], 2>;
536 ////////////////////////////////////////////////////////////////////////////////
537 // Horizontal add/sub  instructions.
538 ////////////////////////////////////////////////////////////////////////////////
540 defm : JWriteResFpuPair<WriteFHAdd,         [JFPU0, JFPA], 3>;
541 defm : JWriteResYMMPair<WriteFHAddY,        [JFPU0, JFPA], 3, [2,2], 2>;
542 defm : JWriteResFpuPair<WritePHAdd,       [JFPU01, JVALU], 1>;
543 defm : JWriteResFpuPair<WritePHAddX,      [JFPU01, JVALU], 1>;
544 defm : X86WriteResPairUnsupported<WritePHAddY>;
546 ////////////////////////////////////////////////////////////////////////////////
547 // Carry-less multiplication instructions.
548 ////////////////////////////////////////////////////////////////////////////////
550 defm : JWriteResFpuPair<WriteCLMul,       [JFPU0, JVIMUL], 2>;
552 ////////////////////////////////////////////////////////////////////////////////
553 // SSE4A instructions.
554 ////////////////////////////////////////////////////////////////////////////////
556 def JWriteINSERTQ: SchedWriteRes<[JFPU01, JVALU]> {
557   let Latency = 2;
558   let ResourceCycles = [1, 4];
560 def : InstRW<[JWriteINSERTQ], (instrs INSERTQ, INSERTQI)>;
562 ////////////////////////////////////////////////////////////////////////////////
563 // AVX instructions.
564 ////////////////////////////////////////////////////////////////////////////////
566 def JWriteVecExtractF128: SchedWriteRes<[JFPU01, JFPX]>;
567 def : InstRW<[JWriteVecExtractF128], (instrs VEXTRACTF128rr)>;
569 def JWriteVBROADCASTYLd: SchedWriteRes<[JLAGU, JFPU01, JFPX]> {
570   let Latency = 6;
571   let ResourceCycles = [1, 2, 4];
572   let NumMicroOps = 2;
574 def : InstRW<[JWriteVBROADCASTYLd], (instrs VBROADCASTSDYrm,
575                                             VBROADCASTSSYrm,
576                                             VBROADCASTF128)>;
578 def JWriteJVZEROALL: SchedWriteRes<[]> {
579   let Latency = 90;
580   let NumMicroOps = 73;
582 def : InstRW<[JWriteJVZEROALL], (instrs VZEROALL)>;
584 def JWriteJVZEROUPPER: SchedWriteRes<[]> {
585   let Latency = 46;
586   let NumMicroOps = 37;
588 def : InstRW<[JWriteJVZEROUPPER], (instrs VZEROUPPER)>;
590 ///////////////////////////////////////////////////////////////////////////////
591 //  SchedWriteVariant definitions.
592 ///////////////////////////////////////////////////////////////////////////////
594 def JWriteZeroLatency : SchedWriteRes<[]> {
595   let Latency = 0;
598 // Certain instructions that use the same register for both source
599 // operands do not have a real dependency on the previous contents of the
600 // register, and thus, do not have to wait before completing. They can be
601 // optimized out at register renaming stage.
602 // Reference: Section 10.8 of the "Software Optimization Guide for AMD Family
603 // 15h Processors".
604 // Reference: Agner's Fog "The microarchitecture of Intel, AMD and VIA CPUs",
605 // Section 21.8 [Dependency-breaking instructions].
607 def JWriteZeroIdiom : SchedWriteVariant<[
608     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
609     SchedVar<NoSchedPred,                          [WriteALU]>
611 def : InstRW<[JWriteZeroIdiom], (instrs SUB32rr, SUB64rr,
612                                         XOR32rr, XOR64rr)>;
614 def JWriteFZeroIdiom : SchedWriteVariant<[
615     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
616     SchedVar<NoSchedPred,                          [WriteFLogic]>
618 def : InstRW<[JWriteFZeroIdiom], (instrs XORPSrr, VXORPSrr, XORPDrr, VXORPDrr,
619                                          ANDNPSrr, VANDNPSrr,
620                                          ANDNPDrr, VANDNPDrr)>;
622 def JWriteVZeroIdiomLogic : SchedWriteVariant<[
623     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
624     SchedVar<NoSchedPred,                          [WriteVecLogic]>
626 def : InstRW<[JWriteVZeroIdiomLogic], (instrs MMX_PXORirr, MMX_PANDNirr)>;
628 def JWriteVZeroIdiomLogicX : SchedWriteVariant<[
629     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
630     SchedVar<NoSchedPred,                          [WriteVecLogicX]>
632 def : InstRW<[JWriteVZeroIdiomLogicX], (instrs PXORrr, VPXORrr,
633                                                PANDNrr, VPANDNrr)>;
635 def JWriteVZeroIdiomALU : SchedWriteVariant<[
636     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
637     SchedVar<NoSchedPred,                          [WriteVecALU]>
639 def : InstRW<[JWriteVZeroIdiomALU], (instrs MMX_PSUBBirr, MMX_PSUBDirr,
640                                             MMX_PSUBQirr, MMX_PSUBWirr,
641                                             MMX_PCMPGTBirr, MMX_PCMPGTDirr,
642                                             MMX_PCMPGTWirr)>;
644 def JWriteVZeroIdiomALUX : SchedWriteVariant<[
645     SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
646     SchedVar<NoSchedPred,                          [WriteVecALUX]>
648 def : InstRW<[JWriteVZeroIdiomALUX], (instrs PSUBBrr, VPSUBBrr,
649                                              PSUBDrr, VPSUBDrr,
650                                              PSUBQrr, VPSUBQrr,
651                                              PSUBWrr, VPSUBWrr,
652                                              PCMPGTBrr, VPCMPGTBrr,
653                                              PCMPGTDrr, VPCMPGTDrr,
654                                              PCMPGTQrr, VPCMPGTQrr,
655                                              PCMPGTWrr, VPCMPGTWrr)>;
657 // This write is used for slow LEA instructions.
658 def JWrite3OpsLEA : SchedWriteRes<[JALU1, JSAGU]> {
659   let Latency = 2;
662 // On Jaguar, a slow LEA is either a 3Ops LEA (base, index, offset), or an LEA
663 // with a `Scale` value different than 1.
664 def JSlowLEAPredicate : MCSchedPredicate<
665   CheckAny<[
666     // A 3-operand LEA (base, index, offset).
667     IsThreeOperandsLEAFn,
668     // An LEA with a "Scale" different than 1.
669     CheckAll<[
670       CheckIsImmOperand<2>,
671       CheckNot<CheckImmOperand<2, 1>>
672     ]>
673   ]>
676 def JWriteLEA : SchedWriteVariant<[
677     SchedVar<JSlowLEAPredicate, [JWrite3OpsLEA]>,
678     SchedVar<NoSchedPred,       [WriteLEA]>
681 def : InstRW<[JWriteLEA], (instrs LEA32r, LEA64r, LEA64_32r)>;
683 def JSlowLEA16r : SchedWriteRes<[JALU01]> {
684   let Latency = 3;
685   let ResourceCycles = [4];
688 def : InstRW<[JSlowLEA16r], (instrs LEA16r)>;
690 } // SchedModel