1056 lines · plain
1//=- X86ScheduleBtVer2.td - X86 BtVer2 (Jaguar) Scheduling ---*- tablegen -*-=//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines the machine model for AMD btver2 (Jaguar) to support10// instruction scheduling and other instruction cost heuristics. Based off AMD Software11// Optimization Guide for AMD Family 16h Processors & Instruction Latency appendix.12//13//===----------------------------------------------------------------------===//14 15def BtVer2Model : SchedMachineModel {16 // All x86 instructions are modeled as a single micro-op, and btver2 can17 // decode 2 instructions per cycle.18 let IssueWidth = 2;19 let MicroOpBufferSize = 64; // Retire Control Unit20 let LoadLatency = 5; // FPU latency (worse case cf Integer 3 cycle latency)21 let HighLatency = 25;22 let MispredictPenalty = 14; // Minimum branch misdirection penalty23 let PostRAScheduler = 1;24 25 // FIXME: SSE4/AVX is unimplemented. This flag is set to allow26 // the scheduler to assign a default model to unrecognized opcodes.27 let CompleteModel = 0;28}29 30let SchedModel = BtVer2Model in {31 32// Jaguar can issue up to 6 micro-ops in one cycle33def JALU0 : ProcResource<1>; // Integer Pipe0: integer ALU0 (also handle FP->INT jam)34def JALU1 : ProcResource<1>; // Integer Pipe1: integer ALU1/MUL/DIV35def JLAGU : ProcResource<1>; // Integer Pipe2: LAGU36def JSAGU : ProcResource<1>; // Integer Pipe3: SAGU (also handles 3-operand LEA)37def JFPU0 : ProcResource<1>; // Vector/FPU Pipe0: VALU0/VIMUL/FPA38def JFPU1 : ProcResource<1>; // Vector/FPU Pipe1: VALU1/STC/FPM39 40// The Integer PRF for Jaguar is 64 entries, and it holds the architectural and41// speculative version of the 64-bit integer registers.42// Reference: www.realworldtech.com/jaguar/4/43//44// The processor always keeps the different parts of an integer register45// together. An instruction that writes to a part of a register will therefore46// have a false dependence on any previous write to the same register or any47// part of it.48// Reference: Section 21.10 "AMD Bobcat and Jaguar pipeline: Partial register49// access" - Agner Fog's "microarchitecture.pdf".50def 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.53 54// The Jaguar FP Retire Queue renames SIMD and FP uOps onto a pool of 72 SSE55// registers. Operations on 256-bit data types are cracked into two COPs.56// Reference: www.realworldtech.com/jaguar/4/57 58// The PRF in the floating point unit can eliminate a move from a MMX or SSE59// register that is know to be zero (i.e. it has been zeroed using a zero-idiom60// dependency breaking instruction, or via VZEROALL).61// Reference: Section 21.8 "AMD Bobcat and Jaguar pipeline: Dependency-breaking62// instructions" - Agner Fog's "microarchitecture.pdf"63def 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.66 67// The retire control unit (RCU) can track up to 64 macro-ops in-flight. It can68// retire up to two macro-ops per cycle.69// Reference: "Software Optimization Guide for AMD Family 16h Processors"70def JRCU : RetireControlUnit<64, 2>;71 72// Integer Pipe Scheduler73def JALU01 : ProcResGroup<[JALU0, JALU1]> {74 let BufferSize=20;75}76 77// AGU Pipe Scheduler78def JLSAGU : ProcResGroup<[JLAGU, JSAGU]> {79 let BufferSize=12;80}81 82// Fpu Pipe Scheduler83def JFPU01 : ProcResGroup<[JFPU0, JFPU1]> {84 let BufferSize=18;85}86 87// Functional units88def JDiv : ProcResource<1>; // integer division89def JMul : ProcResource<1>; // integer multiplication90def JVALU0 : ProcResource<1>; // vector integer91def JVALU1 : ProcResource<1>; // vector integer92def JVIMUL : ProcResource<1>; // vector integer multiplication93def JSTC : ProcResource<1>; // vector store/convert94def JFPM : ProcResource<1>; // FP multiplication95def JFPA : ProcResource<1>; // FP addition96 97// Functional unit groups98def JFPX : ProcResGroup<[JFPA, JFPM]>;99def JVALU : ProcResGroup<[JVALU0, JVALU1]>;100 101// Integer loads are 3 cycles, so ReadAfterLd registers needn't be available until 3102// cycles after the memory operand.103def : ReadAdvance<ReadAfterLd, 3>;104 105// Vector loads are 5 cycles, so ReadAfterVec*Ld registers needn't be available until 5106// cycles after the memory operand.107def : ReadAdvance<ReadAfterVecLd, 5>;108def : ReadAdvance<ReadAfterVecXLd, 5>;109def : ReadAdvance<ReadAfterVecYLd, 5>;110 111/// "Additional 6 cycle transfer operation which moves a floating point112/// operation input value from the integer unit to the floating point unit.113/// Reference: AMDfam16h SOG (Appendix A "Instruction Latencies", Section A.2).114def : ReadAdvance<ReadInt2Fpu, -6>;115 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 appear118// as two micro-ops when dispatched by the schedulers.119// This multiclass defines the resource usage for variants with and without120// folded loads.121multiclass JWriteResIntPair<X86FoldableSchedWrite SchedRW,122 list<ProcResourceKind> ExePorts,123 int Lat, list<int> Res = [], int UOps = 1,124 int LoadUOps = 0> {125 // Register variant is using a single cycle on ExePort.126 def : WriteRes<SchedRW, ExePorts> {127 let Latency = Lat;128 let ReleaseAtCycles = Res;129 let NumMicroOps = UOps;130 }131 132 // Memory variant also uses a cycle on JLAGU and adds 3 cycles to the133 // latency.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);138 }139}140 141multiclass JWriteResFpuPair<X86FoldableSchedWrite SchedRW,142 list<ProcResourceKind> ExePorts,143 int Lat, list<int> Res = [], int UOps = 1,144 int LoadUOps = 0> {145 // Register variant is using a single cycle on ExePort.146 def : WriteRes<SchedRW, ExePorts> {147 let Latency = Lat;148 let ReleaseAtCycles = Res;149 let NumMicroOps = UOps;150 }151 152 // Memory variant also uses a cycle on JLAGU and adds 5 cycles to the153 // latency.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);158 }159}160 161multiclass JWriteResYMMPair<X86FoldableSchedWrite SchedRW,162 list<ProcResourceKind> ExePorts,163 int Lat, list<int> Res = [2], int UOps = 2,164 int LoadUOps = 0> {165 // Register variant is using a single cycle on ExePort.166 def : WriteRes<SchedRW, ExePorts> {167 let Latency = Lat;168 let ReleaseAtCycles = Res;169 let NumMicroOps = UOps;170 }171 172 // Memory variant also uses 2 cycles on JLAGU and adds 5 cycles to the173 // latency.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);178 }179}180 181// Instructions that have local forwarding disabled have an extra +1cy latency.182 183// A folded store needs a cycle on the SAGU for the store data, most RMW184// instructions don't need an extra uop. ALU RMW operations don't seem to185// benefit from STLF, and their observed latency is 6cy. That is the reason why186// this write adds two extra cycles (instead of just 1cy for the store).187defm : X86WriteRes<WriteRMW, [JSAGU], 2, [1], 0>;188 189////////////////////////////////////////////////////////////////////////////////190// Arithmetic.191////////////////////////////////////////////////////////////////////////////////192 193defm : JWriteResIntPair<WriteALU, [JALU01], 1>;194defm : JWriteResIntPair<WriteADC, [JALU01], 1, [2]>;195 196defm : X86WriteRes<WriteBSWAP32, [JALU01], 1, [1], 1>;197defm : X86WriteRes<WriteBSWAP64, [JALU01], 1, [1], 1>;198defm : X86WriteRes<WriteCMPXCHG, [JALU01], 3, [3], 5>;199defm : X86WriteRes<WriteCMPXCHGRMW, [JALU01, JSAGU, JLAGU], 11, [3, 1, 1], 6>;200defm : X86WriteRes<WriteXCHG, [JALU01], 1, [2], 2>;201 202defm : JWriteResIntPair<WriteIMul8, [JALU1, JMul], 3, [1, 1], 1>;203defm : JWriteResIntPair<WriteIMul16, [JALU1, JMul], 3, [1, 3], 3>;204defm : JWriteResIntPair<WriteIMul16Imm, [JALU1, JMul], 4, [1, 2], 2>;205defm : JWriteResIntPair<WriteIMul16Reg, [JALU1, JMul], 3, [1, 1], 1>;206defm : JWriteResIntPair<WriteIMul32, [JALU1, JMul], 3, [1, 2], 2>;207defm : JWriteResIntPair<WriteIMul32Imm, [JALU1, JMul], 3, [1, 1], 1>;208defm : JWriteResIntPair<WriteIMul32Reg, [JALU1, JMul], 3, [1, 1], 1>;209defm : JWriteResIntPair<WriteIMul64, [JALU1, JMul], 6, [1, 4], 2>; 210defm : JWriteResIntPair<WriteIMul64Imm, [JALU1, JMul], 6, [1, 4], 1>;211defm : JWriteResIntPair<WriteIMul64Reg, [JALU1, JMul], 6, [1, 4], 1>;212defm : X86WriteResUnsupported<WriteIMulH>;213defm : X86WriteResUnsupported<WriteIMulHLd>;214defm : X86WriteResPairUnsupported<WriteMULX32>;215defm : X86WriteResPairUnsupported<WriteMULX64>;216 217defm : JWriteResIntPair<WriteDiv8, [JALU1, JDiv], 12, [1, 12], 1>;218defm : JWriteResIntPair<WriteDiv16, [JALU1, JDiv], 17, [1, 17], 2>;219defm : JWriteResIntPair<WriteDiv32, [JALU1, JDiv], 25, [1, 25], 2>;220defm : JWriteResIntPair<WriteDiv64, [JALU1, JDiv], 41, [1, 41], 2>;221defm : JWriteResIntPair<WriteIDiv8, [JALU1, JDiv], 12, [1, 12], 1>;222defm : JWriteResIntPair<WriteIDiv16, [JALU1, JDiv], 17, [1, 17], 2>;223defm : JWriteResIntPair<WriteIDiv32, [JALU1, JDiv], 25, [1, 25], 2>;224defm : JWriteResIntPair<WriteIDiv64, [JALU1, JDiv], 41, [1, 41], 2>;225 226defm : JWriteResIntPair<WriteCRC32, [JALU01], 3, [4], 3>;227 228defm : JWriteResIntPair<WriteCMOV, [JALU01], 1>; // Conditional move.229defm : X86WriteRes<WriteFCMOV, [JFPU0, JFPA], 3, [1,1], 1>; // x87 conditional move.230def : WriteRes<WriteSETCC, [JALU01]>; // Setcc.231def : WriteRes<WriteSETCCStore, [JALU01,JSAGU]>;232def : WriteRes<WriteLAHFSAHF, [JALU01]>;233 234defm : X86WriteRes<WriteBitTest, [JALU01], 1, [1], 1>;235defm : X86WriteRes<WriteBitTestImmLd, [JALU01,JLAGU], 4, [1,1], 1>;236defm : X86WriteRes<WriteBitTestRegLd, [JALU01,JLAGU], 4, [1,1], 5>;237defm : X86WriteRes<WriteBitTestSet, [JALU01], 1, [1], 2>;238defm : X86WriteRes<WriteBitTestSetImmLd, [JALU01,JLAGU], 4, [1,1], 4>;239defm : X86WriteRes<WriteBitTestSetRegLd, [JALU01,JLAGU], 4, [1,1], 8>;240 241// This is for simple LEAs with one or two input operands.242def : WriteRes<WriteLEA, [JALU01]>;243 244// Bit counts.245defm : JWriteResIntPair<WriteBSF, [JALU01], 4, [8], 7>;246defm : JWriteResIntPair<WriteBSR, [JALU01], 5, [8], 8>;247defm : JWriteResIntPair<WritePOPCNT, [JALU01], 1>;248defm : JWriteResIntPair<WriteLZCNT, [JALU01], 1>;249defm : JWriteResIntPair<WriteTZCNT, [JALU01], 2, [2], 2>;250 251// BMI1 BEXTR/BLS, BMI2 BZHI252defm : JWriteResIntPair<WriteBEXTR, [JALU01], 1>;253defm : JWriteResIntPair<WriteBLS, [JALU01], 2, [2], 2>;254defm : X86WriteResPairUnsupported<WriteBZHI>;255 256////////////////////////////////////////////////////////////////////////////////257// Integer shifts and rotates.258////////////////////////////////////////////////////////////////////////////////259 260defm : JWriteResIntPair<WriteShift, [JALU01], 1>;261defm : JWriteResIntPair<WriteShiftCL, [JALU01], 1>;262defm : JWriteResIntPair<WriteRotate, [JALU01], 1>;263defm : JWriteResIntPair<WriteRotateCL, [JALU01], 1>;264 265// SHLD/SHRD.266defm : X86WriteRes<WriteSHDrri, [JALU01], 3, [6], 6>;267defm : X86WriteRes<WriteSHDrrcl,[JALU01], 4, [8], 7>;268defm : X86WriteRes<WriteSHDmri, [JLAGU, JALU01], 9, [1, 22], 8>;269defm : X86WriteRes<WriteSHDmrcl,[JLAGU, JALU01], 9, [1, 22], 8>;270 271////////////////////////////////////////////////////////////////////////////////272// Loads, stores, and moves, not folded with other operations.273////////////////////////////////////////////////////////////////////////////////274 275def : WriteRes<WriteLoad, [JLAGU]> { let Latency = 3; }276def : WriteRes<WriteStore, [JSAGU]>;277def : WriteRes<WriteStoreNT, [JSAGU]>;278def : WriteRes<WriteMove, [JALU01]>;279defm : X86WriteResUnsupported<WriteVecMaskedGatherWriteback>;280 281// Load/store MXCSR.282def : WriteRes<WriteLDMXCSR, [JLAGU]> { let Latency = 3; }283def : WriteRes<WriteSTMXCSR, [JSAGU]>;284 285// Treat misc copies as a move.286def : InstRW<[WriteMove], (instrs COPY)>;287 288////////////////////////////////////////////////////////////////////////////////289// Idioms that clear a register, like xorps %xmm0, %xmm0.290// These can often bypass execution ports completely.291////////////////////////////////////////////////////////////////////////////////292 293def : WriteRes<WriteZero, []>;294 295////////////////////////////////////////////////////////////////////////////////296// Branches don't produce values, so they have no latency, but they still297// consume resources. Indirect branches can fold loads.298////////////////////////////////////////////////////////////////////////////////299 300defm : JWriteResIntPair<WriteJump, [JALU01], 1>;301 302////////////////////////////////////////////////////////////////////////////////303// Special case scheduling classes.304////////////////////////////////////////////////////////////////////////////////305 306def : WriteRes<WriteSystem, [JALU01]> { let Latency = 100; }307def : WriteRes<WriteMicrocoded, [JALU01]> { let Latency = 100; }308def : WriteRes<WriteFence, [JSAGU]>;309 310// Nops don't have dependencies, so there's no actual latency, but we set this311// to '1' to tell the scheduler that the nop uses an ALU slot for a cycle.312def : WriteRes<WriteNop, [JALU01]> { let Latency = 1; }313 314def JWriteCMPXCHG8rr : SchedWriteRes<[JALU01]> {315 let Latency = 3;316 let ReleaseAtCycles = [3];317 let NumMicroOps = 3;318}319 320def JWriteLOCK_CMPXCHG8rm : SchedWriteRes<[JALU01, JLAGU, JSAGU]> {321 let Latency = 16;322 let ReleaseAtCycles = [3,16,16];323 let NumMicroOps = 5;324}325 326def JWriteLOCK_CMPXCHGrm : SchedWriteRes<[JALU01, JLAGU, JSAGU]> {327 let Latency = 17;328 let ReleaseAtCycles = [3,17,17];329 let NumMicroOps = 6;330}331 332def JWriteCMPXCHG8rm : SchedWriteRes<[JALU01, JLAGU, JSAGU]> {333 let Latency = 11;334 let ReleaseAtCycles = [3,1,1];335 let NumMicroOps = 5;336}337 338def JWriteCMPXCHG8B : SchedWriteRes<[JALU01, JLAGU, JSAGU]> {339 let Latency = 11;340 let ReleaseAtCycles = [3,1,1];341 let NumMicroOps = 18;342}343 344def JWriteCMPXCHG16B : SchedWriteRes<[JALU01, JLAGU, JSAGU]> {345 let Latency = 32;346 let ReleaseAtCycles = [6,1,1];347 let NumMicroOps = 28;348}349 350def JWriteLOCK_CMPXCHG8B : SchedWriteRes<[JALU01, JLAGU, JSAGU]> {351 let Latency = 19;352 let ReleaseAtCycles = [3,19,19];353 let NumMicroOps = 18;354}355 356def JWriteLOCK_CMPXCHG16B : SchedWriteRes<[JALU01, JLAGU, JSAGU]> {357 let Latency = 38;358 let ReleaseAtCycles = [6,38,38];359 let NumMicroOps = 28;360}361 362def 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]>373]>;374 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 operands377// including the implicit read of RAX.378def : InstRW<[JWriteCMPXCHGVariant,379 ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault,380 ReadAfterLd, ReadAfterLd], (instrs LCMPXCHG8, LCMPXCHG16,381 LCMPXCHG32, LCMPXCHG64,382 CMPXCHG8rm, CMPXCHG16rm,383 CMPXCHG32rm, CMPXCHG64rm)>;384 385def : InstRW<[JWriteCMPXCHGVariant], (instrs CMPXCHG8rr, CMPXCHG16rr,386 CMPXCHG32rr, CMPXCHG64rr)>;387 388def : 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)>;394 395def JWriteLOCK_ALURMW : SchedWriteRes<[JALU01, JLAGU, JSAGU]> {396 let Latency = 19;397 let ReleaseAtCycles = [1,19,19];398 let NumMicroOps = 1;399}400 401def JWriteLOCK_ALURMWVariant : SchedWriteVariant<[402 SchedVar<MCSchedPredicate<CheckLockPrefix>, [JWriteLOCK_ALURMW]>,403 SchedVar<NoSchedPred, [WriteALURMW]>404]>;405def : InstRW<[JWriteLOCK_ALURMWVariant], (instrs INC8m, INC16m, INC32m, INC64m,406 DEC8m, DEC16m, DEC32m, DEC64m,407 NOT8m, NOT16m, NOT32m, NOT64m,408 NEG8m, NEG16m, NEG32m, NEG64m)>;409 410def JWriteXCHG8rr_XADDrr : SchedWriteRes<[JALU01]> {411 let Latency = 2;412 let ReleaseAtCycles = [3];413 let NumMicroOps = 3;414}415def : InstRW<[JWriteXCHG8rr_XADDrr], (instrs XCHG8rr, XADD8rr, XADD16rr,416 XADD32rr, XADD64rr)>;417 418// This write defines the latency of the in/out register operand of a non-atomic419// XADDrm. This is the first of a pair of writes that model non-atomic420// XADDrm instructions (the second write definition is JWriteXADDrm_LdSt_Part).421//422// We need two writes because the instruction latency differs from the output423// register operand latency. In particular, the first write describes the first424// (and only) output register operand of the instruction. However, the425// instruction latency is set to the MAX of all the write latencies. That's why426// a second write is needed in this case (see example below).427//428// Example:429// XADD %ecx, (%rsp) ## Instruction latency: 11cy430// ## ECX write Latency: 3cy431//432// Register ECX becomes available in 3 cycles. That is because the value of ECX433// is exchanged with the value read from the stack pointer, and the load-to-use434// latency is assumed to be 3cy.435def JWriteXADDrm_XCHG_Part : SchedWriteRes<[JALU01]> {436 let Latency = 3; // load-to-use latency437 let ReleaseAtCycles = [3];438 let NumMicroOps = 3;439}440 441// This write defines the latency of the in/out register operand of an atomic442// XADDrm. This is the first of a sequence of two writes used to model atomic443// XADD instructions. The second write of the sequence is JWriteXCHGrm_LdSt_Part.444//445//446// Example:447// LOCK XADD %ecx, (%rsp) ## Instruction Latency: 16cy448// ## ECX write Latency: 11cy449//450// The value of ECX becomes available only after 11cy from the start of451// execution. This write is used to specifically set that operand latency. 452def JWriteLOCK_XADDrm_XCHG_Part : SchedWriteRes<[JALU01]> {453 let Latency = 11;454 let ReleaseAtCycles = [3];455 let NumMicroOps = 3;456}457 458// This write defines the latency of the in/out register operand of an atomic459// XCHGrm. This write is the first of a sequence of two writes that describe460// atomic XCHG operations. We need two writes because the instruction latency461// differs from the output register write latency. We want to make sure that462// the output register operand becomes visible after 11cy. However, we want to463// set the instruction latency to 16cy.464def JWriteXCHGrm_XCHG_Part : SchedWriteRes<[JALU01]> {465 let Latency = 11;466 let ReleaseAtCycles = [2];467 let NumMicroOps = 2;468}469 470def JWriteXADDrm_LdSt_Part : SchedWriteRes<[JLAGU, JSAGU]> {471 let Latency = 11;472 let ReleaseAtCycles = [1, 1];473 let NumMicroOps = 1;474}475 476def JWriteXCHGrm_LdSt_Part : SchedWriteRes<[JLAGU, JSAGU]> {477 let Latency = 16;478 let ReleaseAtCycles = [16, 16];479 let NumMicroOps = 1;480}481 482def JWriteXADDrm_Part1 : SchedWriteVariant<[483 SchedVar<MCSchedPredicate<CheckLockPrefix>, [JWriteLOCK_XADDrm_XCHG_Part]>,484 SchedVar<NoSchedPred, [JWriteXADDrm_XCHG_Part]>485]>;486 487def JWriteXADDrm_Part2 : SchedWriteVariant<[488 SchedVar<MCSchedPredicate<CheckLockPrefix>, [JWriteXCHGrm_LdSt_Part]>,489 SchedVar<NoSchedPred, [JWriteXADDrm_LdSt_Part]>490]>;491 492def : InstRW<[JWriteXADDrm_Part1, JWriteXADDrm_Part2, ReadAfterLd],493 (instrs XADD8rm, XADD16rm, XADD32rm, XADD64rm,494 LXADD8, LXADD16, LXADD32, LXADD64)>;495 496def : InstRW<[JWriteXCHGrm_XCHG_Part, JWriteXCHGrm_LdSt_Part, ReadAfterLd],497 (instrs XCHG8rm, XCHG16rm, XCHG32rm, XCHG64rm)>;498 499 500////////////////////////////////////////////////////////////////////////////////501// Floating point. This covers both scalar and vector operations.502////////////////////////////////////////////////////////////////////////////////503 504defm : X86WriteRes<WriteFLD0, [JFPU1, JSTC], 3, [1,1], 1>;505defm : X86WriteRes<WriteFLD1, [JFPU1, JSTC], 3, [1,1], 1>;506defm : X86WriteRes<WriteFLDC, [JFPU1, JSTC], 3, [1,1], 1>;507defm : X86WriteRes<WriteFLoad, [JLAGU, JFPU01, JFPX], 5, [1, 1, 1], 1>;508defm : X86WriteRes<WriteFLoadX, [JLAGU], 5, [1], 1>;509defm : X86WriteRes<WriteFLoadY, [JLAGU], 5, [2], 2>;510defm : X86WriteRes<WriteFMaskedLoad, [JLAGU, JFPU01, JFPX], 6, [1, 2, 2], 1>;511defm : X86WriteRes<WriteFMaskedLoadY, [JLAGU, JFPU01, JFPX], 6, [2, 4, 4], 2>;512 513defm : X86WriteRes<WriteFStore, [JSAGU, JFPU1, JSTC], 2, [1, 1, 1], 1>;514defm : X86WriteRes<WriteFStoreX, [JSAGU, JFPU1, JSTC], 1, [1, 1, 1], 1>;515defm : X86WriteRes<WriteFStoreY, [JSAGU, JFPU1, JSTC], 1, [2, 2, 2], 2>;516defm : X86WriteRes<WriteFStoreNT, [JSAGU, JFPU1, JSTC], 3, [1, 1, 1], 1>;517defm : X86WriteRes<WriteFStoreNTX, [JSAGU, JFPU1, JSTC], 3, [1, 1, 1], 1>;518defm : X86WriteRes<WriteFStoreNTY, [JSAGU, JFPU1, JSTC], 3, [2, 2, 2], 1>;519 520defm : X86WriteRes<WriteFMaskedStore32, [JFPU0, JFPA, JFPU1, JSTC, JLAGU, JSAGU, JALU01], 16, [1,1, 5, 5,4,4,4], 19>;521defm : X86WriteRes<WriteFMaskedStore64, [JFPU0, JFPA, JFPU1, JSTC, JLAGU, JSAGU, JALU01], 13, [1,1, 2, 2,2,2,2], 10>;522defm : X86WriteRes<WriteFMaskedStore32Y, [JFPU0, JFPA, JFPU1, JSTC, JLAGU, JSAGU, JALU01], 22, [1,1,10,10,8,8,8], 36>;523defm : X86WriteRes<WriteFMaskedStore64Y, [JFPU0, JFPA, JFPU1, JSTC, JLAGU, JSAGU, JALU01], 16, [1,1, 4, 4,4,4,4], 18>;524 525defm : X86WriteRes<WriteFMove, [JFPU01, JFPX], 1, [1, 1], 1>;526defm : X86WriteRes<WriteFMoveX, [JFPU01, JFPX], 1, [1, 1], 1>;527defm : X86WriteRes<WriteFMoveY, [JFPU01, JFPX], 1, [2, 2], 2>;528defm : X86WriteResUnsupported<WriteFMoveZ>;529 530defm : X86WriteRes<WriteEMMS, [JFPU01, JFPX], 2, [1, 1], 1>;531 532defm : JWriteResFpuPair<WriteFAdd, [JFPU0, JFPA], 3>;533defm : JWriteResFpuPair<WriteFAddX, [JFPU0, JFPA], 3>;534defm : JWriteResYMMPair<WriteFAddY, [JFPU0, JFPA], 3, [2,2], 2>;535defm : X86WriteResPairUnsupported<WriteFAddZ>;536defm : JWriteResFpuPair<WriteFAdd64, [JFPU0, JFPA], 3>;537defm : JWriteResFpuPair<WriteFAdd64X, [JFPU0, JFPA], 3>;538defm : JWriteResYMMPair<WriteFAdd64Y, [JFPU0, JFPA], 3, [2,2], 2>;539defm : X86WriteResPairUnsupported<WriteFAdd64Z>;540defm : JWriteResFpuPair<WriteFCmp, [JFPU0, JFPA], 2>;541defm : JWriteResFpuPair<WriteFCmpX, [JFPU0, JFPA], 2>;542defm : JWriteResYMMPair<WriteFCmpY, [JFPU0, JFPA], 2, [2,2], 2>;543defm : X86WriteResPairUnsupported<WriteFCmpZ>;544defm : JWriteResFpuPair<WriteFCmp64, [JFPU0, JFPA], 2>;545defm : JWriteResFpuPair<WriteFCmp64X, [JFPU0, JFPA], 2>;546defm : JWriteResYMMPair<WriteFCmp64Y, [JFPU0, JFPA], 2, [2,2], 2>;547defm : X86WriteResPairUnsupported<WriteFCmp64Z>;548defm : JWriteResFpuPair<WriteFCom, [JFPU0, JFPA, JALU0], 3>;549defm : JWriteResFpuPair<WriteFComX, [JFPU0, JFPA, JALU0], 3>;550defm : JWriteResFpuPair<WriteFMul, [JFPU1, JFPM], 2>;551defm : JWriteResFpuPair<WriteFMulX, [JFPU1, JFPM], 2>;552defm : JWriteResYMMPair<WriteFMulY, [JFPU1, JFPM], 2, [2,2], 2>;553defm : X86WriteResPairUnsupported<WriteFMulZ>;554defm : JWriteResFpuPair<WriteFMul64, [JFPU1, JFPM], 4, [1,2]>;555defm : JWriteResFpuPair<WriteFMul64X, [JFPU1, JFPM], 4, [1,2]>;556defm : JWriteResYMMPair<WriteFMul64Y, [JFPU1, JFPM], 4, [2,4], 2>;557defm : X86WriteResPairUnsupported<WriteFMul64Z>;558defm : X86WriteResPairUnsupported<WriteFMA>;559defm : X86WriteResPairUnsupported<WriteFMAX>;560defm : X86WriteResPairUnsupported<WriteFMAY>;561defm : X86WriteResPairUnsupported<WriteFMAZ>;562defm : JWriteResFpuPair<WriteDPPD, [JFPU1, JFPM, JFPA], 9, [1, 3, 3], 3>;563defm : JWriteResFpuPair<WriteDPPS, [JFPU1, JFPM, JFPA], 11, [1, 3, 3], 5>;564defm : JWriteResYMMPair<WriteDPPSY, [JFPU1, JFPM, JFPA], 12, [2, 6, 6], 10>;565defm : JWriteResFpuPair<WriteFRcp, [JFPU1, JFPM], 2>;566defm : JWriteResFpuPair<WriteFRcpX, [JFPU1, JFPM], 2>;567defm : JWriteResYMMPair<WriteFRcpY, [JFPU1, JFPM], 2, [2,2], 2>;568defm : X86WriteResPairUnsupported<WriteFRcpZ>;569defm : JWriteResFpuPair<WriteFRsqrt, [JFPU1, JFPM], 2>;570defm : JWriteResFpuPair<WriteFRsqrtX, [JFPU1, JFPM], 2>;571defm : JWriteResYMMPair<WriteFRsqrtY, [JFPU1, JFPM], 2, [2,2], 2>;572defm : X86WriteResPairUnsupported<WriteFRsqrtZ>;573defm : JWriteResFpuPair<WriteFDiv, [JFPU1, JFPM], 19, [1, 19]>;574defm : JWriteResFpuPair<WriteFDivX, [JFPU1, JFPM], 19, [1, 19]>;575defm : JWriteResYMMPair<WriteFDivY, [JFPU1, JFPM], 38, [2, 38], 2>;576defm : X86WriteResPairUnsupported<WriteFDivZ>;577defm : JWriteResFpuPair<WriteFDiv64, [JFPU1, JFPM], 19, [1, 19]>;578defm : JWriteResFpuPair<WriteFDiv64X, [JFPU1, JFPM], 19, [1, 19]>;579defm : JWriteResYMMPair<WriteFDiv64Y, [JFPU1, JFPM], 38, [2, 38], 2>;580defm : X86WriteResPairUnsupported<WriteFDiv64Z>;581defm : JWriteResFpuPair<WriteFSqrt, [JFPU1, JFPM], 21, [1, 21]>;582defm : JWriteResFpuPair<WriteFSqrtX, [JFPU1, JFPM], 21, [1, 21]>;583defm : JWriteResYMMPair<WriteFSqrtY, [JFPU1, JFPM], 42, [2, 42], 2>;584defm : X86WriteResPairUnsupported<WriteFSqrtZ>;585defm : JWriteResFpuPair<WriteFSqrt64, [JFPU1, JFPM], 27, [1, 27]>;586defm : JWriteResFpuPair<WriteFSqrt64X, [JFPU1, JFPM], 27, [1, 27]>;587defm : JWriteResYMMPair<WriteFSqrt64Y, [JFPU1, JFPM], 54, [2, 54], 2>;588defm : X86WriteResPairUnsupported<WriteFSqrt64Z>;589defm : JWriteResFpuPair<WriteFSqrt80, [JFPU1, JFPM], 35, [1, 35]>;590defm : JWriteResFpuPair<WriteFSign, [JFPU1, JFPM], 2>;591defm : JWriteResFpuPair<WriteFRnd, [JFPU1, JSTC], 3>;592defm : JWriteResYMMPair<WriteFRndY, [JFPU1, JSTC], 3, [2,2], 2>;593defm : X86WriteResPairUnsupported<WriteFRndZ>;594defm : JWriteResFpuPair<WriteFLogic, [JFPU01, JFPX], 1>;595defm : JWriteResYMMPair<WriteFLogicY, [JFPU01, JFPX], 1, [2, 2], 2>;596defm : X86WriteResPairUnsupported<WriteFLogicZ>;597defm : JWriteResFpuPair<WriteFTest, [JFPU0, JFPA, JALU0], 3>;598defm : JWriteResYMMPair<WriteFTestY , [JFPU01, JFPX, JFPA, JALU0], 4, [2, 2, 2, 1], 3>;599defm : X86WriteResPairUnsupported<WriteFTestZ>;600defm : JWriteResFpuPair<WriteFShuffle, [JFPU01, JFPX], 1>;601defm : JWriteResYMMPair<WriteFShuffleY, [JFPU01, JFPX], 1, [2, 2], 2>;602defm : X86WriteResPairUnsupported<WriteFShuffleZ>;603defm : JWriteResFpuPair<WriteFVarShuffle, [JFPU01, JFPX], 3, [1, 4], 3>; // +1cy latency.604defm : JWriteResYMMPair<WriteFVarShuffleY,[JFPU01, JFPX], 4, [2, 6], 6>; // +1cy latency.605defm : X86WriteResPairUnsupported<WriteFVarShuffleZ>;606defm : JWriteResFpuPair<WriteFBlend, [JFPU01, JFPX], 1>;607defm : JWriteResYMMPair<WriteFBlendY, [JFPU01, JFPX], 1, [2, 2], 2>;608defm : X86WriteResPairUnsupported<WriteFBlendZ>;609defm : JWriteResFpuPair<WriteFVarBlend, [JFPU01, JFPX], 2, [4, 4], 3>;610defm : JWriteResYMMPair<WriteFVarBlendY, [JFPU01, JFPX], 3, [6, 6], 6>;611defm : X86WriteResPairUnsupported<WriteFVarBlendZ>;612defm : JWriteResFpuPair<WriteFShuffle256, [JFPU01, JFPX], 1, [2, 2], 2>;613defm : X86WriteResPairUnsupported<WriteFVarShuffle256>;614 615////////////////////////////////////////////////////////////////////////////////616// Conversions.617////////////////////////////////////////////////////////////////////////////////618 619defm : JWriteResFpuPair<WriteCvtSS2I, [JFPU1, JSTC, JFPU0, JFPA, JALU0], 7, [1,1,1,1,1], 2>;620defm : JWriteResFpuPair<WriteCvtPS2I, [JFPU1, JSTC], 3, [1,1], 1>;621defm : JWriteResYMMPair<WriteCvtPS2IY, [JFPU1, JSTC], 3, [2,2], 2>;622defm : X86WriteResPairUnsupported<WriteCvtPS2IZ>;623defm : JWriteResFpuPair<WriteCvtSD2I, [JFPU1, JSTC, JFPU0, JFPA, JALU0], 7, [1,1,1,1,1], 2>;624defm : JWriteResFpuPair<WriteCvtPD2I, [JFPU1, JSTC], 3, [1,1], 1>;625defm : JWriteResYMMPair<WriteCvtPD2IY, [JFPU1, JSTC, JFPX], 6, [2,2,4], 3>;626defm : X86WriteResPairUnsupported<WriteCvtPD2IZ>;627 628defm : X86WriteRes<WriteCvtI2SS, [JFPU1, JSTC], 4, [1,1], 2>;629defm : X86WriteRes<WriteCvtI2SSLd, [JLAGU, JFPU1, JSTC], 9, [1,1,1], 1>;630defm : JWriteResFpuPair<WriteCvtI2PS, [JFPU1, JSTC], 3, [1,1], 1>;631defm : JWriteResYMMPair<WriteCvtI2PSY, [JFPU1, JSTC], 3, [2,2], 2>;632defm : X86WriteResPairUnsupported<WriteCvtI2PSZ>;633defm : X86WriteRes<WriteCvtI2SD, [JFPU1, JSTC], 4, [1,1], 2>;634defm : X86WriteRes<WriteCvtI2SDLd, [JLAGU, JFPU1, JSTC], 9, [1,1,1], 1>;635defm : JWriteResFpuPair<WriteCvtI2PD, [JFPU1, JSTC], 3, [1,1], 1>;636defm : JWriteResYMMPair<WriteCvtI2PDY, [JFPU1, JSTC], 3, [2,2], 2>;637defm : X86WriteResPairUnsupported<WriteCvtI2PDZ>;638 639defm : JWriteResFpuPair<WriteCvtSS2SD, [JFPU1, JSTC], 7, [1,2], 2>;640defm : JWriteResFpuPair<WriteCvtPS2PD, [JFPU1, JSTC], 2, [1,1], 1>;641defm : JWriteResYMMPair<WriteCvtPS2PDY, [JFPU1, JSTC], 2, [2,2], 2>;642defm : X86WriteResPairUnsupported<WriteCvtPS2PDZ>;643 644defm : JWriteResFpuPair<WriteCvtSD2SS, [JFPU1, JSTC], 7, [1,2], 2>;645defm : JWriteResFpuPair<WriteCvtPD2PS, [JFPU1, JSTC], 3, [1,1], 1>;646defm : JWriteResYMMPair<WriteCvtPD2PSY, [JFPU1, JSTC, JFPX], 6, [2,2,4], 3>;647defm : X86WriteResPairUnsupported<WriteCvtPD2PSZ>;648 649defm : JWriteResFpuPair<WriteCvtPH2PS, [JFPU1, JSTC], 3, [1,1], 1>;650defm : JWriteResYMMPair<WriteCvtPH2PSY, [JFPU1, JSTC], 3, [2,2], 2>;651defm : X86WriteResPairUnsupported<WriteCvtPH2PSZ>;652 653defm : X86WriteRes<WriteCvtPS2PH, [JFPU1, JSTC], 3, [1,1], 1>;654defm : X86WriteRes<WriteCvtPS2PHY, [JFPU1, JSTC, JFPX], 6, [2,2,2], 3>;655defm : X86WriteResUnsupported<WriteCvtPS2PHZ>;656defm : X86WriteRes<WriteCvtPS2PHSt, [JFPU1, JSTC, JSAGU], 4, [1,1,1], 1>;657defm : X86WriteRes<WriteCvtPS2PHYSt, [JFPU1, JSTC, JFPX, JSAGU], 7, [2,2,2,1], 3>;658defm : X86WriteResUnsupported<WriteCvtPS2PHZSt>;659 660////////////////////////////////////////////////////////////////////////////////661// Vector integer operations.662////////////////////////////////////////////////////////////////////////////////663 664defm : X86WriteRes<WriteVecLoad, [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;665defm : X86WriteRes<WriteVecLoadX, [JLAGU], 5, [1], 1>;666defm : X86WriteRes<WriteVecLoadY, [JLAGU], 5, [2], 2>;667defm : X86WriteRes<WriteVecLoadNT, [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;668defm : X86WriteRes<WriteVecLoadNTY, [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;669defm : X86WriteRes<WriteVecMaskedLoad, [JLAGU, JFPU01, JVALU], 6, [1, 2, 2], 1>;670defm : X86WriteRes<WriteVecMaskedLoadY, [JLAGU, JFPU01, JVALU], 6, [2, 4, 4], 2>;671 672defm : X86WriteRes<WriteVecStore, [JSAGU, JFPU1, JSTC], 2, [1, 1, 1], 1>;673defm : X86WriteRes<WriteVecStoreX, [JSAGU, JFPU1, JSTC], 1, [1, 1, 1], 1>;674defm : X86WriteRes<WriteVecStoreY, [JSAGU, JFPU1, JSTC], 1, [2, 2, 2], 2>;675defm : X86WriteRes<WriteVecStoreNT, [JSAGU, JFPU1, JSTC], 2, [1, 1, 1], 1>;676defm : X86WriteRes<WriteVecStoreNTY, [JSAGU, JFPU1, JSTC], 2, [2, 2, 2], 1>;677defm : X86WriteResUnsupported<WriteVecMaskedStore32>;678defm : X86WriteResUnsupported<WriteVecMaskedStore64>;679defm : X86WriteResUnsupported<WriteVecMaskedStore32Y>;680defm : X86WriteResUnsupported<WriteVecMaskedStore64Y>;681 682defm : X86WriteRes<WriteVecMove, [JFPU01, JVALU], 1, [1, 1], 1>;683defm : X86WriteRes<WriteVecMoveX, [JFPU01, JVALU], 1, [1, 1], 1>;684defm : X86WriteRes<WriteVecMoveY, [JFPU01, JVALU], 1, [2, 2], 2>;685defm : X86WriteResUnsupported<WriteVecMoveZ>;686defm : X86WriteRes<WriteVecMoveToGpr, [JFPU0, JFPA, JALU0], 4, [1, 1, 1], 1>;687defm : X86WriteRes<WriteVecMoveFromGpr, [JFPU01, JFPX], 8, [1, 1], 2>;688 689defm : JWriteResFpuPair<WriteVecALU, [JFPU01, JVALU], 1>;690defm : JWriteResFpuPair<WriteVecALUX, [JFPU01, JVALU], 1>;691defm : X86WriteResPairUnsupported<WriteVecALUY>;692defm : X86WriteResPairUnsupported<WriteVecALUZ>;693defm : JWriteResFpuPair<WriteVecShift, [JFPU01, JVALU], 1>;694defm : JWriteResFpuPair<WriteVecShiftX, [JFPU01, JVALU], 2>; // +1cy latency.695defm : X86WriteResPairUnsupported<WriteVecShiftY>;696defm : X86WriteResPairUnsupported<WriteVecShiftZ>;697defm : JWriteResFpuPair<WriteVecShiftImm, [JFPU01, JVALU], 1>;698defm : JWriteResFpuPair<WriteVecShiftImmX,[JFPU01, JVALU], 2>; // +1cy latency.699defm : X86WriteResPairUnsupported<WriteVecShiftImmY>;700defm : X86WriteResPairUnsupported<WriteVecShiftImmZ>;701defm : X86WriteResPairUnsupported<WriteVarVecShift>;702defm : X86WriteResPairUnsupported<WriteVarVecShiftY>;703defm : X86WriteResPairUnsupported<WriteVarVecShiftZ>;704defm : JWriteResFpuPair<WriteVecIMul, [JFPU0, JVIMUL], 2>;705defm : JWriteResFpuPair<WriteVecIMulX, [JFPU0, JVIMUL], 2>;706defm : X86WriteResPairUnsupported<WriteVecIMulY>;707defm : X86WriteResPairUnsupported<WriteVecIMulZ>;708defm : JWriteResFpuPair<WritePMULLD, [JFPU0, JFPU01, JVIMUL, JVALU], 4, [2, 1, 2, 1], 3>;709defm : X86WriteResPairUnsupported<WritePMULLDY>;710defm : X86WriteResPairUnsupported<WritePMULLDZ>;711defm : JWriteResFpuPair<WriteMPSAD, [JFPU0, JVIMUL], 3, [1, 2], 3>;712defm : X86WriteResPairUnsupported<WriteMPSADY>;713defm : X86WriteResPairUnsupported<WriteMPSADZ>;714defm : JWriteResFpuPair<WritePSADBW, [JFPU01, JVALU], 2>;715defm : JWriteResFpuPair<WritePSADBWX, [JFPU01, JVALU], 2>;716defm : X86WriteResPairUnsupported<WritePSADBWY>;717defm : X86WriteResPairUnsupported<WritePSADBWZ>;718defm : JWriteResFpuPair<WritePHMINPOS, [JFPU01, JVALU], 2>;719defm : JWriteResFpuPair<WriteShuffle, [JFPU01, JVALU], 1>;720defm : JWriteResFpuPair<WriteShuffleX, [JFPU01, JVALU], 1>;721defm : X86WriteResPairUnsupported<WriteShuffleY>;722defm : X86WriteResPairUnsupported<WriteShuffleZ>;723defm : JWriteResFpuPair<WriteVarShuffle, [JFPU01, JVALU], 2, [1, 1], 1>;724defm : JWriteResFpuPair<WriteVarShuffleX, [JFPU01, JVALU], 2, [1, 4], 3>;725defm : X86WriteResPairUnsupported<WriteVarShuffleY>;726defm : X86WriteResPairUnsupported<WriteVarShuffleZ>;727defm : JWriteResFpuPair<WriteBlend, [JFPU01, JVALU], 1>;728defm : X86WriteResPairUnsupported<WriteBlendY>;729defm : X86WriteResPairUnsupported<WriteBlendZ>;730defm : JWriteResFpuPair<WriteVarBlend, [JFPU01, JVALU], 2, [4, 4], 3>;731defm : X86WriteResPairUnsupported<WriteVarBlendY>;732defm : X86WriteResPairUnsupported<WriteVarBlendZ>;733defm : JWriteResFpuPair<WriteVecLogic, [JFPU01, JVALU], 1>;734defm : JWriteResFpuPair<WriteVecLogicX, [JFPU01, JVALU], 1>;735defm : X86WriteResPairUnsupported<WriteVecLogicY>;736defm : X86WriteResPairUnsupported<WriteVecLogicZ>;737defm : JWriteResFpuPair<WriteVecTest, [JFPU0, JFPA, JALU0], 3>;738defm : JWriteResYMMPair<WriteVecTestY, [JFPU01, JFPX, JFPA, JALU0], 4, [2, 2, 2, 1], 3>;739defm : X86WriteResPairUnsupported<WriteVecTestZ>;740defm : X86WriteResPairUnsupported<WriteShuffle256>;741defm : X86WriteResPairUnsupported<WriteVPMOV256>;742defm : X86WriteResPairUnsupported<WriteVarShuffle256>;743 744////////////////////////////////////////////////////////////////////////////////745// Vector insert/extract operations.746////////////////////////////////////////////////////////////////////////////////747 748defm : X86WriteRes<WriteVecInsert, [JFPU01, JVALU], 1, [1,1], 2>;749defm : X86WriteRes<WriteVecInsertLd, [JFPU01, JVALU, JLAGU], 4, [1,1,1], 1>;750defm : X86WriteRes<WriteVecExtract, [JFPU0, JFPA, JALU0], 3, [1,1,1], 1>;751defm : X86WriteRes<WriteVecExtractSt, [JFPU1, JSTC, JSAGU], 3, [1,1,1], 1>;752 753////////////////////////////////////////////////////////////////////////////////754// SSE42 String instructions.755////////////////////////////////////////////////////////////////////////////////756 757defm : JWriteResFpuPair<WritePCmpIStrI, [JFPU1, JVALU1, JFPU0, JFPA, JALU0], 7, [2, 2, 1, 1, 1], 3>;758defm : JWriteResFpuPair<WritePCmpIStrM, [JFPU1, JVALU1, JFPU0, JFPA, JALU0], 8, [2, 2, 1, 1, 1], 3>;759defm : JWriteResFpuPair<WritePCmpEStrI, [JFPU1, JSAGU, JLAGU, JVALU, JVALU1, JFPA, JALU0], 14, [1, 2, 2, 6, 4, 1, 1], 9>;760defm : JWriteResFpuPair<WritePCmpEStrM, [JFPU1, JSAGU, JLAGU, JVALU, JVALU1, JFPA, JALU0], 14, [1, 2, 2, 6, 4, 1, 1], 9>;761 762////////////////////////////////////////////////////////////////////////////////763// MOVMSK Instructions.764////////////////////////////////////////////////////////////////////////////////765 766def : WriteRes<WriteFMOVMSK, [JFPU0, JFPA, JALU0]> { let Latency = 3; }767def : WriteRes<WriteVecMOVMSK, [JFPU0, JFPA, JALU0]> { let Latency = 3; }768defm : X86WriteResUnsupported<WriteVecMOVMSKY>;769def : WriteRes<WriteMMXMOVMSK, [JFPU0, JFPA, JALU0]> { let Latency = 3; }770 771////////////////////////////////////////////////////////////////////////////////772// AES Instructions.773////////////////////////////////////////////////////////////////////////////////774 775defm : JWriteResFpuPair<WriteAESIMC, [JFPU0, JVIMUL], 2>;776defm : JWriteResFpuPair<WriteAESKeyGen, [JFPU0, JVIMUL], 2>;777defm : JWriteResFpuPair<WriteAESDecEnc, [JFPU01, JVALU, JFPU0, JVIMUL], 3, [1,1,1,1], 2>;778 779////////////////////////////////////////////////////////////////////////////////780// Horizontal add/sub instructions.781////////////////////////////////////////////////////////////////////////////////782 783defm : JWriteResFpuPair<WriteFHAdd, [JFPU0, JFPA], 4>; // +1cy latency.784defm : JWriteResYMMPair<WriteFHAddY, [JFPU0, JFPA], 4, [2,2], 2>; // +1cy latency.785defm : JWriteResFpuPair<WritePHAdd, [JFPU01, JVALU], 1>;786defm : JWriteResFpuPair<WritePHAddX, [JFPU01, JVALU], 2>; // +1cy latency.787defm : X86WriteResPairUnsupported<WritePHAddY>;788 789////////////////////////////////////////////////////////////////////////////////790// Carry-less multiplication instructions.791////////////////////////////////////////////////////////////////////////////////792 793defm : JWriteResFpuPair<WriteCLMul, [JFPU0, JVIMUL], 2>;794 795////////////////////////////////////////////////////////////////////////////////796// SSE4A instructions.797////////////////////////////////////////////////////////////////////////////////798 799def JWriteINSERTQ: SchedWriteRes<[JFPU01, JVALU]> {800 let Latency = 2;801 let ReleaseAtCycles = [1, 4];802}803def : InstRW<[JWriteINSERTQ], (instrs INSERTQ, INSERTQI)>;804 805////////////////////////////////////////////////////////////////////////////////806// AVX instructions.807////////////////////////////////////////////////////////////////////////////////808 809def JWriteVecExtractF128: SchedWriteRes<[JFPU01, JFPX]>;810def : InstRW<[JWriteVecExtractF128], (instrs VEXTRACTF128rri)>;811 812def JWriteVBROADCASTYLd: SchedWriteRes<[JLAGU, JFPU01, JFPX]> {813 let Latency = 6;814 let ReleaseAtCycles = [1, 2, 4];815 let NumMicroOps = 2;816}817def : InstRW<[JWriteVBROADCASTYLd], (instrs VBROADCASTSDYrm,818 VBROADCASTSSYrm,819 VBROADCASTF128rm)>;820 821def JWriteJVZEROALL: SchedWriteRes<[]> {822 let Latency = 90;823 let NumMicroOps = 73;824}825def : InstRW<[JWriteJVZEROALL], (instrs VZEROALL)>;826 827def JWriteJVZEROUPPER: SchedWriteRes<[]> {828 let Latency = 46;829 let NumMicroOps = 37;830}831def : InstRW<[JWriteJVZEROUPPER], (instrs VZEROUPPER)>;832 833///////////////////////////////////////////////////////////////////////////////834// SSE2/AVX Store Selected Bytes of Double Quadword - (V)MASKMOVDQ835///////////////////////////////////////////////////////////////////////////////836 837def JWriteMASKMOVDQU: SchedWriteRes<[JFPU0, JFPA, JFPU1, JSTC, JLAGU, JSAGU, JALU01]> {838 let Latency = 34;839 let ReleaseAtCycles = [1, 1, 2, 2, 2, 16, 42];840 let NumMicroOps = 63;841}842def : InstRW<[JWriteMASKMOVDQU], (instrs MASKMOVDQU, MASKMOVDQU64,843 VMASKMOVDQU, VMASKMOVDQU64)>;844 845///////////////////////////////////////////////////////////////////////////////846// SchedWriteVariant definitions.847///////////////////////////////////////////////////////////////////////////////848 849def JWriteZeroLatency : SchedWriteRes<[]> {850 let Latency = 0;851}852 853def JWriteZeroIdiomYmm : SchedWriteRes<[JFPU01, JFPX]> {854 let NumMicroOps = 2;855}856 857// Certain instructions that use the same register for both source858// operands do not have a real dependency on the previous contents of the859// register, and thus, do not have to wait before completing. They can be860// optimized out at register renaming stage.861// Reference: Section 10.8 of the "Software Optimization Guide for AMD Family862// 15h Processors".863// Reference: Agner's Fog "The microarchitecture of Intel, AMD and VIA CPUs",864// Section 21.8 [Dependency-breaking instructions].865 866def JWriteZeroIdiom : SchedWriteVariant<[867 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,868 SchedVar<NoSchedPred, [WriteALU]>869]>;870def : InstRW<[JWriteZeroIdiom], (instrs SUB32rr, SUB64rr,871 XOR32rr, XOR64rr)>;872 873def JWriteFZeroIdiom : SchedWriteVariant<[874 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,875 SchedVar<NoSchedPred, [WriteFLogic]>876]>;877def : InstRW<[JWriteFZeroIdiom], (instrs XORPSrr, VXORPSrr, XORPDrr, VXORPDrr,878 ANDNPSrr, VANDNPSrr,879 ANDNPDrr, VANDNPDrr)>;880 881def JWriteFZeroIdiomY : SchedWriteVariant<[882 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroIdiomYmm]>,883 SchedVar<NoSchedPred, [WriteFLogicY]>884]>;885def : InstRW<[JWriteFZeroIdiomY], (instrs VXORPSYrr, VXORPDYrr,886 VANDNPSYrr, VANDNPDYrr)>;887 888def JWriteVZeroIdiomLogic : SchedWriteVariant<[889 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,890 SchedVar<NoSchedPred, [WriteVecLogic]>891]>;892def : InstRW<[JWriteVZeroIdiomLogic], (instrs MMX_PXORrr, MMX_PANDNrr)>;893 894def JWriteVZeroIdiomLogicX : SchedWriteVariant<[895 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,896 SchedVar<NoSchedPred, [WriteVecLogicX]>897]>;898def : InstRW<[JWriteVZeroIdiomLogicX], (instrs PXORrr, VPXORrr,899 PANDNrr, VPANDNrr)>;900 901def JWriteVZeroIdiomALU : SchedWriteVariant<[902 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,903 SchedVar<NoSchedPred, [WriteVecALU]>904]>;905def : 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,910 MMX_PCMPGTWrr)>;911 912def JWriteVZeroIdiomALUX : SchedWriteVariant<[913 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>,914 SchedVar<NoSchedPred, [WriteVecALUX]>915]>;916def : InstRW<[JWriteVZeroIdiomALUX], (instrs PSUBBrr, VPSUBBrr,917 PSUBDrr, VPSUBDrr,918 PSUBQrr, VPSUBQrr,919 PSUBWrr, VPSUBWrr,920 PSUBSBrr, VPSUBSBrr,921 PSUBSWrr, VPSUBSWrr,922 PSUBUSBrr, VPSUBUSBrr,923 PSUBUSWrr, VPSUBUSWrr,924 PCMPGTBrr, VPCMPGTBrr,925 PCMPGTDrr, VPCMPGTDrr,926 PCMPGTQrr, VPCMPGTQrr,927 PCMPGTWrr, VPCMPGTWrr)>;928 929def JWriteVPERM2F128 : SchedWriteVariant<[930 SchedVar<MCSchedPredicate<ZeroIdiomVPERMPredicate>, [JWriteZeroIdiomYmm]>,931 SchedVar<NoSchedPred, [WriteFShuffle256]>932]>;933def : InstRW<[JWriteVPERM2F128], (instrs VPERM2F128rri)>;934 935// This write is used for slow LEA instructions.936def JWrite3OpsLEA : SchedWriteRes<[JALU1, JSAGU]> {937 let Latency = 2;938}939 940// On Jaguar, a slow LEA is either a 3Ops LEA (base, index, offset), or an LEA941// with a `Scale` value different than 1.942def JSlowLEAPredicate : MCSchedPredicate<943 CheckAny<[944 // A 3-operand LEA (base, index, offset).945 IsThreeOperandsLEAFn,946 // An LEA with a "Scale" different than 1.947 CheckAll<[948 CheckIsImmOperand<2>,949 CheckNot<CheckImmOperand<2, 1>>950 ]>951 ]>952>;953 954def JWriteLEA : SchedWriteVariant<[955 SchedVar<JSlowLEAPredicate, [JWrite3OpsLEA]>,956 SchedVar<NoSchedPred, [WriteLEA]>957]>;958 959def : InstRW<[JWriteLEA], (instrs LEA32r, LEA64r, LEA64_32r)>;960 961def JSlowLEA16r : SchedWriteRes<[JALU01]> {962 let Latency = 3;963 let ReleaseAtCycles = [4];964}965 966def : InstRW<[JSlowLEA16r], (instrs LEA16r)>;967 968///////////////////////////////////////////////////////////////////////////////969// Dependency breaking instructions.970///////////////////////////////////////////////////////////////////////////////971 972def : IsZeroIdiomFunction<[973 // GPR Zero-idioms.974 DepBreakingClass<[ SUB32rr, SUB64rr, XOR32rr, XOR64rr ], ZeroIdiomPredicate>,975 976 // MMX Zero-idioms.977 DepBreakingClass<[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_PCMPGTWrr982 ], ZeroIdiomPredicate>,983 984 // SSE Zero-idioms.985 DepBreakingClass<[986 // fp variants.987 XORPSrr, XORPDrr, ANDNPSrr, ANDNPDrr,988 989 // int variants.990 PXORrr, PANDNrr,991 PSUBBrr, PSUBWrr, PSUBDrr, PSUBQrr,992 PSUBSBrr, PSUBSWrr, PSUBUSBrr, PSUBUSWrr,993 PCMPGTBrr, PCMPGTDrr, PCMPGTQrr, PCMPGTWrr994 ], ZeroIdiomPredicate>,995 996 // AVX Zero-idioms.997 DepBreakingClass<[998 // xmm fp variants.999 VXORPSrr, VXORPDrr, VANDNPSrr, VANDNPDrr,1000 1001 // xmm int variants.1002 VPXORrr, VPANDNrr,1003 VPSUBBrr, VPSUBWrr, VPSUBDrr, VPSUBQrr,1004 VPSUBSBrr, VPSUBSWrr, VPSUBUSBrr, VPSUBUSWrr,1005 VPCMPGTBrr, VPCMPGTWrr, VPCMPGTDrr, VPCMPGTQrr,1006 1007 // ymm variants.1008 VXORPSYrr, VXORPDYrr, VANDNPSYrr, VANDNPDYrr1009 ], ZeroIdiomPredicate>,1010 1011 DepBreakingClass<[ VPERM2F128rri ], ZeroIdiomVPERMPredicate>1012]>;1013 1014def : IsDepBreakingFunction<[1015 // GPR1016 DepBreakingClass<[ SBB32rr, SBB64rr ], ZeroIdiomPredicate>,1017 DepBreakingClass<[ CMP32rr, CMP64rr ], CheckSameRegOperand<0, 1> >,1018 1019 // MMX1020 DepBreakingClass<[1021 MMX_PCMPEQBrr, MMX_PCMPEQDrr, MMX_PCMPEQWrr1022 ], ZeroIdiomPredicate>,1023 1024 // SSE1025 DepBreakingClass<[ 1026 PCMPEQBrr, PCMPEQWrr, PCMPEQDrr, PCMPEQQrr1027 ], ZeroIdiomPredicate>,1028 1029 // AVX1030 DepBreakingClass<[1031 VPCMPEQBrr, VPCMPEQWrr, VPCMPEQDrr, VPCMPEQQrr1032 ], ZeroIdiomPredicate>1033]>;1034 1035def : IsOptimizableRegisterMove<[1036 InstructionEquivalenceClass<[1037 // GPR variants.1038 MOV32rr, MOV64rr,1039 1040 // MMX variants.1041 MMX_MOVQ64rr,1042 1043 // SSE variants.1044 MOVAPSrr, MOVUPSrr,1045 MOVAPDrr, MOVUPDrr,1046 MOVDQArr, MOVDQUrr,1047 1048 // AVX variants.1049 VMOVAPSrr, VMOVUPSrr,1050 VMOVAPDrr, VMOVUPDrr,1051 VMOVDQArr, VMOVDQUrr1052 ], TruePred >1053]>;1054 1055} // SchedModel1056