brintos

brintos / llvm-project-archived public Read only

0
0
Text · 90.2 KiB · ac4d31d Raw
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