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-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file defines the machine model for AMD btver2 (Jaguar) to support 10// instruction scheduling and other instruction cost heuristics. Based off AMD Software 11// Optimization Guide for AMD Family 16h Processors & Instruction Latency appendix. 12// 13//===----------------------------------------------------------------------===// 14 15def BtVer2Model : SchedMachineModel { 16 // All x86 instructions are modeled as a single micro-op, and btver2 can 17 // decode 2 instructions per cycle. 18 let IssueWidth = 2; 19 let MicroOpBufferSize = 64; // Retire Control Unit 20 let LoadLatency = 5; // FPU latency (worse case cf Integer 3 cycle latency) 21 let HighLatency = 25; 22 let MispredictPenalty = 14; // Minimum branch misdirection penalty 23 let PostRAScheduler = 1; 24 25 // FIXME: SSE4/AVX is unimplemented. This flag is set to allow 26 // the scheduler to assign a default model to unrecognized opcodes. 27 let CompleteModel = 0; 28} 29 30let SchedModel = BtVer2Model in { 31 32// Jaguar can issue up to 6 micro-ops in one cycle 33def JALU0 : ProcResource<1>; // Integer Pipe0: integer ALU0 (also handle FP->INT jam) 34def JALU1 : ProcResource<1>; // Integer Pipe1: integer ALU1/MUL/DIV 35def JLAGU : ProcResource<1>; // Integer Pipe2: LAGU 36def JSAGU : ProcResource<1>; // Integer Pipe3: SAGU (also handles 3-operand LEA) 37def JFPU0 : ProcResource<1>; // Vector/FPU Pipe0: VALU0/VIMUL/FPA 38def JFPU1 : ProcResource<1>; // Vector/FPU Pipe1: VALU1/STC/FPM 39 40// The Integer PRF for Jaguar is 64 entries, and it holds the architectural and 41// speculative version of the 64-bit integer registers. 42// Reference: www.realworldtech.com/jaguar/4/ 43// 44// The processor always keeps the different parts of an integer register 45// together. An instruction that writes to a part of a register will therefore 46// have a false dependence on any previous write to the same register or any 47// part of it. 48// Reference: Section 21.10 "AMD Bobcat and Jaguar pipeline: Partial register 49// 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 SSE 55// 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 SSE 59// register that is know to be zero (i.e. it has been zeroed using a zero-idiom 60// dependency breaking instruction, or via VZEROALL). 61// Reference: Section 21.8 "AMD Bobcat and Jaguar pipeline: Dependency-breaking 62// instructions" - Agner Fog's "microarchitecture.pdf" 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 can 68// 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 Scheduler 73def JALU01 : ProcResGroup<[JALU0, JALU1]> { 74 let BufferSize=20; 75} 76 77// AGU Pipe Scheduler 78def JLSAGU : ProcResGroup<[JLAGU, JSAGU]> { 79 let BufferSize=12; 80} 81 82// Fpu Pipe Scheduler 83def JFPU01 : ProcResGroup<[JFPU0, JFPU1]> { 84 let BufferSize=18; 85} 86 87// Functional units 88def JDiv : ProcResource<1>; // integer division 89def JMul : ProcResource<1>; // integer multiplication 90def JVALU0 : ProcResource<1>; // vector integer 91def JVALU1 : ProcResource<1>; // vector integer 92def JVIMUL : ProcResource<1>; // vector integer multiplication 93def JSTC : ProcResource<1>; // vector store/convert 94def JFPM : ProcResource<1>; // FP multiplication 95def JFPA : ProcResource<1>; // FP addition 96 97// Functional unit groups 98def JFPX : ProcResGroup<[JFPA, JFPM]>; 99def JVALU : ProcResGroup<[JVALU0, JVALU1]>; 100 101// Integer loads are 3 cycles, so ReadAfterLd registers needn't be available until 3 102// 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 5 106// 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 point 112/// operation input value from the integer unit to the floating point unit. 113/// Reference: AMDfam16h SOG (Appendix A "Instruction Latencies", Section A.2). 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 appear 118// as two micro-ops when dispatched by the schedulers. 119// This multiclass defines the resource usage for variants with and without 120// 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 the 133 // 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 the 153 // 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 the 173 // 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 RMW 184// instructions don't need an extra uop. ALU RMW operations don't seem to 185// benefit from STLF, and their observed latency is 6cy. That is the reason why 186// this write adds two extra cycles (instead of just 1cy for the store). 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 BZHI 252defm : 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 still 297// 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 this 311// 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 operands 377// 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-atomic 419// XADDrm. This is the first of a pair of writes that model non-atomic 420// XADDrm instructions (the second write definition is JWriteXADDrm_LdSt_Part). 421// 422// We need two writes because the instruction latency differs from the output 423// register operand latency. In particular, the first write describes the first 424// (and only) output register operand of the instruction. However, the 425// instruction latency is set to the MAX of all the write latencies. That's why 426// a second write is needed in this case (see example below). 427// 428// Example: 429// XADD %ecx, (%rsp) ## Instruction latency: 11cy 430// ## ECX write Latency: 3cy 431// 432// Register ECX becomes available in 3 cycles. That is because the value of ECX 433// is exchanged with the value read from the stack pointer, and the load-to-use 434// latency is assumed to be 3cy. 435def JWriteXADDrm_XCHG_Part : SchedWriteRes<[JALU01]> { 436 let Latency = 3; // load-to-use latency 437 let ReleaseAtCycles = [3]; 438 let NumMicroOps = 3; 439} 440 441// This write defines the latency of the in/out register operand of an atomic 442// XADDrm. This is the first of a sequence of two writes used to model atomic 443// XADD instructions. The second write of the sequence is JWriteXCHGrm_LdSt_Part. 444// 445// 446// Example: 447// LOCK XADD %ecx, (%rsp) ## Instruction Latency: 16cy 448// ## ECX write Latency: 11cy 449// 450// The value of ECX becomes available only after 11cy from the start of 451// execution. This write is used to specifically set that operand latency. 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 atomic 459// XCHGrm. This write is the first of a sequence of two writes that describe 460// atomic XCHG operations. We need two writes because the instruction latency 461// differs from the output register write latency. We want to make sure that 462// the output register operand becomes visible after 11cy. However, we want to 463// set the instruction latency to 16cy. 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 VEXTRACTF128rr)>; 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)MASKMOVDQ 835/////////////////////////////////////////////////////////////////////////////// 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 source 858// operands do not have a real dependency on the previous contents of the 859// register, and thus, do not have to wait before completing. They can be 860// optimized out at register renaming stage. 861// Reference: Section 10.8 of the "Software Optimization Guide for AMD Family 862// 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 VPERM2F128rr)>; 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 LEA 941// 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_PCMPGTWrr 982 ], 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, PCMPGTWrr 994 ], 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, VANDNPDYrr 1009 ], ZeroIdiomPredicate>, 1010 1011 DepBreakingClass<[ VPERM2F128rr ], ZeroIdiomVPERMPredicate> 1012]>; 1013 1014def : IsDepBreakingFunction<[ 1015 // GPR 1016 DepBreakingClass<[ SBB32rr, SBB64rr ], ZeroIdiomPredicate>, 1017 DepBreakingClass<[ CMP32rr, CMP64rr ], CheckSameRegOperand<0, 1> >, 1018 1019 // MMX 1020 DepBreakingClass<[ 1021 MMX_PCMPEQBrr, MMX_PCMPEQDrr, MMX_PCMPEQWrr 1022 ], ZeroIdiomPredicate>, 1023 1024 // SSE 1025 DepBreakingClass<[ 1026 PCMPEQBrr, PCMPEQWrr, PCMPEQDrr, PCMPEQQrr 1027 ], ZeroIdiomPredicate>, 1028 1029 // AVX 1030 DepBreakingClass<[ 1031 VPCMPEQBrr, VPCMPEQWrr, VPCMPEQDrr, VPCMPEQQrr 1032 ], 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, VMOVDQUrr 1052 ], TruePred > 1053]>; 1054 1055} // SchedModel 1056