2059 lines · plain
1//=- X86ScheduleZnver4.td - X86 Znver4 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 Znver4 to support instruction10// scheduling and other instruction cost heuristics.11// Based on:12// * AMD Software Optimization Guide for the AMD Family 19h (Zen4) 13// Microarchitecture14// https://www.amd.com/system/files/TechDocs/57647.zip15//===----------------------------------------------------------------------===//16 17def Znver4Model : SchedMachineModel {18 // AMD SOG Zen4, 2.9.8 Dispatch19 // The processor may dispatch up to 6 macro ops per cycle20 // into the execution engine.21 let IssueWidth = 6;22 // AMD SOG Zen4, 2.10.323 // The retire control unit (RCU) tracks the completion status of all24 // outstanding operations (integer, load/store, and floating-point) and is25 // the final arbiter for exception processing and recovery.26 // The unit can receive up to 6 macro ops dispatched per cycle and track up27 // to 320 macro ops in-flight in non-SMT mode or 160 per thread in SMT mode.28 let MicroOpBufferSize = 320;29 // AMD SOG Zen4, 2.9.1 Op Cache30 // The op cache is organized as an associative cache with 64 sets and 8 ways.31 // At each set-way intersection is an entry containing up to 8 macro ops.32 // The maximum capacity of the op cache is 6.75K ops.33 // Assuming a maximum dispatch of 9 ops/cy and a mispredict cost of 12cy from34 // the op-cache, we limit the loop buffer to 9*12 = 108 to avoid loop35 // unrolling leading to excessive filling of the op-cache from frontend.36 let LoopMicroOpBufferSize = 108;37 // AMD SOG Zen4, 2.6.2 L1 Data Cache38 // The L1 data cache has a 4- or 5- cycle integer load-to-use latency.39 // AMD SOG Zen4, 2.12 L1 Data Cache40 // The AGU and LS pipelines are optimized for simple address generation modes.41 // <...> and can achieve 4-cycle load-to-use integer load latency.42 let LoadLatency = 4;43 // AMD SOG Zen4, 2.12 L1 Data Cache44 // The AGU and LS pipelines are optimized for simple address generation modes.45 // <...> and can achieve <...> 7-cycle load-to-use FP load latency.46 int VecLoadLatency = 7;47 // Latency of a simple store operation.48 int StoreLatency = 1;49 // Mean and median value for all instructions with latencies >650 // Source: Zen4 Instruction Latencies spreadsheet (included with SOG)51 let HighLatency = 13;52 // AMD SOG Zen4, 2.8 Optimizing Branching53 // The branch misprediction penalty is in the range from 11 to 18 cycles,54 // <...>. The common case penalty is 13 cycles.55 let MispredictPenalty = 13;56 57 let PostRAScheduler = 1; // Enable Post RegAlloc Scheduler pass.58 59 let CompleteModel = 1;60}61 62let SchedModel = Znver4Model in {63 64 65//===----------------------------------------------------------------------===//66// RCU67//===----------------------------------------------------------------------===//68 69// AMD SOG Zen4, 2.10.3 Retire Control Unit70// The unit can receive up to 6 macro ops dispatched per cycle and track up to71// 320 macro ops in-flight in non-SMT mode or 128 per thread in SMT mode. <...>72// The retire unit handles in-order commit of up to nine macro ops per cycle.73def Zn4RCU : RetireControlUnit<Znver4Model.MicroOpBufferSize, 9>;74 75//===----------------------------------------------------------------------===//76// Integer Execution Unit77//78 79// AMD SOG Zen4, 2.4 Superscalar Organization80// The processor uses four decoupled independent integer scheduler queues,81// each one servicing one ALU pipeline and one or two other pipelines82 83//84// Execution pipes85//===----------------------------------------------------------------------===//86 87// AMD SOG Zen4, 2.10.2 Execution Units88// The processor contains 4 general purpose integer execution pipes.89// Each pipe has an ALU capable of general purpose integer operations.90def Zn4ALU0 : ProcResource<1>;91def Zn4ALU1 : ProcResource<1>;92def Zn4ALU2 : ProcResource<1>;93def Zn4ALU3 : ProcResource<1>;94 95// AMD SOG Zen4, 2.10.2 Execution Units96// There is also a separate branch execution unit.97def Zn4BRU1 : ProcResource<1>;98 99// AMD SOG Zen4, 2.10.2 Execution Units100// There are three Address Generation Units (AGUs) for all load and store101// address generation. There are also 3 store data movement units102// associated with the same schedulers as the AGUs.103def Zn4AGU0 : ProcResource<1>;104def Zn4AGU1 : ProcResource<1>;105def Zn4AGU2 : ProcResource<1>;106 107//108// Execution Units109//===----------------------------------------------------------------------===//110 111// AMD SOG Zen4, 2.10.2 Execution Units112// ALU0 additionally has divide <...> execution capability.113defvar Zn4Divider = Zn4ALU0;114 115// AMD SOG Zen4, 2.10.2 Execution Units116// ALU0 additionally has <...> branch execution capability.117defvar Zn4BRU0 = Zn4ALU0;118 119// Integer Multiplication issued on ALU1.120defvar Zn4Multiplier = Zn4ALU1;121 122// Execution pipeline grouping123//===----------------------------------------------------------------------===//124 125// General ALU operations126def Zn4ALU0123 : ProcResGroup<[Zn4ALU0, Zn4ALU1, Zn4ALU2, Zn4ALU3]>;127 128// General AGU operations129def Zn4AGU012 : ProcResGroup<[Zn4AGU0, Zn4AGU1, Zn4AGU2]>;130 131// Control flow: jumps, calls132def Zn4BRU01 : ProcResGroup<[Zn4BRU0, Zn4BRU1]>;133 134// Everything that isn't control flow, but still needs to access CC register,135// namely: conditional moves, SETcc.136def Zn4ALU03 : ProcResGroup<[Zn4ALU0, Zn4ALU3]>;137 138// Zn4ALU1 handles complex bit twiddling: CRC/PDEP/PEXT139 140// Simple bit twiddling: bit test, shift/rotate, bit extraction141def Zn4ALU12 : ProcResGroup<[Zn4ALU1, Zn4ALU2]>;142 143 144//145// Scheduling146//===----------------------------------------------------------------------===//147 148// AMD SOG Zen4, 2.10.3 Retire Control Unit149// The integer physical register file (PRF) consists of 224 registers.150def Zn4IntegerPRF : RegisterFile<224, [GR64, CCR], [1, 1], [1, 0],151 6, // Max moves that can be eliminated per cycle.152 0>; // Restrict move elimination to zero regs.153 154// anandtech, The integer scheduler has a 4*24 entry macro op capacity.155// AMD SOG Zen4, 2.10.1 Schedulers156// The schedulers can receive up to six macro ops per cycle, with a limit of157// two per scheduler. Each scheduler can issue one micro op per cycle into158// each of its associated pipelines159def Zn4Int : ProcResGroup<[Zn4ALU0, Zn4AGU0, Zn4BRU0, // scheduler 0160 Zn4ALU1, Zn4AGU1, // scheduler 1161 Zn4ALU2, Zn4AGU2, // scheduler 2162 Zn4ALU3, Zn4BRU1 // scheduler 3163 ]> {164 let BufferSize = !mul(4, 24);165}166 167 168//===----------------------------------------------------------------------===//169// Floating-Point Unit170//171 172// AMD SOG Zen4, 2.4 Superscalar Organization173// The processor uses <...> two decoupled independent floating point schedulers174// each servicing two FP pipelines and one store or FP-to-integer pipeline.175 176//177// Execution pipes178//===----------------------------------------------------------------------===//179 180// AMD SOG Zen4, 2.10.1 Schedulers181// <...>, and six FPU pipes.182// Agner, 22.10 Floating point execution pipes183// There are six floating point/vector execution pipes,184def Zn4FP0 : ProcResource<1>;185def Zn4FP1 : ProcResource<1>;186def Zn4FP2 : ProcResource<1>;187def Zn4FP3 : ProcResource<1>;188def Zn4FP45 : ProcResource<2>;189 190//191// Execution Units192//===----------------------------------------------------------------------===//193// AMD SOG Zen4, 2.11.1 Floating Point Execution Resources194 195// (v)FMUL*, (v)FMA*, Floating Point Compares, Blendv(DQ)196defvar Zn4FPFMul0 = Zn4FP0;197defvar Zn4FPFMul1 = Zn4FP1;198 199// (v)FADD*200defvar Zn4FPFAdd0 = Zn4FP2;201defvar Zn4FPFAdd1 = Zn4FP3;202 203// All convert operations except pack/unpack204defvar Zn4FPFCvt0 = Zn4FP2;205defvar Zn4FPFCvt1 = Zn4FP3;206 207// All Divide and Square Root except Reciprocal Approximation208// AMD SOG Zen4, 2.11.1 Floating Point Execution Resources209// FDIV unit can support 2 simultaneous operations in flight210// even though it occupies a single pipe.211// FIXME: BufferSize=2 ?212defvar Zn4FPFDiv = Zn4FP1;213 214// Moves and Logical operations on Floating Point Data Types215defvar Zn4FPFMisc0 = Zn4FP0;216defvar Zn4FPFMisc1 = Zn4FP1;217defvar Zn4FPFMisc2 = Zn4FP2;218defvar Zn4FPFMisc3 = Zn4FP3;219 220// Integer Adds, Subtracts, and Compares221// Some complex VADD operations are not available in all pipes.222defvar Zn4FPVAdd0 = Zn4FP0;223defvar Zn4FPVAdd1 = Zn4FP1;224defvar Zn4FPVAdd2 = Zn4FP2;225defvar Zn4FPVAdd3 = Zn4FP3;226 227// Integer Multiplies, SAD, Blendvb228defvar Zn4FPVMul0 = Zn4FP0;229defvar Zn4FPVMul1 = Zn4FP3;230 231// Data Shuffles, Packs, Unpacks, Permute232// Some complex shuffle operations are only available in pipe1.233defvar Zn4FPVShuf = Zn4FP1;234defvar Zn4FPVShufAux = Zn4FP2;235 236// Bit Shift Left/Right operations237defvar Zn4FPVShift0 = Zn4FP1;238defvar Zn4FPVShift1 = Zn4FP2;239 240// Moves and Logical operations on Packed Integer Data Types241defvar Zn4FPVMisc0 = Zn4FP0;242defvar Zn4FPVMisc1 = Zn4FP1;243defvar Zn4FPVMisc2 = Zn4FP2;244defvar Zn4FPVMisc3 = Zn4FP3;245 246// *AES*247defvar Zn4FPAES0 = Zn4FP0;248defvar Zn4FPAES1 = Zn4FP1;249 250// *CLM*251defvar Zn4FPCLM0 = Zn4FP0;252defvar Zn4FPCLM1 = Zn4FP1;253 254// Execution pipeline grouping255//===----------------------------------------------------------------------===//256 257// AMD SOG Zen4, 2.11 Floating-Point Unit258// Stores and floating point to general purpose register transfer259// have 2 dedicated pipelines (pipe 5 and 6).260def Zn4FPU0123 : ProcResGroup<[Zn4FP0, Zn4FP1, Zn4FP2, Zn4FP3]>;261 262// (v)FMUL*, (v)FMA*, Floating Point Compares, Blendv(DQ)263def Zn4FPFMul01 : ProcResGroup<[Zn4FPFMul0, Zn4FPFMul1]>;264 265// (v)FADD*266// Some complex VADD operations are not available in all pipes.267def Zn4FPFAdd01 : ProcResGroup<[Zn4FPFAdd0, Zn4FPFAdd1]>;268 269// All convert operations except pack/unpack270def Zn4FPFCvt01 : ProcResGroup<[Zn4FPFCvt0, Zn4FPFCvt1]>;271 272// All Divide and Square Root except Reciprocal Approximation273// def Zn4FPFDiv : ProcResGroup<[Zn4FPFDiv]>;274 275// Moves and Logical operations on Floating Point Data Types276def Zn4FPFMisc0123 : ProcResGroup<[Zn4FPFMisc0, Zn4FPFMisc1, Zn4FPFMisc2, Zn4FPFMisc3]>;277 278// FIXUP and RANGE use FP01 pipelines279def Zn4FPFMisc01 : ProcResGroup<[Zn4FPFMisc0, Zn4FPFMisc1]>;280def Zn4FPFMisc12 : ProcResGroup<[Zn4FPFMisc1, Zn4FPFMisc2]>;281// SCALE instructions use FP23 pipelines282def Zn4FPFMisc23 : ProcResGroup<[Zn4FPFMisc2, Zn4FPFMisc3]>;283def Zn4FPFMisc123 : ProcResGroup<[Zn4FPFMisc1,Zn4FPFMisc2, Zn4FPFMisc3]>;284 285// Loads, Stores and Move to General Register (EX) Operations286// AMD SOG Zen4, 2.11 Floating-Point Unit287// Stores and floating point to general purpose register transfer288// have 2 dedicated pipelines (pipe 5 and 6).289defvar Zn4FPLd01 = Zn4FP45;290 291// AMD SOG Zen4, 2.11 Floating-Point Unit292// Note that FP stores are supported on two pipelines,293// but throughput is limited to one per cycle.294let Super = Zn4FP45 in295def Zn4FPSt : ProcResource<1>;296 297// Integer Adds, Subtracts, and Compares298// Some complex VADD operations are not available in all pipes.299def Zn4FPVAdd0123 : ProcResGroup<[Zn4FPVAdd0, Zn4FPVAdd1, Zn4FPVAdd2, Zn4FPVAdd3]>;300 301def Zn4FPVAdd01: ProcResGroup<[Zn4FPVAdd0, Zn4FPVAdd1]>;302def Zn4FPVAdd12: ProcResGroup<[Zn4FPVAdd1, Zn4FPVAdd2]>;303 304// AVX512 Opmask pipelines305def Zn4FPOpMask01: ProcResGroup<[Zn4FP2, Zn4FP3]>;306def Zn4FPOpMask4: ProcResGroup<[Zn4FP45]>;307 308// Integer Multiplies, SAD, Blendvb309def Zn4FPVMul01 : ProcResGroup<[Zn4FPVMul0, Zn4FPVMul1]>;310 311// Data Shuffles, Packs, Unpacks, Permute312// Some complex shuffle operations are only available in pipe1.313def Zn4FPVShuf01 : ProcResGroup<[Zn4FPVShuf, Zn4FPVShufAux]>;314 315// Bit Shift Left/Right operations316def Zn4FPVShift01 : ProcResGroup<[Zn4FPVShift0, Zn4FPVShift1]>;317 318// Moves and Logical operations on Packed Integer Data Types319def Zn4FPVMisc0123 : ProcResGroup<[Zn4FPVMisc0, Zn4FPVMisc1, Zn4FPVMisc2, Zn4FPVMisc3]>;320 321// *AES*322def Zn4FPAES01 : ProcResGroup<[Zn4FPAES0, Zn4FPAES1]>;323 324// *CLM*325def Zn4FPCLM01 : ProcResGroup<[Zn4FPCLM0, Zn4FPCLM1]>;326 327 328//329// Scheduling330//===----------------------------------------------------------------------===//331 332// Agner, 21.8 Register renaming and out-of-order schedulers333// The floating point register file has 192 vector registers334// of 512b each in zen4.335def Zn4FpPRF : RegisterFile<192, [VR64, VR128, VR256, VR512], [1, 1, 1, 1], [0, 1, 1],336 6, // Max moves that can be eliminated per cycle.337 0>; // Restrict move elimination to zero regs.338 339// AMD SOG Zen4, 2.11 Floating-Point Unit340// The floating-point scheduler has a 2*32 entry macro op capacity.341// AMD SOG Zen4, 2.11 Floating-Point Unit342// <...> the scheduler can issue 1 micro op per cycle for each pipe.343// FIXME: those are two separate schedulers, not a single big one.344def Zn4FP : ProcResGroup<[Zn4FP0, Zn4FP2, /*Zn4FP4,*/ // scheduler 0345 Zn4FP1, Zn4FP3, Zn4FP45 /*Zn4FP5*/ // scheduler 1346 ]> {347 let BufferSize = !mul(2, 32);348}349 350// AMD SOG Zen4, 2.11 Floating-Point Unit351// Macro ops can be dispatched to the 64 entry Non Scheduling Queue (NSQ)352// even if floating-point scheduler is full.353// FIXME: how to model this properly?354 355 356//===----------------------------------------------------------------------===//357// Load-Store Unit358//359 360// AMD SOG Zen4, 2.12 Load-Store Unit361// The LS unit contains three largely independent pipe-lines362// enabling the execution of three 256-bit memory operations per cycle.363def Zn4LSU : ProcResource<3>;364 365// AMD SOG Zen4, 2.12 Load-Store Unit366// All three memory operations can be loads.367let Super = Zn4LSU in368def Zn4Load : ProcResource<3> {369 // AMD SOG Zen4, 2.12 Load-Store Unit370 // The LS unit can process up to 72 out-of-order loads.371 let BufferSize = 72;372}373 374def Zn4LoadQueue : LoadQueue<Zn4Load>;375 376// AMD SOG Zen4, 2.12 Load-Store Unit377// A maximum of two of the memory operations can be stores.378let Super = Zn4LSU in379def Zn4Store : ProcResource<2> {380 // AMD SOG Zen4, 2.12 Load-Store Unit381 // The LS unit utilizes a 64-entry store queue (STQ).382 let BufferSize = 64;383}384 385def Zn4StoreQueue : StoreQueue<Zn4Store>;386 387//===----------------------------------------------------------------------===//388// Basic helper classes.389//===----------------------------------------------------------------------===//390 391// Many SchedWrites are defined in pairs with and without a folded load.392// Instructions with folded loads are usually micro-fused, so they only appear393// as two micro-ops when dispatched by the schedulers.394// This multiclass defines the resource usage for variants with and without395// folded loads.396 397multiclass __Zn4WriteRes<SchedWrite SchedRW, list<ProcResourceKind> ExePorts,398 int Lat = 1, list<int> Res = [], int UOps = 1> {399 def : WriteRes<SchedRW, ExePorts> {400 let Latency = Lat;401 let ReleaseAtCycles = Res;402 let NumMicroOps = UOps;403 }404}405 406multiclass __Zn4WriteResPair<X86FoldableSchedWrite SchedRW,407 list<ProcResourceKind> ExePorts, int Lat,408 list<int> Res, int UOps, int LoadLat, int LoadUOps,409 ProcResourceKind AGU, int LoadRes> {410 defm : __Zn4WriteRes<SchedRW, ExePorts, Lat, Res, UOps>;411 412 defm : __Zn4WriteRes<SchedRW.Folded,413 !listconcat([AGU, Zn4Load], ExePorts),414 !add(Lat, LoadLat),415 !if(!and(!empty(Res), !eq(LoadRes, 1)),416 [],417 !listconcat([1, LoadRes],418 !if(!empty(Res),419 !listsplat(1, !size(ExePorts)),420 Res))),421 !add(UOps, LoadUOps)>;422}423 424// For classes without folded loads.425multiclass Zn4WriteResInt<SchedWrite SchedRW,426 list<ProcResourceKind> ExePorts, int Lat = 1,427 list<int> Res = [], int UOps = 1> {428 defm : __Zn4WriteRes<SchedRW, ExePorts, Lat, Res, UOps>;429}430 431multiclass Zn4WriteResXMM<SchedWrite SchedRW,432 list<ProcResourceKind> ExePorts, int Lat = 1,433 list<int> Res = [], int UOps = 1> {434 defm : __Zn4WriteRes<SchedRW, ExePorts, Lat, Res, UOps>;435}436 437multiclass Zn4WriteResYMM<SchedWrite SchedRW,438 list<ProcResourceKind> ExePorts, int Lat = 1,439 list<int> Res = [], int UOps = 1> {440 defm : __Zn4WriteRes<SchedRW, ExePorts, Lat, Res, UOps>;441}442 443multiclass Zn4WriteResZMM<SchedWrite SchedRW,444 list<ProcResourceKind> ExePorts, int Lat = 1,445 list<int> Res = [], int UOps = 1> {446 defm : __Zn4WriteRes<SchedRW, ExePorts, Lat, Res, UOps>;447}448 449// For classes with folded loads.450multiclass Zn4WriteResIntPair<X86FoldableSchedWrite SchedRW,451 list<ProcResourceKind> ExePorts, int Lat = 1,452 list<int> Res = [], int UOps = 1,453 int LoadUOps = 0, int LoadRes = 1> {454 defm : __Zn4WriteResPair<SchedRW, ExePorts, Lat, Res, UOps,455 Znver4Model.LoadLatency,456 LoadUOps, Zn4AGU012, LoadRes>;457}458 459multiclass Zn4WriteResXMMPair<X86FoldableSchedWrite SchedRW,460 list<ProcResourceKind> ExePorts, int Lat = 1,461 list<int> Res = [], int UOps = 1,462 int LoadUOps = 0, int LoadRes = 1> {463 defm : __Zn4WriteResPair<SchedRW, ExePorts, Lat, Res, UOps,464 Znver4Model.VecLoadLatency,465 LoadUOps, Zn4FPLd01, LoadRes>;466}467 468multiclass Zn4WriteResYMMPair<X86FoldableSchedWrite SchedRW,469 list<ProcResourceKind> ExePorts, int Lat = 1,470 list<int> Res = [], int UOps = 1,471 int LoadUOps = 0, int LoadRes = 1> {472 defm : __Zn4WriteResPair<SchedRW, ExePorts, Lat, Res, UOps,473 Znver4Model.VecLoadLatency,474 LoadUOps, Zn4FPLd01, LoadRes>;475}476 477multiclass Zn4WriteResZMMPair<X86FoldableSchedWrite SchedRW,478 list<ProcResourceKind> ExePorts, int Lat = 1,479 list<int> Res = [], int UOps = 2,480 int LoadUOps = 0, int LoadRes = 1> {481 defm : __Zn4WriteResPair<SchedRW, ExePorts, Lat, Res, UOps,482 Znver4Model.VecLoadLatency,483 LoadUOps, Zn4FPLd01, LoadRes>;484}485 486//===----------------------------------------------------------------------===//487// Here be dragons.488//===----------------------------------------------------------------------===//489 490def : ReadAdvance<ReadAfterLd, Znver4Model.LoadLatency>;491 492def : ReadAdvance<ReadAfterVecLd, Znver4Model.VecLoadLatency>;493def : ReadAdvance<ReadAfterVecXLd, Znver4Model.VecLoadLatency>;494def : ReadAdvance<ReadAfterVecYLd, Znver4Model.VecLoadLatency>;495 496// AMD SOG Zen4, 2.11 Floating-Point Unit497// There is 1 cycle of added latency for a result to cross498// from F to I or I to F domain.499def : ReadAdvance<ReadInt2Fpu, -1>;500 501// Instructions with both a load and a store folded are modeled as a folded502// load + WriteRMW.503defm : Zn4WriteResInt<WriteRMW, [Zn4AGU012, Zn4Store], Znver4Model.StoreLatency, [1, 1], 0>;504 505// Loads, stores, and moves, not folded with other operations.506defm : Zn4WriteResInt<WriteLoad, [Zn4AGU012, Zn4Load], !add(Znver4Model.LoadLatency, 1), [1, 1], 1>;507 508// Model the effect of clobbering the read-write mask operand of the GATHER operation.509// Does not cost anything by itself, only has latency, matching that of the WriteLoad,510defm : Zn4WriteResInt<WriteVecMaskedGatherWriteback, [], !add(Znver4Model.LoadLatency, 1), [], 0>;511 512def Zn4WriteMOVSlow : SchedWriteRes<[Zn4AGU012, Zn4Load]> {513 let Latency = !add(Znver4Model.LoadLatency, 1);514 let ReleaseAtCycles = [3, 1];515 let NumMicroOps = 1;516}517def : InstRW<[Zn4WriteMOVSlow], (instrs MOV8rm, MOV8rm_NOREX, MOV16rm, MOVSX16rm16, MOVSX16rm32, MOVZX16rm16, MOVSX16rm8, MOVZX16rm8)>;518 519defm : Zn4WriteResInt<WriteStore, [Zn4AGU012, Zn4Store], Znver4Model.StoreLatency, [1, 2], 1>;520defm : Zn4WriteResInt<WriteStoreNT, [Zn4AGU012, Zn4Store], Znver4Model.StoreLatency, [1, 2], 1>;521defm : Zn4WriteResInt<WriteMove, [Zn4ALU0123], 1, [4], 1>;522 523// Treat misc copies as a move.524def : InstRW<[WriteMove], (instrs COPY)>;525 526def Zn4WriteMOVBE16rm : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4ALU0123]> {527 let Latency = Znver4Model.LoadLatency;528 let ReleaseAtCycles = [1, 1, 4];529 let NumMicroOps = 1;530}531def : InstRW<[Zn4WriteMOVBE16rm], (instrs MOVBE16rm)>;532 533def Zn4WriteMOVBEmr : SchedWriteRes<[Zn4ALU0123, Zn4AGU012, Zn4Store]> {534 let Latency = Znver4Model.StoreLatency;535 let ReleaseAtCycles = [4, 1, 1];536 let NumMicroOps = 2;537}538def : InstRW<[Zn4WriteMOVBEmr], (instrs MOVBE16mr, MOVBE32mr, MOVBE64mr)>;539 540// Arithmetic.541defm : Zn4WriteResIntPair<WriteALU, [Zn4ALU0123], 1, [1], 1>; // Simple integer ALU op.542 543def Zn4WriteALUSlow : SchedWriteRes<[Zn4ALU0123]> {544 let Latency = 1;545 let ReleaseAtCycles = [4];546 let NumMicroOps = 1;547}548def : InstRW<[Zn4WriteALUSlow], (instrs ADD8i8, ADD16i16, ADD32i32, ADD64i32,549 AND8i8, AND16i16, AND32i32, AND64i32,550 OR8i8, OR16i16, OR32i32, OR64i32,551 SUB8i8, SUB16i16, SUB32i32, SUB64i32,552 XOR8i8, XOR16i16, XOR32i32, XOR64i32)>;553 554def Zn4WriteMoveExtend : SchedWriteRes<[Zn4ALU0123]> {555 let Latency = 1;556 let ReleaseAtCycles = [4];557 let NumMicroOps = 1;558}559def : InstRW<[Zn4WriteMoveExtend], (instrs MOVSX16rr16, MOVSX16rr32, MOVZX16rr16, MOVSX16rr8, MOVZX16rr8)>;560 561def Zn4WriteMaterialize32bitImm: SchedWriteRes<[Zn4ALU0123]> {562 let Latency = 1;563 let ReleaseAtCycles = [2];564 let NumMicroOps = 1;565}566def : InstRW<[Zn4WriteMaterialize32bitImm], (instrs MOV32ri, MOV32ri_alt, MOV64ri32)>;567 568def Zn4WritePDEP_PEXT : SchedWriteRes<[Zn4ALU1]> {569 let Latency = 3;570 let ReleaseAtCycles = [1];571 let NumMicroOps = 1;572}573def : InstRW<[Zn4WritePDEP_PEXT], (instrs PDEP32rr, PDEP64rr,574 PEXT32rr, PEXT64rr)>;575 576defm : Zn4WriteResIntPair<WriteADC, [Zn4ALU0123], 1, [4], 1>; // Integer ALU + flags op.577 578def Zn4WriteADC8mr_SBB8mr : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4ALU0123, Zn4Store]> {579 let Latency = 1;580 let ReleaseAtCycles = [1, 1, 7, 1];581 let NumMicroOps = 1;582}583def : InstRW<[Zn4WriteADC8mr_SBB8mr], (instrs ADC8mr, SBB8mr)>;584 585// This is for simple LEAs with one or two input operands.586defm : Zn4WriteResInt<WriteLEA, [Zn4AGU012], 1, [1], 1>; // LEA instructions can't fold loads.587 588// This write is used for slow LEA instructions.589def Zn4Write3OpsLEA : SchedWriteRes<[Zn4ALU0123]> {590 let Latency = 2;591 let ReleaseAtCycles = [1];592 let NumMicroOps = 2;593}594 595// On Znver4, a slow LEA is either a 3Ops LEA (base, index, offset),596// or an LEA with a `Scale` value different than 1.597def Zn4SlowLEAPredicate : MCSchedPredicate<598 CheckAny<[599 // A 3-operand LEA (base, index, offset).600 IsThreeOperandsLEAFn,601 // An LEA with a "Scale" different than 1.602 CheckAll<[603 CheckIsImmOperand<2>,604 CheckNot<CheckImmOperand<2, 1>>605 ]>606 ]>607>;608 609def Zn4WriteLEA : SchedWriteVariant<[610 SchedVar<Zn4SlowLEAPredicate, [Zn4Write3OpsLEA]>,611 SchedVar<NoSchedPred, [WriteLEA]>612]>;613 614def : InstRW<[Zn4WriteLEA], (instrs LEA32r, LEA64r, LEA64_32r)>;615 616// values from uops.info617def Zn4SlowLEA16r : SchedWriteRes<[Zn4ALU0123]> {618 let Latency = 2; // FIXME: not from llvm-exegesis619 let ReleaseAtCycles = [4];620 let NumMicroOps = 2;621}622 623def : InstRW<[Zn4SlowLEA16r], (instrs LEA16r)>;624 625// Integer multiplication626defm : Zn4WriteResIntPair<WriteIMul8, [Zn4Multiplier], 3, [3], 1>; // Integer 8-bit multiplication.627defm : Zn4WriteResIntPair<WriteIMul16, [Zn4Multiplier], 3, [3], 3, /*LoadUOps=*/1>; // Integer 16-bit multiplication.628defm : Zn4WriteResIntPair<WriteIMul16Imm, [Zn4Multiplier], 4, [4], 2>; // Integer 16-bit multiplication by immediate.629defm : Zn4WriteResIntPair<WriteIMul16Reg, [Zn4Multiplier], 3, [1], 1>; // Integer 16-bit multiplication by register.630defm : Zn4WriteResIntPair<WriteIMul32, [Zn4Multiplier], 3, [3], 2>; // Integer 32-bit multiplication.631defm : Zn4WriteResIntPair<WriteMULX32, [Zn4Multiplier], 3, [1], 2>; // Integer 32-bit Unsigned Multiply Without Affecting Flags.632defm : Zn4WriteResIntPair<WriteIMul32Imm, [Zn4Multiplier], 3, [1], 1>; // Integer 32-bit multiplication by immediate.633defm : Zn4WriteResIntPair<WriteIMul32Reg, [Zn4Multiplier], 3, [1], 1>; // Integer 32-bit multiplication by register.634defm : Zn4WriteResIntPair<WriteIMul64, [Zn4Multiplier], 3, [3], 2>; // Integer 64-bit multiplication.635defm : Zn4WriteResIntPair<WriteMULX64, [Zn4Multiplier], 3, [1], 2>; // Integer 32-bit Unsigned Multiply Without Affecting Flags.636defm : Zn4WriteResIntPair<WriteIMul64Imm, [Zn4Multiplier], 3, [1], 1>; // Integer 64-bit multiplication by immediate.637defm : Zn4WriteResIntPair<WriteIMul64Reg, [Zn4Multiplier], 3, [1], 1>; // Integer 64-bit multiplication by register.638defm : Zn4WriteResInt<WriteIMulHLd, [], !add(4, Znver4Model.LoadLatency), [], 0>; // Integer multiplication, high part.639defm : Zn4WriteResInt<WriteIMulH, [], 4, [], 0>; // Integer multiplication, high part.640 641defm : Zn4WriteResInt<WriteBSWAP32, [Zn4ALU0123], 1, [1], 1>; // Byte Order (Endianness) 32-bit Swap.642defm : Zn4WriteResInt<WriteBSWAP64, [Zn4ALU0123], 1, [1], 1>; // Byte Order (Endianness) 64-bit Swap.643 644defm : Zn4WriteResIntPair<WriteCMPXCHG, [Zn4ALU0123], 3, [12], 5>; // Compare and set, compare and swap.645 646def Zn4WriteCMPXCHG8rr : SchedWriteRes<[Zn4ALU0123]> {647 let Latency = 3;648 let ReleaseAtCycles = [12];649 let NumMicroOps = 3;650}651def : InstRW<[Zn4WriteCMPXCHG8rr], (instrs CMPXCHG8rr)>;652 653defm : Zn4WriteResInt<WriteCMPXCHGRMW, [Zn4ALU0123], 3, [12], 6>; // Compare and set, compare and swap.654 655def Zn4WriteCMPXCHG8rm_LCMPXCHG8 : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4ALU0123]> {656 let Latency = !add(Znver4Model.LoadLatency, Zn4WriteCMPXCHG8rr.Latency);657 let ReleaseAtCycles = [1, 1, 12];658 let NumMicroOps = !add(Zn4WriteCMPXCHG8rr.NumMicroOps, 2);659}660def : InstRW<[Zn4WriteCMPXCHG8rm_LCMPXCHG8], (instrs CMPXCHG8rm, LCMPXCHG8)>;661 662def Zn4WriteCMPXCHG8B : SchedWriteRes<[Zn4ALU0123]> {663 let Latency = 3; // FIXME: not from llvm-exegesis664 let ReleaseAtCycles = [20];665 let NumMicroOps = 15;666}667def : InstRW<[Zn4WriteCMPXCHG8B], (instrs CMPXCHG8B)>;668 669def Zn4WriteCMPXCHG16B_LCMPXCHG16B : SchedWriteRes<[Zn4ALU0123]> {670 let Latency = 2; // FIXME: not from llvm-exegesis671 let ReleaseAtCycles = [40];672 let NumMicroOps = 26;673}674def : InstRW<[Zn4WriteCMPXCHG16B_LCMPXCHG16B], (instrs CMPXCHG16B, LCMPXCHG16B)>;675 676def Zn4WriteWriteXCHGUnrenameable : SchedWriteRes<[Zn4ALU0123]> {677 let Latency = 1;678 let ReleaseAtCycles = [2];679 let NumMicroOps = 2;680}681def : InstRW<[Zn4WriteWriteXCHGUnrenameable], (instrs XCHG8rr, XCHG16rr, XCHG16ar)>;682 683def Zn4WriteXCHG8rm_XCHG16rm : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4ALU0123]> {684 let Latency = !add(Znver4Model.LoadLatency, 3); // FIXME: not from llvm-exegesis685 let ReleaseAtCycles = [1, 1, 2];686 let NumMicroOps = 2;687}688def : InstRW<[Zn4WriteXCHG8rm_XCHG16rm], (instrs XCHG8rm, XCHG16rm)>;689 690def Zn4WriteXCHG32rm_XCHG64rm : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4ALU0123]> {691 let Latency = !add(Znver4Model.LoadLatency, 2); // FIXME: not from llvm-exegesis692 let ReleaseAtCycles = [1, 1, 2];693 let NumMicroOps = 2;694}695def : InstRW<[Zn4WriteXCHG32rm_XCHG64rm], (instrs XCHG32rm, XCHG64rm)>;696 697// Integer division.698defm : Zn4WriteResIntPair<WriteDiv8, [Zn4Divider], 9, [9], 2>;699defm : Zn4WriteResIntPair<WriteDiv16, [Zn4Divider], 10, [10], 2>;700defm : Zn4WriteResIntPair<WriteDiv32, [Zn4Divider], 12, [12], 2>;701defm : Zn4WriteResIntPair<WriteDiv64, [Zn4Divider], 18, [18], 2>;702defm : Zn4WriteResIntPair<WriteIDiv8, [Zn4Divider], 9, [9], 2>;703defm : Zn4WriteResIntPair<WriteIDiv16, [Zn4Divider], 10, [10], 2>;704defm : Zn4WriteResIntPair<WriteIDiv32, [Zn4Divider], 12, [12], 2>;705defm : Zn4WriteResIntPair<WriteIDiv64, [Zn4Divider], 18, [18], 2>;706 707defm : Zn4WriteResIntPair<WriteBSF, [Zn4ALU1], 1, [1], 1, /*LoadUOps=*/1>; // Bit scan forward.708defm : Zn4WriteResIntPair<WriteBSR, [Zn4ALU1], 1, [1], 1, /*LoadUOps=*/1>; // Bit scan reverse.709 710defm : Zn4WriteResIntPair<WritePOPCNT, [Zn4ALU0123], 1, [1], 1>; // Bit population count.711 712def Zn4WritePOPCNT16rr : SchedWriteRes<[Zn4ALU0123]> {713 let Latency = 1;714 let ReleaseAtCycles = [4];715 let NumMicroOps = 1;716}717def : InstRW<[Zn4WritePOPCNT16rr], (instrs POPCNT16rr)>;718 719defm : Zn4WriteResIntPair<WriteLZCNT, [Zn4ALU0123], 1, [1], 1>; // Leading zero count.720 721def Zn4WriteLZCNT16rr : SchedWriteRes<[Zn4ALU0123]> {722 let Latency = 1;723 let ReleaseAtCycles = [4];724 let NumMicroOps = 1;725}726def : InstRW<[Zn4WriteLZCNT16rr], (instrs LZCNT16rr)>;727 728defm : Zn4WriteResIntPair<WriteTZCNT, [Zn4ALU12], 1, [1], 1>; // Trailing zero count.729 730def Zn4WriteTZCNT16rr : SchedWriteRes<[Zn4ALU0123]> {731 let Latency = 1;732 let ReleaseAtCycles = [1];733 let NumMicroOps = 1;734}735def : InstRW<[Zn4WriteTZCNT16rr], (instrs TZCNT16rr)>;736 737defm : Zn4WriteResIntPair<WriteCMOV, [Zn4ALU03], 1, [1], 1>; // Conditional move.738defm : Zn4WriteResInt<WriteFCMOV, [Zn4ALU0123], 7, [28], 7>; // FIXME: not from llvm-exegesis // X87 conditional move.739defm : Zn4WriteResInt<WriteSETCC, [Zn4ALU03], 1, [2], 1>; // Set register based on condition code.740defm : Zn4WriteResInt<WriteSETCCStore, [Zn4ALU03, Zn4AGU012, Zn4Store], 2, [2, 1, 1], 2>; // FIXME: latency not from llvm-exegesis741defm : Zn4WriteResInt<WriteLAHFSAHF, [Zn4ALU3], 1, [1], 1>; // Load/Store flags in AH.742 743defm : Zn4WriteResInt<WriteBitTest, [Zn4ALU12], 1, [1], 1>; // Bit Test744defm : Zn4WriteResInt<WriteBitTestImmLd, [Zn4AGU012, Zn4Load, Zn4ALU12], !add(Znver4Model.LoadLatency, 1), [1, 1, 1], 2>;745defm : Zn4WriteResInt<WriteBitTestRegLd, [Zn4AGU012, Zn4Load, Zn4ALU12], !add(Znver4Model.LoadLatency, 1), [1, 1, 1], 7>;746 747defm : Zn4WriteResInt<WriteBitTestSet, [Zn4ALU12], 2, [2], 2>; // Bit Test + Set748defm : Zn4WriteResInt<WriteBitTestSetImmLd, [Zn4AGU012, Zn4Load, Zn4ALU12], !add(Znver4Model.LoadLatency, 2), [1, 1, 1], 4>;749defm : Zn4WriteResInt<WriteBitTestSetRegLd, [Zn4AGU012, Zn4Load, Zn4ALU12], !add(Znver4Model.LoadLatency, 2), [1, 1, 1], 9>;750 751// Integer shifts and rotates.752defm : Zn4WriteResIntPair<WriteShift, [Zn4ALU12], 1, [1], 1, /*LoadUOps=*/1>;753defm : Zn4WriteResIntPair<WriteShiftCL, [Zn4ALU12], 1, [1], 1, /*LoadUOps=*/1>;754defm : Zn4WriteResIntPair<WriteRotate, [Zn4ALU12], 1, [1], 1, /*LoadUOps=*/1>;755 756def Zn4WriteRotateR1 : SchedWriteRes<[Zn4ALU12]> {757 let Latency = 1;758 let ReleaseAtCycles = [2];759 let NumMicroOps = 1;760}761def : InstRW<[Zn4WriteRotateR1], (instrs RCL8r1, RCL16r1, RCL32r1, RCL64r1,762 RCR8r1, RCR16r1, RCR32r1, RCR64r1)>;763 764def Zn4WriteRotateM1 : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4ALU12]> {765 let Latency = !add(Znver4Model.LoadLatency, Zn4WriteRotateR1.Latency);766 let ReleaseAtCycles = [1, 1, 2];767 let NumMicroOps = !add(Zn4WriteRotateR1.NumMicroOps, 1);768}769def : InstRW<[Zn4WriteRotateM1], (instrs RCL8m1, RCL16m1, RCL32m1, RCL64m1,770 RCR8m1, RCR16m1, RCR32m1, RCR64m1)>;771 772def Zn4WriteRotateRightRI : SchedWriteRes<[Zn4ALU12]> {773 let Latency = 3;774 let ReleaseAtCycles = [6];775 let NumMicroOps = 7;776}777def : InstRW<[Zn4WriteRotateRightRI], (instrs RCR8ri, RCR16ri, RCR32ri, RCR64ri)>;778 779def Zn4WriteRotateRightMI : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4ALU12]> {780 let Latency = !add(Znver4Model.LoadLatency, Zn4WriteRotateRightRI.Latency);781 let ReleaseAtCycles = [1, 1, 8];782 let NumMicroOps = !add(Zn4WriteRotateRightRI.NumMicroOps, 3);783}784def : InstRW<[Zn4WriteRotateRightMI], (instrs RCR8mi, RCR16mi, RCR32mi, RCR64mi)>;785 786def Zn4WriteRotateLeftRI : SchedWriteRes<[Zn4ALU12]> {787 let Latency = 4;788 let ReleaseAtCycles = [8];789 let NumMicroOps = 9;790}791def : InstRW<[Zn4WriteRotateLeftRI], (instrs RCL8ri, RCL16ri, RCL32ri, RCL64ri)>;792 793def Zn4WriteRotateLeftMI : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4ALU12]> {794 let Latency = !add(Znver4Model.LoadLatency, Zn4WriteRotateLeftRI.Latency);795 let ReleaseAtCycles = [1, 1, 8];796 let NumMicroOps = !add(Zn4WriteRotateLeftRI.NumMicroOps, 2);797}798def : InstRW<[Zn4WriteRotateLeftMI], (instrs RCL8mi, RCL16mi, RCL32mi, RCL64mi)>;799 800defm : Zn4WriteResIntPair<WriteRotateCL, [Zn4ALU12], 1, [1], 1, /*LoadUOps=*/1>;801 802def Zn4WriteRotateRightRCL : SchedWriteRes<[Zn4ALU12]> {803 let Latency = 3;804 let ReleaseAtCycles = [6];805 let NumMicroOps = 7;806}807def : InstRW<[Zn4WriteRotateRightRCL], (instrs RCR8rCL, RCR16rCL, RCR32rCL, RCR64rCL)>;808 809def Zn4WriteRotateRightMCL : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4ALU12]> {810 let Latency = !add(Znver4Model.LoadLatency, Zn4WriteRotateRightRCL.Latency);811 let ReleaseAtCycles = [1, 1, 8];812 let NumMicroOps = !add(Zn4WriteRotateRightRCL.NumMicroOps, 2);813}814def : InstRW<[Zn4WriteRotateRightMCL], (instrs RCR8mCL, RCR16mCL, RCR32mCL, RCR64mCL)>;815 816def Zn4WriteRotateLeftRCL : SchedWriteRes<[Zn4ALU12]> {817 let Latency = 4;818 let ReleaseAtCycles = [8];819 let NumMicroOps = 9;820}821def : InstRW<[Zn4WriteRotateLeftRCL], (instrs RCL8rCL, RCL16rCL, RCL32rCL, RCL64rCL)>;822 823def Zn4WriteRotateLeftMCL : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4ALU12]> {824 let Latency = !add(Znver4Model.LoadLatency, Zn4WriteRotateLeftRCL.Latency);825 let ReleaseAtCycles = [1, 1, 8];826 let NumMicroOps = !add(Zn4WriteRotateLeftRCL.NumMicroOps, 2);827}828def : InstRW<[Zn4WriteRotateLeftMCL], (instrs RCL8mCL, RCL16mCL, RCL32mCL, RCL64mCL)>;829 830// Double shift instructions.831defm : Zn4WriteResInt<WriteSHDrri, [Zn4ALU12], 2, [3], 4>;832defm : Zn4WriteResInt<WriteSHDrrcl, [Zn4ALU12], 2, [3], 5>;833defm : Zn4WriteResInt<WriteSHDmri, [Zn4AGU012, Zn4Load, Zn4ALU12], !add(Znver4Model.LoadLatency, 2), [1, 1, 4], 6>;834defm : Zn4WriteResInt<WriteSHDmrcl, [Zn4AGU012, Zn4Load, Zn4ALU12], !add(Znver4Model.LoadLatency, 2), [1, 1, 4], 6>;835 836// BMI1 BEXTR/BLS, BMI2 BZHI837defm : Zn4WriteResIntPair<WriteBEXTR, [Zn4ALU12], 1, [1], 1, /*LoadUOps=*/1>;838defm : Zn4WriteResIntPair<WriteBLS, [Zn4ALU0123], 1, [1], 1, /*LoadUOps=*/1>;839defm : Zn4WriteResIntPair<WriteBZHI, [Zn4ALU12], 1, [1], 1, /*LoadUOps=*/1>;840 841// Idioms that clear a register, like xorps %xmm0, %xmm0.842// These can often bypass execution ports completely.843defm : Zn4WriteResInt<WriteZero, [Zn4ALU0123], 0, [0], 1>;844 845// Branches don't produce values, so they have no latency, but they still846// consume resources. Indirect branches can fold loads.847defm : Zn4WriteResIntPair<WriteJump, [Zn4BRU01], 1, [1], 1>; // FIXME: not from llvm-exegesis848 849// Floating point. This covers both scalar and vector operations.850defm : Zn4WriteResInt<WriteFLD0, [Zn4FPLd01, Zn4Load, Zn4FP1], !add(Znver4Model.LoadLatency, 4), [1, 1, 1], 1>;851defm : Zn4WriteResInt<WriteFLD1, [Zn4FPLd01, Zn4Load, Zn4FP1], !add(Znver4Model.LoadLatency, 7), [1, 1, 1], 1>;852defm : Zn4WriteResInt<WriteFLDC, [Zn4FPLd01, Zn4Load, Zn4FP1], !add(Znver4Model.LoadLatency, 7), [1, 1, 1], 1>;853defm : Zn4WriteResXMM<WriteFLoad, [Zn4FPLd01, Zn4Load], !add(Znver4Model.VecLoadLatency, 1), [1, 1], 1>;854defm : Zn4WriteResXMM<WriteFLoadX, [Zn4FPLd01, Zn4Load], !add(Znver4Model.VecLoadLatency, 1), [1, 1], 1>;855defm : Zn4WriteResYMM<WriteFLoadY, [Zn4FPLd01, Zn4Load], !add(Znver4Model.VecLoadLatency, 1), [1, 1], 1>;856defm : Zn4WriteResXMM<WriteFMaskedLoad, [Zn4FPLd01, Zn4Load], !add(Znver4Model.VecLoadLatency, 1), [1, 1], 1>;857defm : Zn4WriteResYMM<WriteFMaskedLoadY, [Zn4FPLd01, Zn4Load], !add(Znver4Model.VecLoadLatency, 1), [1, 1], 1>;858defm : Zn4WriteResXMM<WriteFStore, [Zn4FPSt, Zn4Store], Znver4Model.StoreLatency, [1, 1], 1>;859 860def Zn4WriteWriteFStoreMMX : SchedWriteRes<[Zn4FPSt, Zn4Store]> {861 let Latency = 2; // FIXME: not from llvm-exegesis862 let ReleaseAtCycles = [1, 1];863 let NumMicroOps = 2;864}865def : InstRW<[Zn4WriteWriteFStoreMMX], (instrs MOVHPDmr, MOVHPSmr,866 VMOVHPDmr, VMOVHPSmr)>;867 868defm : Zn4WriteResXMM<WriteFStoreX, [Zn4FPSt, Zn4Store], Znver4Model.StoreLatency, [1, 1], 1>;869defm : Zn4WriteResYMM<WriteFStoreY, [Zn4FPSt, Zn4Store], Znver4Model.StoreLatency, [1, 1], 1>;870defm : Zn4WriteResXMM<WriteFStoreNT, [Zn4FPSt, Zn4Store], Znver4Model.StoreLatency, [1, 1], 1>;871defm : Zn4WriteResXMM<WriteFStoreNTX, [Zn4FPSt, Zn4Store], Znver4Model.StoreLatency, [1, 1], 1>;872defm : Zn4WriteResYMM<WriteFStoreNTY, [Zn4FPSt, Zn4Store], Znver4Model.StoreLatency, [1, 1], 1>;873 874defm : Zn4WriteResXMM<WriteFMaskedStore32, [Zn4FPSt, Zn4Store], Znver4Model.StoreLatency, [6, 1], 18>;875defm : Zn4WriteResXMM<WriteFMaskedStore64, [Zn4FPSt, Zn4Store], Znver4Model.StoreLatency, [4, 1], 10>;876defm : Zn4WriteResYMM<WriteFMaskedStore32Y, [Zn4FPSt, Zn4Store], Znver4Model.StoreLatency, [12, 1], 42>;877defm : Zn4WriteResYMM<WriteFMaskedStore64Y, [Zn4FPSt, Zn4Store], Znver4Model.StoreLatency, [6, 1], 18>;878 879defm : Zn4WriteResXMMPair<WriteFAdd, [Zn4FPFAdd01], 3, [1], 1>; // Floating point add/sub.880 881def Zn4WriteX87Arith : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4FPU0123]> {882 let Latency = !add(Znver4Model.LoadLatency, 1); // FIXME: not from llvm-exegesis883 let ReleaseAtCycles = [1, 1, 24];884 let NumMicroOps = 2;885}886def : InstRW<[Zn4WriteX87Arith], (instrs ADD_FI16m, ADD_FI32m,887 SUB_FI16m, SUB_FI32m,888 SUBR_FI16m, SUBR_FI32m,889 MUL_FI16m, MUL_FI32m)>;890 891def Zn4WriteX87Div : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4FPU0123]> {892 let Latency = !add(Znver4Model.LoadLatency, 1); // FIXME: not from llvm-exegesis893 let ReleaseAtCycles = [1, 1, 62];894 let NumMicroOps = 2;895}896def : InstRW<[Zn4WriteX87Div], (instrs DIV_FI16m, DIV_FI32m,897 DIVR_FI16m, DIVR_FI32m)>;898 899defm : Zn4WriteResXMMPair<WriteFAddX, [Zn4FPFAdd01], 3, [1], 1>; // Floating point add/sub (XMM).900defm : Zn4WriteResYMMPair<WriteFAddY, [Zn4FPFAdd01], 3, [1], 1>; // Floating point add/sub (YMM).901defm : Zn4WriteResZMMPair<WriteFAddZ, [Zn4FPFAdd01], 3, [2], 1>; // Floating point add/sub (ZMM).902defm : Zn4WriteResXMMPair<WriteFAdd64, [Zn4FPFAdd01], 3, [1], 1>; // Floating point double add/sub.903defm : Zn4WriteResXMMPair<WriteFAdd64X, [Zn4FPFAdd01], 3, [1], 1>; // Floating point double add/sub (XMM).904defm : Zn4WriteResYMMPair<WriteFAdd64Y, [Zn4FPFAdd01], 3, [1], 1>; // Floating point double add/sub (YMM).905defm : Zn4WriteResZMMPair<WriteFAdd64Z, [Zn4FPFAdd01], 3, [2], 1>; // Floating point double add/sub (ZMM).906defm : Zn4WriteResXMMPair<WriteFCmp, [Zn4FPFMul01], 2, [2], 1>; // Floating point compare.907defm : Zn4WriteResXMMPair<WriteFCmpX, [Zn4FPFMul01], 2, [1], 1>; // Floating point compare (XMM).908defm : Zn4WriteResYMMPair<WriteFCmpY, [Zn4FPFMul01], 2, [1], 1>; // Floating point compare (YMM).909defm : Zn4WriteResZMMPair<WriteFCmpZ, [Zn4FPFMul01], 2, [2], 1>; // Floating point compare (ZMM).910defm : Zn4WriteResXMMPair<WriteFCmp64, [Zn4FPFMul01], 1, [1], 1>; // Floating point double compare.911defm : Zn4WriteResXMMPair<WriteFCmp64X, [Zn4FPFMul01], 2, [1], 1>; // Floating point double compare (XMM).912defm : Zn4WriteResYMMPair<WriteFCmp64Y, [Zn4FPFMul01], 2, [1], 1>; // Floating point double compare (YMM).913defm : Zn4WriteResZMMPair<WriteFCmp64Z, [Zn4FPFMul01], 2, [2], 1>; // Floating point double compare (ZMM).914defm : Zn4WriteResXMMPair<WriteFCom, [Zn4FPFMul01], 3, [2], 1>; // FIXME: latency not from llvm-exegesis // Floating point compare to flags (X87).915defm : Zn4WriteResXMMPair<WriteFComX, [Zn4FPFMul01], 4, [2], 2>; // FIXME: latency not from llvm-exegesis // Floating point compare to flags (SSE).916defm : Zn4WriteResXMMPair<WriteFMul, [Zn4FPFMul01], 3, [1], 1>; // Floating point multiplication.917defm : Zn4WriteResXMMPair<WriteFMulX, [Zn4FPFMul01], 3, [1], 1>; // Floating point multiplication (XMM).918defm : Zn4WriteResYMMPair<WriteFMulY, [Zn4FPFMul01], 3, [1], 1>; // Floating point multiplication (YMM).919defm : Zn4WriteResZMMPair<WriteFMulZ, [Zn4FPFMul01], 3, [2], 1>; // Floating point multiplication (ZMM).920defm : Zn4WriteResXMMPair<WriteFMul64, [Zn4FPFMul01], 3, [1], 1>; // Floating point double multiplication.921defm : Zn4WriteResXMMPair<WriteFMul64X, [Zn4FPFMul01], 3, [1], 1>; // Floating point double multiplication (XMM).922defm : Zn4WriteResYMMPair<WriteFMul64Y, [Zn4FPFMul01], 3, [1], 1>; // Floating point double multiplication (YMM).923defm : Zn4WriteResZMMPair<WriteFMul64Z, [Zn4FPFMul01], 3, [2], 1>; // Floating point double multiplication (ZMM).924defm : Zn4WriteResXMMPair<WriteFDiv, [Zn4FPFDiv], 11, [3], 1>; // Floating point division.925defm : Zn4WriteResXMMPair<WriteFDivX, [Zn4FPFDiv], 11, [3], 1>; // Floating point division (XMM).926defm : Zn4WriteResYMMPair<WriteFDivY, [Zn4FPFDiv], 11, [3], 1>; // Floating point division (YMM).927defm : Zn4WriteResZMMPair<WriteFDivZ, [Zn4FPFDiv], 11, [6], 1>; // Floating point division (ZMM).928defm : Zn4WriteResXMMPair<WriteFDiv64, [Zn4FPFDiv], 13, [5], 1>; // Floating point double division.929defm : Zn4WriteResXMMPair<WriteFDiv64X, [Zn4FPFDiv], 13, [5], 1>; // Floating point double division (XMM).930defm : Zn4WriteResYMMPair<WriteFDiv64Y, [Zn4FPFDiv], 13, [5], 1>; // Floating point double division (YMM).931defm : Zn4WriteResZMMPair<WriteFDiv64Z, [Zn4FPFDiv], 13, [10], 1>; // Floating point double division (ZMM).932defm : Zn4WriteResXMMPair<WriteFSqrt, [Zn4FPFDiv], 15, [5], 1>; // Floating point square root.933defm : Zn4WriteResXMMPair<WriteFSqrtX, [Zn4FPFDiv], 15, [5], 1>; // Floating point square root (XMM).934defm : Zn4WriteResYMMPair<WriteFSqrtY, [Zn4FPFDiv], 15, [5], 1>; // Floating point square root (YMM).935defm : Zn4WriteResZMMPair<WriteFSqrtZ, [Zn4FPFDiv], 15, [10], 1>; // Floating point square root (ZMM).936defm : Zn4WriteResXMMPair<WriteFSqrt64, [Zn4FPFDiv], 21, [9], 1>; // Floating point double square root.937defm : Zn4WriteResXMMPair<WriteFSqrt64X, [Zn4FPFDiv], 21, [9], 1>; // Floating point double square root (XMM).938defm : Zn4WriteResYMMPair<WriteFSqrt64Y, [Zn4FPFDiv], 21, [9], 1>; // Floating point double square root (YMM).939defm : Zn4WriteResZMMPair<WriteFSqrt64Z, [Zn4FPFDiv], 21, [18], 1>; // Floating point double square root (ZMM).940defm : Zn4WriteResXMMPair<WriteFSqrt80, [Zn4FPFDiv], 22, [23], 1>; // FIXME: latency not from llvm-exegesis // Floating point long double square root.941defm : Zn4WriteResXMMPair<WriteFRcp, [Zn4FPFMul01], 4, [1], 1>; // Floating point reciprocal estimate.942defm : Zn4WriteResXMMPair<WriteFRcpX, [Zn4FPFMul01], 4, [1], 1>; // Floating point reciprocal estimate (XMM).943defm : Zn4WriteResYMMPair<WriteFRcpY, [Zn4FPFMul01], 5, [1], 1>; // Floating point reciprocal estimate (YMM).944defm : Zn4WriteResZMMPair<WriteFRcpZ, [Zn4FPFMul01], 5, [2], 1>; // Floating point reciprocal estimate (ZMM).945defm : Zn4WriteResXMMPair<WriteFRsqrt, [Zn4FPFDiv], 4, [1], 1>; // Floating point reciprocal square root estimate.946defm : Zn4WriteResXMMPair<WriteFRsqrtX, [Zn4FPFDiv], 4, [1], 1>; // Floating point reciprocal square root estimate (XMM).947defm : Zn4WriteResYMMPair<WriteFRsqrtY, [Zn4FPFDiv], 4, [1], 1>; // Floating point reciprocal square root estimate (YMM).948defm : Zn4WriteResZMMPair<WriteFRsqrtZ, [Zn4FPFDiv], 5, [2], 1>; // Floating point reciprocal square root estimate (ZMM).949defm : Zn4WriteResXMMPair<WriteFMA, [Zn4FPFMul01], 4, [2], 1>; // Fused Multiply Add.950defm : Zn4WriteResXMMPair<WriteFMAX, [Zn4FPFMul01], 4, [1], 1>; // Fused Multiply Add (XMM).951defm : Zn4WriteResYMMPair<WriteFMAY, [Zn4FPFMul01], 4, [1], 1>; // Fused Multiply Add (YMM).952defm : Zn4WriteResZMMPair<WriteFMAZ, [Zn4FPFMul01], 4, [2], 1>; // Fused Multiply Add (ZMM).953defm : Zn4WriteResXMMPair<WriteDPPD, [Zn4FPFMul01], 7, [6], 3, /*LoadUOps=*/2>; // Floating point double dot product.954defm : Zn4WriteResXMMPair<WriteDPPS, [Zn4FPFMul01], 11, [8], 8, /*LoadUOps=*/2>; // Floating point single dot product.955defm : Zn4WriteResYMMPair<WriteDPPSY, [Zn4FPFMul01], 11, [8], 7, /*LoadUOps=*/1>; // Floating point single dot product (YMM).956defm : Zn4WriteResXMMPair<WriteFSign, [Zn4FPFMul01], 1, [2], 1>; // FIXME: latency not from llvm-exegesis // Floating point fabs/fchs.957defm : Zn4WriteResXMMPair<WriteFRnd, [Zn4FPFCvt01], 3, [1], 1>; // Floating point rounding.958defm : Zn4WriteResYMMPair<WriteFRndY, [Zn4FPFCvt01], 3, [1], 1>; // Floating point rounding (YMM).959defm : Zn4WriteResZMMPair<WriteFRndZ, [Zn4FPFCvt01], 3, [2], 1>; // Floating point rounding (ZMM).960 961defm : Zn4WriteResXMMPair<WriteFLogic, [Zn4FPVMisc0123], 1, [1], 1>; // Floating point and/or/xor logicals.962defm : Zn4WriteResYMMPair<WriteFLogicY, [Zn4FPVMisc0123], 1, [1], 1>; // Floating point and/or/xor logicals (YMM).963defm : Zn4WriteResZMMPair<WriteFLogicZ, [Zn4FPVMisc0123], 1, [2], 1>; // Floating point and/or/xor logicals (ZMM).964defm : Zn4WriteResXMMPair<WriteFTest, [Zn4FPFMisc12], 1, [2], 2>; // FIXME: latency not from llvm-exegesis // Floating point TEST instructions.965defm : Zn4WriteResYMMPair<WriteFTestY, [Zn4FPFMisc12], 1, [2], 2>; // FIXME: latency not from llvm-exegesis // Floating point TEST instructions (YMM).966defm : Zn4WriteResZMMPair<WriteFTestZ, [Zn4FPFMisc12], 1, [4], 1>; // FIXME: latency not from llvm-exegesis // Floating point TEST instructions (ZMM).967defm : Zn4WriteResXMMPair<WriteFShuffle, [Zn4FPVShuf01], 1, [1], 1>; // Floating point vector shuffles.968defm : Zn4WriteResYMMPair<WriteFShuffleY, [Zn4FPVShuf01], 1, [1], 1>; // Floating point vector shuffles (YMM).969defm : Zn4WriteResZMMPair<WriteFShuffleZ, [Zn4FPVShuf01], 1, [2], 1>; // Floating point vector shuffles (ZMM).970defm : Zn4WriteResXMMPair<WriteFVarShuffle, [Zn4FPVShuf01], 3, [1], 1>; // Floating point vector variable shuffles.971defm : Zn4WriteResYMMPair<WriteFVarShuffleY, [Zn4FPVShuf01], 3, [1], 1>; // Floating point vector variable shuffles (YMM).972defm : Zn4WriteResZMMPair<WriteFVarShuffleZ, [Zn4FPVShuf01], 3, [2], 1>; // Floating point vector variable shuffles (ZMM).973defm : Zn4WriteResXMMPair<WriteFBlend, [Zn4FPFMul01], 1, [1], 1>; // Floating point vector blends.974defm : Zn4WriteResYMMPair<WriteFBlendY, [Zn4FPFMul01], 1, [1], 1>; // Floating point vector blends (YMM).975defm : Zn4WriteResZMMPair<WriteFBlendZ, [Zn4FPFMul01], 1, [2], 1>; // Floating point vector blends (ZMM).976defm : Zn4WriteResXMMPair<WriteFVarBlend, [Zn4FPFMul01], 1, [1], 1>; // Fp vector variable blends.977defm : Zn4WriteResYMMPair<WriteFVarBlendY, [Zn4FPFMul01], 1, [1], 1>; // Fp vector variable blends (YMM).978defm : Zn4WriteResZMMPair<WriteFVarBlendZ, [Zn4FPFMul01], 1, [2], 1>; // Fp vector variable blends (ZMM).979 980// Horizontal Add/Sub (float and integer)981defm : Zn4WriteResXMMPair<WriteFHAdd, [Zn4FPFAdd0], 4, [2], 3>;982defm : Zn4WriteResYMMPair<WriteFHAddY, [Zn4FPFAdd0], 4, [2], 3, /*LoadUOps=*/1>;983defm : Zn4WriteResZMMPair<WriteFHAddZ, [Zn4FPFAdd0], 6, [4], 3, /*LoadUOps=*/1>;984defm : Zn4WriteResXMMPair<WritePHAdd, [Zn4FPVAdd0], 2, [2], 3, /*LoadUOps=*/1>;985defm : Zn4WriteResXMMPair<WritePHAddX, [Zn4FPVAdd0], 2, [2], 3>;986defm : Zn4WriteResYMMPair<WritePHAddY, [Zn4FPVAdd0], 3, [3], 3, /*LoadUOps=*/1>;987defm : Zn4WriteResZMMPair<WritePHAddZ, [Zn4FPVAdd0], 2, [4], 3, /*LoadUOps=*/1>;988 989// Vector integer operations.990defm : Zn4WriteResXMM<WriteVecLoad, [Zn4FPLd01, Zn4Load], !add(Znver4Model.VecLoadLatency, 1), [1, 1], 1>;991defm : Zn4WriteResXMM<WriteVecLoadX, [Zn4FPLd01, Zn4Load], !add(Znver4Model.VecLoadLatency, 1), [1, 1], 1>;992defm : Zn4WriteResYMM<WriteVecLoadY, [Zn4FPLd01, Zn4Load], !add(Znver4Model.VecLoadLatency, 1), [1, 1], 1>;993defm : Zn4WriteResXMM<WriteVecLoadNT, [Zn4FPLd01, Zn4Load], !add(Znver4Model.VecLoadLatency, 1), [1, 1], 1>;994defm : Zn4WriteResYMM<WriteVecLoadNTY, [Zn4FPLd01, Zn4Load], !add(Znver4Model.VecLoadLatency, 1), [1, 1], 1>;995defm : Zn4WriteResXMM<WriteVecMaskedLoad, [Zn4FPLd01, Zn4Load], !add(Znver4Model.VecLoadLatency, 1), [1, 1], 1>;996defm : Zn4WriteResYMM<WriteVecMaskedLoadY, [Zn4FPLd01, Zn4Load], !add(Znver4Model.VecLoadLatency, 1), [1, 1], 1>;997defm : Zn4WriteResXMM<WriteVecStore, [Zn4FPSt, Zn4Store], Znver4Model.StoreLatency, [1, 1], 1>;998defm : Zn4WriteResXMM<WriteVecStoreX, [Zn4FPSt, Zn4Store], Znver4Model.StoreLatency, [1, 1], 1>;999 1000def Zn4WriteVEXTRACTF128rr_VEXTRACTI128rr : SchedWriteRes<[Zn4FPFMisc0]> {1001 let Latency = 4;1002 let ReleaseAtCycles = [1];1003 let NumMicroOps = 1;1004}1005def : InstRW<[Zn4WriteVEXTRACTF128rr_VEXTRACTI128rr], (instrs VEXTRACTF128rri, VEXTRACTI128rri)>;1006 1007def Zn4WriteVEXTRACTI128mr : SchedWriteRes<[Zn4FPFMisc0, Zn4FPSt, Zn4Store]> {1008 let Latency = !add(Znver4Model.VecLoadLatency, Zn4WriteVEXTRACTF128rr_VEXTRACTI128rr.Latency);1009 let ReleaseAtCycles = [1, 1, 1];1010 let NumMicroOps = !add(Zn4WriteVEXTRACTF128rr_VEXTRACTI128rr.NumMicroOps, 1);1011}1012def : InstRW<[Zn4WriteVEXTRACTI128mr], (instrs VEXTRACTI128mri, VEXTRACTF128mri)>;1013 1014def Zn4WriteVINSERTF128rmr : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4FPFMisc0]> {1015 let Latency = !add(Znver4Model.VecLoadLatency, Zn4WriteVEXTRACTF128rr_VEXTRACTI128rr.Latency);1016 let ReleaseAtCycles = [1, 1, 1];1017 let NumMicroOps = !add(Zn4WriteVEXTRACTF128rr_VEXTRACTI128rr.NumMicroOps, 0);1018}1019def : InstRW<[Zn4WriteVINSERTF128rmr], (instrs VINSERTF128rmi)>;1020 1021defm : Zn4WriteResYMM<WriteVecStoreY, [Zn4FPSt, Zn4Store], Znver4Model.StoreLatency, [1, 1], 1>;1022defm : Zn4WriteResXMM<WriteVecStoreNT, [Zn4FPSt, Zn4Store], Znver4Model.StoreLatency, [1, 1], 1>;1023defm : Zn4WriteResYMM<WriteVecStoreNTY, [Zn4FPSt, Zn4Store], Znver4Model.StoreLatency, [1, 1], 1>;1024defm : Zn4WriteResXMM<WriteVecMaskedStore32, [Zn4FPSt, Zn4Store], Znver4Model.StoreLatency, [6, 1], 18>;1025defm : Zn4WriteResXMM<WriteVecMaskedStore64, [Zn4FPSt, Zn4Store], Znver4Model.StoreLatency, [4, 1], 10>;1026defm : Zn4WriteResYMM<WriteVecMaskedStore32Y, [Zn4FPSt, Zn4Store], Znver4Model.StoreLatency, [12, 1], 42>;1027defm : Zn4WriteResYMM<WriteVecMaskedStore64Y, [Zn4FPSt, Zn4Store], Znver4Model.StoreLatency, [6, 1], 18>;1028 1029defm : Zn4WriteResXMM<WriteVecMoveToGpr, [Zn4FPLd01], 1, [2], 1>;1030defm : Zn4WriteResXMM<WriteVecMoveFromGpr, [Zn4FPLd01], 1, [2], 1>;1031 1032def Zn4WriteMOVMMX : SchedWriteRes<[Zn4FPLd01, Zn4FPFMisc0123]> {1033 let Latency = 1;1034 let ReleaseAtCycles = [1, 2];1035 let NumMicroOps = 2;1036}1037def : InstRW<[Zn4WriteMOVMMX], (instrs MMX_MOVQ2FR64rr, MMX_MOVQ2DQrr)>;1038 1039def Zn4WriteMOVMMXSlow : SchedWriteRes<[Zn4FPLd01, Zn4FPFMisc0123]> {1040 let Latency = 1;1041 let ReleaseAtCycles = [1, 4];1042 let NumMicroOps = 2;1043}1044def : InstRW<[Zn4WriteMOVMMXSlow], (instrs MMX_MOVD64rr, MMX_MOVD64to64rr)>;1045 1046defm : Zn4WriteResXMMPair<WriteVecALU, [Zn4FPVAdd0123], 1, [1], 1>; // Vector integer ALU op, no logicals.1047 1048def Zn4WriteEXTRQ_INSERTQ : SchedWriteRes<[Zn4FPVShuf01, Zn4FPLd01]> {1049 let Latency = 3;1050 let ReleaseAtCycles = [1, 1];1051 let NumMicroOps = 1;1052}1053def : InstRW<[Zn4WriteEXTRQ_INSERTQ], (instrs EXTRQ, INSERTQ)>;1054 1055def Zn4WriteEXTRQI_INSERTQI : SchedWriteRes<[Zn4FPVShuf01, Zn4FPLd01]> {1056 let Latency = 3;1057 let ReleaseAtCycles = [1, 1];1058 let NumMicroOps = 2;1059}1060def : InstRW<[Zn4WriteEXTRQI_INSERTQI], (instrs EXTRQI, INSERTQI)>;1061 1062defm : Zn4WriteResXMMPair<WriteVecALUX, [Zn4FPVAdd0123], 1, [1], 1>; // Vector integer ALU op, no logicals (XMM).1063 1064def Zn4WriteVecALUXSlow : SchedWriteRes<[Zn4FPVAdd01]> {1065 let Latency = 2;1066 let ReleaseAtCycles = [2];1067 let NumMicroOps = 1;1068}1069def : InstRW<[Zn4WriteVecALUXSlow], (instrs PABSBrr, PABSDrr, PABSWrr,1070 PADDSBrr, PADDSWrr, PADDUSBrr, PADDUSWrr,1071 PAVGBrr, PAVGWrr,1072 PSIGNBrr, PSIGNDrr, PSIGNWrr,1073 VPABSBrr, VPABSDrr, VPABSWrr,1074 VPADDSBrr, VPADDSWrr, VPADDUSBrr, VPADDUSWrr,1075 VPAVGBrr, VPAVGWrr,1076 VPCMPEQQrr,1077 VPSIGNBrr, VPSIGNDrr, VPSIGNWrr,1078 PSUBSBrr, PSUBSWrr, PSUBUSBrr, PSUBUSWrr, VPSUBSBrr, VPSUBSWrr, VPSUBUSBrr, VPSUBUSWrr)>;1079 1080def Zn4WriteVecOpMask : SchedWriteRes<[Zn4FPOpMask01]> {1081 let Latency = 1;1082 let ReleaseAtCycles = [1];1083 let NumMicroOps = 1;1084}1085def : InstRW<[Zn4WriteVecOpMask], (instrs KADDBkk, KADDDkk, KADDQkk, KADDWkk,1086 KANDBkk, KANDDkk, KANDQkk, KANDWkk,1087 KANDNBkk, KANDNDkk, KANDNQkk, KANDNWkk,1088 KMOVBkk, KMOVDkk, KMOVQkk, KMOVWkk,1089 KMOVBrk, KMOVDrk, KMOVQrk, KMOVWrk,1090 KNOTBkk, KNOTDkk, KNOTQkk, KNOTWkk,1091 KORBkk, KORDkk, KORQkk, KORWkk,1092 KORTESTBkk, KORTESTDkk, KORTESTQkk, KORTESTWkk,1093 KTESTBkk, KTESTDkk, KTESTQkk, KTESTWkk,1094 KUNPCKBWkk, KUNPCKDQkk, KUNPCKWDkk,1095 KXNORBkk, KXNORDkk, KXNORQkk, KXNORWkk,1096 KXORBkk, KXORDkk, KXORQkk, KXORWkk)>;1097 1098def Zn4WriteVecOpMaskMemMov : SchedWriteRes<[Zn4FPOpMask4]> {1099 let Latency = 1;1100 let ReleaseAtCycles = [1];1101 let NumMicroOps = 1;1102}1103def : InstRW<[Zn4WriteVecOpMaskMemMov], (instrs KMOVBmk, KMOVDmk, KMOVQmk, KMOVWmk)>;1104 1105def Zn4WriteVecOpMaskKRMov : SchedWriteRes<[Zn4FPOpMask4]> {1106 let Latency = 1;1107 let ReleaseAtCycles = [1];1108 let NumMicroOps = 1;1109}1110def : InstRW<[Zn4WriteVecOpMaskKRMov], (instrs KMOVBkr, KMOVDkr, KMOVQkr, KMOVWkr)>;1111 1112// 128-bit VALIGN1113def Zn4WriteXMMVecALU2Slow : SchedWriteRes<[Zn4FPVAdd12]> {1114 let Latency = 2;1115 let ReleaseAtCycles = [1];1116 let NumMicroOps = 1;1117}1118 1119// 256-bit VALIGN1120def Zn4WriteYMMVecALU2Slow : SchedWriteRes<[Zn4FPVAdd12]> {1121 let Latency = 3;1122 let ReleaseAtCycles = [1];1123 let NumMicroOps = 1;1124}1125 1126// 512-bit VALIGN1127def Zn4WriteZMMVecALU2Slow : SchedWriteRes<[Zn4FPVAdd12]> {1128 let Latency = 4;1129 let ReleaseAtCycles = [2];1130 let NumMicroOps = 1;1131}1132 1133def : InstRW<[Zn4WriteXMMVecALU2Slow], (instrs VALIGNDZrri, VALIGNQZrri)>;1134def : InstRW<[Zn4WriteYMMVecALU2Slow], (instrs VALIGNDZ128rri, VALIGNQZ128rri)>;1135def : InstRW<[Zn4WriteZMMVecALU2Slow], (instrs VALIGNDZ256rri, VALIGNQZ256rri)>;1136 1137defm : Zn4WriteResYMMPair<WriteVecALUY, [Zn4FPVAdd0123], 1, [1], 1>; // Vector integer ALU op, no logicals (YMM).1138 1139def Zn4WriteVecALUYSlow : SchedWriteRes<[Zn4FPVAdd01]> {1140 let Latency = 1;1141 let ReleaseAtCycles = [1];1142 let NumMicroOps = 1;1143}1144def : InstRW<[Zn4WriteVecALUYSlow], (instrs VPABSBYrr, VPABSDYrr, VPABSWYrr,1145 VPADDSBYrr, VPADDSWYrr, VPADDUSBYrr, VPADDUSWYrr,1146 VPSUBSBYrr, VPSUBSWYrr, VPSUBUSBYrr, VPSUBUSWYrr,1147 VPAVGBYrr, VPAVGWYrr,1148 VPCMPEQQYrr,1149 VPSIGNBYrr, VPSIGNDYrr, VPSIGNWYrr)>;1150 1151defm : Zn4WriteResZMMPair<WriteVecALUZ, [Zn4FPVAdd0123], 1, [2], 1>; // Vector integer ALU op, no logicals (ZMM).1152 1153defm : Zn4WriteResXMMPair<WriteVecLogic, [Zn4FPVMisc0123], 1, [1], 1>; // Vector integer and/or/xor logicals.1154defm : Zn4WriteResXMMPair<WriteVecLogicX, [Zn4FPVMisc0123], 1, [1], 1>; // Vector integer and/or/xor logicals (XMM).1155defm : Zn4WriteResYMMPair<WriteVecLogicY, [Zn4FPVMisc0123], 1, [1], 1>; // Vector integer and/or/xor logicals (YMM).1156defm : Zn4WriteResZMMPair<WriteVecLogicZ, [Zn4FPVMisc0123], 1, [2], 1>; // Vector integer and/or/xor logicals (ZMM).1157defm : Zn4WriteResXMMPair<WriteVecTest, [Zn4FPVAdd12, Zn4FPSt], 1, [1, 1], 2>; // FIXME: latency not from llvm-exegesis // Vector integer TEST instructions.1158defm : Zn4WriteResYMMPair<WriteVecTestY, [Zn4FPVAdd12, Zn4FPSt], 1, [1, 1], 2>; // FIXME: latency not from llvm-exegesis // Vector integer TEST instructions (YMM).1159defm : Zn4WriteResZMMPair<WriteVecTestZ, [Zn4FPVAdd12, Zn4FPSt], 1, [2, 2], 2>; // FIXME: latency not from llvm-exegesis // Vector integer TEST instructions (ZMM).1160defm : Zn4WriteResXMMPair<WriteVecShift, [Zn4FPVShift01], 1, [1], 1>; // Vector integer shifts (default).1161defm : Zn4WriteResXMMPair<WriteVecShiftX, [Zn4FPVShift01], 2, [2], 1>; // Vector integer shifts (XMM).1162defm : Zn4WriteResYMMPair<WriteVecShiftY, [Zn4FPVShift01], 1, [1], 1>; // Vector integer shifts (YMM).1163defm : Zn4WriteResZMMPair<WriteVecShiftZ, [Zn4FPVShift01], 1, [2], 1>; // Vector integer shifts (ZMM).1164defm : Zn4WriteResXMMPair<WriteVecShiftImm, [Zn4FPVShift01], 1, [1], 1>; // Vector integer immediate shifts (default).1165defm : Zn4WriteResXMMPair<WriteVecShiftImmX, [Zn4FPVShift01], 1, [1], 1>; // Vector integer immediate shifts (XMM).1166defm : Zn4WriteResYMMPair<WriteVecShiftImmY, [Zn4FPVShift01], 1, [1], 1>; // Vector integer immediate shifts (YMM).1167defm : Zn4WriteResZMMPair<WriteVecShiftImmZ, [Zn4FPVShift01], 1, [2], 1>; // Vector integer immediate shifts (ZMM).1168defm : Zn4WriteResXMMPair<WriteVecIMul, [Zn4FPVMul01], 3, [1], 1>; // Vector integer multiply (default).1169defm : Zn4WriteResXMMPair<WriteVecIMulX, [Zn4FPVMul01], 3, [1], 1>; // Vector integer multiply (XMM).1170defm : Zn4WriteResYMMPair<WriteVecIMulY, [Zn4FPVMul01], 3, [1], 1>; // Vector integer multiply (YMM).1171defm : Zn4WriteResZMMPair<WriteVecIMulZ, [Zn4FPVMul01], 3, [2], 1>; // Vector integer multiply (ZMM).1172defm : Zn4WriteResXMMPair<WritePMULLD, [Zn4FPVMul01], 3, [1], 1>; // Vector PMULLD.1173defm : Zn4WriteResYMMPair<WritePMULLDY, [Zn4FPVMul01], 3, [1], 1>; // Vector PMULLD (YMM).1174defm : Zn4WriteResZMMPair<WritePMULLDZ, [Zn4FPVMul01], 3, [2], 1>; // Vector PMULLD (ZMM).1175defm : Zn4WriteResXMMPair<WriteShuffle, [Zn4FPVShuf01], 1, [1], 1>; // Vector shuffles.1176defm : Zn4WriteResXMMPair<WriteShuffleX, [Zn4FPVShuf01], 1, [1], 1>; // Vector shuffles (XMM).1177defm : Zn4WriteResYMMPair<WriteShuffleY, [Zn4FPVShuf01], 1, [1], 1>; // Vector shuffles (YMM).1178defm : Zn4WriteResZMMPair<WriteShuffleZ, [Zn4FPVShuf01], 1, [2], 1>; // Vector shuffles (ZMM).1179defm : Zn4WriteResXMMPair<WriteVarShuffle, [Zn4FPVShuf01], 1, [1], 1>; // Vector variable shuffles.1180defm : Zn4WriteResXMMPair<WriteVarShuffleX, [Zn4FPVShuf01], 1, [1], 1>; // Vector variable shuffles (XMM).1181defm : Zn4WriteResYMMPair<WriteVarShuffleY, [Zn4FPVShuf01], 1, [1], 1>; // Vector variable shuffles (YMM).1182defm : Zn4WriteResZMMPair<WriteVarShuffleZ, [Zn4FPVShuf01], 1, [2], 1>; // Vector variable shuffles (ZMM).1183defm : Zn4WriteResXMMPair<WriteBlend, [Zn4FPVMisc0123], 1, [1], 1>; // Vector blends.1184defm : Zn4WriteResYMMPair<WriteBlendY, [Zn4FPVMisc0123], 1, [1], 1>; // Vector blends (YMM).1185defm : Zn4WriteResZMMPair<WriteBlendZ, [Zn4FPVMisc0123], 1, [2], 1>; // Vector blends (ZMM).1186defm : Zn4WriteResXMMPair<WriteVarBlend, [Zn4FPVMul01], 1, [1], 1>; // Vector variable blends.1187defm : Zn4WriteResYMMPair<WriteVarBlendY, [Zn4FPVMul01], 1, [1], 1>; // Vector variable blends (YMM).1188defm : Zn4WriteResZMMPair<WriteVarBlendZ, [Zn4FPVMul01], 1, [2], 1>; // Vector variable blends (ZMM).1189defm : Zn4WriteResXMMPair<WritePSADBW, [Zn4FPVAdd0123], 3, [2], 1>; // Vector PSADBW.1190defm : Zn4WriteResXMMPair<WritePSADBWX, [Zn4FPVAdd0123], 3, [2], 1>; // Vector PSADBW (XMM).1191defm : Zn4WriteResYMMPair<WritePSADBWY, [Zn4FPVAdd0123], 3, [2], 1>; // Vector PSADBW (YMM).1192defm : Zn4WriteResZMMPair<WritePSADBWZ, [Zn4FPVAdd0123], 4, [4], 1>; // Vector PSADBW (ZMM).1193defm : Zn4WriteResXMMPair<WriteMPSAD, [Zn4FPVAdd0123], 4, [8], 4, /*LoadUOps=*/2>; // Vector MPSAD.1194defm : Zn4WriteResYMMPair<WriteMPSADY, [Zn4FPVAdd0123], 4, [8], 3, /*LoadUOps=*/1>; // Vector MPSAD (YMM).1195defm : Zn4WriteResZMMPair<WriteMPSADZ, [Zn4FPVAdd0123], 4, [16], 3, /*LoadUOps=*/1>; // Vector MPSAD (ZMM).1196defm : Zn4WriteResXMMPair<WritePHMINPOS, [Zn4FPVAdd01], 3, [1], 1>; // Vector PHMINPOS.1197 1198// Vector insert/extract operations.1199defm : Zn4WriteResXMMPair<WriteVecInsert, [Zn4FPLd01], 1, [2], 2, /*LoadUOps=*/-1>; // Insert gpr to vector element.1200defm : Zn4WriteResXMM<WriteVecExtract, [Zn4FPLd01], 1, [2], 2>; // Extract vector element to gpr.1201defm : Zn4WriteResXMM<WriteVecExtractSt, [Zn4FPSt, Zn4Store], !add(1, Znver4Model.StoreLatency), [1, 1], 2>; // Extract vector element and store.1202 1203// MOVMSK operations.1204defm : Zn4WriteResXMM<WriteFMOVMSK, [Zn4FPVMisc2], 1, [1], 1>;1205defm : Zn4WriteResXMM<WriteVecMOVMSK, [Zn4FPVMisc2], 1, [1], 1>;1206defm : Zn4WriteResYMM<WriteVecMOVMSKY, [Zn4FPVMisc2], 1, [1], 1>;1207defm : Zn4WriteResXMM<WriteMMXMOVMSK, [Zn4FPVMisc2], 1, [1], 1>;1208 1209// Conversion between integer and float.1210defm : Zn4WriteResXMMPair<WriteCvtSD2I, [Zn4FPFCvt01], 1, [1], 1>; // Double -> Integer.1211defm : Zn4WriteResXMMPair<WriteCvtPD2I, [Zn4FPFCvt01], 3, [2], 1>; // Double -> Integer (XMM).1212defm : Zn4WriteResYMMPair<WriteCvtPD2IY, [Zn4FPFCvt01], 3, [2], 2>; // Double -> Integer (YMM).1213defm : Zn4WriteResZMMPair<WriteCvtPD2IZ, [Zn4FPFCvt01], 3, [4], 2>; // Double -> Integer (ZMM).1214 1215def Zn4WriteCvtPD2IMMX : SchedWriteRes<[Zn4FPFCvt01]> {1216 let Latency = 1;1217 let ReleaseAtCycles = [2];1218 let NumMicroOps = 2;1219}1220defm : Zn4WriteResXMMPair<WriteCvtSS2I, [Zn4FPFCvt01], 5, [5], 2>; // Float -> Integer.1221 1222defm : Zn4WriteResXMMPair<WriteCvtPS2I, [Zn4FPFCvt01], 3, [1], 1>; // Float -> Integer (XMM).1223defm : Zn4WriteResYMMPair<WriteCvtPS2IY, [Zn4FPFCvt01], 4, [1], 1>; // Float -> Integer (YMM).1224defm : Zn4WriteResZMMPair<WriteCvtPS2IZ, [Zn4FPFCvt01], 4, [2], 2>; // Float -> Integer (ZMM).1225 1226defm : Zn4WriteResXMMPair<WriteCvtI2SD, [Zn4FPFCvt01], 4, [2], 2, /*LoadUOps=*/-1>; // Integer -> Double.1227defm : Zn4WriteResXMMPair<WriteCvtI2PD, [Zn4FPFCvt01], 3, [1], 1>; // Integer -> Double (XMM).1228defm : Zn4WriteResYMMPair<WriteCvtI2PDY, [Zn4FPFCvt01], 3, [2], 2, /*LoadUOps=*/-1>; // Integer -> Double (YMM).1229defm : Zn4WriteResZMMPair<WriteCvtI2PDZ, [Zn4FPFCvt01], 4, [4], 4, /*LoadUOps=*/-1>; // Integer -> Double (ZMM).1230 1231def Zn4WriteCvtI2PDMMX : SchedWriteRes<[Zn4FPFCvt01]> {1232 let Latency = 2;1233 let ReleaseAtCycles = [6];1234 let NumMicroOps = 2;1235}1236 1237defm : Zn4WriteResXMMPair<WriteCvtI2SS, [Zn4FPFCvt01], 3, [2], 2, /*LoadUOps=*/-1>; // Integer -> Float.1238defm : Zn4WriteResXMMPair<WriteCvtI2PS, [Zn4FPFCvt01], 3, [1], 1>; // Integer -> Float (XMM).1239defm : Zn4WriteResYMMPair<WriteCvtI2PSY, [Zn4FPFCvt01], 3, [1], 1>; // Integer -> Float (YMM).1240defm : Zn4WriteResZMMPair<WriteCvtI2PSZ, [Zn4FPFCvt01], 3, [2], 2>; // Integer -> Float (ZMM).1241 1242def Zn4WriteCvtI2PSMMX : SchedWriteRes<[Zn4FPFCvt01]> {1243 let Latency = 3;1244 let ReleaseAtCycles = [1];1245 let NumMicroOps = 2;1246}1247 1248defm : Zn4WriteResXMMPair<WriteCvtSS2SD, [Zn4FPFCvt01], 3, [1], 1>; // Float -> Double size conversion.1249defm : Zn4WriteResXMMPair<WriteCvtPS2PD, [Zn4FPFCvt01], 3, [1], 1>; // Float -> Double size conversion (XMM).1250defm : Zn4WriteResYMMPair<WriteCvtPS2PDY, [Zn4FPFCvt01], 4, [2], 2, /*LoadUOps=*/-1>; // Float -> Double size conversion (YMM).1251defm : Zn4WriteResZMMPair<WriteCvtPS2PDZ, [Zn4FPFCvt01], 6, [4], 4, /*LoadUOps=*/-1>; // Float -> Double size conversion (ZMM).1252 1253defm : Zn4WriteResXMMPair<WriteCvtSD2SS, [Zn4FPFCvt01], 3, [1], 1>; // Double -> Float size conversion.1254defm : Zn4WriteResXMMPair<WriteCvtPD2PS, [Zn4FPFCvt01], 3, [1], 1>; // Double -> Float size conversion (XMM).1255defm : Zn4WriteResYMMPair<WriteCvtPD2PSY, [Zn4FPFCvt01], 6, [2], 2>; // Double -> Float size conversion (YMM).1256defm : Zn4WriteResZMMPair<WriteCvtPD2PSZ, [Zn4FPFCvt01], 6, [4], 4>; // Double -> Float size conversion (ZMM).1257 1258defm : Zn4WriteResXMMPair<WriteCvtPH2PS, [Zn4FPFCvt01], 3, [1], 1>; // Half -> Float size conversion.1259defm : Zn4WriteResYMMPair<WriteCvtPH2PSY, [Zn4FPFCvt01], 4, [2], 2, /*LoadUOps=*/-1>; // Half -> Float size conversion (YMM).1260defm : Zn4WriteResZMMPair<WriteCvtPH2PSZ, [Zn4FPFCvt01], 4, [4], 4, /*LoadUOps=*/-1>; // Half -> Float size conversion (ZMM).1261 1262defm : Zn4WriteResXMM<WriteCvtPS2PH, [Zn4FPFCvt01], 3, [2], 1>; // Float -> Half size conversion.1263defm : Zn4WriteResYMM<WriteCvtPS2PHY, [Zn4FPFCvt01], 6, [2], 2>; // Float -> Half size conversion (YMM).1264defm : Zn4WriteResZMM<WriteCvtPS2PHZ, [Zn4FPFCvt01], 6, [2], 2>; // Float -> Half size conversion (ZMM).1265 1266defm : Zn4WriteResXMM<WriteCvtPS2PHSt, [Zn4FPFCvt01, Zn4FPSt, Zn4Store], !add(3, Znver4Model.StoreLatency), [1, 1, 1], 2>; // Float -> Half + store size conversion.1267defm : Zn4WriteResYMM<WriteCvtPS2PHYSt, [Zn4FPFCvt01, Zn4FPSt, Zn4Store], !add(6, Znver4Model.StoreLatency), [2, 1, 1], 3>; // Float -> Half + store size conversion (YMM).1268defm : Zn4WriteResYMM<WriteCvtPS2PHZSt, [Zn4FPFCvt01, Zn4FPSt, Zn4Store], !add(6, Znver4Model.StoreLatency), [2, 1, 1], 3>; // Float -> Half + store size conversion (ZMM).1269 1270// CRC32 instruction.1271defm : Zn4WriteResIntPair<WriteCRC32, [Zn4ALU1], 3, [1], 1>;1272 1273def Zn4WriteSHA1MSG1rr : SchedWriteRes<[Zn4FPU0123]> {1274 let Latency = 2;1275 let ReleaseAtCycles = [2];1276 let NumMicroOps = 2;1277}1278def : InstRW<[Zn4WriteSHA1MSG1rr], (instrs SHA1MSG1rr)>;1279 1280def Zn4WriteSHA1MSG1rm : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4FPU0123]> {1281 let Latency = !add(Znver4Model.VecLoadLatency, Zn4WriteSHA1MSG1rr.Latency);1282 let ReleaseAtCycles = [1, 1, 2];1283 let NumMicroOps = !add(Zn4WriteSHA1MSG1rr.NumMicroOps, 0);1284}1285def : InstRW<[Zn4WriteSHA1MSG1rm], (instrs SHA1MSG1rm)>;1286 1287def Zn4WriteSHA1MSG2rr_SHA1NEXTErr : SchedWriteRes<[Zn4FPU0123]> {1288 let Latency = 1;1289 let ReleaseAtCycles = [2];1290 let NumMicroOps = 1;1291}1292def : InstRW<[Zn4WriteSHA1MSG2rr_SHA1NEXTErr], (instrs SHA1MSG2rr, SHA1NEXTErr)>;1293 1294def Zn4Writerm_SHA1MSG2rm_SHA1NEXTErm : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4FPU0123]> {1295 let Latency = !add(Znver4Model.VecLoadLatency, Zn4WriteSHA1MSG2rr_SHA1NEXTErr.Latency);1296 let ReleaseAtCycles = [1, 1, 2];1297 let NumMicroOps = !add(Zn4WriteSHA1MSG2rr_SHA1NEXTErr.NumMicroOps, 0);1298}1299def : InstRW<[Zn4Writerm_SHA1MSG2rm_SHA1NEXTErm], (instrs SHA1MSG2rm, SHA1NEXTErm)>;1300 1301def Zn4WriteSHA256MSG1rr : SchedWriteRes<[Zn4FPU0123]> {1302 let Latency = 2;1303 let ReleaseAtCycles = [3];1304 let NumMicroOps = 2;1305}1306def : InstRW<[Zn4WriteSHA256MSG1rr], (instrs SHA256MSG1rr)>;1307 1308def Zn4Writerm_SHA256MSG1rm : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4FPU0123]> {1309 let Latency = !add(Znver4Model.VecLoadLatency, Zn4WriteSHA256MSG1rr.Latency);1310 let ReleaseAtCycles = [1, 1, 3];1311 let NumMicroOps = !add(Zn4WriteSHA256MSG1rr.NumMicroOps, 0);1312}1313def : InstRW<[Zn4Writerm_SHA256MSG1rm], (instrs SHA256MSG1rm)>;1314 1315def Zn4WriteSHA256MSG2rr : SchedWriteRes<[Zn4FPU0123]> {1316 let Latency = 3;1317 let ReleaseAtCycles = [8];1318 let NumMicroOps = 4;1319}1320def : InstRW<[Zn4WriteSHA256MSG2rr], (instrs SHA256MSG2rr)>;1321 1322def Zn4WriteSHA256MSG2rm : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4FPU0123]> {1323 let Latency = !add(Znver4Model.VecLoadLatency, Zn4WriteSHA256MSG2rr.Latency);1324 let ReleaseAtCycles = [1, 1, 8];1325 let NumMicroOps = !add(Zn4WriteSHA256MSG2rr.NumMicroOps, 1);1326}1327def : InstRW<[Zn4WriteSHA256MSG2rm], (instrs SHA256MSG2rm)>;1328 1329def Zn4WriteSHA1RNDS4rri : SchedWriteRes<[Zn4FPU0123]> {1330 let Latency = 6;1331 let ReleaseAtCycles = [8];1332 let NumMicroOps = 1;1333}1334def : InstRW<[Zn4WriteSHA1RNDS4rri], (instrs SHA1RNDS4rri)>;1335 1336def Zn4WriteSHA256RNDS2rr : SchedWriteRes<[Zn4FPU0123]> {1337 let Latency = 4;1338 let ReleaseAtCycles = [8];1339 let NumMicroOps = 1;1340}1341def : InstRW<[Zn4WriteSHA256RNDS2rr], (instrs SHA256RNDS2rr)>;1342 1343// Strings instructions.1344// Packed Compare Implicit Length Strings, Return Mask1345defm : Zn4WriteResXMMPair<WritePCmpIStrM, [Zn4FPVAdd0123], 7, [8], 3, /*LoadUOps=*/1>;1346// Packed Compare Explicit Length Strings, Return Mask1347defm : Zn4WriteResXMMPair<WritePCmpEStrM, [Zn4FPVAdd0123], 7, [12], 7, /*LoadUOps=*/5>;1348// Packed Compare Implicit Length Strings, Return Index1349defm : Zn4WriteResXMMPair<WritePCmpIStrI, [Zn4FPVAdd0123], 2, [8], 4>;1350// Packed Compare Explicit Length Strings, Return Index1351defm : Zn4WriteResXMMPair<WritePCmpEStrI, [Zn4FPVAdd0123], 6, [12], 8, /*LoadUOps=*/4>;1352 1353// AES instructions.1354defm : Zn4WriteResXMMPair<WriteAESDecEnc, [Zn4FPAES01], 4, [1], 1>; // Decryption, encryption.1355defm : Zn4WriteResXMMPair<WriteAESIMC, [Zn4FPAES01], 4, [1], 1>; // InvMixColumn.1356defm : Zn4WriteResXMMPair<WriteAESKeyGen, [Zn4FPAES01], 4, [1], 1>; // Key Generation.1357 1358// Carry-less multiplication instructions.1359defm : Zn4WriteResXMMPair<WriteCLMul, [Zn4FPCLM01], 4, [3], 4>;1360 1361// EMMS/FEMMS1362defm : Zn4WriteResInt<WriteEMMS, [Zn4ALU0123], 2, [1], 1>; // FIXME: latency not from llvm-exegesis1363 1364// Load/store MXCSR1365defm : Zn4WriteResInt<WriteLDMXCSR, [Zn4AGU012, Zn4Load, Zn4ALU0123], !add(Znver4Model.LoadLatency, 1), [1, 1, 6], 1>; // FIXME: latency not from llvm-exegesis1366defm : Zn4WriteResInt<WriteSTMXCSR, [Zn4ALU0123, Zn4AGU012, Zn4Store], !add(1, Znver4Model.StoreLatency), [60, 1, 1], 2>; // FIXME: latency not from llvm-exegesis1367 1368// Catch-all for expensive system instructions.1369defm : Zn4WriteResInt<WriteSystem, [Zn4ALU0123], 100, [100], 100>;1370 1371def Zn4WriteVZEROUPPER : SchedWriteRes<[Zn4FPU0123]> {1372 let Latency = 0; // FIXME: not from llvm-exegesis1373 let ReleaseAtCycles = [1];1374 let NumMicroOps = 1;1375}1376def : InstRW<[Zn4WriteVZEROUPPER], (instrs VZEROUPPER)>;1377 1378def Zn4WriteVZEROALL : SchedWriteRes<[Zn4FPU0123]> {1379 let Latency = 10; // FIXME: not from llvm-exegesis1380 let ReleaseAtCycles = [24];1381 let NumMicroOps = 18;1382}1383def : InstRW<[Zn4WriteVZEROALL], (instrs VZEROALL)>;1384 1385// AVX2.1386defm : Zn4WriteResYMMPair<WriteFShuffle256, [Zn4FPVShuf], 2, [1], 1, /*LoadUOps=*/2>; // Fp 256-bit width vector shuffles.1387defm : Zn4WriteResYMMPair<WriteFVarShuffle256, [Zn4FPVShuf], 7, [1], 2, /*LoadUOps=*/1>; // Fp 256-bit width variable shuffles.1388defm : Zn4WriteResYMMPair<WriteShuffle256, [Zn4FPVShuf], 1, [1], 1>; // 256-bit width vector shuffles.1389 1390def Zn4WriteVPERM2I128rr_VPERM2F128rr : SchedWriteRes<[Zn4FPVShuf]> {1391 let Latency = 3;1392 let ReleaseAtCycles = [1];1393 let NumMicroOps = 1;1394}1395def : InstRW<[Zn4WriteVPERM2I128rr_VPERM2F128rr], (instrs VPERM2I128rri, VPERM2F128rri)>;1396 1397def Zn4WriteVPERM2F128rm : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4FPVShuf]> {1398 let Latency = !add(Znver4Model.VecLoadLatency, Zn4WriteVPERM2I128rr_VPERM2F128rr.Latency);1399 let ReleaseAtCycles = [1, 1, 1];1400 let NumMicroOps = !add(Zn4WriteVPERM2I128rr_VPERM2F128rr.NumMicroOps, 0);1401}1402def : InstRW<[Zn4WriteVPERM2F128rm], (instrs VPERM2F128rmi)>;1403 1404def Zn4WriteVPERMPSYrr : SchedWriteRes<[Zn4FPVShuf]> {1405 let Latency = 4;1406 let ReleaseAtCycles = [1];1407 let NumMicroOps = 1;1408}1409def : InstRW<[Zn4WriteVPERMPSYrr], (instrs VPERMPSYrr)>;1410 1411def Zn4WriteVPERMPSYrm : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4FPVShuf]> {1412 let Latency = !add(Znver4Model.VecLoadLatency, Zn4WriteVPERMPSYrr.Latency);1413 let ReleaseAtCycles = [1, 1, 1];1414 let NumMicroOps = 1;1415}1416def : InstRW<[Zn4WriteVPERMPSYrm], (instrs VPERMPSYrm)>;1417 1418def Zn4WriteVPERMYri : SchedWriteRes<[Zn4FPVShuf]> {1419 let Latency = 4;1420 let ReleaseAtCycles = [1];1421 let NumMicroOps = 1;1422}1423def : InstRW<[Zn4WriteVPERMYri], (instrs VPERMPDYri, VPERMQYri)>;1424 1425def Zn4WriteVPERMPDYmi : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4FPVShuf]> {1426 let Latency = !add(Znver4Model.VecLoadLatency, Zn4WriteVPERMYri.Latency);1427 let ReleaseAtCycles = [1, 1, 1];1428 let NumMicroOps = 1;1429}1430def : InstRW<[Zn4WriteVPERMPDYmi], (instrs VPERMPDYmi)>;1431 1432def Zn4WriteVPERMDYrr : SchedWriteRes<[Zn4FPVShuf]> {1433 let Latency = 4;1434 let ReleaseAtCycles = [1];1435 let NumMicroOps = 1;1436}1437def : InstRW<[Zn4WriteVPERMDYrr], (instrs VPERMDYrr)>;1438 1439def Zn4WriteVPERMYm : SchedWriteRes<[Zn4AGU012, Zn4Load, Zn4FPVShuf]> {1440 let Latency = !add(Znver4Model.VecLoadLatency, Zn4WriteVPERMDYrr.Latency);1441 let ReleaseAtCycles = [1, 1, 1];1442 let NumMicroOps = 1;1443}1444def : InstRW<[Zn4WriteVPERMYm], (instrs VPERMQYmi, VPERMDYrm)>;1445 1446defm : Zn4WriteResYMMPair<WriteVPMOV256, [Zn4FPVShuf01], 4, [3], 2, /*LoadUOps=*/-1>; // 256-bit width packed vector width-changing move.1447defm : Zn4WriteResYMMPair<WriteVarShuffle256, [Zn4FPVShuf01], 1, [1], 2>; // 256-bit width vector variable shuffles.1448defm : Zn4WriteResXMMPair<WriteVarVecShift, [Zn4FPVShift01], 1, [1], 1>; // Variable vector shifts.1449defm : Zn4WriteResYMMPair<WriteVarVecShiftY, [Zn4FPVShift01], 1, [1], 1>; // Variable vector shifts (YMM).1450defm : Zn4WriteResZMMPair<WriteVarVecShiftZ, [Zn4FPVShift01], 1, [2], 2>; // Variable vector shifts (ZMM).1451 1452// Old microcoded instructions that nobody use.1453defm : Zn4WriteResInt<WriteMicrocoded, [Zn4ALU0123], 100, [100], 100>;1454 1455// Fence instructions.1456defm : Zn4WriteResInt<WriteFence, [Zn4ALU0123], 1, [100], 1>;1457 1458def Zn4WriteLFENCE : SchedWriteRes<[Zn4LSU]> {1459 let Latency = 1;1460 let ReleaseAtCycles = [30];1461 let NumMicroOps = 1;1462}1463def : InstRW<[Zn4WriteLFENCE], (instrs LFENCE)>;1464 1465def Zn4WriteSFENCE : SchedWriteRes<[Zn4LSU]> {1466 let Latency = 1;1467 let ReleaseAtCycles = [1];1468 let NumMicroOps = 1;1469}1470def : InstRW<[Zn4WriteSFENCE], (instrs SFENCE)>;1471 1472// Nop, not very useful expect it provides a model for nops!1473defm : Zn4WriteResInt<WriteNop, [Zn4ALU0123], 0, [1], 1>; // FIXME: latency not from llvm-exegesis1474 1475 1476///////////////////////////////////////////////////////////////////////////////1477// Zero Cycle Move1478///////////////////////////////////////////////////////////////////////////////1479 1480def Zn4WriteZeroLatency : SchedWriteRes<[]> {1481 let Latency = 0;1482 let ReleaseAtCycles = [];1483 let NumMicroOps = 1;1484}1485def : InstRW<[Zn4WriteZeroLatency], (instrs MOV32rr, MOV32rr_REV,1486 MOV64rr, MOV64rr_REV,1487 MOVSX32rr32)>;1488 1489def Zn4WriteSwapRenameable : SchedWriteRes<[]> {1490 let Latency = 0;1491 let ReleaseAtCycles = [];1492 let NumMicroOps = 2;1493}1494def : InstRW<[Zn4WriteSwapRenameable], (instrs XCHG32rr, XCHG32ar,1495 XCHG64rr, XCHG64ar)>;1496 1497defm : Zn4WriteResInt<WriteXCHG, [Zn4ALU0123], 0, [8], 2>; // Compare+Exchange - TODO RMW support.1498 1499defm : Zn4WriteResXMM<WriteFMoveX, [], 0, [], 1>;1500defm : Zn4WriteResYMM<WriteFMoveY, [], 0, [], 1>;1501defm : Zn4WriteResYMM<WriteFMoveZ, [], 0, [], 1>;1502 1503defm : Zn4WriteResXMM<WriteVecMove, [Zn4FPFMisc0123], 1, [1], 1>; // MMX1504defm : Zn4WriteResXMM<WriteVecMoveX, [], 0, [], 1>;1505defm : Zn4WriteResYMM<WriteVecMoveY, [], 0, [], 1>;1506defm : Zn4WriteResYMM<WriteVecMoveZ, [], 0, [], 1>;1507 1508def : IsOptimizableRegisterMove<[1509 InstructionEquivalenceClass<[1510 // GPR variants.1511 MOV32rr, MOV32rr_REV,1512 MOV64rr, MOV64rr_REV,1513 MOVSX32rr32,1514 XCHG32rr, XCHG32ar,1515 XCHG64rr, XCHG64ar,1516 1517 // MMX variants.1518 // MMX moves are *NOT* eliminated.1519 1520 // SSE variants.1521 MOVAPSrr, MOVAPSrr_REV,1522 MOVUPSrr, MOVUPSrr_REV,1523 MOVAPDrr, MOVAPDrr_REV,1524 MOVUPDrr, MOVUPDrr_REV,1525 MOVDQArr, MOVDQArr_REV,1526 MOVDQUrr, MOVDQUrr_REV,1527 1528 // AVX variants.1529 VMOVAPSrr, VMOVAPSrr_REV,1530 VMOVUPSrr, VMOVUPSrr_REV,1531 VMOVAPDrr, VMOVAPDrr_REV,1532 VMOVUPDrr, VMOVUPDrr_REV,1533 VMOVDQArr, VMOVDQArr_REV,1534 VMOVDQUrr, VMOVDQUrr_REV,1535 1536 // AVX YMM variants.1537 VMOVAPSYrr, VMOVAPSYrr_REV,1538 VMOVUPSYrr, VMOVUPSYrr_REV,1539 VMOVAPDYrr, VMOVAPDYrr_REV,1540 VMOVUPDYrr, VMOVUPDYrr_REV,1541 VMOVDQAYrr, VMOVDQAYrr_REV,1542 VMOVDQUYrr, VMOVDQUYrr_REV,1543 ], TruePred >1544]>;1545 1546// FIXUP and RANGE Instructions1547def Zn4WriteVFIXUPIMMPDZrr_VRANGESDrr : SchedWriteRes<[Zn4FPFMisc01]> {1548 let Latency = 2;1549 let ReleaseAtCycles = [2];1550 let NumMicroOps = 1;1551}1552def : InstRW<[Zn4WriteVFIXUPIMMPDZrr_VRANGESDrr], (instregex1553 "VFIXUPIMM(S|P)(S|D)(Z|Z128|Z256?)rrik", "VFIXUPIMM(S|P)(S|D)(Z?|Z128?|Z256?)rrikz", 1554 "VFIXUPIMM(S|P)(S|D)(Z128|Z256?)rri", "VRANGE(S|P)(S|D)(Z?|Z128?|Z256?)rri(b?)",1555 "VRANGE(S|P)(S|D)(Z|Z128|Z256?)rri(b?)k","VRANGE(S|P)(S|D)(Z?|Z128?|Z256?)rri(b?)kz"1556 )>;1557 1558// SCALE & REDUCE instructions1559def Zn4WriteSCALErr: SchedWriteRes<[Zn4FPFMisc23]> {1560 let Latency = 6;1561 let ReleaseAtCycles = [6];1562 let NumMicroOps = 2;1563}1564def : InstRW<[Zn4WriteSCALErr], (instregex1565 "V(SCALEF|REDUCE)(S|P)(S|D)(Z?|Z128?|Z256?)(rr|rrb|rrkz|rrik|rrikz|rri)(_Int?)",1566 "(V?)REDUCE(PD|PS|SD|SS)(Z?|Z128?)(rri|rrikz|rrib)"1567 )>;1568 1569//BF16PS Instructions1570def Zn4WriteBF16: SchedWriteRes<[Zn4FPFMisc23]> {1571 let Latency = 6;1572 let ReleaseAtCycles = [6];1573 let NumMicroOps = 2;1574}1575def : InstRW<[Zn4WriteBF16], (instregex1576 "(V?)DPBF16PS(Z?|Z128?|Z256?)(r|rk|rkz)"1577 )>;1578 1579// BUSD and VPMADD Instructions1580def Zn4WriteBUSDr_VPMADDr: SchedWriteRes<[Zn4FPFMisc01]> {1581 let Latency = 4;1582 let ReleaseAtCycles = [4];1583 let NumMicroOps = 1;1584}1585def : InstRW<[Zn4WriteBUSDr_VPMADDr], (instregex1586 "VPDP(BU|WS)(S|P)(S|D|DS)(Z?|Z128?|Z256?|Y?)r(r|rk|rkz)",1587 "VPMADD52(H|L)UQ(Z|Z128|Z256)(r|rk|rkz)"1588 )>;1589 1590// SHIFT instructions1591def Zn4WriteSHIFTrr: SchedWriteRes<[Zn4FPFMisc01]> {1592 let Latency = 2;1593 let ReleaseAtCycles = [2];1594 let NumMicroOps = 1;1595}1596def : InstRW<[Zn4WriteSHIFTrr], (instregex1597 "VP(LZCNT|SHLD|SHRD?)(D|Q|W|VD|VQ|VW?)(Z?|Z128?|Z256?)(rr|rk|rrk|rrkz|rri|rrik|rrikz)",1598 "(V?)P(SLL|SRL|SRA)(D|Q|W|DQ)(Y?|Z?|Z128?|Z256?)(rr|rrk|rrkz)",1599 "(V?)P(SLL|SRL|SRA)DQYri",1600 "(V?)P(SLL|SRL)DQ(Z?|Z256?)ri",1601 "(V?)P(SHUFB)(Y|Z|Z128|Z256?)(rr|rrk|rrkz)",1602 "(V?)P(ROL|ROR)(D|Q|VD|VQ)(Z?|Z128?|Z256?)(rr|rrk|rrkz)",1603 "(V?)P(ROL|ROR)(D|Q|VD|VQ)(Z256?)(ri|rik|rikz)",1604 "(V?)P(ROL|ROR)(D|Q)(Z?|Z128?)(ri|rik|rikz)",1605 "VPSHUFBITQMBZ128rr", "VFMSUB231SSZrkz_Int"1606 )>;1607 1608def Zn4WriteSHIFTri: SchedWriteRes<[Zn4FPFMisc01]> {1609 let Latency = 1;1610 let ReleaseAtCycles = [1];1611 let NumMicroOps = 1;1612}1613def : InstRW<[Zn4WriteSHIFTri], (instregex1614 "VP(SLL|SRL|SRA)(D|Q|W)(Z|Z128|Z256?)(ri|rik|rikz)"1615 )>;1616 1617// ALIGNR Instructions1618def Zn4WriteALIGNR: SchedWriteRes<[Zn4FPFMisc12]> {1619 let Latency = 2;1620 let ReleaseAtCycles = [1];1621 let NumMicroOps = 1;1622}1623def : InstRW<[Zn4WriteALIGNR], (instregex1624 "(V?)PALIGNR(Y?|Z128?|Z256?)(rri|rrik|rrikz)"1625 )>;1626def Zn4WriteALIGNRZ: SchedWriteRes<[Zn4FPFMisc12]> {1627 let Latency = 2;1628 let ReleaseAtCycles = [2];1629 let NumMicroOps = 1;1630}1631def : InstRW<[Zn4WriteALIGNRZ], (instregex1632 "(V?)PALIGNRZ(rri|rrik|rrikz)"1633 )>;1634 1635// PACK Instructions1636def Zn4WritePACK: SchedWriteRes<[Zn4FPFMisc12]> {1637 let Latency = 2;1638 let ReleaseAtCycles = [1];1639 let NumMicroOps = 1;1640}1641def : InstRW<[Zn4WritePACK], (instregex1642 "(V?)PACK(SS|US)(DW|WB)(Y?|Z128?|Z256?)(rr|rrk|rrkz)"1643 )>;1644def Zn4WritePACKZ: SchedWriteRes<[Zn4FPFMisc12]> {1645 let Latency = 2;1646 let ReleaseAtCycles = [2];1647 let NumMicroOps = 1;1648}1649def : InstRW<[Zn4WritePACKZ], (instregex1650 "(V?)PACK(SS|US)(DW|WB)Z(rr|rrk|rrkz)"1651 )>;1652 1653// MAX and MIN Instructions1654def Zn4WriteFCmp64: SchedWriteRes<[Zn4FPFMisc01]> {1655 let Latency = 2;1656 let ReleaseAtCycles = [2];1657 let NumMicroOps = 1;1658}1659def : InstRW<[Zn4WriteFCmp64], (instregex1660 "(V?)CMP(S|P)(S|D)(rr|rri|rr_Int)",1661 "(V?|VP?)(MAX|MIN|MINC|MAXC)(S|P|U)(S|D|Q)(Z?|Z128?|Z256?)(rr|rri|rrk|rrkz)(_Int?)",1662 "VP(MAX|MIN)(SQ|UQ)(Z|Z128|Z256)(rr|rrk|rrkz)",1663 "(V?)(MAX|MAXC|MIN|MINC)PD(Z|Z128|Z256?)(rr|rrk|rrkz)"1664 )>;1665 1666// MOV Instructions1667def Zn4MOVDUPZ: SchedWriteRes<[Zn4FPFMisc12]> {1668 let Latency = 2;1669 let ReleaseAtCycles = [2];1670 let NumMicroOps = 1;1671}1672def : InstRW<[Zn4MOVDUPZ], (instregex1673 "(V?)VMOVDDUP(Z|Z128|Z256)(rr|rrk|rrkz)"1674 )>;1675 1676def Zn4MOVS: SchedWriteRes<[Zn4FPFMisc12]> {1677 let Latency = 2;1678 let ReleaseAtCycles = [1];1679 let NumMicroOps = 1;1680}1681def : InstRW<[Zn4MOVS], (instregex1682 "(V?)PMOV(SX|ZX)(BD|BQ|BW|WD|WQ|DQ)(Y?|Z128?|Z256?)(rr|rrk|rrkz)",1683 "(V?)PMOV(S?|US?)(DB|DW|QB|QD|QW|WB)(Z128|Z256)(rr|rrk|rrkz)"1684 )>;1685 1686def Zn4MOVSZ: SchedWriteRes<[Zn4FPFMisc12]> {1687 let Latency = 4;1688 let ReleaseAtCycles = [2];1689 let NumMicroOps = 1;1690}1691def : InstRW<[Zn4MOVSZ], (instregex1692 "(V?)PMOV(SX|ZX)(BD|BQ|BW|WD|WQ|DQ)Z(rr|rrk|rrkz)"1693 )>;1694 1695def Zn4MOVSrr: SchedWriteRes<[Zn4FPFMisc12]> {1696 let Latency = 5;1697 let ReleaseAtCycles = [2];1698 let NumMicroOps = 1;1699}1700def : InstRW<[Zn4MOVSrr], (instregex1701 "(V?)PMOV(S?|US?)(DB|DW|QB|QD|QW|WB)Z(rr|rrk|rrkz)"1702 )>;1703 1704 1705//VPTEST Instructions1706def Zn4VPTESTZ128: SchedWriteRes<[Zn4FPFMisc01]> {1707 let Latency = 3;1708 let ReleaseAtCycles = [3];1709 let NumMicroOps = 1;1710}1711def : InstRW<[Zn4VPTESTZ128], (instregex1712 "(V?)PTEST(N?)(MB|MD|MQ|MW)(Z128?)(rrk)"1713 )>;1714 1715def Zn4VPTESTZ256: SchedWriteRes<[Zn4FPFMisc01]> {1716 let Latency = 4;1717 let ReleaseAtCycles = [4];1718 let NumMicroOps = 1;1719}1720def : InstRW<[Zn4VPTESTZ256], (instregex1721 "(V?)PTEST(N?)(MB|MD|MQ|MW)(Z256?)(rr|rrk)"1722 )>;1723 1724def Zn4VPTESTZ: SchedWriteRes<[Zn4FPFMisc01]> {1725 let Latency = 5;1726 let ReleaseAtCycles = [5];1727 let NumMicroOps = 1;1728}1729def : InstRW<[Zn4VPTESTZ], (instregex1730 "(V?)PTEST(N?)(MB|MD|MQ|MW)(Z?)(rrk)"1731 )>;1732 1733// CONFLICT Instructions1734def Zn4CONFLICTZ128: SchedWriteRes<[Zn4FPFMisc01]> {1735 let Latency = 2;1736 let ReleaseAtCycles = [2];1737 let NumMicroOps = 1;1738}1739def : InstRW<[Zn4CONFLICTZ128], (instregex1740 "VPCONFLICT(D|Q)(Z128)(rr|rrk|rrkz)"1741 )>;1742 1743def Zn4CONFLICTrr: SchedWriteRes<[Zn4FPFMisc01,Zn4FPFMisc12,Zn4FPFMisc23]> {1744 let Latency = 6;1745 let ReleaseAtCycles = [2,2,2];1746 let NumMicroOps = 4;1747}1748def : InstRW<[Zn4CONFLICTrr], (instregex1749 "VPCONFLICT(D|Q)(Z|Z256)(rr|rrkz)"1750 )>;1751 1752// RSQRT Instructions1753def Zn4VRSQRT14PDZ256: SchedWriteRes<[Zn4FPFMisc01]> {1754 let Latency = 5;1755 let ReleaseAtCycles = [2];1756 let NumMicroOps = 1;1757}1758def : InstRW<[Zn4VRSQRT14PDZ256], (instregex1759 "VRSQRT14(PD|PS)(Z?|Z128?|Z256?)(r|rr|rk|rrk|rkz|rrkz)"1760 )>;1761 1762 1763// PERM Instructions1764def Zn4PERMILP: SchedWriteRes<[Zn4FPFMisc123]> {1765 let Latency = 2;1766 let ReleaseAtCycles = [2];1767 let NumMicroOps = 1;1768}1769def : InstRW<[Zn4PERMILP], (instregex1770 "VPERMILP(S|D)(Y|Z|Z128|Z256)(rr|rrk|rrkz)"1771 )>;1772 1773def Zn4PERMIT2_128: SchedWriteRes<[Zn4FPFMisc12]> {1774 let Latency = 3;1775 let ReleaseAtCycles = [2];1776 let NumMicroOps = 1;1777}1778def : InstRW<[Zn4PERMIT2_128], (instregex1779 "VPERM(I2|T2)(PS|PD|W)Z128(rr|rrk|rrkz)",1780 "VPERM(I2|T2)(B|D|Q)Z128(rr|rrk|rrkz)"1781 )>;1782 1783def Zn4PERMIT2_128rr:SchedWriteRes<[Zn4FPFMisc12]> {1784 let Latency = 2;1785 let ReleaseAtCycles = [2];1786 let NumMicroOps = 1;1787}1788def : InstRW<[Zn4PERMIT2_128rr], (instregex1789 "V(P?)COMPRESS(B|W|D|Q|PD|PS|SD|SQ)Z128(rr|rrk|rrkz)",1790 "VPERM(B|D|Q|W)(Z128?)(rr|rrk|rrkz)"1791 )>;1792 1793def Zn4PERMIT2_256: SchedWriteRes<[Zn4FPFMisc12]> {1794 let Latency = 4;1795 let ReleaseAtCycles = [2];1796 let NumMicroOps = 1;1797}1798def : InstRW<[Zn4PERMIT2_256], (instregex1799 "VPERM(I2|T2)(PS|PD|W)Z256(rr|rrk|rrkz)",1800 "VPERMP(S|D)Z256(rr|rrk|rrkz)",1801 "V(P?)COMPRESS(B|W|D|Q|PD|PS|SD|SQ)Z256(rr|rrk|rrkz)",1802 "VPERM(B|D|Q|W)Z256(rr|rrk|rrkz)",1803 "VPERM(I2|Q|T2)(B|D|Q)Z256(rr|rrk|rrkz)",1804 "VPEXPAND(B|W)Z256(rr|rrk|rrkz)"1805 )>;1806 1807def Zn4PERMIT2Z: SchedWriteRes<[Zn4FPFMisc12]> {1808 let Latency = 5;1809 let ReleaseAtCycles = [2];1810 let NumMicroOps = 1;1811}1812def : InstRW<[Zn4PERMIT2Z], (instregex1813 "VPERM(I2|T2)(PS|PD|W)Z(rr|rrk|rrkz)",1814 "VPERM(B|D|W)Z(rr|rrk|rrkz)",1815 "VPERM(I2|Q|T2)(B|D|Q)Z(rr|rrk|rrkz)",1816 "V(P?)COMPRESS(B|W|D|Q|PD|PS|SD|SQ)Z(rr|rrk|rrkz)",1817 "VPEXPAND(B|W)Z(rr|rrk|rrkz)",1818 "VPERMP(S|D)Z(rr|rrk|rrkz)"1819 )>;1820 1821// ALU SLOW Misc Instructions1822def Zn4VecALUZSlow: SchedWriteRes<[Zn4FPFMisc01]> {1823 let Latency = 2;1824 let ReleaseAtCycles = [2];1825 let NumMicroOps = 1;1826}1827def : InstRW<[Zn4VecALUZSlow], (instrs 1828 VPABSBZ128rr, VPABSBZ128rrk, VPABSBZ128rrkz, VPABSDZ128rr, 1829 VPABSDZ128rrk, VPABSDZ128rrkz, VPABSQZ128rr, VPABSQZ128rrk, 1830 VPABSQZ128rrkz, VPABSWZ128rr, VPABSWZ128rrk, VPABSWZ128rrkz, 1831 VPADDSBZ128rr, VPADDSBZ128rrk, VPADDSBZ128rrkz, VPADDSWZ128rr, 1832 VPADDSWZ128rrk, VPADDSWZ128rrkz,VPADDUSBZ128rr, VPADDUSBZ128rrk, 1833 VPADDUSBZ128rrkz, VPADDUSWZ128rr, VPADDUSWZ128rrk, VPADDUSWZ128rrkz, 1834 VPAVGBZ128rr, VPAVGBZ128rrk, VPAVGBZ128rrkz, VPAVGWZ128rr, 1835 VPAVGWZ128rrk, VPAVGWZ128rrkz, VPOPCNTBZ128rr, VPOPCNTBZ128rrk, 1836 VPOPCNTBZ128rrkz, VPOPCNTDZ128rr, VPOPCNTDZ128rrk, VPOPCNTDZ128rrkz, 1837 VPOPCNTQZ128rr, VPOPCNTQZ128rrk,VPOPCNTQZ128rrkz, VPOPCNTWZ128rr, 1838 VPOPCNTWZ128rrk, VPOPCNTWZ128rrkz,VPSUBSBZ128rr, VPSUBSBZ128rrk, 1839 VPSUBSBZ128rrkz, VPSUBSWZ128rr, VPSUBSWZ128rrk, VPSUBSWZ128rrkz, 1840 VPSUBUSBZ128rr, VPSUBUSBZ128rrk, VPSUBUSBZ128rrkz,VPSUBUSWZ128rr, 1841 VPSUBUSWZ128rrk, VPSUBUSWZ128rrkz1842 )>;1843 1844 1845///////////////////////////////////////////////////////////////////////////////1846// Dependency breaking instructions.1847///////////////////////////////////////////////////////////////////////////////1848 1849def Zn4WriteZeroIdiom : SchedWriteVariant<[1850 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [Zn4WriteZeroLatency]>,1851 SchedVar<NoSchedPred, [WriteALU]>1852]>;1853def : InstRW<[Zn4WriteZeroIdiom], (instrs XOR32rr, XOR32rr_REV,1854 XOR64rr, XOR64rr_REV,1855 SUB32rr, SUB32rr_REV,1856 SUB64rr, SUB64rr_REV)>;1857 1858def Zn4WriteZeroIdiomEFLAGS : SchedWriteVariant<[1859 SchedVar<MCSchedPredicate<CheckSameRegOperand<0, 1>>, [Zn4WriteZeroLatency]>,1860 SchedVar<NoSchedPred, [WriteALU]>1861]>;1862def : InstRW<[Zn4WriteZeroIdiomEFLAGS], (instrs CMP8rr, CMP8rr_REV,1863 CMP16rr, CMP16rr_REV,1864 CMP32rr, CMP32rr_REV,1865 CMP64rr, CMP64rr_REV)>;1866 1867def Zn4WriteFZeroIdiom : SchedWriteVariant<[1868 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [Zn4WriteZeroLatency]>,1869 SchedVar<NoSchedPred, [WriteFLogic]>1870]>;1871// NOTE: XORPSrr, XORPDrr are not zero-cycle!1872def : InstRW<[Zn4WriteFZeroIdiom], (instrs VXORPSrr, VXORPDrr,1873 VXORPSZ128rr,1874 VXORPDZ128rr,1875 VANDNPSrr, VANDNPDrr,1876 VANDNPSZ128rr,1877 VANDNPDZ128rr)>;1878 1879def Zn4WriteFZeroIdiomY : SchedWriteVariant<[1880 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [Zn4WriteZeroLatency]>,1881 SchedVar<NoSchedPred, [WriteFLogicY]>1882]>;1883def : InstRW<[Zn4WriteFZeroIdiomY], (instrs VXORPSYrr, VXORPDYrr,1884 VXORPSZ256rr,1885 VXORPDZ256rr,1886 VANDNPSYrr, VANDNPDYrr,1887 VANDNPSZ256rr,1888 VANDNPDZ256rr)>;1889 1890def Zn4WriteFZeroIdiomZ : SchedWriteVariant<[1891 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [Zn4WriteZeroLatency]>,1892 SchedVar<NoSchedPred, [WriteFLogicZ]>1893]>;1894def : InstRW<[Zn4WriteFZeroIdiomZ], (instrs VXORPSZrr, VXORPDZrr,1895 VANDNPSZrr, VANDNPDZrr)>;1896 1897def Zn4WriteVZeroIdiomLogicX : SchedWriteVariant<[1898 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [Zn4WriteZeroLatency]>,1899 SchedVar<NoSchedPred, [WriteVecLogicX]>1900]>;1901// NOTE: PXORrr,PANDNrr are not zero-cycle!1902def : InstRW<[Zn4WriteVZeroIdiomLogicX], (instrs VPXORrr,1903 VPXORDZ128rr,1904 VPXORQZ128rr,1905 VPANDNrr,1906 VPANDNDZ128rr,1907 VPANDNQZ128rr)>;1908 1909def Zn4WriteVZeroIdiomLogicY : SchedWriteVariant<[1910 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [Zn4WriteZeroLatency]>,1911 SchedVar<NoSchedPred, [WriteVecLogicY]>1912]>;1913def : InstRW<[Zn4WriteVZeroIdiomLogicY], (instrs VPXORYrr,1914 VPXORDZ256rr,1915 VPXORQZ256rr,1916 VPANDNYrr,1917 VPANDNDZ256rr,1918 VPANDNQZ256rr)>;1919 1920def Zn4WriteVZeroIdiomLogicZ : SchedWriteVariant<[1921 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [Zn4WriteZeroLatency]>,1922 SchedVar<NoSchedPred, [WriteVecLogicZ]>1923]>;1924def : InstRW<[Zn4WriteVZeroIdiomLogicZ], (instrs VPXORDZrr, VPXORQZrr,1925 VPANDNDZrr, VPANDNQZrr)>;1926 1927def Zn4WriteVZeroIdiomALUX : SchedWriteVariant<[1928 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [Zn4WriteZeroLatency]>,1929 SchedVar<NoSchedPred, [WriteVecALUX]>1930]>;1931// NOTE: PSUBBrr, PSUBWrr, PSUBDrr, PSUBQrr,1932// PCMPGTBrr, PCMPGTWrr, PCMPGTDrr, PCMPGTQrr are not zero-cycle!1933def : InstRW<[Zn4WriteVZeroIdiomALUX],1934 (instrs VPSUBBrr, VPSUBWrr, VPSUBDrr, VPSUBQrr,1935 VPSUBBZ128rr, VPSUBWZ128rr, VPSUBDZ128rr, VPSUBQZ128rr,1936 VPCMPGTBrr, VPCMPGTWrr, VPCMPGTDrr, VPCMPGTQrr,1937 VPCMPGTBZ128rr, VPCMPGTWZ128rr,1938 VPCMPGTDZ128rr, VPCMPGTQZ128rr)>;1939 1940def Zn4WriteVZeroIdiomALUY : SchedWriteVariant<[1941 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [Zn4WriteZeroLatency]>,1942 SchedVar<NoSchedPred, [WriteVecALUY]>1943]>;1944def : InstRW<[Zn4WriteVZeroIdiomALUY],1945 (instrs VPSUBBYrr, VPSUBWYrr, VPSUBDYrr, VPSUBQYrr,1946 VPSUBBZ256rr, VPSUBWZ256rr, VPSUBDZ256rr, VPSUBQZ256rr,1947 VPCMPGTBYrr, VPCMPGTWYrr, VPCMPGTDYrr, VPCMPGTQYrr,1948 VPCMPGTBZ256rr, VPCMPGTWZ256rr,1949 VPCMPGTDZ256rr, VPCMPGTQZ256rr)>;1950 1951def Zn4WriteVZeroIdiomALUZ : SchedWriteVariant<[1952 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [Zn4WriteZeroLatency]>,1953 SchedVar<NoSchedPred, [WriteVecALUZ]>1954]>;1955def : InstRW<[Zn4WriteVZeroIdiomALUY],1956 (instrs VPSUBBZrr, VPSUBWZrr, VPSUBDZrr, VPSUBQZrr,1957 VPCMPGTBZrr, VPCMPGTWZrr, VPCMPGTDZrr, VPCMPGTQZrr)>;1958 1959def : IsZeroIdiomFunction<[1960 // GPR Zero-idioms.1961 DepBreakingClass<[ XOR32rr, XOR32rr_REV,1962 XOR64rr, XOR64rr_REV,1963 SUB32rr, SUB32rr_REV,1964 SUB64rr, SUB64rr_REV ], ZeroIdiomPredicate>,1965 1966 // SSE XMM Zero-idioms.1967 DepBreakingClass<[1968 // fp variants.1969 XORPSrr, XORPDrr,1970 ANDNPSrr, ANDNPDrr,1971 1972 // int variants.1973 PXORrr,1974 PANDNrr,1975 PSUBBrr, PSUBWrr, PSUBDrr, PSUBQrr,1976 PSUBSBrr, PSUBSWrr,1977 PSUBUSBrr, PSUBUSWrr,1978 PCMPGTBrr, PCMPGTWrr, PCMPGTDrr, PCMPGTQrr1979 ], ZeroIdiomPredicate>,1980 1981 // AVX XMM Zero-idioms.1982 DepBreakingClass<[1983 // fp variants.1984 VXORPSrr, VXORPDrr,1985 VANDNPSrr, VANDNPDrr,1986 1987 // int variants.1988 VPXORrr,1989 VPANDNrr,1990 VPSUBBrr, VPSUBWrr, VPSUBDrr, VPSUBQrr,1991 VPSUBSBrr, VPSUBSWrr,1992 VPSUBUSBrr, VPSUBUSWrr,1993 VPCMPGTBrr, VPCMPGTWrr, VPCMPGTDrr, VPCMPGTQrr,1994 ], ZeroIdiomPredicate>,1995 1996 // AVX YMM Zero-idioms.1997 DepBreakingClass<[1998 // fp variants.1999 VXORPSYrr, VXORPDYrr,2000 VANDNPSYrr, VANDNPDYrr,2001 2002 // int variants.2003 VPXORYrr,2004 VPANDNYrr,2005 VPSUBBYrr, VPSUBWYrr, VPSUBDYrr, VPSUBQYrr,2006 VPSUBSBYrr, VPSUBSWYrr,2007 VPSUBUSBYrr, VPSUBUSWYrr,2008 VPCMPGTBYrr, VPCMPGTWYrr, VPCMPGTDYrr, VPCMPGTQYrr2009 ], ZeroIdiomPredicate>,2010 2011 // AVX ZMM Zero-idioms.2012 DepBreakingClass<[2013 // fp variants.2014 VXORPSZrr, VXORPDZrr,2015 VXORPSZ128rr, VXORPDZ128rr, VXORPSZ256rr, VXORPDZ256rr,2016 VANDNPSZrr, VANDNPDZrr,2017 VANDNPSZ128rr, VANDNPDZ128rr, VANDNPSZ256rr, VANDNPDZ256rr,2018 2019 // int variants.2020 VPCMPGTBZrr, VPCMPGTWZrr, VPCMPGTDZrr, VPCMPGTQZrr,2021 VPCMPGTBZ128rr, VPCMPGTWZ128rr, VPCMPGTDZ128rr, VPCMPGTQZ128rr,2022 VPCMPGTBZ256rr, VPCMPGTWZ256rr, VPCMPGTDZ256rr, VPCMPGTQZ256rr,2023 VPANDNDZrr, VPANDNQZrr,2024 VPANDNDZ128rr, VPANDNQZ128rr, VPANDNDZ256rr, VPANDNQZ256rr,2025 VPXORDZrr, VPXORQZrr,2026 VPXORDZ128rr, VPXORQZ128rr, VPXORDZ256rr, VPXORQZ256rr,2027 VPSUBBZrr, VPSUBWZrr, VPSUBDZrr, VPSUBQZrr,2028 VPSUBBZ128rr, VPSUBWZ128rr, VPSUBDZ128rr, VPSUBQZ128rr,2029 VPSUBBZ256rr, VPSUBWZ256rr, VPSUBDZ256rr, VPSUBQZ256rr,2030 ], ZeroIdiomPredicate>,2031]>;2032 2033def : IsDepBreakingFunction<[2034 // GPR2035 DepBreakingClass<[ SBB32rr, SBB32rr_REV,2036 SBB64rr, SBB64rr_REV ], ZeroIdiomPredicate>,2037 DepBreakingClass<[ CMP8rr, CMP8rr_REV,2038 CMP16rr, CMP16rr_REV,2039 CMP32rr, CMP32rr_REV,2040 CMP64rr, CMP64rr_REV ], CheckSameRegOperand<0, 1> >,2041 // SSE2042 DepBreakingClass<[2043 PCMPEQBrr, PCMPEQWrr, PCMPEQDrr, PCMPEQQrr2044 ], ZeroIdiomPredicate>,2045 2046 // AVX XMM2047 DepBreakingClass<[2048 VPCMPEQBrr, VPCMPEQWrr, VPCMPEQDrr, VPCMPEQQrr2049 ], ZeroIdiomPredicate>,2050 2051 // AVX YMM2052 DepBreakingClass<[2053 VPCMPEQBYrr, VPCMPEQWYrr, VPCMPEQDYrr, VPCMPEQQYrr2054 ], ZeroIdiomPredicate>,2055]>;2056 2057} // SchedModel2058 2059