1 //=- X86ScheduleBtVer2.td - X86 BtVer2 (Jaguar) Scheduling ---*- tablegen -*-=//
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
7 //===----------------------------------------------------------------------===//
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.
19 let MicroOpBufferSize = 64; // Retire Control Unit
20 let LoadLatency = 5; // FPU latency (worse case cf Integer 3 cycle latency)
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
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]> {
78 def JLSAGU : ProcResGroup<[JLAGU, JSAGU]> {
83 def JFPU01 : ProcResGroup<[JFPU0, JFPU1]> {
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
121 multiclass JWriteResIntPair<X86FoldableSchedWrite SchedRW,
122 list<ProcResourceKind> ExePorts,
123 int Lat, list<int> Res = [], int UOps = 1,
125 // Register variant is using a single cycle on ExePort.
126 def : WriteRes<SchedRW, ExePorts> {
128 let ReleaseAtCycles = Res;
129 let NumMicroOps = UOps;
132 // Memory variant also uses a cycle on JLAGU and adds 3 cycles to the
134 def : WriteRes<SchedRW.Folded, !listconcat([JLAGU], ExePorts)> {
135 let Latency = !add(Lat, 3);
136 let ReleaseAtCycles = !if(!empty(Res), [], !listconcat([1], Res));
137 let NumMicroOps = !add(UOps, LoadUOps);
141 multiclass JWriteResFpuPair<X86FoldableSchedWrite SchedRW,
142 list<ProcResourceKind> ExePorts,
143 int Lat, list<int> Res = [], int UOps = 1,
145 // Register variant is using a single cycle on ExePort.
146 def : WriteRes<SchedRW, ExePorts> {
148 let ReleaseAtCycles = Res;
149 let NumMicroOps = UOps;
152 // Memory variant also uses a cycle on JLAGU and adds 5 cycles to the
154 def : WriteRes<SchedRW.Folded, !listconcat([JLAGU], ExePorts)> {
155 let Latency = !add(Lat, 5);
156 let ReleaseAtCycles = !if(!empty(Res), [], !listconcat([1], Res));
157 let NumMicroOps = !add(UOps, LoadUOps);
161 multiclass JWriteResYMMPair<X86FoldableSchedWrite SchedRW,
162 list<ProcResourceKind> ExePorts,
163 int Lat, list<int> Res = [2], int UOps = 2,
165 // Register variant is using a single cycle on ExePort.
166 def : WriteRes<SchedRW, ExePorts> {
168 let ReleaseAtCycles = Res;
169 let NumMicroOps = UOps;
172 // Memory variant also uses 2 cycles on JLAGU and adds 5 cycles to the
174 def : WriteRes<SchedRW.Folded, !listconcat([JLAGU], ExePorts)> {
175 let Latency = !add(Lat, 5);
176 let ReleaseAtCycles = !listconcat([2], Res);
177 let NumMicroOps = !add(UOps, LoadUOps);
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, most RMW
184 // instructions don't need an extra uop. ALU RMW operations don't seem to
185 // benefit from STLF, and their observed latency is 6cy. That is the reason why
186 // this write adds two extra cycles (instead of just 1cy for the store).
187 defm : X86WriteRes<WriteRMW, [JSAGU], 2, [1], 0>;
189 ////////////////////////////////////////////////////////////////////////////////
191 ////////////////////////////////////////////////////////////////////////////////
193 defm : JWriteResIntPair<WriteALU, [JALU01], 1>;
194 defm : JWriteResIntPair<WriteADC, [JALU01], 1, [2]>;
196 defm : X86WriteRes<WriteBSWAP32, [JALU01], 1, [1], 1>;
197 defm : X86WriteRes<WriteBSWAP64, [JALU01], 1, [1], 1>;
198 defm : X86WriteRes<WriteCMPXCHG, [JALU01], 3, [3], 5>;
199 defm : X86WriteRes<WriteCMPXCHGRMW, [JALU01, JSAGU, JLAGU], 11, [3, 1, 1], 6>;
200 defm : X86WriteRes<WriteXCHG, [JALU01], 1, [2], 2>;
202 defm : JWriteResIntPair<WriteIMul8, [JALU1, JMul], 3, [1, 1], 1>;
203 defm : JWriteResIntPair<WriteIMul16, [JALU1, JMul], 3, [1, 3], 3>;
204 defm : JWriteResIntPair<WriteIMul16Imm, [JALU1, JMul], 4, [1, 2], 2>;
205 defm : JWriteResIntPair<WriteIMul16Reg, [JALU1, JMul], 3, [1, 1], 1>;
206 defm : JWriteResIntPair<WriteIMul32, [JALU1, JMul], 3, [1, 2], 2>;
207 defm : JWriteResIntPair<WriteIMul32Imm, [JALU1, JMul], 3, [1, 1], 1>;
208 defm : JWriteResIntPair<WriteIMul32Reg, [JALU1, JMul], 3, [1, 1], 1>;
209 defm : JWriteResIntPair<WriteIMul64, [JALU1, JMul], 6, [1, 4], 2>;
210 defm : JWriteResIntPair<WriteIMul64Imm, [JALU1, JMul], 6, [1, 4], 1>;
211 defm : JWriteResIntPair<WriteIMul64Reg, [JALU1, JMul], 6, [1, 4], 1>;
212 defm : X86WriteResUnsupported<WriteIMulH>;
213 defm : X86WriteResUnsupported<WriteIMulHLd>;
214 defm : X86WriteResPairUnsupported<WriteMULX32>;
215 defm : X86WriteResPairUnsupported<WriteMULX64>;
217 defm : JWriteResIntPair<WriteDiv8, [JALU1, JDiv], 12, [1, 12], 1>;
218 defm : JWriteResIntPair<WriteDiv16, [JALU1, JDiv], 17, [1, 17], 2>;
219 defm : JWriteResIntPair<WriteDiv32, [JALU1, JDiv], 25, [1, 25], 2>;
220 defm : JWriteResIntPair<WriteDiv64, [JALU1, JDiv], 41, [1, 41], 2>;
221 defm : JWriteResIntPair<WriteIDiv8, [JALU1, JDiv], 12, [1, 12], 1>;
222 defm : JWriteResIntPair<WriteIDiv16, [JALU1, JDiv], 17, [1, 17], 2>;
223 defm : JWriteResIntPair<WriteIDiv32, [JALU1, JDiv], 25, [1, 25], 2>;
224 defm : JWriteResIntPair<WriteIDiv64, [JALU1, JDiv], 41, [1, 41], 2>;
226 defm : JWriteResIntPair<WriteCRC32, [JALU01], 3, [4], 3>;
228 defm : JWriteResIntPair<WriteCMOV, [JALU01], 1>; // Conditional move.
229 defm : X86WriteRes<WriteFCMOV, [JFPU0, JFPA], 3, [1,1], 1>; // x87 conditional move.
230 def : WriteRes<WriteSETCC, [JALU01]>; // Setcc.
231 def : WriteRes<WriteSETCCStore, [JALU01,JSAGU]>;
232 def : WriteRes<WriteLAHFSAHF, [JALU01]>;
234 defm : X86WriteRes<WriteBitTest, [JALU01], 1, [1], 1>;
235 defm : X86WriteRes<WriteBitTestImmLd, [JALU01,JLAGU], 4, [1,1], 1>;
236 defm : X86WriteRes<WriteBitTestRegLd, [JALU01,JLAGU], 4, [1,1], 5>;
237 defm : X86WriteRes<WriteBitTestSet, [JALU01], 1, [1], 2>;
238 defm : X86WriteRes<WriteBitTestSetImmLd, [JALU01,JLAGU], 4, [1,1], 4>;
239 defm : X86WriteRes<WriteBitTestSetRegLd, [JALU01,JLAGU], 4, [1,1], 8>;
241 // This is for simple LEAs with one or two input operands.
242 def : WriteRes<WriteLEA, [JALU01]>;
245 defm : JWriteResIntPair<WriteBSF, [JALU01], 4, [8], 7>;
246 defm : JWriteResIntPair<WriteBSR, [JALU01], 5, [8], 8>;
247 defm : JWriteResIntPair<WritePOPCNT, [JALU01], 1>;
248 defm : JWriteResIntPair<WriteLZCNT, [JALU01], 1>;
249 defm : JWriteResIntPair<WriteTZCNT, [JALU01], 2, [2], 2>;
251 // BMI1 BEXTR/BLS, BMI2 BZHI
252 defm : JWriteResIntPair<WriteBEXTR, [JALU01], 1>;
253 defm : JWriteResIntPair<WriteBLS, [JALU01], 2, [2], 2>;
254 defm : X86WriteResPairUnsupported<WriteBZHI>;
256 ////////////////////////////////////////////////////////////////////////////////
257 // Integer shifts and rotates.
258 ////////////////////////////////////////////////////////////////////////////////
260 defm : JWriteResIntPair<WriteShift, [JALU01], 1>;
261 defm : JWriteResIntPair<WriteShiftCL, [JALU01], 1>;
262 defm : JWriteResIntPair<WriteRotate, [JALU01], 1>;
263 defm : JWriteResIntPair<WriteRotateCL, [JALU01], 1>;
266 defm : X86WriteRes<WriteSHDrri, [JALU01], 3, [6], 6>;
267 defm : X86WriteRes<WriteSHDrrcl,[JALU01], 4, [8], 7>;
268 defm : X86WriteRes<WriteSHDmri, [JLAGU, JALU01], 9, [1, 22], 8>;
269 defm : X86WriteRes<WriteSHDmrcl,[JLAGU, JALU01], 9, [1, 22], 8>;
271 ////////////////////////////////////////////////////////////////////////////////
272 // Loads, stores, and moves, not folded with other operations.
273 ////////////////////////////////////////////////////////////////////////////////
275 def : WriteRes<WriteLoad, [JLAGU]> { let Latency = 3; }
276 def : WriteRes<WriteStore, [JSAGU]>;
277 def : WriteRes<WriteStoreNT, [JSAGU]>;
278 def : WriteRes<WriteMove, [JALU01]>;
279 defm : X86WriteResUnsupported<WriteVecMaskedGatherWriteback>;
282 def : WriteRes<WriteLDMXCSR, [JLAGU]> { let Latency = 3; }
283 def : WriteRes<WriteSTMXCSR, [JSAGU]>;
285 // Treat misc copies as a move.
286 def : InstRW<[WriteMove], (instrs COPY)>;
288 ////////////////////////////////////////////////////////////////////////////////
289 // Idioms that clear a register, like xorps %xmm0, %xmm0.
290 // These can often bypass execution ports completely.
291 ////////////////////////////////////////////////////////////////////////////////
293 def : WriteRes<WriteZero, []>;
295 ////////////////////////////////////////////////////////////////////////////////
296 // Branches don't produce values, so they have no latency, but they still
297 // consume resources. Indirect branches can fold loads.
298 ////////////////////////////////////////////////////////////////////////////////
300 defm : JWriteResIntPair<WriteJump, [JALU01], 1>;
302 ////////////////////////////////////////////////////////////////////////////////
303 // Special case scheduling classes.
304 ////////////////////////////////////////////////////////////////////////////////
306 def : WriteRes<WriteSystem, [JALU01]> { let Latency = 100; }
307 def : WriteRes<WriteMicrocoded, [JALU01]> { let Latency = 100; }
308 def : WriteRes<WriteFence, [JSAGU]>;
310 // Nops don't have dependencies, so there's no actual latency, but we set this
311 // to '1' to tell the scheduler that the nop uses an ALU slot for a cycle.
312 def : WriteRes<WriteNop, [JALU01]> { let Latency = 1; }
314 def JWriteCMPXCHG8rr : SchedWriteRes<[JALU01]> {
316 let ReleaseAtCycles = [3];
320 def JWriteLOCK_CMPXCHG8rm : SchedWriteRes<[JALU01, JLAGU, JSAGU]> {
322 let ReleaseAtCycles = [3,16,16];
326 def JWriteLOCK_CMPXCHGrm : SchedWriteRes<[JALU01, JLAGU, JSAGU]> {
328 let ReleaseAtCycles = [3,17,17];
332 def JWriteCMPXCHG8rm : SchedWriteRes<[JALU01, JLAGU, JSAGU]> {
334 let ReleaseAtCycles = [3,1,1];
338 def JWriteCMPXCHG8B : SchedWriteRes<[JALU01, JLAGU, JSAGU]> {
340 let ReleaseAtCycles = [3,1,1];
341 let NumMicroOps = 18;
344 def JWriteCMPXCHG16B : SchedWriteRes<[JALU01, JLAGU, JSAGU]> {
346 let ReleaseAtCycles = [6,1,1];
347 let NumMicroOps = 28;
350 def JWriteLOCK_CMPXCHG8B : SchedWriteRes<[JALU01, JLAGU, JSAGU]> {
352 let ReleaseAtCycles = [3,19,19];
353 let NumMicroOps = 18;
356 def JWriteLOCK_CMPXCHG16B : SchedWriteRes<[JALU01, JLAGU, JSAGU]> {
358 let ReleaseAtCycles = [6,38,38];
359 let NumMicroOps = 28;
362 def JWriteCMPXCHGVariant : SchedWriteVariant<[
363 SchedVar<MCSchedPredicate<IsAtomicCompareAndSwap8B>, [JWriteLOCK_CMPXCHG8B]>,
364 SchedVar<MCSchedPredicate<IsAtomicCompareAndSwap16B>, [JWriteLOCK_CMPXCHG16B]>,
365 SchedVar<MCSchedPredicate<IsAtomicCompareAndSwap_8>, [JWriteLOCK_CMPXCHG8rm]>,
366 SchedVar<MCSchedPredicate<IsAtomicCompareAndSwap>, [JWriteLOCK_CMPXCHGrm]>,
367 SchedVar<MCSchedPredicate<IsCompareAndSwap8B>, [JWriteCMPXCHG8B]>,
368 SchedVar<MCSchedPredicate<IsCompareAndSwap16B>, [JWriteCMPXCHG16B]>,
369 SchedVar<MCSchedPredicate<IsRegMemCompareAndSwap_8>, [JWriteCMPXCHG8rm]>,
370 SchedVar<MCSchedPredicate<IsRegMemCompareAndSwap>, [WriteCMPXCHGRMW]>,
371 SchedVar<MCSchedPredicate<IsRegRegCompareAndSwap_8>, [JWriteCMPXCHG8rr]>,
372 SchedVar<NoSchedPred, [WriteCMPXCHG]>
375 // The first five reads are contributed by the memory load operand.
376 // We ignore those reads and set a read-advance for the other input operands
377 // including the implicit read of RAX.
378 def : InstRW<[JWriteCMPXCHGVariant,
379 ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault,
380 ReadAfterLd, ReadAfterLd], (instrs LCMPXCHG8, LCMPXCHG16,
381 LCMPXCHG32, LCMPXCHG64,
382 CMPXCHG8rm, CMPXCHG16rm,
383 CMPXCHG32rm, CMPXCHG64rm)>;
385 def : InstRW<[JWriteCMPXCHGVariant], (instrs CMPXCHG8rr, CMPXCHG16rr,
386 CMPXCHG32rr, CMPXCHG64rr)>;
388 def : InstRW<[JWriteCMPXCHGVariant,
389 // Ignore reads contributed by the memory operand.
390 ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault,
391 // Add a read-advance to every implicit register read.
392 ReadAfterLd, ReadAfterLd, ReadAfterLd, ReadAfterLd], (instrs LCMPXCHG8B, LCMPXCHG16B,
393 CMPXCHG8B, CMPXCHG16B)>;
395 def JWriteLOCK_ALURMW : SchedWriteRes<[JALU01, JLAGU, JSAGU]> {
397 let ReleaseAtCycles = [1,19,19];
401 def JWriteLOCK_ALURMWVariant : SchedWriteVariant<[
402 SchedVar<MCSchedPredicate<CheckLockPrefix>, [JWriteLOCK_ALURMW]>,
403 SchedVar<NoSchedPred, [WriteALURMW]>
405 def : InstRW<[JWriteLOCK_ALURMWVariant], (instrs INC8m, INC16m, INC32m, INC64m,
406 DEC8m, DEC16m, DEC32m, DEC64m,
407 NOT8m, NOT16m, NOT32m, NOT64m,
408 NEG8m, NEG16m, NEG32m, NEG64m)>;
410 def JWriteXCHG8rr_XADDrr : SchedWriteRes<[JALU01]> {
412 let ReleaseAtCycles = [3];
415 def : InstRW<[JWriteXCHG8rr_XADDrr], (instrs XCHG8rr, XADD8rr, XADD16rr,
416 XADD32rr, XADD64rr)>;
418 // This write defines the latency of the in/out register operand of a non-atomic
419 // XADDrm. This is the first of a pair of writes that model non-atomic
420 // XADDrm instructions (the second write definition is JWriteXADDrm_LdSt_Part).
422 // We need two writes because the instruction latency differs from the output
423 // register operand latency. In particular, the first write describes the first
424 // (and only) output register operand of the instruction. However, the
425 // instruction latency is set to the MAX of all the write latencies. That's why
426 // a second write is needed in this case (see example below).
429 // XADD %ecx, (%rsp) ## Instruction latency: 11cy
430 // ## ECX write Latency: 3cy
432 // Register ECX becomes available in 3 cycles. That is because the value of ECX
433 // is exchanged with the value read from the stack pointer, and the load-to-use
434 // latency is assumed to be 3cy.
435 def JWriteXADDrm_XCHG_Part : SchedWriteRes<[JALU01]> {
436 let Latency = 3; // load-to-use latency
437 let ReleaseAtCycles = [3];
441 // This write defines the latency of the in/out register operand of an atomic
442 // XADDrm. This is the first of a sequence of two writes used to model atomic
443 // XADD instructions. The second write of the sequence is JWriteXCHGrm_LdSt_Part.
447 // LOCK XADD %ecx, (%rsp) ## Instruction Latency: 16cy
448 // ## ECX write Latency: 11cy
450 // The value of ECX becomes available only after 11cy from the start of
451 // execution. This write is used to specifically set that operand latency.
452 def JWriteLOCK_XADDrm_XCHG_Part : SchedWriteRes<[JALU01]> {
454 let ReleaseAtCycles = [3];
458 // This write defines the latency of the in/out register operand of an atomic
459 // XCHGrm. This write is the first of a sequence of two writes that describe
460 // atomic XCHG operations. We need two writes because the instruction latency
461 // differs from the output register write latency. We want to make sure that
462 // the output register operand becomes visible after 11cy. However, we want to
463 // set the instruction latency to 16cy.
464 def JWriteXCHGrm_XCHG_Part : SchedWriteRes<[JALU01]> {
466 let ReleaseAtCycles = [2];
470 def JWriteXADDrm_LdSt_Part : SchedWriteRes<[JLAGU, JSAGU]> {
472 let ReleaseAtCycles = [1, 1];
476 def JWriteXCHGrm_LdSt_Part : SchedWriteRes<[JLAGU, JSAGU]> {
478 let ReleaseAtCycles = [16, 16];
482 def JWriteXADDrm_Part1 : SchedWriteVariant<[
483 SchedVar<MCSchedPredicate<CheckLockPrefix>, [JWriteLOCK_XADDrm_XCHG_Part]>,
484 SchedVar<NoSchedPred, [JWriteXADDrm_XCHG_Part]>
487 def JWriteXADDrm_Part2 : SchedWriteVariant<[
488 SchedVar<MCSchedPredicate<CheckLockPrefix>, [JWriteXCHGrm_LdSt_Part]>,
489 SchedVar<NoSchedPred, [JWriteXADDrm_LdSt_Part]>
492 def : InstRW<[JWriteXADDrm_Part1, JWriteXADDrm_Part2, ReadAfterLd],
493 (instrs XADD8rm, XADD16rm, XADD32rm, XADD64rm,
494 LXADD8, LXADD16, LXADD32, LXADD64)>;
496 def : InstRW<[JWriteXCHGrm_XCHG_Part, JWriteXCHGrm_LdSt_Part, ReadAfterLd],
497 (instrs XCHG8rm, XCHG16rm, XCHG32rm, XCHG64rm)>;
500 ////////////////////////////////////////////////////////////////////////////////
501 // Floating point. This covers both scalar and vector operations.
502 ////////////////////////////////////////////////////////////////////////////////
504 defm : X86WriteRes<WriteFLD0, [JFPU1, JSTC], 3, [1,1], 1>;
505 defm : X86WriteRes<WriteFLD1, [JFPU1, JSTC], 3, [1,1], 1>;
506 defm : X86WriteRes<WriteFLDC, [JFPU1, JSTC], 3, [1,1], 1>;
507 defm : X86WriteRes<WriteFLoad, [JLAGU, JFPU01, JFPX], 5, [1, 1, 1], 1>;
508 defm : X86WriteRes<WriteFLoadX, [JLAGU], 5, [1], 1>;
509 defm : X86WriteRes<WriteFLoadY, [JLAGU], 5, [2], 2>;
510 defm : X86WriteRes<WriteFMaskedLoad, [JLAGU, JFPU01, JFPX], 6, [1, 2, 2], 1>;
511 defm : X86WriteRes<WriteFMaskedLoadY, [JLAGU, JFPU01, JFPX], 6, [2, 4, 4], 2>;
513 defm : X86WriteRes<WriteFStore, [JSAGU, JFPU1, JSTC], 2, [1, 1, 1], 1>;
514 defm : X86WriteRes<WriteFStoreX, [JSAGU, JFPU1, JSTC], 1, [1, 1, 1], 1>;
515 defm : X86WriteRes<WriteFStoreY, [JSAGU, JFPU1, JSTC], 1, [2, 2, 2], 2>;
516 defm : X86WriteRes<WriteFStoreNT, [JSAGU, JFPU1, JSTC], 3, [1, 1, 1], 1>;
517 defm : X86WriteRes<WriteFStoreNTX, [JSAGU, JFPU1, JSTC], 3, [1, 1, 1], 1>;
518 defm : X86WriteRes<WriteFStoreNTY, [JSAGU, JFPU1, JSTC], 3, [2, 2, 2], 1>;
520 defm : X86WriteRes<WriteFMaskedStore32, [JFPU0, JFPA, JFPU1, JSTC, JLAGU, JSAGU, JALU01], 16, [1,1, 5, 5,4,4,4], 19>;
521 defm : X86WriteRes<WriteFMaskedStore64, [JFPU0, JFPA, JFPU1, JSTC, JLAGU, JSAGU, JALU01], 13, [1,1, 2, 2,2,2,2], 10>;
522 defm : X86WriteRes<WriteFMaskedStore32Y, [JFPU0, JFPA, JFPU1, JSTC, JLAGU, JSAGU, JALU01], 22, [1,1,10,10,8,8,8], 36>;
523 defm : X86WriteRes<WriteFMaskedStore64Y, [JFPU0, JFPA, JFPU1, JSTC, JLAGU, JSAGU, JALU01], 16, [1,1, 4, 4,4,4,4], 18>;
525 defm : X86WriteRes<WriteFMove, [JFPU01, JFPX], 1, [1, 1], 1>;
526 defm : X86WriteRes<WriteFMoveX, [JFPU01, JFPX], 1, [1, 1], 1>;
527 defm : X86WriteRes<WriteFMoveY, [JFPU01, JFPX], 1, [2, 2], 2>;
528 defm : X86WriteResUnsupported<WriteFMoveZ>;
530 defm : X86WriteRes<WriteEMMS, [JFPU01, JFPX], 2, [1, 1], 1>;
532 defm : JWriteResFpuPair<WriteFAdd, [JFPU0, JFPA], 3>;
533 defm : JWriteResFpuPair<WriteFAddX, [JFPU0, JFPA], 3>;
534 defm : JWriteResYMMPair<WriteFAddY, [JFPU0, JFPA], 3, [2,2], 2>;
535 defm : X86WriteResPairUnsupported<WriteFAddZ>;
536 defm : JWriteResFpuPair<WriteFAdd64, [JFPU0, JFPA], 3>;
537 defm : JWriteResFpuPair<WriteFAdd64X, [JFPU0, JFPA], 3>;
538 defm : JWriteResYMMPair<WriteFAdd64Y, [JFPU0, JFPA], 3, [2,2], 2>;
539 defm : X86WriteResPairUnsupported<WriteFAdd64Z>;
540 defm : JWriteResFpuPair<WriteFCmp, [JFPU0, JFPA], 2>;
541 defm : JWriteResFpuPair<WriteFCmpX, [JFPU0, JFPA], 2>;
542 defm : JWriteResYMMPair<WriteFCmpY, [JFPU0, JFPA], 2, [2,2], 2>;
543 defm : X86WriteResPairUnsupported<WriteFCmpZ>;
544 defm : JWriteResFpuPair<WriteFCmp64, [JFPU0, JFPA], 2>;
545 defm : JWriteResFpuPair<WriteFCmp64X, [JFPU0, JFPA], 2>;
546 defm : JWriteResYMMPair<WriteFCmp64Y, [JFPU0, JFPA], 2, [2,2], 2>;
547 defm : X86WriteResPairUnsupported<WriteFCmp64Z>;
548 defm : JWriteResFpuPair<WriteFCom, [JFPU0, JFPA, JALU0], 3>;
549 defm : JWriteResFpuPair<WriteFComX, [JFPU0, JFPA, JALU0], 3>;
550 defm : JWriteResFpuPair<WriteFMul, [JFPU1, JFPM], 2>;
551 defm : JWriteResFpuPair<WriteFMulX, [JFPU1, JFPM], 2>;
552 defm : JWriteResYMMPair<WriteFMulY, [JFPU1, JFPM], 2, [2,2], 2>;
553 defm : X86WriteResPairUnsupported<WriteFMulZ>;
554 defm : JWriteResFpuPair<WriteFMul64, [JFPU1, JFPM], 4, [1,2]>;
555 defm : JWriteResFpuPair<WriteFMul64X, [JFPU1, JFPM], 4, [1,2]>;
556 defm : JWriteResYMMPair<WriteFMul64Y, [JFPU1, JFPM], 4, [2,4], 2>;
557 defm : X86WriteResPairUnsupported<WriteFMul64Z>;
558 defm : X86WriteResPairUnsupported<WriteFMA>;
559 defm : X86WriteResPairUnsupported<WriteFMAX>;
560 defm : X86WriteResPairUnsupported<WriteFMAY>;
561 defm : X86WriteResPairUnsupported<WriteFMAZ>;
562 defm : JWriteResFpuPair<WriteDPPD, [JFPU1, JFPM, JFPA], 9, [1, 3, 3], 3>;
563 defm : JWriteResFpuPair<WriteDPPS, [JFPU1, JFPM, JFPA], 11, [1, 3, 3], 5>;
564 defm : JWriteResYMMPair<WriteDPPSY, [JFPU1, JFPM, JFPA], 12, [2, 6, 6], 10>;
565 defm : JWriteResFpuPair<WriteFRcp, [JFPU1, JFPM], 2>;
566 defm : JWriteResFpuPair<WriteFRcpX, [JFPU1, JFPM], 2>;
567 defm : JWriteResYMMPair<WriteFRcpY, [JFPU1, JFPM], 2, [2,2], 2>;
568 defm : X86WriteResPairUnsupported<WriteFRcpZ>;
569 defm : JWriteResFpuPair<WriteFRsqrt, [JFPU1, JFPM], 2>;
570 defm : JWriteResFpuPair<WriteFRsqrtX, [JFPU1, JFPM], 2>;
571 defm : JWriteResYMMPair<WriteFRsqrtY, [JFPU1, JFPM], 2, [2,2], 2>;
572 defm : X86WriteResPairUnsupported<WriteFRsqrtZ>;
573 defm : JWriteResFpuPair<WriteFDiv, [JFPU1, JFPM], 19, [1, 19]>;
574 defm : JWriteResFpuPair<WriteFDivX, [JFPU1, JFPM], 19, [1, 19]>;
575 defm : JWriteResYMMPair<WriteFDivY, [JFPU1, JFPM], 38, [2, 38], 2>;
576 defm : X86WriteResPairUnsupported<WriteFDivZ>;
577 defm : JWriteResFpuPair<WriteFDiv64, [JFPU1, JFPM], 19, [1, 19]>;
578 defm : JWriteResFpuPair<WriteFDiv64X, [JFPU1, JFPM], 19, [1, 19]>;
579 defm : JWriteResYMMPair<WriteFDiv64Y, [JFPU1, JFPM], 38, [2, 38], 2>;
580 defm : X86WriteResPairUnsupported<WriteFDiv64Z>;
581 defm : JWriteResFpuPair<WriteFSqrt, [JFPU1, JFPM], 21, [1, 21]>;
582 defm : JWriteResFpuPair<WriteFSqrtX, [JFPU1, JFPM], 21, [1, 21]>;
583 defm : JWriteResYMMPair<WriteFSqrtY, [JFPU1, JFPM], 42, [2, 42], 2>;
584 defm : X86WriteResPairUnsupported<WriteFSqrtZ>;
585 defm : JWriteResFpuPair<WriteFSqrt64, [JFPU1, JFPM], 27, [1, 27]>;
586 defm : JWriteResFpuPair<WriteFSqrt64X, [JFPU1, JFPM], 27, [1, 27]>;
587 defm : JWriteResYMMPair<WriteFSqrt64Y, [JFPU1, JFPM], 54, [2, 54], 2>;
588 defm : X86WriteResPairUnsupported<WriteFSqrt64Z>;
589 defm : JWriteResFpuPair<WriteFSqrt80, [JFPU1, JFPM], 35, [1, 35]>;
590 defm : JWriteResFpuPair<WriteFSign, [JFPU1, JFPM], 2>;
591 defm : JWriteResFpuPair<WriteFRnd, [JFPU1, JSTC], 3>;
592 defm : JWriteResYMMPair<WriteFRndY, [JFPU1, JSTC], 3, [2,2], 2>;
593 defm : X86WriteResPairUnsupported<WriteFRndZ>;
594 defm : JWriteResFpuPair<WriteFLogic, [JFPU01, JFPX], 1>;
595 defm : JWriteResYMMPair<WriteFLogicY, [JFPU01, JFPX], 1, [2, 2], 2>;
596 defm : X86WriteResPairUnsupported<WriteFLogicZ>;
597 defm : JWriteResFpuPair<WriteFTest, [JFPU0, JFPA, JALU0], 3>;
598 defm : JWriteResYMMPair<WriteFTestY , [JFPU01, JFPX, JFPA, JALU0], 4, [2, 2, 2, 1], 3>;
599 defm : X86WriteResPairUnsupported<WriteFTestZ>;
600 defm : JWriteResFpuPair<WriteFShuffle, [JFPU01, JFPX], 1>;
601 defm : JWriteResYMMPair<WriteFShuffleY, [JFPU01, JFPX], 1, [2, 2], 2>;
602 defm : X86WriteResPairUnsupported<WriteFShuffleZ>;
603 defm : JWriteResFpuPair<WriteFVarShuffle, [JFPU01, JFPX], 3, [1, 4], 3>; // +1cy latency.
604 defm : JWriteResYMMPair<WriteFVarShuffleY,[JFPU01, JFPX], 4, [2, 6], 6>; // +1cy latency.
605 defm : X86WriteResPairUnsupported<WriteFVarShuffleZ>;
606 defm : JWriteResFpuPair<WriteFBlend, [JFPU01, JFPX], 1>;
607 defm : JWriteResYMMPair<WriteFBlendY, [JFPU01, JFPX], 1, [2, 2], 2>;
608 defm : X86WriteResPairUnsupported<WriteFBlendZ>;
609 defm : JWriteResFpuPair<WriteFVarBlend, [JFPU01, JFPX], 2, [4, 4], 3>;
610 defm : JWriteResYMMPair<WriteFVarBlendY, [JFPU01, JFPX], 3, [6, 6], 6>;
611 defm : X86WriteResPairUnsupported<WriteFVarBlendZ>;
612 defm : JWriteResFpuPair<WriteFShuffle256, [JFPU01, JFPX], 1, [2, 2], 2>;
613 defm : X86WriteResPairUnsupported<WriteFVarShuffle256>;
615 ////////////////////////////////////////////////////////////////////////////////
617 ////////////////////////////////////////////////////////////////////////////////
619 defm : JWriteResFpuPair<WriteCvtSS2I, [JFPU1, JSTC, JFPU0, JFPA, JALU0], 7, [1,1,1,1,1], 2>;
620 defm : JWriteResFpuPair<WriteCvtPS2I, [JFPU1, JSTC], 3, [1,1], 1>;
621 defm : JWriteResYMMPair<WriteCvtPS2IY, [JFPU1, JSTC], 3, [2,2], 2>;
622 defm : X86WriteResPairUnsupported<WriteCvtPS2IZ>;
623 defm : JWriteResFpuPair<WriteCvtSD2I, [JFPU1, JSTC, JFPU0, JFPA, JALU0], 7, [1,1,1,1,1], 2>;
624 defm : JWriteResFpuPair<WriteCvtPD2I, [JFPU1, JSTC], 3, [1,1], 1>;
625 defm : JWriteResYMMPair<WriteCvtPD2IY, [JFPU1, JSTC, JFPX], 6, [2,2,4], 3>;
626 defm : X86WriteResPairUnsupported<WriteCvtPD2IZ>;
628 defm : X86WriteRes<WriteCvtI2SS, [JFPU1, JSTC], 4, [1,1], 2>;
629 defm : X86WriteRes<WriteCvtI2SSLd, [JLAGU, JFPU1, JSTC], 9, [1,1,1], 1>;
630 defm : JWriteResFpuPair<WriteCvtI2PS, [JFPU1, JSTC], 3, [1,1], 1>;
631 defm : JWriteResYMMPair<WriteCvtI2PSY, [JFPU1, JSTC], 3, [2,2], 2>;
632 defm : X86WriteResPairUnsupported<WriteCvtI2PSZ>;
633 defm : X86WriteRes<WriteCvtI2SD, [JFPU1, JSTC], 4, [1,1], 2>;
634 defm : X86WriteRes<WriteCvtI2SDLd, [JLAGU, JFPU1, JSTC], 9, [1,1,1], 1>;
635 defm : JWriteResFpuPair<WriteCvtI2PD, [JFPU1, JSTC], 3, [1,1], 1>;
636 defm : JWriteResYMMPair<WriteCvtI2PDY, [JFPU1, JSTC], 3, [2,2], 2>;
637 defm : X86WriteResPairUnsupported<WriteCvtI2PDZ>;
639 defm : JWriteResFpuPair<WriteCvtSS2SD, [JFPU1, JSTC], 7, [1,2], 2>;
640 defm : JWriteResFpuPair<WriteCvtPS2PD, [JFPU1, JSTC], 2, [1,1], 1>;
641 defm : JWriteResYMMPair<WriteCvtPS2PDY, [JFPU1, JSTC], 2, [2,2], 2>;
642 defm : X86WriteResPairUnsupported<WriteCvtPS2PDZ>;
644 defm : JWriteResFpuPair<WriteCvtSD2SS, [JFPU1, JSTC], 7, [1,2], 2>;
645 defm : JWriteResFpuPair<WriteCvtPD2PS, [JFPU1, JSTC], 3, [1,1], 1>;
646 defm : JWriteResYMMPair<WriteCvtPD2PSY, [JFPU1, JSTC, JFPX], 6, [2,2,4], 3>;
647 defm : X86WriteResPairUnsupported<WriteCvtPD2PSZ>;
649 defm : JWriteResFpuPair<WriteCvtPH2PS, [JFPU1, JSTC], 3, [1,1], 1>;
650 defm : JWriteResYMMPair<WriteCvtPH2PSY, [JFPU1, JSTC], 3, [2,2], 2>;
651 defm : X86WriteResPairUnsupported<WriteCvtPH2PSZ>;
653 defm : X86WriteRes<WriteCvtPS2PH, [JFPU1, JSTC], 3, [1,1], 1>;
654 defm : X86WriteRes<WriteCvtPS2PHY, [JFPU1, JSTC, JFPX], 6, [2,2,2], 3>;
655 defm : X86WriteResUnsupported<WriteCvtPS2PHZ>;
656 defm : X86WriteRes<WriteCvtPS2PHSt, [JFPU1, JSTC, JSAGU], 4, [1,1,1], 1>;
657 defm : X86WriteRes<WriteCvtPS2PHYSt, [JFPU1, JSTC, JFPX, JSAGU], 7, [2,2,2,1], 3>;
658 defm : X86WriteResUnsupported<WriteCvtPS2PHZSt>;
660 ////////////////////////////////////////////////////////////////////////////////
661 // Vector integer operations.
662 ////////////////////////////////////////////////////////////////////////////////
664 defm : X86WriteRes<WriteVecLoad, [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
665 defm : X86WriteRes<WriteVecLoadX, [JLAGU], 5, [1], 1>;
666 defm : X86WriteRes<WriteVecLoadY, [JLAGU], 5, [2], 2>;
667 defm : X86WriteRes<WriteVecLoadNT, [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
668 defm : X86WriteRes<WriteVecLoadNTY, [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
669 defm : X86WriteRes<WriteVecMaskedLoad, [JLAGU, JFPU01, JVALU], 6, [1, 2, 2], 1>;
670 defm : X86WriteRes<WriteVecMaskedLoadY, [JLAGU, JFPU01, JVALU], 6, [2, 4, 4], 2>;
672 defm : X86WriteRes<WriteVecStore, [JSAGU, JFPU1, JSTC], 2, [1, 1, 1], 1>;
673 defm : X86WriteRes<WriteVecStoreX, [JSAGU, JFPU1, JSTC], 1, [1, 1, 1], 1>;
674 defm : X86WriteRes<WriteVecStoreY, [JSAGU, JFPU1, JSTC], 1, [2, 2, 2], 2>;
675 defm : X86WriteRes<WriteVecStoreNT, [JSAGU, JFPU1, JSTC], 2, [1, 1, 1], 1>;
676 defm : X86WriteRes<WriteVecStoreNTY, [JSAGU, JFPU1, JSTC], 2, [2, 2, 2], 1>;
677 defm : X86WriteResUnsupported<WriteVecMaskedStore32>;
678 defm : X86WriteResUnsupported<WriteVecMaskedStore64>;
679 defm : X86WriteResUnsupported<WriteVecMaskedStore32Y>;
680 defm : X86WriteResUnsupported<WriteVecMaskedStore64Y>;
682 defm : X86WriteRes<WriteVecMove, [JFPU01, JVALU], 1, [1, 1], 1>;
683 defm : X86WriteRes<WriteVecMoveX, [JFPU01, JVALU], 1, [1, 1], 1>;
684 defm : X86WriteRes<WriteVecMoveY, [JFPU01, JVALU], 1, [2, 2], 2>;
685 defm : X86WriteResUnsupported<WriteVecMoveZ>;
686 defm : X86WriteRes<WriteVecMoveToGpr, [JFPU0, JFPA, JALU0], 4, [1, 1, 1], 1>;
687 defm : X86WriteRes<WriteVecMoveFromGpr, [JFPU01, JFPX], 8, [1, 1], 2>;
689 defm : JWriteResFpuPair<WriteVecALU, [JFPU01, JVALU], 1>;
690 defm : JWriteResFpuPair<WriteVecALUX, [JFPU01, JVALU], 1>;
691 defm : X86WriteResPairUnsupported<WriteVecALUY>;
692 defm : X86WriteResPairUnsupported<WriteVecALUZ>;
693 defm : JWriteResFpuPair<WriteVecShift, [JFPU01, JVALU], 1>;
694 defm : JWriteResFpuPair<WriteVecShiftX, [JFPU01, JVALU], 2>; // +1cy latency.
695 defm : X86WriteResPairUnsupported<WriteVecShiftY>;
696 defm : X86WriteResPairUnsupported<WriteVecShiftZ>;
697 defm : JWriteResFpuPair<WriteVecShiftImm, [JFPU01, JVALU], 1>;
698 defm : JWriteResFpuPair<WriteVecShiftImmX,[JFPU01, JVALU], 2>; // +1cy latency.
699 defm : X86WriteResPairUnsupported<WriteVecShiftImmY>;
700 defm : X86WriteResPairUnsupported<WriteVecShiftImmZ>;
701 defm : X86WriteResPairUnsupported<WriteVarVecShift>;
702 defm : X86WriteResPairUnsupported<WriteVarVecShiftY>;
703 defm : X86WriteResPairUnsupported<WriteVarVecShiftZ>;
704 defm : JWriteResFpuPair<WriteVecIMul, [JFPU0, JVIMUL], 2>;
705 defm : JWriteResFpuPair<WriteVecIMulX, [JFPU0, JVIMUL], 2>;
706 defm : X86WriteResPairUnsupported<WriteVecIMulY>;
707 defm : X86WriteResPairUnsupported<WriteVecIMulZ>;
708 defm : JWriteResFpuPair<WritePMULLD, [JFPU0, JFPU01, JVIMUL, JVALU], 4, [2, 1, 2, 1], 3>;
709 defm : X86WriteResPairUnsupported<WritePMULLDY>;
710 defm : X86WriteResPairUnsupported<WritePMULLDZ>;
711 defm : JWriteResFpuPair<WriteMPSAD, [JFPU0, JVIMUL], 3, [1, 2], 3>;
712 defm : X86WriteResPairUnsupported<WriteMPSADY>;
713 defm : X86WriteResPairUnsupported<WriteMPSADZ>;
714 defm : JWriteResFpuPair<WritePSADBW, [JFPU01, JVALU], 2>;
715 defm : JWriteResFpuPair<WritePSADBWX, [JFPU01, JVALU], 2>;
716 defm : X86WriteResPairUnsupported<WritePSADBWY>;
717 defm : X86WriteResPairUnsupported<WritePSADBWZ>;
718 defm : JWriteResFpuPair<WritePHMINPOS, [JFPU01, JVALU], 2>;
719 defm : JWriteResFpuPair<WriteShuffle, [JFPU01, JVALU], 1>;
720 defm : JWriteResFpuPair<WriteShuffleX, [JFPU01, JVALU], 1>;
721 defm : X86WriteResPairUnsupported<WriteShuffleY>;
722 defm : X86WriteResPairUnsupported<WriteShuffleZ>;
723 defm : JWriteResFpuPair<WriteVarShuffle, [JFPU01, JVALU], 2, [1, 1], 1>;
724 defm : JWriteResFpuPair<WriteVarShuffleX, [JFPU01, JVALU], 2, [1, 4], 3>;
725 defm : X86WriteResPairUnsupported<WriteVarShuffleY>;
726 defm : X86WriteResPairUnsupported<WriteVarShuffleZ>;
727 defm : JWriteResFpuPair<WriteBlend, [JFPU01, JVALU], 1>;
728 defm : X86WriteResPairUnsupported<WriteBlendY>;
729 defm : X86WriteResPairUnsupported<WriteBlendZ>;
730 defm : JWriteResFpuPair<WriteVarBlend, [JFPU01, JVALU], 2, [4, 4], 3>;
731 defm : X86WriteResPairUnsupported<WriteVarBlendY>;
732 defm : X86WriteResPairUnsupported<WriteVarBlendZ>;
733 defm : JWriteResFpuPair<WriteVecLogic, [JFPU01, JVALU], 1>;
734 defm : JWriteResFpuPair<WriteVecLogicX, [JFPU01, JVALU], 1>;
735 defm : X86WriteResPairUnsupported<WriteVecLogicY>;
736 defm : X86WriteResPairUnsupported<WriteVecLogicZ>;
737 defm : JWriteResFpuPair<WriteVecTest, [JFPU0, JFPA, JALU0], 3>;
738 defm : JWriteResYMMPair<WriteVecTestY, [JFPU01, JFPX, JFPA, JALU0], 4, [2, 2, 2, 1], 3>;
739 defm : X86WriteResPairUnsupported<WriteVecTestZ>;
740 defm : X86WriteResPairUnsupported<WriteShuffle256>;
741 defm : X86WriteResPairUnsupported<WriteVPMOV256>;
742 defm : X86WriteResPairUnsupported<WriteVarShuffle256>;
744 ////////////////////////////////////////////////////////////////////////////////
745 // Vector insert/extract operations.
746 ////////////////////////////////////////////////////////////////////////////////
748 defm : X86WriteRes<WriteVecInsert, [JFPU01, JVALU], 1, [1,1], 2>;
749 defm : X86WriteRes<WriteVecInsertLd, [JFPU01, JVALU, JLAGU], 4, [1,1,1], 1>;
750 defm : X86WriteRes<WriteVecExtract, [JFPU0, JFPA, JALU0], 3, [1,1,1], 1>;
751 defm : X86WriteRes<WriteVecExtractSt, [JFPU1, JSTC, JSAGU], 3, [1,1,1], 1>;
753 ////////////////////////////////////////////////////////////////////////////////
754 // SSE42 String instructions.
755 ////////////////////////////////////////////////////////////////////////////////
757 defm : JWriteResFpuPair<WritePCmpIStrI, [JFPU1, JVALU1, JFPU0, JFPA, JALU0], 7, [2, 2, 1, 1, 1], 3>;
758 defm : JWriteResFpuPair<WritePCmpIStrM, [JFPU1, JVALU1, JFPU0, JFPA, JALU0], 8, [2, 2, 1, 1, 1], 3>;
759 defm : JWriteResFpuPair<WritePCmpEStrI, [JFPU1, JSAGU, JLAGU, JVALU, JVALU1, JFPA, JALU0], 14, [1, 2, 2, 6, 4, 1, 1], 9>;
760 defm : JWriteResFpuPair<WritePCmpEStrM, [JFPU1, JSAGU, JLAGU, JVALU, JVALU1, JFPA, JALU0], 14, [1, 2, 2, 6, 4, 1, 1], 9>;
762 ////////////////////////////////////////////////////////////////////////////////
763 // MOVMSK Instructions.
764 ////////////////////////////////////////////////////////////////////////////////
766 def : WriteRes<WriteFMOVMSK, [JFPU0, JFPA, JALU0]> { let Latency = 3; }
767 def : WriteRes<WriteVecMOVMSK, [JFPU0, JFPA, JALU0]> { let Latency = 3; }
768 defm : X86WriteResUnsupported<WriteVecMOVMSKY>;
769 def : WriteRes<WriteMMXMOVMSK, [JFPU0, JFPA, JALU0]> { let Latency = 3; }
771 ////////////////////////////////////////////////////////////////////////////////
773 ////////////////////////////////////////////////////////////////////////////////
775 defm : JWriteResFpuPair<WriteAESIMC, [JFPU0, JVIMUL], 2>;
776 defm : JWriteResFpuPair<WriteAESKeyGen, [JFPU0, JVIMUL], 2>;
777 defm : JWriteResFpuPair<WriteAESDecEnc, [JFPU01, JVALU, JFPU0, JVIMUL], 3, [1,1,1,1], 2>;
779 ////////////////////////////////////////////////////////////////////////////////
780 // Horizontal add/sub instructions.
781 ////////////////////////////////////////////////////////////////////////////////
783 defm : JWriteResFpuPair<WriteFHAdd, [JFPU0, JFPA], 4>; // +1cy latency.
784 defm : JWriteResYMMPair<WriteFHAddY, [JFPU0, JFPA], 4, [2,2], 2>; // +1cy latency.
785 defm : JWriteResFpuPair<WritePHAdd, [JFPU01, JVALU], 1>;
786 defm : JWriteResFpuPair<WritePHAddX, [JFPU01, JVALU], 2>; // +1cy latency.
787 defm : X86WriteResPairUnsupported<WritePHAddY>;
789 ////////////////////////////////////////////////////////////////////////////////
790 // Carry-less multiplication instructions.
791 ////////////////////////////////////////////////////////////////////////////////
793 defm : JWriteResFpuPair<WriteCLMul, [JFPU0, JVIMUL], 2>;
795 ////////////////////////////////////////////////////////////////////////////////
796 // SSE4A instructions.
797 ////////////////////////////////////////////////////////////////////////////////
799 def JWriteINSERTQ: SchedWriteRes<[JFPU01, JVALU]> {
801 let ReleaseAtCycles = [1, 4];
803 def : InstRW<[JWriteINSERTQ], (instrs INSERTQ, INSERTQI)>;
805 ////////////////////////////////////////////////////////////////////////////////
807 ////////////////////////////////////////////////////////////////////////////////
809 def JWriteVecExtractF128: SchedWriteRes<[JFPU01, JFPX]>;
810 def : InstRW<[JWriteVecExtractF128], (instrs VEXTRACTF128rri)>;
812 def JWriteVBROADCASTYLd: SchedWriteRes<[JLAGU, JFPU01, JFPX]> {
814 let ReleaseAtCycles = [1, 2, 4];
817 def : InstRW<[JWriteVBROADCASTYLd], (instrs VBROADCASTSDYrm,
821 def JWriteJVZEROALL: SchedWriteRes<[]> {
823 let NumMicroOps = 73;
825 def : InstRW<[JWriteJVZEROALL], (instrs VZEROALL)>;
827 def JWriteJVZEROUPPER: SchedWriteRes<[]> {
829 let NumMicroOps = 37;
831 def : InstRW<[JWriteJVZEROUPPER], (instrs VZEROUPPER)>;
833 ///////////////////////////////////////////////////////////////////////////////
834 // SSE2/AVX Store Selected Bytes of Double Quadword - (V)MASKMOVDQ
835 ///////////////////////////////////////////////////////////////////////////////
837 def JWriteMASKMOVDQU: SchedWriteRes<[JFPU0, JFPA, JFPU1, JSTC, JLAGU, JSAGU, JALU01]> {
839 let ReleaseAtCycles = [1, 1, 2, 2, 2, 16, 42];
840 let NumMicroOps = 63;
842 def : InstRW<[JWriteMASKMOVDQU], (instrs MASKMOVDQU, MASKMOVDQU64,
843 VMASKMOVDQU, VMASKMOVDQU64)>;
845 ///////////////////////////////////////////////////////////////////////////////
846 // SchedWriteVariant definitions.
847 ///////////////////////////////////////////////////////////////////////////////
849 def JWriteZeroLatency : SchedWriteRes<[]> {
853 def JWriteZeroIdiomYmm : SchedWriteRes<[JFPU01, JFPX]> {
857 // Certain instructions that use the same register for both source
858 // operands do not have a real dependency on the previous contents of the
859 // register, and thus, do not have to wait before completing. They can be
860 // optimized out at register renaming stage.
861 // Reference: Section 10.8 of the "Software Optimization Guide for AMD Family
863 // Reference: Agner's Fog "The microarchitecture of Intel, AMD and VIA CPUs",
864 // Section 21.8 [Dependency-breaking instructions].
866 def JWriteZeroIdiom : SchedWriteVariant<[
867 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
868 SchedVar<NoSchedPred, [WriteALU]>
870 def : InstRW<[JWriteZeroIdiom], (instrs SUB32rr, SUB64rr,
873 def JWriteFZeroIdiom : SchedWriteVariant<[
874 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
875 SchedVar<NoSchedPred, [WriteFLogic]>
877 def : InstRW<[JWriteFZeroIdiom], (instrs XORPSrr, VXORPSrr, XORPDrr, VXORPDrr,
879 ANDNPDrr, VANDNPDrr)>;
881 def JWriteFZeroIdiomY : SchedWriteVariant<[
882 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroIdiomYmm]>,
883 SchedVar<NoSchedPred, [WriteFLogicY]>
885 def : InstRW<[JWriteFZeroIdiomY], (instrs VXORPSYrr, VXORPDYrr,
886 VANDNPSYrr, VANDNPDYrr)>;
888 def JWriteVZeroIdiomLogic : SchedWriteVariant<[
889 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
890 SchedVar<NoSchedPred, [WriteVecLogic]>
892 def : InstRW<[JWriteVZeroIdiomLogic], (instrs MMX_PXORrr, MMX_PANDNrr)>;
894 def JWriteVZeroIdiomLogicX : SchedWriteVariant<[
895 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
896 SchedVar<NoSchedPred, [WriteVecLogicX]>
898 def : InstRW<[JWriteVZeroIdiomLogicX], (instrs PXORrr, VPXORrr,
901 def JWriteVZeroIdiomALU : SchedWriteVariant<[
902 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
903 SchedVar<NoSchedPred, [WriteVecALU]>
905 def : InstRW<[JWriteVZeroIdiomALU], (instrs MMX_PSUBBrr, MMX_PSUBDrr,
906 MMX_PSUBQrr, MMX_PSUBWrr,
907 MMX_PSUBSBrr, MMX_PSUBSWrr,
908 MMX_PSUBUSBrr, MMX_PSUBUSWrr,
909 MMX_PCMPGTBrr, MMX_PCMPGTDrr,
912 def JWriteVZeroIdiomALUX : SchedWriteVariant<[
913 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,
914 SchedVar<NoSchedPred, [WriteVecALUX]>
916 def : InstRW<[JWriteVZeroIdiomALUX], (instrs PSUBBrr, VPSUBBrr,
922 PSUBUSBrr, VPSUBUSBrr,
923 PSUBUSWrr, VPSUBUSWrr,
924 PCMPGTBrr, VPCMPGTBrr,
925 PCMPGTDrr, VPCMPGTDrr,
926 PCMPGTQrr, VPCMPGTQrr,
927 PCMPGTWrr, VPCMPGTWrr)>;
929 def JWriteVPERM2F128 : SchedWriteVariant<[
930 SchedVar<MCSchedPredicate<ZeroIdiomVPERMPredicate>, [JWriteZeroIdiomYmm]>,
931 SchedVar<NoSchedPred, [WriteFShuffle256]>
933 def : InstRW<[JWriteVPERM2F128], (instrs VPERM2F128rri)>;
935 // This write is used for slow LEA instructions.
936 def JWrite3OpsLEA : SchedWriteRes<[JALU1, JSAGU]> {
940 // On Jaguar, a slow LEA is either a 3Ops LEA (base, index, offset), or an LEA
941 // with a `Scale` value different than 1.
942 def JSlowLEAPredicate : MCSchedPredicate<
944 // A 3-operand LEA (base, index, offset).
945 IsThreeOperandsLEAFn,
946 // An LEA with a "Scale" different than 1.
948 CheckIsImmOperand<2>,
949 CheckNot<CheckImmOperand<2, 1>>
954 def JWriteLEA : SchedWriteVariant<[
955 SchedVar<JSlowLEAPredicate, [JWrite3OpsLEA]>,
956 SchedVar<NoSchedPred, [WriteLEA]>
959 def : InstRW<[JWriteLEA], (instrs LEA32r, LEA64r, LEA64_32r)>;
961 def JSlowLEA16r : SchedWriteRes<[JALU01]> {
963 let ReleaseAtCycles = [4];
966 def : InstRW<[JSlowLEA16r], (instrs LEA16r)>;
968 ///////////////////////////////////////////////////////////////////////////////
969 // Dependency breaking instructions.
970 ///////////////////////////////////////////////////////////////////////////////
972 def : IsZeroIdiomFunction<[
974 DepBreakingClass<[ SUB32rr, SUB64rr, XOR32rr, XOR64rr ], ZeroIdiomPredicate>,
978 MMX_PXORrr, MMX_PANDNrr, MMX_PSUBBrr,
979 MMX_PSUBDrr, MMX_PSUBQrr, MMX_PSUBWrr,
980 MMX_PSUBSBrr, MMX_PSUBSWrr, MMX_PSUBUSBrr, MMX_PSUBUSWrr,
981 MMX_PCMPGTBrr, MMX_PCMPGTDrr, MMX_PCMPGTWrr
982 ], ZeroIdiomPredicate>,
987 XORPSrr, XORPDrr, ANDNPSrr, ANDNPDrr,
991 PSUBBrr, PSUBWrr, PSUBDrr, PSUBQrr,
992 PSUBSBrr, PSUBSWrr, PSUBUSBrr, PSUBUSWrr,
993 PCMPGTBrr, PCMPGTDrr, PCMPGTQrr, PCMPGTWrr
994 ], ZeroIdiomPredicate>,
999 VXORPSrr, VXORPDrr, VANDNPSrr, VANDNPDrr,
1001 // xmm int variants.
1003 VPSUBBrr, VPSUBWrr, VPSUBDrr, VPSUBQrr,
1004 VPSUBSBrr, VPSUBSWrr, VPSUBUSBrr, VPSUBUSWrr,
1005 VPCMPGTBrr, VPCMPGTWrr, VPCMPGTDrr, VPCMPGTQrr,
1008 VXORPSYrr, VXORPDYrr, VANDNPSYrr, VANDNPDYrr
1009 ], ZeroIdiomPredicate>,
1011 DepBreakingClass<[ VPERM2F128rri ], ZeroIdiomVPERMPredicate>
1014 def : IsDepBreakingFunction<[
1016 DepBreakingClass<[ SBB32rr, SBB64rr ], ZeroIdiomPredicate>,
1017 DepBreakingClass<[ CMP32rr, CMP64rr ], CheckSameRegOperand<0, 1> >,
1021 MMX_PCMPEQBrr, MMX_PCMPEQDrr, MMX_PCMPEQWrr
1022 ], ZeroIdiomPredicate>,
1026 PCMPEQBrr, PCMPEQWrr, PCMPEQDrr, PCMPEQQrr
1027 ], ZeroIdiomPredicate>,
1031 VPCMPEQBrr, VPCMPEQWrr, VPCMPEQDrr, VPCMPEQQrr
1032 ], ZeroIdiomPredicate>
1035 def : IsOptimizableRegisterMove<[
1036 InstructionEquivalenceClass<[
1049 VMOVAPSrr, VMOVUPSrr,
1050 VMOVAPDrr, VMOVUPDrr,
1051 VMOVDQArr, VMOVDQUrr