1 //=- X86ScheduleBdVer2.td - X86 BdVer2 (Piledriver) 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 bdver2 (Piledriver) to support
10 // instruction scheduling and other instruction cost heuristics.
12 // * AMD Software Optimization Guide for AMD Family 15h Processors.
13 // https://support.amd.com/TechDocs/47414_15h_sw_opt_guide.pdf
14 // * The microarchitecture of Intel, AMD and VIA CPUs, By Agner Fog
15 // http://www.agner.org/optimize/microarchitecture.pdf
16 // * https://www.realworldtech.com/bulldozer/
17 // Yes, that is for Bulldozer aka bdver1, not Piledriver aka bdver2.
19 //===----------------------------------------------------------------------===//
21 def BdVer2Model : SchedMachineModel {
22 let IssueWidth = 4; // Up to 4 IPC can be decoded, issued, retired.
23 let MicroOpBufferSize = 128; // RCU reorder buffer size, which is unconfirmed.
24 let LoopMicroOpBufferSize = -1; // There does not seem to be a loop buffer.
25 let LoadLatency = 4; // L1 data cache has a 4-cycle load-to-use latency.
26 let HighLatency = 25; // FIXME: any better choice?
27 let MispredictPenalty = 20; // Minimum branch misdirection penalty.
29 let PostRAScheduler = 1; // Enable Post RegAlloc Scheduler pass.
31 // FIXME: Incomplete. This flag is set to allow the scheduler to assign
32 // a default model to unrecognized opcodes.
33 let CompleteModel = 0;
34 } // SchedMachineModel
36 let SchedModel = BdVer2Model in {
39 //===----------------------------------------------------------------------===//
41 //===----------------------------------------------------------------------===//
43 // There are total of eight pipes.
45 //===----------------------------------------------------------------------===//
46 // Integer execution pipes
49 // Two EX (ALU) pipes.
50 def PdEX0 : ProcResource<1>; // ALU, Integer Pipe0
51 def PdEX1 : ProcResource<1>; // ALU, Integer Pipe1
52 def PdEX01 : ProcResGroup<[PdEX0, PdEX1]>;
54 // Two AGLU pipes, identical.
55 def PdAGLU01 : ProcResource<2>; // AGU, Integer Pipe[23]
57 //===----------------------------------------------------------------------===//
58 // Floating point execution pipes
63 def PdFPU0 : ProcResource<1>; // Vector/FPU Pipe0
64 def PdFPU1 : ProcResource<1>; // Vector/FPU Pipe1
65 def PdFPU2 : ProcResource<1>; // Vector/FPU Pipe2
66 def PdFPU3 : ProcResource<1>; // Vector/FPU Pipe3
69 def PdFPU01 : ProcResGroup<[PdFPU0, PdFPU1]>;
70 def PdFPU23 : ProcResGroup<[PdFPU2, PdFPU3]>;
73 //===----------------------------------------------------------------------===//
75 //===----------------------------------------------------------------------===//
77 // The Retire Control Unit on Piledriver can retire up to 4 macro-ops per cycle.
78 // On the other hand, the RCU reorder buffer size for Piledriver does not
79 // seem be specified in any trustworthy source.
80 // But as per https://www.realworldtech.com/bulldozer/6/ the Bulldozer had
81 // RCU reorder buffer size of 128. So that is a good guess for now.
82 def PdRCU : RetireControlUnit<128, 4>;
85 //===----------------------------------------------------------------------===//
87 //===----------------------------------------------------------------------===//
89 // There are total of two pipelines, each one with it's own scheduler.
91 //===----------------------------------------------------------------------===//
92 // Integer Pipeline Scheduling
95 // There is one Integer Scheduler per core.
97 // Integer physical register file has 96 registers of 64-bit.
98 def PdIntegerPRF : RegisterFile<96, [GR64, CCR]>;
100 // Unified Integer, Memory Scheduler has 40 entries.
101 def PdEX : ProcResGroup<[PdEX0, PdEX1, PdAGLU01]> {
102 // Up to 4 IPC can be decoded, issued, retired.
107 //===----------------------------------------------------------------------===//
108 // FPU Pipeline Scheduling
111 // The FPU unit is shared between the two cores.
113 // FP physical register file has 160 registers of 128-bit.
114 // Operations on 256-bit data types are cracked into two COPs.
115 def PdFpuPRF : RegisterFile<160, [VR64, VR128, VR256], [1, 1, 2]>;
117 // Unified FP Scheduler has 64 entries,
118 def PdFPU : ProcResGroup<[PdFPU0, PdFPU1, PdFPU2, PdFPU3]> {
119 // Up to 4 IPC can be decoded, issued, retired.
124 //===----------------------------------------------------------------------===//
126 //===----------------------------------------------------------------------===//
128 //===----------------------------------------------------------------------===//
132 let Super = PdAGLU01 in
133 def PdLoad : ProcResource<2> {
134 // For Piledriver, the load queue is 40 entries deep.
138 def PdLoadQueue : LoadQueue<PdLoad>;
140 let Super = PdAGLU01 in
141 def PdStore : ProcResource<1> {
142 // For Piledriver, the store queue is 24 entries deep.
146 def PdStoreQueue : StoreQueue<PdStore>;
148 //===----------------------------------------------------------------------===//
149 // Integer Execution Units
152 def PdDiv : ProcResource<1>; // PdEX0; unpipelined integer division
153 def PdCount : ProcResource<1>; // PdEX0; POPCNT, LZCOUNT
155 def PdMul : ProcResource<1>; // PdEX1; integer multiplication
156 def PdBranch : ProcResource<1>; // PdEX1; JMP, fused branches
158 //===----------------------------------------------------------------------===//
159 // Floating-Point Units
162 // Two FMAC/FPFMA units.
163 def PdFPFMA : ProcResource<2>; // PdFPU0, PdFPU1
165 // One 128-bit integer multiply-accumulate unit.
166 def PdFPMMA : ProcResource<1>; // PdFPU0
168 // One fp conversion unit.
169 def PdFPCVT : ProcResource<1>; // PdFPU0
171 // One unit for shuffles, packs, permutes, shifts.
172 def PdFPXBR : ProcResource<1>; // PdFPU1
174 // Two 128-bit packed integer units.
175 def PdFPMAL : ProcResource<2>; // PdFPU2, PdFPU3
177 // One FP store unit.
178 def PdFPSTO : ProcResource<1>; // PdFPU3
181 //===----------------------------------------------------------------------===//
182 // Basic helper classes.
183 //===----------------------------------------------------------------------===//
185 // Many SchedWrites are defined in pairs with and without a folded load.
186 // Instructions with folded loads are usually micro-fused, so they only appear
187 // as two micro-ops when dispatched by the schedulers.
188 // This multiclass defines the resource usage for variants with and without
190 multiclass PdWriteRes<SchedWrite SchedRW,
191 list<ProcResourceKind> ExePorts, int Lat = 1,
192 list<int> Res = [], int UOps = 1> {
193 def : WriteRes<SchedRW, ExePorts> {
195 let ReleaseAtCycles = Res;
196 let NumMicroOps = UOps;
200 multiclass __pdWriteResPair<X86FoldableSchedWrite SchedRW,
201 list<ProcResourceKind> ExePorts, int Lat,
202 list<int> Res, int UOps,
203 int LoadLat, int LoadRes, int LoadUOps> {
204 defm : PdWriteRes<SchedRW, ExePorts, Lat, Res, UOps>;
206 defm : PdWriteRes<SchedRW.Folded,
207 !listconcat([PdLoad], ExePorts),
209 !if(!and(!empty(Res), !eq(LoadRes, 1)),
211 !listconcat([LoadRes],
213 !listsplat(1, !size(ExePorts)),
215 !add(UOps, LoadUOps)>;
218 multiclass PdWriteResExPair<X86FoldableSchedWrite SchedRW,
219 list<ProcResourceKind> ExePorts, int Lat = 1,
220 list<int> Res = [], int UOps = 1,
222 defm : __pdWriteResPair<SchedRW, ExePorts, Lat, Res, UOps,
223 /*LoadLat*/4, /*LoadRes*/3, LoadUOps>;
226 multiclass PdWriteResXMMPair<X86FoldableSchedWrite SchedRW,
227 list<ProcResourceKind> ExePorts, int Lat = 1,
228 list<int> Res = [], int UOps = 1,
230 defm : __pdWriteResPair<SchedRW, ExePorts, Lat, Res, UOps,
231 /*LoadLat*/5, /*LoadRes*/3, LoadUOps>;
234 multiclass PdWriteResYMMPair<X86FoldableSchedWrite SchedRW,
235 list<ProcResourceKind> ExePorts, int Lat,
236 list<int> Res = [], int UOps = 2,
238 defm : __pdWriteResPair<SchedRW, ExePorts, Lat, Res, UOps,
239 /*LoadLat*/5, /*LoadRes*/3, LoadUOps>;
242 //===----------------------------------------------------------------------===//
244 //===----------------------------------------------------------------------===//
246 // L1 data cache has a 4-cycle load-to-use latency, so ReadAfterLd registers
247 // needn't be available until 4 cycles after the memory operand.
248 def : ReadAdvance<ReadAfterLd, 4>;
250 // Vector loads are 5 cycles, so ReadAfterVec*Ld registers needn't be available
251 // until 5 cycles after the memory operand.
252 def : ReadAdvance<ReadAfterVecLd, 5>;
253 def : ReadAdvance<ReadAfterVecXLd, 5>;
254 def : ReadAdvance<ReadAfterVecYLd, 5>;
256 // Transfer from int domain to ivec domain incurs additional latency of 8..10cy
257 // Reference: Agner, Microarchitecture, "AMD Bulldozer, Piledriver, Steamroller
258 // and Excavator pipeline", "Data delay between different execution domains"
259 def : ReadAdvance<ReadInt2Fpu, -10>;
261 // A folded store needs a cycle on the PdStore for the store data.
262 def : WriteRes<WriteRMW, [PdStore]>;
264 ////////////////////////////////////////////////////////////////////////////////
265 // Loads, stores, and moves, not folded with other operations.
266 ////////////////////////////////////////////////////////////////////////////////
268 def : WriteRes<WriteLoad, [PdLoad]> { let Latency = 5; let ReleaseAtCycles = [2]; }
269 def : WriteRes<WriteStore, [PdStore]>;
270 def : WriteRes<WriteStoreNT, [PdStore]>;
271 def : WriteRes<WriteMove, [PdEX01]> { let ReleaseAtCycles = [2]; }
272 defm : X86WriteResUnsupported<WriteVecMaskedGatherWriteback>;
275 // FIXME: These are copy and pasted from WriteLoad/Store.
276 def : WriteRes<WriteLDMXCSR, [PdLoad]> { let Latency = 5; }
277 def : WriteRes<WriteSTMXCSR, [PdStore]> { let NumMicroOps = 2; let ReleaseAtCycles = [18]; }
279 // Treat misc copies as a move.
280 def : InstRW<[WriteMove], (instrs COPY)>;
282 ////////////////////////////////////////////////////////////////////////////////
283 // Idioms that clear a register, like xorps %xmm0, %xmm0.
284 // These can often bypass execution ports completely.
285 ////////////////////////////////////////////////////////////////////////////////
287 def : WriteRes<WriteZero, [/*No ExePorts*/]>;
289 ////////////////////////////////////////////////////////////////////////////////
290 // Branches don't produce values, so they have no latency, but they still
291 // consume resources. Indirect branches can fold loads.
292 ////////////////////////////////////////////////////////////////////////////////
294 defm : PdWriteResExPair<WriteJump, [PdEX1, PdBranch]>;
296 ////////////////////////////////////////////////////////////////////////////////
297 // Special case scheduling classes.
298 ////////////////////////////////////////////////////////////////////////////////
300 def : WriteRes<WriteSystem, [PdEX01]> { let Latency = 100; }
301 def : WriteRes<WriteMicrocoded, [PdEX01]> { let Latency = 100; }
302 def : WriteRes<WriteFence, [PdStore]>;
304 def PdWriteXLAT : SchedWriteRes<[PdEX01]> {
307 def : InstRW<[PdWriteXLAT], (instrs XLAT)>;
309 def PdWriteLARrr : SchedWriteRes<[PdEX01]> {
311 let ReleaseAtCycles = [375];
312 let NumMicroOps = 45;
314 def : InstRW<[PdWriteLARrr], (instregex "LAR(16|32|64)rr",
317 // Nops don't have dependencies, so there's no actual latency, but we set this
318 // to '1' to tell the scheduler that the nop uses an ALU slot for a cycle.
319 def : WriteRes<WriteNop, [PdEX01]> { let ReleaseAtCycles = [2]; }
321 ////////////////////////////////////////////////////////////////////////////////
323 ////////////////////////////////////////////////////////////////////////////////
325 defm : PdWriteResExPair<WriteALU, [PdEX01], 1, [2]>;
327 def PdWriteALURMW : SchedWriteRes<[PdLoad, PdEX01, PdStore]> {
329 let ReleaseAtCycles = [3, 2, 1];
332 def : SchedAlias<WriteALURMW, PdWriteALURMW>;
334 def PdWriteLXADD : SchedWriteRes<[PdEX01]> {
336 let ReleaseAtCycles = [88];
339 def : InstRW<[PdWriteLXADD], (instrs LXADD8, LXADD16, LXADD32, LXADD64)>;
341 def PdWriteBMI1 : SchedWriteRes<[PdEX01]> {
343 let ReleaseAtCycles = [2];
346 def : InstRW<[PdWriteBMI1],
347 (instrs BLCFILL32rr, BLCFILL64rr, BLCI32rr, BLCI64rr,
348 BLCIC32rr, BLCIC64rr, BLCMSK32rr, BLCMSK64rr,
349 BLCS32rr, BLCS64rr, BLSFILL32rr, BLSFILL64rr,
350 BLSIC32rr, BLSIC64rr, T1MSKC32rr, T1MSKC64rr,
351 TZMSK32rr, TZMSK64rr)>;
353 def PdWriteBMI1m : SchedWriteRes<[PdLoad, PdEX01]> {
355 let ReleaseAtCycles = [3, 3];
358 def : InstRW<[PdWriteBMI1m],
359 (instrs BLCFILL32rm, BLCFILL64rm, BLCI32rm, BLCI64rm,
360 BLCIC32rm, BLCIC64rm, BLCMSK32rm, BLCMSK64rm,
361 BLCS32rm, BLCS64rm, BLSFILL32rm, BLSFILL64rm,
362 BLSIC32rm, BLSIC64rm, T1MSKC32rm, T1MSKC64rm,
363 TZMSK32rm, TZMSK64rm)>;
365 defm : PdWriteResExPair<WriteADC, [PdEX01], 1, [2]>;
367 def PdWriteADCSBB64ri32 : SchedWriteRes<[PdEX01]> {
368 let ReleaseAtCycles = [3];
370 def : InstRW<[PdWriteADCSBB64ri32], (instrs ADC64ri32, SBB64ri32)>;
372 defm : PdWriteRes<WriteBSWAP32, [PdEX01]>;
373 defm : PdWriteRes<WriteBSWAP64, [PdEX01]>;
374 defm : PdWriteRes<WriteCMPXCHG, [PdEX1], 3, [3], 5>;
375 defm : PdWriteRes<WriteCMPXCHGRMW, [PdEX1, PdStore, PdLoad], 3, [44, 1, 1], 2>;
376 defm : PdWriteRes<WriteXCHG, [PdEX1], 1, [], 2>;
378 def PdWriteCMPXCHG8rr : SchedWriteRes<[PdEX1]> {
380 let ReleaseAtCycles = [3];
383 def : InstRW<[PdWriteCMPXCHG8rr], (instrs CMPXCHG8rr)>;
385 def PdWriteCMPXCHG8rm : SchedWriteRes<[PdEX1]> {
387 let ReleaseAtCycles = [23];
390 def : InstRW<[PdWriteCMPXCHG8rm], (instrs CMPXCHG8rm)>;
392 def PdWriteCMPXCHG16rm_CMPXCHG32rm_CMPXCHG64rm : SchedWriteRes<[PdEX1]> {
394 let ReleaseAtCycles = [21];
397 def : InstRW<[PdWriteCMPXCHG16rm_CMPXCHG32rm_CMPXCHG64rm],
398 (instrs CMPXCHG16rm, CMPXCHG32rm, CMPXCHG64rm)>;
400 def PdWriteCMPXCHG8B : SchedWriteRes<[PdEX1]> {
402 let ReleaseAtCycles = [26];
403 let NumMicroOps = 18;
405 def : InstRW<[PdWriteCMPXCHG8B], (instrs CMPXCHG8B)>;
407 def PdWriteCMPXCHG16B : SchedWriteRes<[PdEX1]> {
409 let ReleaseAtCycles = [69];
410 let NumMicroOps = 22;
412 def : InstRW<[PdWriteCMPXCHG16B], (instrs CMPXCHG16B)>;
414 def PdWriteXADDm : SchedWriteRes<[PdEX1]> {
416 let ReleaseAtCycles = [20];
419 def : InstRW<[PdWriteXADDm], (instrs XADD8rm, XADD16rm, XADD32rm, XADD64rm)>;
421 defm : PdWriteResExPair<WriteIMul8, [PdEX1, PdMul], 4, [1, 4]>;
422 defm : PdWriteResExPair<WriteIMul16, [PdEX1, PdMul], 4, [1, 5], 2>;
423 defm : PdWriteResExPair<WriteIMul16Imm, [PdEX1, PdMul], 5, [1, 5], 2>;
424 defm : PdWriteResExPair<WriteIMul16Reg, [PdEX1, PdMul], 4, [1, 2]>;
425 defm : PdWriteResExPair<WriteIMul32, [PdEX1, PdMul], 4, [1, 4]>;
426 defm : PdWriteResExPair<WriteIMul32Imm, [PdEX1, PdMul], 4, [1, 2], 1, 1>;
427 defm : PdWriteResExPair<WriteIMul32Reg, [PdEX1, PdMul], 4, [1, 2]>;
428 defm : PdWriteResExPair<WriteIMul64, [PdEX1, PdMul], 6, [1, 6]>;
429 defm : PdWriteResExPair<WriteIMul64Imm, [PdEX1, PdMul], 6, [1, 4],1, 1>;
430 defm : PdWriteResExPair<WriteIMul64Reg, [PdEX1, PdMul], 6, [1, 4]>;
433 defm : X86WriteResUnsupported<WriteIMulH>;
434 defm : X86WriteResUnsupported<WriteIMulHLd>;
435 defm : X86WriteResPairUnsupported<WriteMULX32>;
436 defm : X86WriteResPairUnsupported<WriteMULX64>;
438 defm : PdWriteResExPair<WriteDiv8, [PdEX1, PdDiv], 12, [1, 12]>;
439 defm : PdWriteResExPair<WriteDiv16, [PdEX1, PdDiv], 15, [1, 15], 2>;
440 defm : PdWriteResExPair<WriteDiv32, [PdEX1, PdDiv], 14, [1, 14], 2>;
441 defm : PdWriteResExPair<WriteDiv64, [PdEX1, PdDiv], 14, [1, 14], 2>;
443 defm : PdWriteResExPair<WriteIDiv8, [PdEX1, PdDiv], 12, [1, 12]>;
444 defm : PdWriteResExPair<WriteIDiv16, [PdEX1, PdDiv], 15, [1, 17], 2>;
445 defm : PdWriteResExPair<WriteIDiv32, [PdEX1, PdDiv], 14, [1, 25], 2>;
446 defm : PdWriteResExPair<WriteIDiv64, [PdEX1, PdDiv], 14, [1, 14], 2>;
448 defm : PdWriteResExPair<WriteCRC32, [PdEX01], 2, [4], 3>;
450 def PdWriteCRC32r32r16 : SchedWriteRes<[PdEX01]> {
452 let ReleaseAtCycles = [10];
455 def : InstRW<[PdWriteCRC32r32r16], (instrs CRC32r32r16)>;
457 def PdWriteCRC32r32r32 : SchedWriteRes<[PdEX01]> {
459 let ReleaseAtCycles = [12];
462 def : InstRW<[PdWriteCRC32r32r32], (instrs CRC32r32r32)>;
464 def PdWriteCRC32r64r64 : SchedWriteRes<[PdEX01]> {
466 let ReleaseAtCycles = [17];
467 let NumMicroOps = 11;
469 def : InstRW<[PdWriteCRC32r64r64], (instrs CRC32r64r64)>;
471 defm : PdWriteResExPair<WriteCMOV, [PdEX01]>; // Conditional move.
473 def PdWriteCMOVm : SchedWriteRes<[PdLoad, PdEX01]> {
475 let ReleaseAtCycles = [3, 3];
479 def PdWriteCMOVmVar : SchedWriteVariant<[
480 SchedVar<MCSchedPredicate<CheckImmOperand_s<7, "X86::COND_BE">>, [PdWriteCMOVm]>,
481 SchedVar<MCSchedPredicate<CheckImmOperand_s<7, "X86::COND_A">>, [PdWriteCMOVm]>,
482 SchedVar<MCSchedPredicate<CheckImmOperand_s<7, "X86::COND_L">>, [PdWriteCMOVm]>,
483 SchedVar<MCSchedPredicate<CheckImmOperand_s<7, "X86::COND_GE">>, [PdWriteCMOVm]>,
484 SchedVar<MCSchedPredicate<CheckImmOperand_s<7, "X86::COND_LE">>, [PdWriteCMOVm]>,
485 SchedVar<MCSchedPredicate<CheckImmOperand_s<7, "X86::COND_G">>, [PdWriteCMOVm]>,
486 SchedVar<NoSchedPred, [WriteCMOV.Folded]>
489 def : InstRW<[PdWriteCMOVmVar], (instrs CMOV16rm, CMOV32rm, CMOV64rm)>;
491 defm : PdWriteRes<WriteFCMOV, [PdFPU0, PdFPFMA]>; // x87 conditional move.
493 def : WriteRes<WriteSETCC, [PdEX01]>; // Setcc.
494 def : WriteRes<WriteSETCCStore, [PdEX01, PdStore]>;
496 def PdWriteSETGEmSETGmSETLEmSETLm : SchedWriteRes<[PdEX01]> {
497 let ReleaseAtCycles = [2];
501 def PdSETGEmSETGmSETLEmSETLm : SchedWriteVariant<[
502 SchedVar<MCSchedPredicate<CheckImmOperand_s<5, "X86::COND_GE">>, [PdWriteSETGEmSETGmSETLEmSETLm]>,
503 SchedVar<MCSchedPredicate<CheckImmOperand_s<5, "X86::COND_G">>, [PdWriteSETGEmSETGmSETLEmSETLm]>,
504 SchedVar<MCSchedPredicate<CheckImmOperand_s<5, "X86::COND_LE">>, [PdWriteSETGEmSETGmSETLEmSETLm]>,
505 SchedVar<MCSchedPredicate<CheckImmOperand_s<5, "X86::COND_L">>, [PdWriteSETGEmSETGmSETLEmSETLm]>,
506 SchedVar<NoSchedPred, [WriteSETCCStore]>
508 def : InstRW<[PdSETGEmSETGmSETLEmSETLm], (instrs SETCCm)>;
510 defm : PdWriteRes<WriteLAHFSAHF, [PdEX01], 2, [4], 2>;
512 def PdWriteLAHF : SchedWriteRes<[PdEX01]> {
514 let ReleaseAtCycles = [4];
517 def : InstRW<[PdWriteLAHF], (instrs LAHF)>;
519 def PdWriteSAHF : SchedWriteRes<[PdEX01]> {
521 let ReleaseAtCycles = [2];
524 def : InstRW<[PdWriteSAHF], (instrs SAHF)>;
526 defm : PdWriteRes<WriteBitTest, [PdEX01], 1, [2], 1>;
527 defm : PdWriteRes<WriteBitTestImmLd, [PdEX01, PdLoad], 5, [2, 3], 1>;
528 defm : PdWriteRes<WriteBitTestRegLd, [PdEX01, PdLoad], 5, [7, 2], 7>;
529 defm : PdWriteRes<WriteBitTestSet, [PdEX01], 2, [2], 2>;
530 defm : PdWriteRes<WriteBitTestSetImmLd, [PdEX01, PdLoad], 6, [1, 1], 4>;
531 defm : PdWriteRes<WriteBitTestSetRegLd, [PdEX01, PdLoad], 6, [1, 1], 10>;
533 def PdWriteBTSIm : SchedWriteRes<[PdEX01, PdLoad]> {
535 let ReleaseAtCycles = [42, 1];
538 def : SchedAlias<WriteBitTestSetImmRMW, PdWriteBTSIm>;
539 def PdWriteBTSRm : SchedWriteRes<[PdEX01, PdLoad]> {
541 let ReleaseAtCycles = [44, 1];
542 let NumMicroOps = 10;
544 def : SchedAlias<WriteBitTestSetRegRMW, PdWriteBTSRm>;
546 // This is for simple LEAs with one or two input operands.
547 def : WriteRes<WriteLEA, [PdEX01]> { let ReleaseAtCycles = [2]; }
549 // This write is used for slow LEA instructions.
550 def PdWrite3OpsLEA : SchedWriteRes<[PdEX01]> {
552 let ReleaseAtCycles = [2];
555 // On Piledriver, a slow LEA is either a 3Ops LEA (base, index, offset),
556 // or an LEA with a `Scale` value different than 1.
557 def PdSlowLEAPredicate : MCSchedPredicate<
559 // A 3-operand LEA (base, index, offset).
560 IsThreeOperandsLEAFn,
561 // An LEA with a "Scale" different than 1.
563 CheckIsImmOperand<2>,
564 CheckNot<CheckImmOperand<2, 1>>
569 def PdWriteLEA : SchedWriteVariant<[
570 SchedVar<PdSlowLEAPredicate, [PdWrite3OpsLEA]>,
571 SchedVar<NoSchedPred, [WriteLEA]>
574 def : InstRW<[PdWriteLEA], (instrs LEA32r, LEA64r, LEA64_32r)>;
576 def PdWriteLEA16r : SchedWriteRes<[PdEX01]> {
577 let ReleaseAtCycles = [3];
580 def : InstRW<[PdWriteLEA16r], (instrs LEA16r)>;
583 defm : PdWriteResExPair<WriteBSF, [PdEX01], 3, [6], 6, 2>;
584 defm : PdWriteResExPair<WriteBSR, [PdEX01], 4, [8], 7, 2>;
585 defm : PdWriteResExPair<WritePOPCNT, [PdEX01], 4, [4]>;
586 defm : PdWriteResExPair<WriteLZCNT, [PdEX0], 2, [2], 2>;
587 defm : PdWriteResExPair<WriteTZCNT, [PdEX0], 2, [2], 2>;
589 // BMI1 BEXTR, BMI2 BZHI
590 defm : PdWriteResExPair<WriteBEXTR, [PdEX01], 2, [2], 2>;
591 defm : PdWriteResExPair<WriteBLS, [PdEX01], 2, [2], 2>;
592 defm : PdWriteResExPair<WriteBZHI, [PdEX01]>;
594 def PdWriteBEXTRI : SchedWriteRes<[PdEX01]> {
596 let ReleaseAtCycles = [4];
599 def : InstRW<[PdWriteBEXTRI], (instrs BEXTRI32ri, BEXTRI64ri)>;
601 def PdWriteBEXTRIm : SchedWriteRes<[PdEX01]> {
603 let ReleaseAtCycles = [5];
606 def : InstRW<[PdWriteBEXTRIm], (instrs BEXTRI32mi, BEXTRI64mi)>;
608 ////////////////////////////////////////////////////////////////////////////////
609 // Integer shifts and rotates.
610 ////////////////////////////////////////////////////////////////////////////////
612 defm : PdWriteResExPair<WriteShift, [PdEX01], 1, [2]>;
613 defm : PdWriteResExPair<WriteShiftCL, [PdEX01]>;
614 defm : PdWriteResExPair<WriteRotate, [PdEX01], 1, [2]>;
615 defm : PdWriteResExPair<WriteRotateCL, [PdEX01]>;
617 def PdWriteRCL8rCL : SchedWriteRes<[PdEX01]> {
619 let ReleaseAtCycles = [24];
620 let NumMicroOps = 26;
622 def : InstRW<[PdWriteRCL8rCL], (instrs RCL8rCL)>;
624 def PdWriteRCR8ri : SchedWriteRes<[PdEX01]> {
626 let ReleaseAtCycles = [23];
627 let NumMicroOps = 23;
629 def : InstRW<[PdWriteRCR8ri], (instrs RCR8ri)>;
631 def PdWriteRCR8rCL : SchedWriteRes<[PdEX01]> {
633 let ReleaseAtCycles = [22];
634 let NumMicroOps = 24;
636 def : InstRW<[PdWriteRCR8rCL], (instrs RCR8rCL)>;
638 def PdWriteRCL16rCL : SchedWriteRes<[PdEX01]> {
640 let ReleaseAtCycles = [20];
641 let NumMicroOps = 22;
643 def : InstRW<[PdWriteRCL16rCL], (instrs RCL16rCL)>;
645 def PdWriteRCR16ri : SchedWriteRes<[PdEX01]> {
647 let ReleaseAtCycles = [19];
648 let NumMicroOps = 19;
650 def : InstRW<[PdWriteRCR16ri], (instrs RCR16ri)>;
652 def PdWriteRCL3264rCL : SchedWriteRes<[PdEX01]> {
654 let ReleaseAtCycles = [14];
655 let NumMicroOps = 17;
657 def : InstRW<[PdWriteRCL3264rCL], (instrs RCL32rCL, RCL64rCL)>;
659 def PdWriteRCR3264rCL : SchedWriteRes<[PdEX01]> {
661 let ReleaseAtCycles = [13];
662 let NumMicroOps = 16;
664 def : InstRW<[PdWriteRCR3264rCL], (instrs RCR32rCL, RCR64rCL)>;
666 def PdWriteRCR32riRCR64ri : SchedWriteRes<[PdEX01]> {
668 let ReleaseAtCycles = [14];
669 let NumMicroOps = 15;
671 def : InstRW<[PdWriteRCR32riRCR64ri], (instrs RCR32ri, RCR64ri)>;
674 def PdWriteRCR16rCL : SchedWriteRes<[PdEX01]> {
676 let ReleaseAtCycles = [18];
677 let NumMicroOps = 20;
679 def : InstRW<[PdWriteRCR16rCL], (instrs RCR16rCL)>;
681 def PdWriteRCL16ri : SchedWriteRes<[PdEX01]> {
683 let ReleaseAtCycles = [21];
684 let NumMicroOps = 21;
686 def : InstRW<[PdWriteRCL16ri], (instrs RCL16ri)>;
688 def PdWriteRCL3264ri : SchedWriteRes<[PdEX01]> {
690 let ReleaseAtCycles = [15];
691 let NumMicroOps = 16;
693 def : InstRW<[PdWriteRCL3264ri], (instrs RCL32ri, RCL64ri)>;
695 def PdWriteRCL8ri : SchedWriteRes<[PdEX01]> {
697 let ReleaseAtCycles = [25];
698 let NumMicroOps = 25;
700 def : InstRW<[PdWriteRCL8ri], (instrs RCL8ri)>;
703 defm : PdWriteRes<WriteSHDrri, [PdEX01], 3, [6], 6>;
704 defm : PdWriteRes<WriteSHDrrcl, [PdEX01], 3, [8], 7>;
706 def PdWriteSHLD16rrCLSHLD32rrCLSHRD32rrCL : SchedWriteRes<[PdEX01]> {
708 let ReleaseAtCycles = [6];
711 def : InstRW<[PdWriteSHLD16rrCLSHLD32rrCLSHRD32rrCL], (instrs SHLD16rrCL,
715 defm : PdWriteRes<WriteSHDmri, [PdLoad, PdEX01], 4, [1, 22], 8>;
716 defm : PdWriteRes<WriteSHDmrcl, [PdLoad, PdEX01], 4, [1, 22], 8>;
718 ////////////////////////////////////////////////////////////////////////////////
719 // Floating point. This covers both scalar and vector operations.
720 ////////////////////////////////////////////////////////////////////////////////
722 defm : PdWriteRes<WriteFLD0, [PdFPU1, PdFPSTO], 3>;
723 defm : PdWriteRes<WriteFLD1, [PdFPU1, PdFPSTO], 3>;
724 defm : PdWriteRes<WriteFLDC, [PdFPU1, PdFPSTO], 3>;
726 defm : PdWriteRes<WriteFLoad, [PdLoad, PdFPU01, PdFPFMA], 5, [3, 1, 3]>;
727 defm : PdWriteRes<WriteFLoadX, [PdLoad, PdFPU01, PdFPFMA], 5, [3, 1, 3]>;
728 defm : PdWriteRes<WriteFLoadY, [PdLoad, PdFPU01, PdFPFMA], 5, [3, 1, 3], 2>;
730 defm : PdWriteRes<WriteFMaskedLoad, [PdLoad, PdFPU01, PdFPFMA], 6, [3, 1, 4]>;
731 defm : PdWriteRes<WriteFMaskedLoadY, [PdLoad, PdFPU01, PdFPFMA], 6, [3, 2, 4], 2>;
733 defm : PdWriteRes<WriteFStore, [PdStore, PdFPU23, PdFPSTO], 2, [1, 3, 1]>;
734 defm : PdWriteRes<WriteFStoreX, [PdStore, PdFPU23, PdFPSTO], 1, [1, 3, 1]>;
735 defm : PdWriteRes<WriteFStoreY, [PdStore, PdFPU23, PdFPSTO], 1, [1, 36, 2], 4>;
737 def PdWriteMOVHPm : SchedWriteRes<[PdStore, PdFPU23, PdFPSTO]> {
739 let ReleaseAtCycles = [1, 3, 1];
742 def : InstRW<[PdWriteMOVHPm], (instrs MOVHPDmr, MOVHPSmr, VMOVHPDmr, VMOVHPSmr)>;
744 def PdWriteVMOVUPDYmrVMOVUPSYmr : SchedWriteRes<[PdStore, PdFPU1, PdFPSTO]> {
747 def : InstRW<[PdWriteVMOVUPDYmrVMOVUPSYmr], (instrs VMOVUPDYmr, VMOVUPSYmr)>;
749 defm : PdWriteRes<WriteFStoreNT, [PdStore, PdFPU1, PdFPSTO], 3>;
750 defm : PdWriteRes<WriteFStoreNTX, [PdStore, PdFPU1, PdFPSTO], 3>;
751 defm : PdWriteRes<WriteFStoreNTY, [PdStore, PdFPU1, PdFPSTO], 3, [2, 2, 2], 4>;
753 defm : PdWriteRes<WriteFMaskedStore32, [PdStore, PdFPU01, PdFPFMA], 6, [1, 1, 188], 18>;
754 defm : PdWriteRes<WriteFMaskedStore64, [PdStore, PdFPU01, PdFPFMA], 6, [1, 1, 188], 18>;
755 defm : PdWriteRes<WriteFMaskedStore32Y, [PdStore, PdFPU01, PdFPFMA], 6, [2, 2, 376], 34>;
756 defm : PdWriteRes<WriteFMaskedStore64Y, [PdStore, PdFPU01, PdFPFMA], 6, [2, 2, 376], 34>;
758 defm : PdWriteRes<WriteFMove, [PdFPU01, PdFPFMA]>;
759 defm : PdWriteRes<WriteFMoveX, [PdFPU01, PdFPFMA], 1, [1, 2]>;
760 defm : PdWriteRes<WriteFMoveY, [PdFPU01, PdFPFMA], 2, [2, 2], 2>;
761 defm : X86WriteResUnsupported<WriteFMoveZ>;
763 defm : PdWriteRes<WriteEMMS, [PdFPU01, PdFPFMA], 2>;
765 defm : PdWriteResXMMPair<WriteFAdd, [PdFPU0, PdFPFMA], 5>;
766 defm : PdWriteResXMMPair<WriteFAddX, [PdFPU0, PdFPFMA], 5>;
767 defm : PdWriteResYMMPair<WriteFAddY, [PdFPU0, PdFPFMA], 5, [1, 2]>;
768 defm : X86WriteResPairUnsupported<WriteFAddZ>;
770 def PdWriteX87Add: SchedWriteRes<[PdLoad, PdFPU0, PdFPFMA]> {
772 let ReleaseAtCycles = [3, 1, 10];
774 def : InstRW<[PdWriteX87Add], (instrs ADD_FI16m, ADD_FI32m, ADD_F32m, ADD_F64m,
775 SUB_FI16m, SUB_FI32m, SUB_F32m, SUB_F64m,
776 SUBR_FI16m, SUBR_FI32m, SUBR_F32m, SUBR_F64m)>;
778 defm : PdWriteResXMMPair<WriteFAdd64, [PdFPU0, PdFPFMA], 5>;
779 defm : PdWriteResXMMPair<WriteFAdd64X, [PdFPU0, PdFPFMA], 5>;
780 defm : PdWriteResYMMPair<WriteFAdd64Y, [PdFPU0, PdFPFMA], 5, [1, 2]>;
781 defm : X86WriteResPairUnsupported<WriteFAdd64Z>;
783 defm : PdWriteResXMMPair<WriteFCmp, [PdFPU0, PdFPFMA], 2>;
784 defm : PdWriteResXMMPair<WriteFCmpX, [PdFPU0, PdFPFMA], 2>;
785 defm : PdWriteResYMMPair<WriteFCmpY, [PdFPU0, PdFPFMA], 2, [1, 2]>;
786 defm : X86WriteResPairUnsupported<WriteFCmpZ>;
788 defm : PdWriteResXMMPair<WriteFCmp64, [PdFPU0, PdFPFMA], 2>;
789 defm : PdWriteResXMMPair<WriteFCmp64X, [PdFPU0, PdFPFMA], 2>;
790 defm : PdWriteResYMMPair<WriteFCmp64Y, [PdFPU0, PdFPFMA], 2, [1, 2]>;
791 defm : X86WriteResPairUnsupported<WriteFCmp64Z>;
793 defm : PdWriteResXMMPair<WriteFCom, [PdFPU0, PdFPFMA, PdEX0], 1, [], 2>;
794 defm : PdWriteResXMMPair<WriteFComX, [PdFPU0, PdFPFMA, PdEX0], 1, [], 2>;
796 def PdWriteFCOMPm : SchedWriteRes<[PdFPU1, PdFPFMA]> {
799 def : InstRW<[PdWriteFCOMPm], (instrs FCOM32m, FCOM64m, FCOMP32m, FCOMP64m)>;
801 def PdWriteTST_F_UCOM_FPPr : SchedWriteRes<[PdFPU1, PdFPFMA]>;
802 def : InstRW<[PdWriteTST_F_UCOM_FPPr], (instrs TST_F, UCOM_FPPr)>;
804 defm : PdWriteResXMMPair<WriteFMul, [PdFPU1, PdFPFMA], 5>;
805 defm : PdWriteResXMMPair<WriteFMulX, [PdFPU1, PdFPFMA], 5>;
806 defm : PdWriteResYMMPair<WriteFMulY, [PdFPU1, PdFPFMA], 5, [1, 2]>;
807 defm : X86WriteResPairUnsupported<WriteFMulZ>;
809 def PdWriteX87Mul: SchedWriteRes<[PdLoad, PdFPU1, PdFPFMA]> {
811 let ReleaseAtCycles = [3, 1, 10];
813 def : InstRW<[PdWriteX87Mul], (instrs MUL_FI16m, MUL_FI32m, MUL_F32m, MUL_F64m)>;
815 defm : PdWriteResXMMPair<WriteFMul64, [PdFPU1, PdFPFMA], 5>;
816 defm : PdWriteResXMMPair<WriteFMul64X, [PdFPU1, PdFPFMA], 5>;
817 defm : PdWriteResYMMPair<WriteFMul64Y, [PdFPU1, PdFPFMA], 5, [1, 2]>;
818 defm : X86WriteResPairUnsupported<WriteFMul64Z>;
820 defm : PdWriteResXMMPair<WriteFMA, [PdFPU, PdFPFMA], 5, [1, 3]>;
821 defm : PdWriteResXMMPair<WriteFMAX, [PdFPU, PdFPFMA], 5, [1, 3]>;
822 defm : PdWriteResYMMPair<WriteFMAY, [PdFPU, PdFPFMA], 5, [1, 3]>;
823 defm : X86WriteResPairUnsupported<WriteFMAZ>;
825 defm : PdWriteResXMMPair<WriteDPPD, [PdFPU1, PdFPFMA], 15, [1, 10], 15, 2>;
827 defm : PdWriteResXMMPair<WriteDPPS, [PdFPU1, PdFPFMA], 25, [1, 14], 16, 2>;
828 defm : PdWriteResYMMPair<WriteDPPSY, [PdFPU1, PdFPFMA], 27, [2, 25], /*or 29*/ 25, 4>;
830 def PdWriteVDPPSrri : SchedWriteRes<[PdFPU1, PdFPFMA]> {
832 let ReleaseAtCycles = [1, 14];
833 let NumMicroOps = 17;
835 def : InstRW<[PdWriteVDPPSrri], (instrs VDPPSrri)>;
837 defm : PdWriteResXMMPair<WriteFRcp, [PdFPU1, PdFPFMA], 5>;
838 defm : PdWriteResXMMPair<WriteFRcpX, [PdFPU1, PdFPFMA], 5>;
839 defm : PdWriteResYMMPair<WriteFRcpY, [PdFPU1, PdFPFMA], 5, [2, 1]>;
840 defm : X86WriteResPairUnsupported<WriteFRcpZ>;
842 defm : PdWriteResXMMPair<WriteFRsqrt, [PdFPU1, PdFPFMA], 5, [1, 2]>;
843 defm : PdWriteResXMMPair<WriteFRsqrtX, [PdFPU1, PdFPFMA], 5>;
844 defm : PdWriteResYMMPair<WriteFRsqrtY, [PdFPU1, PdFPFMA], 5, [2, 2]>;
845 defm : X86WriteResPairUnsupported<WriteFRsqrtZ>;
847 defm : PdWriteResXMMPair<WriteFDiv, [PdFPU1, PdFPFMA], 9, [1, 9]>;
848 defm : PdWriteResXMMPair<WriteFDivX, [PdFPU1, PdFPFMA], 9, [1, 9]>;
849 defm : PdWriteResYMMPair<WriteFDivY, [PdFPU1, PdFPFMA], 9, [2, 18]>;
850 defm : X86WriteResPairUnsupported<WriteFDivZ>;
852 def PdWriteX87Div: SchedWriteRes<[PdLoad, PdFPU0, PdFPFMA]> {
854 let ReleaseAtCycles = [3, 1, 18];
856 def : InstRW<[PdWriteX87Div], (instrs DIV_FI16m, DIV_FI32m,
857 DIVR_FI16m, DIVR_FI32m,
859 DIVR_F32m, DIVR_F64m)>;
861 defm : PdWriteResXMMPair<WriteFDiv64, [PdFPU1, PdFPFMA], 9, [1, 9]>;
862 defm : PdWriteResXMMPair<WriteFDiv64X, [PdFPU1, PdFPFMA], 9, [1, 9]>;
863 defm : PdWriteResYMMPair<WriteFDiv64Y, [PdFPU1, PdFPFMA], 9, [2, 18]>;
864 defm : X86WriteResPairUnsupported<WriteFDiv64Z>;
866 defm : PdWriteResXMMPair<WriteFSqrt, [PdFPU1, PdFPFMA], 9, [1, 9]>;
867 defm : PdWriteResXMMPair<WriteFSqrtX, [PdFPU1, PdFPFMA], 9, [1, 9]>;
868 defm : PdWriteResYMMPair<WriteFSqrtY, [PdFPU1, PdFPFMA], 9, [2, 18]>;
869 defm : X86WriteResPairUnsupported<WriteFSqrtZ>;
871 defm : PdWriteResXMMPair<WriteFSqrt64, [PdFPU1, PdFPFMA], 9, [1, 9]>;
872 defm : PdWriteResXMMPair<WriteFSqrt64X, [PdFPU1, PdFPFMA], 9, [1, 9]>;
873 defm : PdWriteResYMMPair<WriteFSqrt64Y, [PdFPU1, PdFPFMA], 9, [2, 18]>;
874 defm : X86WriteResPairUnsupported<WriteFSqrt64Z>;
876 defm : PdWriteResXMMPair<WriteFSqrt80, [PdFPU1, PdFPFMA], 1, [1, 18]>;
877 defm : PdWriteResXMMPair<WriteFSign, [PdFPU1, PdFPFMA], 1, [1, 4]>;
879 defm : PdWriteResXMMPair<WriteFRnd, [PdFPU1, PdFPSTO], 4, []>;
880 defm : PdWriteResYMMPair<WriteFRndY, [PdFPU1, PdFPSTO], 4, [2, 1], 2>;
881 defm : X86WriteResPairUnsupported<WriteFRndZ>;
883 def PdWriteVFRCZP : SchedWriteRes<[PdFPU1, PdFPSTO]> {
885 let ReleaseAtCycles = [2, 1];
888 def : InstRW<[PdWriteVFRCZP], (instrs VFRCZPDrr, VFRCZPSrr)>;
890 def PdWriteVFRCZS : SchedWriteRes<[PdFPU1, PdFPSTO]> {
892 let ReleaseAtCycles = [10, 1];
895 def : InstRW<[PdWriteVFRCZS], (instrs VFRCZSDrr, VFRCZSSrr)>;
897 def PdWriteVFRCZm : SchedWriteRes<[PdFPU1, PdFPSTO]> {
899 let ReleaseAtCycles = [2, 1];
902 def : InstRW<[PdWriteVFRCZm], (instrs VFRCZPDrm, VFRCZPSrm,
903 VFRCZSDrm, VFRCZSSrm)>;
905 def PdWriteVFRCZY : SchedWriteRes<[PdFPU1, PdFPSTO]> {
907 let ReleaseAtCycles = [3, 1];
910 def : InstRW<[PdWriteVFRCZY], (instrs VFRCZPSYrr, VFRCZPDYrr)>;
912 def PdWriteVFRCZYm : SchedWriteRes<[PdFPU1, PdFPSTO]> {
914 let ReleaseAtCycles = [4, 1];
917 def : InstRW<[PdWriteVFRCZYm], (instrs VFRCZPSYrm, VFRCZPDYrm)>;
919 defm : PdWriteResXMMPair<WriteFLogic, [PdFPU23, PdFPMAL], 2>;
920 defm : PdWriteResYMMPair<WriteFLogicY, [PdFPU23, PdFPMAL], 2, [2, 2]>;
921 defm : X86WriteResPairUnsupported<WriteFLogicZ>;
923 defm : PdWriteResXMMPair<WriteFTest, [PdFPU0, PdFPFMA, PdEX0], 1, [], 2>;
924 defm : PdWriteResYMMPair<WriteFTestY, [PdFPU01, PdFPFMA, PdEX0], 1, [4, 4, 1], 4, 2>;
925 defm : X86WriteResPairUnsupported<WriteFTestZ>;
927 defm : PdWriteResXMMPair<WriteFShuffle, [PdFPU01, PdFPFMA], 2, [1, 2]>;
928 defm : PdWriteResYMMPair<WriteFShuffleY, [PdFPU01, PdFPFMA], 2, [2, 4], 2>;
929 defm : X86WriteResPairUnsupported<WriteFShuffleZ>;
931 def PdWriteVBROADCASTF128 : SchedWriteRes<[PdFPU01, PdFPFMA]> {
933 let ReleaseAtCycles = [1, 3];
936 def : InstRW<[PdWriteVBROADCASTF128], (instrs VBROADCASTF128rm)>;
938 defm : PdWriteResXMMPair<WriteFVarShuffle, [PdFPU1, PdFPXBR], 3>;
939 defm : PdWriteResYMMPair<WriteFVarShuffleY, [PdFPU1, PdFPXBR], 3, [2, 2], 2>;
940 defm : X86WriteResPairUnsupported<WriteFVarShuffleZ>;
942 defm : PdWriteResXMMPair<WriteFBlend, [PdFPU23, PdFPMAL], 2>;
943 defm : PdWriteResYMMPair<WriteFBlendY, [PdFPU23, PdFPMAL], 2, [2, 2], 2>;
944 defm : X86WriteResPairUnsupported<WriteFBlendZ>;
946 defm : PdWriteResXMMPair<WriteFVarBlend, [PdFPU1, PdFPXBR], 2>;
947 defm : PdWriteResYMMPair<WriteFVarBlendY, [PdFPU1, PdFPXBR], 2, [2, 2], 2>;
948 defm : X86WriteResPairUnsupported<WriteFVarBlendZ>;
950 defm : PdWriteResXMMPair<WriteFShuffle256, [PdFPU01, PdFPFMA], 2, [1, 3], 2>;
951 defm : X86WriteResPairUnsupported<WriteFVarShuffle256>;
953 def PdWriteVEXTRACTF128rr : SchedWriteRes<[PdFPU01, PdFPFMA]> {
955 let ReleaseAtCycles = [1, 2];
957 def : InstRW<[PdWriteVEXTRACTF128rr], (instrs VEXTRACTF128rr)>;
959 def PdWriteVEXTRACTF128mr : SchedWriteRes<[PdFPU01, PdFPFMA]> {
961 let ReleaseAtCycles = [1, 4];
964 def : InstRW<[PdWriteVEXTRACTF128mr], (instrs VEXTRACTF128mr)>;
966 def PdWriteVPERM2F128rr : SchedWriteRes<[PdFPU01, PdFPFMA]> {
968 let ReleaseAtCycles = [1, 6];
971 def : InstRW<[PdWriteVPERM2F128rr], (instrs VPERM2F128rr)>;
973 def PdWriteVPERM2F128rm : SchedWriteRes<[PdFPU01, PdFPFMA]> {
974 let Latency = 8; // 4 + 4
975 let ReleaseAtCycles = [1, 8];
976 let NumMicroOps = 10;
978 def : InstRW<[PdWriteVPERM2F128rm], (instrs VPERM2F128rm)>;
980 ////////////////////////////////////////////////////////////////////////////////
982 ////////////////////////////////////////////////////////////////////////////////
984 defm : PdWriteResXMMPair<WriteCvtSS2I, [PdFPU0, PdFPCVT, PdFPSTO, PdFPFMA, PdEX0], 13, [], 2>;
986 defm : PdWriteResXMMPair<WriteCvtPS2I, [PdFPU0, PdFPCVT, PdFPSTO], 4>;
987 defm : PdWriteResYMMPair<WriteCvtPS2IY, [PdFPU0, PdFPCVT, PdFPSTO], 4, [1, 2, 1]>;
988 defm : X86WriteResPairUnsupported<WriteCvtPS2IZ>;
990 defm : PdWriteResXMMPair<WriteCvtSD2I, [PdFPU0, PdFPCVT, PdFPSTO, PdFPFMA, PdEX0], 13, [], 2>;
992 defm : PdWriteResXMMPair<WriteCvtPD2I, [PdFPU0, PdFPCVT, PdFPSTO], 8, [], 2>;
993 defm : PdWriteResYMMPair<WriteCvtPD2IY, [PdFPU0, PdFPCVT, PdFPSTO, PdFPFMA], 8, [1, 2, 1, 1], 4>;
994 defm : X86WriteResPairUnsupported<WriteCvtPD2IZ>;
996 def PdWriteMMX_CVTTPD2PIrr : SchedWriteRes<[PdFPU0, PdFPCVT, PdFPSTO]> {
1000 def : InstRW<[PdWriteMMX_CVTTPD2PIrr], (instrs MMX_CVTTPD2PIrr)>;
1002 // FIXME: f+3 ST, LD+STC latency
1003 defm : PdWriteResXMMPair<WriteCvtI2SS, [PdFPU0, PdFPCVT, PdFPSTO], 4, [], 2>;
1004 // FIXME: .Folded version is one NumMicroOp *less*..
1006 defm : PdWriteResXMMPair<WriteCvtI2PS, [PdFPU0, PdFPCVT, PdFPSTO], 4>;
1007 defm : PdWriteResYMMPair<WriteCvtI2PSY, [PdFPU0, PdFPCVT, PdFPSTO], 4, [1, 2, 1]>;
1008 defm : X86WriteResPairUnsupported<WriteCvtI2PSZ>;
1010 defm : PdWriteResXMMPair<WriteCvtI2SD, [PdFPU0, PdFPCVT, PdFPSTO], 4, [], 2>;
1011 // FIXME: .Folded version is one NumMicroOp *less*..
1013 def PdWriteCVTSI642SDrr_CVTSI642SSrr_CVTSI2SDr_CVTSI2SSrr : SchedWriteRes<[PdFPU0, PdFPCVT, PdFPSTO]> {
1015 let ReleaseAtCycles = [1, 3, 1];
1016 let NumMicroOps = 2;
1018 def : InstRW<[PdWriteCVTSI642SDrr_CVTSI642SSrr_CVTSI2SDr_CVTSI2SSrr], (instrs CVTSI642SDrr, CVTSI642SSrr, CVTSI2SDrr, CVTSI2SSrr)>;
1020 defm : PdWriteResXMMPair<WriteCvtI2PD, [PdFPU0, PdFPCVT, PdFPSTO], 8, [], 2>;
1021 defm : PdWriteResYMMPair<WriteCvtI2PDY, [PdFPU0, PdFPCVT, PdFPSTO], 8, [1, 2, 1], 4, 1>;
1022 defm : X86WriteResPairUnsupported<WriteCvtI2PDZ>;
1024 defm : PdWriteResXMMPair<WriteCvtSS2SD, [PdFPU0, PdFPCVT, PdFPSTO], 4, [1, 2, 1]>;
1026 defm : PdWriteResXMMPair<WriteCvtPS2PD, [PdFPU0, PdFPCVT, PdFPSTO], 8, [], 2>;
1027 defm : PdWriteResYMMPair<WriteCvtPS2PDY, [PdFPU0, PdFPCVT, PdFPSTO], 8, [1, 2, 1], 4, 1>;
1028 defm : X86WriteResPairUnsupported<WriteCvtPS2PDZ>;
1030 defm : PdWriteResXMMPair<WriteCvtSD2SS, [PdFPU0, PdFPCVT, PdFPSTO], 4, [1, 2, 1]>;
1032 defm : PdWriteResXMMPair<WriteCvtPD2PS, [PdFPU0, PdFPCVT, PdFPSTO], 8, [], 2>;
1033 defm : PdWriteResYMMPair<WriteCvtPD2PSY, [PdFPU0, PdFPCVT, PdFPSTO, PdFPFMA], 8, [1, 2, 1, 1], 4>;
1034 defm : X86WriteResPairUnsupported<WriteCvtPD2PSZ>;
1036 def PdWriteMMX_CVTPD2PIrrMMX_CVTPI2PDrr : SchedWriteRes<[PdFPU0, PdFPCVT, PdFPSTO]> {
1038 let NumMicroOps = 2;
1040 def : InstRW<[PdWriteMMX_CVTPD2PIrrMMX_CVTPI2PDrr], (instrs MMX_CVTPD2PIrr,
1043 def PdWriteMMX_CVTPI2PSrr : SchedWriteRes<[PdFPU0, PdFPCVT, PdFPSTO]> {
1045 let NumMicroOps = 2;
1047 def : InstRW<[PdWriteMMX_CVTPI2PSrr], (instrs MMX_CVTPI2PSrr)>;
1049 defm : PdWriteResXMMPair<WriteCvtPH2PS, [PdFPU0, PdFPCVT, PdFPSTO], 8, [1, 2, 1], 2, 1>;
1050 defm : PdWriteResYMMPair<WriteCvtPH2PSY, [PdFPU0, PdFPCVT, PdFPSTO], 8, [1, 2, 1], 4, 3>;
1051 defm : X86WriteResPairUnsupported<WriteCvtPH2PSZ>;
1053 defm : PdWriteRes<WriteCvtPS2PH, [PdFPU0, PdFPCVT, PdFPSTO], 8, [1, 2, 1], 2>;
1054 defm : PdWriteRes<WriteCvtPS2PHY, [PdFPU0, PdFPCVT, PdFPSTO, PdFPFMA], 8, [1, 2, 1, 1], 4>;
1055 defm : X86WriteResUnsupported<WriteCvtPS2PHZ>;
1057 defm : PdWriteRes<WriteCvtPS2PHSt, [PdFPU0, PdFPCVT, PdFPSTO, PdStore], 4, [1, 2, 1, 1], 3>;
1058 defm : PdWriteRes<WriteCvtPS2PHYSt, [PdFPU0, PdFPCVT, PdFPSTO, PdFPFMA, PdStore], 4, [1, 2, 1, 1, 1], 4>;
1059 defm : X86WriteResUnsupported<WriteCvtPS2PHZSt>;
1061 ////////////////////////////////////////////////////////////////////////////////
1062 // Vector integer operations.
1063 ////////////////////////////////////////////////////////////////////////////////
1065 defm : PdWriteRes<WriteVecLoad, [PdLoad, PdFPU01, PdFPMAL], 5, [3, 1, 3]>;
1066 defm : PdWriteRes<WriteVecLoadX, [PdLoad, PdFPU01, PdFPMAL], 5, [3, 1, 3]>;
1067 defm : PdWriteRes<WriteVecLoadY, [PdLoad, PdFPU01, PdFPMAL], 5, [3, 2, 3], 2>;
1069 defm : PdWriteRes<WriteVecLoadNT, [PdLoad, PdFPU01, PdFPMAL], 5, [3, 1, 4]>;
1070 defm : PdWriteRes<WriteVecLoadNTY, [PdLoad, PdFPU01, PdFPMAL], 5, [3, 2, 4]>;
1072 defm : PdWriteRes<WriteVecMaskedLoad, [PdLoad, PdFPU01, PdFPMAL], 6, [3, 1, 2]>;
1073 defm : PdWriteRes<WriteVecMaskedLoadY, [PdLoad, PdFPU01, PdFPMAL], 6, [3, 2, 4], 2>;
1075 defm : PdWriteRes<WriteVecStore, [PdStore, PdFPU23, PdFPSTO], 2, [1, 3, 1]>;
1076 defm : PdWriteRes<WriteVecStoreX, [PdStore, PdFPU23, PdFPSTO], 1, [1, 3, 1]>;
1077 defm : PdWriteRes<WriteVecStoreY, [PdStore, PdFPU23, PdFPSTO], 1, [2, 36, 2], 4>;
1079 def PdWriteVMOVDQUYmr : SchedWriteRes<[PdStore, PdFPU1, PdFPSTO]> {
1080 let NumMicroOps = 8;
1082 def : InstRW<[PdWriteVMOVDQUYmr], (instrs VMOVDQUYmr)>;
1084 defm : PdWriteRes<WriteVecStoreNT, [PdStore, PdFPU1, PdFPSTO], 2>;
1085 defm : PdWriteRes<WriteVecStoreNTY, [PdStore, PdFPU1, PdFPSTO], 2, [2, 2, 2], 4>;
1087 defm : X86WriteResUnsupported<WriteVecMaskedStore32>;
1088 defm : X86WriteResUnsupported<WriteVecMaskedStore32Y>;
1089 defm : X86WriteResUnsupported<WriteVecMaskedStore64>;
1090 defm : X86WriteResUnsupported<WriteVecMaskedStore64Y>;
1092 defm : PdWriteRes<WriteVecMove, [PdFPU01, PdFPMAL], 2>;
1093 defm : PdWriteRes<WriteVecMoveX, [PdFPU01, PdFPMAL], 1, [1, 2]>;
1094 defm : PdWriteRes<WriteVecMoveY, [PdFPU01, PdFPMAL], 2, [2, 2], 2>;
1095 defm : X86WriteResUnsupported<WriteVecMoveZ>;
1097 def PdWriteMOVDQArr : SchedWriteRes<[PdFPU01, PdFPMAL]> {
1099 def : InstRW<[PdWriteMOVDQArr], (instrs MOVDQArr)>;
1101 def PdWriteMOVQ2DQrr : SchedWriteRes<[PdFPU01, PdFPMAL]> {
1104 def : InstRW<[PdWriteMOVQ2DQrr], (instrs MMX_MOVQ2DQrr)>;
1106 defm : PdWriteRes<WriteVecMoveToGpr, [PdFPU0, PdFPFMA, PdEX0], 11>;
1107 defm : PdWriteRes<WriteVecMoveFromGpr, [PdFPU01, PdFPFMA], 11, [1, 2], 2>;
1109 defm : PdWriteResXMMPair<WriteVecALU, [PdFPU23, PdFPMAL], 2>;
1110 defm : PdWriteResXMMPair<WriteVecALUX, [PdFPU23, PdFPMAL], 2>;
1111 defm : X86WriteResPairUnsupported<WriteVecALUY>;
1112 defm : X86WriteResPairUnsupported<WriteVecALUZ>;
1114 defm : PdWriteResXMMPair<WriteVecShift, [PdFPU1, PdFPXBR], 3>;
1115 defm : PdWriteResXMMPair<WriteVecShiftX, [PdFPU1, PdFPXBR], 3>;
1116 defm : X86WriteResPairUnsupported<WriteVecShiftY>;
1117 defm : X86WriteResPairUnsupported<WriteVecShiftZ>;
1119 defm : PdWriteResXMMPair<WriteVecShiftImm, [PdFPU1, PdFPXBR], 2>;
1120 defm : PdWriteResXMMPair<WriteVecShiftImmX, [PdFPU1, PdFPXBR], 2>;
1121 defm : X86WriteResPairUnsupported<WriteVecShiftImmY>;
1122 defm : X86WriteResPairUnsupported<WriteVecShiftImmZ>;
1124 defm : PdWriteResXMMPair<WriteVecIMul, [PdFPU0, PdFPMMA], 4>;
1125 defm : PdWriteResXMMPair<WriteVecIMulX, [PdFPU0, PdFPMMA], 4>;
1126 defm : X86WriteResPairUnsupported<WriteVecIMulY>;
1127 defm : X86WriteResPairUnsupported<WriteVecIMulZ>;
1129 defm : PdWriteResXMMPair<WritePMULLD, [PdFPU0, PdFPU01, PdFPMMA, PdFPMAL], 5, [2, 1, 2, 1]>;
1130 defm : X86WriteResPairUnsupported<WritePMULLDY>;
1131 defm : X86WriteResPairUnsupported<WritePMULLDZ>;
1133 def PdWriteVPMACS : SchedWriteRes<[PdFPU0, PdFPMMA, PdFPMAL]> {
1136 def : InstRW<[PdWriteVPMACS], (instrs VPMACSDQHrr, VPMACSDQLrr, VPMACSSDQHrr,
1139 // FIXME: Investigate RR vs RM differences.
1140 defm : PdWriteRes<WriteMPSAD, [PdFPU0, PdFPMMA], 8, [1, 4], 8>;
1141 defm : PdWriteRes<WriteMPSADLd, [PdFPU0, PdFPMMA, PdLoad], 14, [1, 4, 3], 8>;
1142 defm : X86WriteResPairUnsupported<WriteMPSADY>;
1143 defm : X86WriteResPairUnsupported<WriteMPSADZ>;
1145 defm : PdWriteResXMMPair<WritePSADBW, [PdFPU01, PdFPMAL], 4, [1, 2], 2>;
1146 defm : PdWriteResXMMPair<WritePSADBWX, [PdFPU01, PdFPMAL], 4, [1, 2], 2>;
1147 defm : X86WriteResPairUnsupported<WritePSADBWY>;
1148 defm : X86WriteResPairUnsupported<WritePSADBWZ>;
1150 defm : PdWriteResXMMPair<WritePHMINPOS, [PdFPU0, PdFPMAL], 4, [], 2>;
1152 defm : PdWriteResXMMPair<WriteShuffle, [PdFPU1, PdFPXBR], 2>;
1153 defm : PdWriteResXMMPair<WriteShuffleX, [PdFPU1, PdFPXBR], 2>;
1154 defm : PdWriteResYMMPair<WriteShuffleY, [PdFPU1, PdFPXBR], 2, [2, 2]>;
1155 defm : X86WriteResPairUnsupported<WriteShuffleZ>;
1157 defm : PdWriteResXMMPair<WriteVarShuffle, [PdFPU1, PdFPXBR], 3>;
1158 defm : PdWriteResXMMPair<WriteVarShuffleX, [PdFPU1, PdFPXBR], 3>;
1159 defm : X86WriteResPairUnsupported<WriteVarShuffleY>;
1160 defm : X86WriteResPairUnsupported<WriteVarShuffleZ>;
1162 def PdWriteVPPERM : SchedWriteRes<[PdFPU1, PdFPXBR]> {
1164 let ReleaseAtCycles = [1, 1];
1166 def : InstRW<[PdWriteVPPERM], (instrs VPPERMrrr, VPPERMrrr_REV)>;
1168 def PdWriteVPPERMLd : SchedWriteRes<[PdFPU1, PdFPXBR, PdLoad]> {
1170 let ReleaseAtCycles = [1, 1, 3];
1172 def : InstRW<[PdWriteVPPERMLd], (instrs VPPERMrrm, VPPERMrmr)>;
1174 defm : PdWriteResXMMPair<WriteBlend, [PdFPU23, PdFPMAL], 2>;
1175 defm : X86WriteResPairUnsupported<WriteBlendY>;
1176 defm : X86WriteResPairUnsupported<WriteBlendZ>;
1178 defm : PdWriteResXMMPair<WriteVarBlend, [PdFPU1, PdFPXBR], 2>;
1179 defm : X86WriteResPairUnsupported<WriteVarBlendY>;
1180 defm : X86WriteResPairUnsupported<WriteVarBlendZ>;
1182 defm : PdWriteResXMMPair<WriteVecLogic, [PdFPU23, PdFPMAL], 2>;
1183 defm : PdWriteResXMMPair<WriteVecLogicX, [PdFPU23, PdFPMAL], 2>;
1184 defm : X86WriteResPairUnsupported<WriteVecLogicY>;
1185 defm : X86WriteResPairUnsupported<WriteVecLogicZ>;
1187 defm : PdWriteResXMMPair<WriteVecTest, [PdFPU0, PdFPFMA, PdEX0], 1, [], 2>;
1188 defm : PdWriteResYMMPair<WriteVecTestY, [PdFPU01, PdFPFMA, PdEX0], 1, [2, 4, 1], 4, 2>;
1189 defm : X86WriteResPairUnsupported<WriteVecTestZ>;
1191 defm : PdWriteResXMMPair<WriteShuffle256, [PdFPU01, PdFPMAL]>;
1192 defm : PdWriteResXMMPair<WriteVPMOV256, [PdFPU01, PdFPMAL]>;
1193 defm : PdWriteResXMMPair<WriteVarShuffle256, [PdFPU01, PdFPMAL]>;
1195 defm : PdWriteResXMMPair<WriteVarVecShift, [PdFPU1, PdFPXBR], 3>;
1196 defm : X86WriteResPairUnsupported<WriteVarVecShiftY>;
1197 defm : X86WriteResPairUnsupported<WriteVarVecShiftZ>;
1199 ////////////////////////////////////////////////////////////////////////////////
1200 // Vector insert/extract operations.
1201 ////////////////////////////////////////////////////////////////////////////////
1203 defm : PdWriteRes<WriteVecInsert, [PdFPU01, PdFPMAL], 2, [1, 3], 2>;
1204 defm : PdWriteRes<WriteVecInsertLd, [PdFPU01, PdFPMAL, PdLoad], 6, [1, 4, 3], 2>;
1206 defm : PdWriteRes<WriteVecExtract, [PdFPU0, PdFPFMA, PdEX0], 12, [1, 3, 1], 2>;
1207 defm : PdWriteRes<WriteVecExtractSt, [PdFPU1, PdFPSTO, PdStore], 13, [2, 1, 1], 2>;
1209 def PdWriteEXTRQ : SchedWriteRes<[PdFPU01, PdFPMAL]> {
1211 let ReleaseAtCycles = [1, 3];
1213 def : InstRW<[PdWriteEXTRQ], (instrs EXTRQ, EXTRQI)>;
1215 ////////////////////////////////////////////////////////////////////////////////
1216 // SSE42 String instructions.
1217 ////////////////////////////////////////////////////////////////////////////////
1219 defm : PdWriteResXMMPair<WritePCmpIStrI, [PdFPU1, PdFPFMA, PdEX0], 11, [1, 6, 1], 7, 1>;
1220 defm : PdWriteResXMMPair<WritePCmpIStrM, [PdFPU1, PdFPFMA, PdEX0], 7, [1, 8, 1], 7, 2>;
1222 defm : PdWriteResXMMPair<WritePCmpEStrI, [PdFPU1, PdStore, PdLoad, PdFPMAL, PdFPFMA, PdEX0], 14, [1, 10, 10, 10, 1, 1], 27, 1>;
1223 defm : PdWriteResXMMPair<WritePCmpEStrM, [PdFPU1, PdStore, PdLoad, PdFPMAL, PdFPFMA, PdEX0], 10, [1, 10, 10, 10, 1, 1], 27, 1>;
1225 ////////////////////////////////////////////////////////////////////////////////
1226 // MOVMSK Instructions.
1227 ////////////////////////////////////////////////////////////////////////////////
1229 defm : PdWriteRes<WriteFMOVMSK, [PdFPU0, PdFPFMA, PdEX0], 12, [], 2>;
1231 defm : PdWriteRes<WriteVecMOVMSK, [PdFPU0, PdFPFMA, PdEX0], 12, [], 2>;
1232 defm : X86WriteResUnsupported<WriteVecMOVMSKY>;
1233 // defm : X86WriteResUnsupported<WriteVecMOVMSKZ>;
1235 defm : PdWriteRes<WriteMMXMOVMSK, [PdFPU0, PdFPFMA, PdEX0], 10, [], 2>;
1237 ////////////////////////////////////////////////////////////////////////////////
1238 // AES Instructions.
1239 ////////////////////////////////////////////////////////////////////////////////
1241 defm : PdWriteResXMMPair<WriteAESIMC, [PdFPU0, PdFPMMA], 5>;
1242 defm : PdWriteResXMMPair<WriteAESKeyGen, [PdFPU0, PdFPMMA], 5>;
1243 defm : PdWriteResXMMPair<WriteAESDecEnc, [PdFPU0, PdFPMMA], 9, [], 2>;
1245 ////////////////////////////////////////////////////////////////////////////////
1246 // Horizontal add/sub instructions.
1247 ////////////////////////////////////////////////////////////////////////////////
1249 defm : PdWriteResXMMPair<WriteFHAdd, [PdFPU0, PdFPFMA], 11, [1, 5], 3, 1>;
1250 defm : PdWriteResYMMPair<WriteFHAddY, [PdFPU0, PdFPFMA], 11, [1, 8], 8, 2>;
1251 defm : X86WriteResPairUnsupported<WriteFHAddZ>;
1253 defm : PdWriteResXMMPair<WritePHAdd, [PdFPU01, PdFPMAL], 5, [1, 4], 3, 1>;
1254 defm : PdWriteResXMMPair<WritePHAddX, [PdFPU01, PdFPMAL], 2, [1, 2]>;
1255 defm : X86WriteResPairUnsupported<WritePHAddY>;
1256 defm : X86WriteResPairUnsupported<WritePHAddZ>;
1258 def : InstRW<[WritePHAdd], (instrs PHADDDrr, PHSUBDrr,
1260 PHADDSWrr, PHSUBSWrr,
1261 VPHADDDrr, VPHSUBDrr,
1262 VPHADDWrr, VPHSUBWrr,
1263 VPHADDSWrr, VPHSUBSWrr)>;
1265 def : InstRW<[WritePHAdd.Folded], (instrs PHADDDrm, PHSUBDrm,
1267 PHADDSWrm, PHSUBSWrm,
1268 VPHADDDrm, VPHSUBDrm,
1269 VPHADDWrm, VPHSUBWrm,
1270 VPHADDSWrm, VPHSUBSWrm)>;
1272 ////////////////////////////////////////////////////////////////////////////////
1273 // Carry-less multiplication instructions.
1274 ////////////////////////////////////////////////////////////////////////////////
1276 defm : PdWriteResXMMPair<WriteCLMul, [PdFPU0, PdFPMMA], 12, [1, 7], 5, 1>;
1278 def PdWriteVPCLMULQDQrr : SchedWriteRes<[PdFPU0, PdFPMMA]> {
1280 let ReleaseAtCycles = [1, 7];
1281 let NumMicroOps = 6;
1283 def : InstRW<[PdWriteVPCLMULQDQrr], (instrs VPCLMULQDQrr)>;
1285 ////////////////////////////////////////////////////////////////////////////////
1286 // SSE4A instructions.
1287 ////////////////////////////////////////////////////////////////////////////////
1289 def PdWriteINSERTQ : SchedWriteRes<[PdFPU01, PdFPMAL]> {
1291 let ReleaseAtCycles = [1, 2];
1293 def : InstRW<[PdWriteINSERTQ], (instrs INSERTQ)>;
1295 def PdWriteINSERTQI : SchedWriteRes<[PdFPU01, PdFPMAL]> {
1297 let ReleaseAtCycles = [1, 3];
1299 def : InstRW<[PdWriteINSERTQI], (instrs INSERTQI)>;
1301 ////////////////////////////////////////////////////////////////////////////////
1302 // AVX instructions.
1303 ////////////////////////////////////////////////////////////////////////////////
1305 def PdWriteVBROADCASTYLd : SchedWriteRes<[PdLoad, PdFPU01, PdFPFMA]> {
1307 let ReleaseAtCycles = [1, 2, 4];
1308 let NumMicroOps = 2;
1310 def : InstRW<[PdWriteVBROADCASTYLd, ReadAfterLd], (instrs VBROADCASTSDYrm,
1313 def PdWriteVZEROALL : SchedWriteRes<[]> {
1315 let NumMicroOps = 32;
1317 def : InstRW<[PdWriteVZEROALL], (instrs VZEROALL)>;
1319 def PdWriteVZEROUPPER : SchedWriteRes<[]> {
1321 let NumMicroOps = 16;
1323 def : InstRW<[PdWriteVZEROUPPER], (instrs VZEROUPPER)>;
1325 ///////////////////////////////////////////////////////////////////////////////
1326 // SchedWriteVariant definitions.
1327 ///////////////////////////////////////////////////////////////////////////////
1329 def PdWriteZeroLatency : SchedWriteRes<[]> {
1333 def PdWriteZeroIdiom : SchedWriteVariant<[
1334 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [PdWriteZeroLatency]>,
1335 SchedVar<MCSchedPredicate<TruePred>, [WriteALU]>
1337 def : InstRW<[PdWriteZeroIdiom], (instrs SUB32rr, SUB64rr,
1340 def PdWriteFZeroIdiom : SchedWriteVariant<[
1341 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [PdWriteZeroLatency]>,
1342 SchedVar<MCSchedPredicate<TruePred>, [WriteFLogic]>
1344 def : InstRW<[PdWriteFZeroIdiom], (instrs XORPSrr, VXORPSrr,
1346 ANDNPSrr, VANDNPSrr,
1347 ANDNPDrr, VANDNPDrr)>;
1349 // VXORPSYrr, VXORPDYrr, VANDNPSYrr, VANDNPDYrr "zero-idioms" have latency of 1.
1351 def PdWriteVZeroIdiomLogic : SchedWriteVariant<[
1352 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [PdWriteZeroLatency]>,
1353 SchedVar<MCSchedPredicate<TruePred>, [WriteVecLogic]>
1355 def : InstRW<[PdWriteVZeroIdiomLogic], (instrs MMX_PXORrr, MMX_PANDNrr)>;
1357 def PdWriteVZeroIdiomLogicX : SchedWriteVariant<[
1358 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [PdWriteZeroLatency]>,
1359 SchedVar<MCSchedPredicate<TruePred>, [WriteVecLogicX]>
1361 def : InstRW<[PdWriteVZeroIdiomLogicX], (instrs PXORrr, VPXORrr,
1362 PANDNrr, VPANDNrr)>;
1364 def PdWriteVZeroIdiomALU : SchedWriteVariant<[
1365 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [PdWriteZeroLatency]>,
1366 SchedVar<MCSchedPredicate<TruePred>, [WriteVecALU]>
1368 def : InstRW<[PdWriteVZeroIdiomALU], (instrs MMX_PSUBBrr, MMX_PSUBDrr,
1369 MMX_PSUBQrr, MMX_PSUBWrr,
1374 def PdWriteVZeroIdiomALUX : SchedWriteVariant<[
1375 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [PdWriteZeroLatency]>,
1376 SchedVar<MCSchedPredicate<TruePred>, [WriteVecALUX]>
1378 def : InstRW<[PdWriteVZeroIdiomALUX], (instrs PSUBBrr, VPSUBBrr,
1382 PCMPGTBrr, VPCMPGTBrr,
1383 PCMPGTDrr, VPCMPGTDrr,
1384 PCMPGTWrr, VPCMPGTWrr)>;
1386 ///////////////////////////////////////////////////////////////////////////////
1387 // Dependency breaking instructions.
1388 ///////////////////////////////////////////////////////////////////////////////
1390 // VPCMPGTQ, but not PCMPGTQ!
1392 def : IsZeroIdiomFunction<[
1394 DepBreakingClass<[ SUB32rr, SUB64rr, XOR32rr, XOR64rr ], ZeroIdiomPredicate>,
1398 MMX_PXORrr, MMX_PANDNrr, MMX_PSUBBrr,
1399 MMX_PSUBDrr, MMX_PSUBQrr, MMX_PSUBWrr,
1400 MMX_PSUBSBrr, MMX_PSUBSWrr, MMX_PSUBUSBrr, MMX_PSUBUSWrr,
1401 MMX_PCMPGTBrr, MMX_PCMPGTDrr, MMX_PCMPGTWrr
1402 ], ZeroIdiomPredicate>,
1407 XORPSrr, XORPDrr, ANDNPSrr, ANDNPDrr,
1411 PSUBBrr, PSUBWrr, PSUBDrr, PSUBQrr,
1412 PSUBSBrr, PSUBSWrr, PSUBUSBrr, PSUBUSWrr,
1413 PCMPGTBrr, PCMPGTDrr, PCMPGTWrr
1414 ], ZeroIdiomPredicate>,
1419 VXORPSrr, VXORPDrr, VANDNPSrr, VANDNPDrr,
1421 // xmm int variants.
1423 VPSUBBrr, VPSUBWrr, VPSUBDrr, VPSUBQrr,
1424 VPSUBSBrr, VPSUBSWrr, VPSUBUSBrr, VPSUBUSWrr,
1425 VPCMPGTBrr, VPCMPGTWrr, VPCMPGTDrr, VPCMPGTQrr,
1428 VXORPSYrr, VXORPDYrr, VANDNPSYrr, VANDNPDYrr
1429 ], ZeroIdiomPredicate>
1432 def : IsDepBreakingFunction<[
1434 DepBreakingClass<[ SBB32rr, SBB64rr ], ZeroIdiomPredicate>,
1435 DepBreakingClass<[ CMP32rr, CMP64rr ], CheckSameRegOperand<0, 1> >,
1439 MMX_PCMPEQBrr, MMX_PCMPEQDrr, MMX_PCMPEQWrr
1440 ], ZeroIdiomPredicate>,
1444 PCMPEQBrr, PCMPEQWrr, PCMPEQDrr
1445 // But not PCMPEQQrr.
1446 ], ZeroIdiomPredicate>,
1450 VPCMPEQBrr, VPCMPEQWrr, VPCMPEQDrr
1451 // But not VPCMPEQQrr.
1452 ], ZeroIdiomPredicate>