[llvm] [AArch64] Initial sched model for Neoverse V3, V3AE (PR #163932)
Simon Wallis via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 21 08:15:08 PDT 2025
================
@@ -0,0 +1,2781 @@
+//=- AArch64SchedNeoverseV3.td - NeoverseV3 Scheduling Defs --*- tablegen -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the scheduling model for the Arm Neoverse V3 processors.
+// All information is taken from the V3 Software Optimization guide:
+//
+// https://developer.arm.com/documentation/109678/300/?lang=en
+//
+//===----------------------------------------------------------------------===//
+
+def NeoverseV3Model : SchedMachineModel {
+ let IssueWidth = 8; // Expect best value to be slightly higher than V2
+ let MicroOpBufferSize = 320; // Entries in micro-op re-order buffer.
+ let LoadLatency = 4; // Optimistic load latency.
+ let MispredictPenalty = 10; // Extra cycles for mispredicted branch. NOTE: Copied from N2.
+ let LoopMicroOpBufferSize = 16; // NOTE: Copied from Cortex-A57.
+ let CompleteModel = 1;
+
+ list<Predicate> UnsupportedFeatures = !listconcat(SMEUnsupported.F,
+ [HasSVE2p1, HasSVEB16B16,
+ HasCPA, HasCSSC]);
+}
+
+//===----------------------------------------------------------------------===//
+// Define each kind of processor resource and number available on Neoverse V3.
+// Instructions are first fetched and then decoded into internal macro-ops
+// (MOPs). From there, the MOPs proceed through register renaming and dispatch
+// stages. A MOP can be split into two micro-ops further down the pipeline
+// after the decode stage. Once dispatched, micro-ops wait for their operands
+// and issue out-of-order to one of twenty-one issue pipelines. Each issue
+// pipeline can accept one micro-op per cycle.
+
+let SchedModel = NeoverseV3Model in {
+
+// Define the (21) issue ports.
+def V3UnitB : ProcResource<3>; // Branch 0/1/2
+def V3UnitS0 : ProcResource<1>; // Integer single-cycle 0
+def V3UnitS1 : ProcResource<1>; // Integer single-cycle 1
+def V3UnitS2 : ProcResource<1>; // Integer single-cycle 2
+def V3UnitS3 : ProcResource<1>; // Integer single-cycle 3
+def V3UnitS4 : ProcResource<1>; // Integer single-cycle 4
+def V3UnitS5 : ProcResource<1>; // Integer single-cycle 5
+def V3UnitM0 : ProcResource<1>; // Integer single/multicycle 0
+def V3UnitM1 : ProcResource<1>; // Integer single/multicycle 1
+def V3UnitV0 : ProcResource<1>; // FP/ASIMD 0
+def V3UnitV1 : ProcResource<1>; // FP/ASIMD 1
+def V3UnitV2 : ProcResource<1>; // FP/ASIMD 2
+def V3UnitV3 : ProcResource<1>; // FP/ASIMD 3
+def V3UnitLS0 : ProcResource<1>; // Load/Store 0
+def V3UnitL12 : ProcResource<2>; // Load 1/2
+def V3UnitST1 : ProcResource<1>; // Store 1
+def V3UnitD : ProcResource<2>; // Store data 0/1
+def V3UnitFlg : ProcResource<8>; // Flags
+
+def V3UnitS : ProcResGroup<[V3UnitS0, V3UnitS1, V3UnitS2, V3UnitS3, V3UnitS4, V3UnitS5]>; // Integer single-cycle 0/1/2/3/4/5
+def V3UnitI : ProcResGroup<[V3UnitS0, V3UnitS1, V3UnitS2, V3UnitS3, V3UnitS4, V3UnitS5, V3UnitM0, V3UnitM1]>; // Integer single-cycle 0/1/2/3/4/5 and single/multicycle 0/1
+def V3UnitM : ProcResGroup<[V3UnitM0, V3UnitM1]>; // Integer single/multicycle 0/1
+def V3UnitLSA : ProcResGroup<[V3UnitLS0, V3UnitL12, V3UnitST1]>; // Supergroup of L+SA
+def V3UnitL : ProcResGroup<[V3UnitLS0, V3UnitL12]>; // Load/Store 0 and Load 1/2
+def V3UnitSA : ProcResGroup<[V3UnitLS0, V3UnitST1]>; // Load/Store 0 and Store 1
+def V3UnitV : ProcResGroup<[V3UnitV0, V3UnitV1, V3UnitV2, V3UnitV3]>; // FP/ASIMD 0/1/2/3
+def V3UnitV01 : ProcResGroup<[V3UnitV0, V3UnitV1]>; // FP/ASIMD 0/1
+def V3UnitV02 : ProcResGroup<[V3UnitV0, V3UnitV2]>; // FP/ASIMD 0/2
+def V3UnitV13 : ProcResGroup<[V3UnitV1, V3UnitV3]>; // FP/ASIMD 1/3
+
+// Define commonly used read types.
+
+// No forwarding is provided for these types.
+def : ReadAdvance<ReadI, 0>;
+def : ReadAdvance<ReadISReg, 0>;
+def : ReadAdvance<ReadIEReg, 0>;
+def : ReadAdvance<ReadIM, 0>;
+def : ReadAdvance<ReadIMA, 0>;
+def : ReadAdvance<ReadID, 0>;
+def : ReadAdvance<ReadExtrHi, 0>;
+def : ReadAdvance<ReadAdrBase, 0>;
+def : ReadAdvance<ReadST, 0>;
+def : ReadAdvance<ReadVLD, 0>;
+
+// NOTE: Copied from N2.
+def : WriteRes<WriteAtomic, []> { let Unsupported = 1; }
+def : WriteRes<WriteBarrier, []> { let Latency = 1; }
+def : WriteRes<WriteHint, []> { let Latency = 1; }
+def : WriteRes<WriteLDHi, []> { let Latency = 4; }
+
+//===----------------------------------------------------------------------===//
+// Define customized scheduler read/write types specific to the Neoverse V3.
+
+//===----------------------------------------------------------------------===//
+
+// Define generic 0 micro-op types
+def V3Write_0c : SchedWriteRes<[]> { let Latency = 0; }
+
+// Define generic 1 micro-op types
+
+def V3Write_1c_1B : SchedWriteRes<[V3UnitB]> { let Latency = 1; }
+def V3Write_1c_1I_1Flg : SchedWriteRes<[V3UnitI, V3UnitFlg]> { let Latency = 1; }
+def V3Write_1c_1I : SchedWriteRes<[V3UnitI]> { let Latency = 1; }
+def V3Write_1c_1M : SchedWriteRes<[V3UnitM]> { let Latency = 1; }
+def V3Write_1c_1SA : SchedWriteRes<[V3UnitSA]> { let Latency = 1; }
+def V3Write_2c_1M : SchedWriteRes<[V3UnitM]> { let Latency = 2; }
+def V3Write_2c_1M_1Flg : SchedWriteRes<[V3UnitM, V3UnitFlg]> { let Latency = 2; }
+def V3Write_3c_1M : SchedWriteRes<[V3UnitM]> { let Latency = 3; }
+def V3Write_2c_1M0 : SchedWriteRes<[V3UnitM0]> { let Latency = 2; }
+def V3Write_3c_1M0 : SchedWriteRes<[V3UnitM0]> { let Latency = 3; }
+def V3Write_4c_1M0 : SchedWriteRes<[V3UnitM0]> { let Latency = 4; }
+def V3Write_12c_1M0 : SchedWriteRes<[V3UnitM0]> { let Latency = 12;
+ let ReleaseAtCycles = [12]; }
+def V3Write_20c_1M0 : SchedWriteRes<[V3UnitM0]> { let Latency = 20;
+ let ReleaseAtCycles = [20]; }
+def V3Write_4c_1L : SchedWriteRes<[V3UnitL]> { let Latency = 4; }
+def V3Write_6c_1L : SchedWriteRes<[V3UnitL]> { let Latency = 6; }
+def V3Write_2c_1V : SchedWriteRes<[V3UnitV]> { let Latency = 2; }
+def V3Write_2c_1V0 : SchedWriteRes<[V3UnitV0]> { let Latency = 2; }
+def V3Write_3c_1V : SchedWriteRes<[V3UnitV]> { let Latency = 3; }
+def V3Write_3c_1V01 : SchedWriteRes<[V3UnitV01]> { let Latency = 3;
+ let ReleaseAtCycles = [2]; }
+def V3Write_4c_1V : SchedWriteRes<[V3UnitV]> { let Latency = 4; }
+def V3Write_5c_1V : SchedWriteRes<[V3UnitV]> { let Latency = 5; }
+def V3Write_6c_1V : SchedWriteRes<[V3UnitV]> { let Latency = 6; }
+def V3Write_12c_1V : SchedWriteRes<[V3UnitV]> { let Latency = 12; }
+def V3Write_3c_1V0 : SchedWriteRes<[V3UnitV0]> { let Latency = 3; }
+def V3Write_3c_1V02 : SchedWriteRes<[V3UnitV02]> { let Latency = 3; }
+def V3Write_4c_1V0 : SchedWriteRes<[V3UnitV0]> { let Latency = 4; }
+def V3Write_4c_1V02 : SchedWriteRes<[V3UnitV02]> { let Latency = 4; }
+def V3Write_7c_1V0 : SchedWriteRes<[V3UnitV0]> { let Latency = 7;
+ let ReleaseAtCycles = [7]; }
+def V3Write_9c_1V0 : SchedWriteRes<[V3UnitV0]> { let Latency = 9; }
+def V3Write_10c_1V0 : SchedWriteRes<[V3UnitV0]> { let Latency = 10; }
+def V3Write_8c_1V1 : SchedWriteRes<[V3UnitV1]> { let Latency = 8;
+ let ReleaseAtCycles = [2]; }
+def V3Write_12c_1V0 : SchedWriteRes<[V3UnitV0]> { let Latency = 12;
+ let ReleaseAtCycles = [11]; }
+def V3Write_13c_1V0 : SchedWriteRes<[V3UnitV0]> { let Latency = 13; }
+def V3Write_15c_1V0 : SchedWriteRes<[V3UnitV0]> { let Latency = 15; }
+def V3Write_13c_1V1 : SchedWriteRes<[V3UnitV1]> { let Latency = 13;
+ let ReleaseAtCycles = [8]; }
+def V3Write_16c_1V0 : SchedWriteRes<[V3UnitV0]> { let Latency = 16; }
+def V3Write_16c_1V02 : SchedWriteRes<[V3UnitV02]> { let Latency = 16;
+ let ReleaseAtCycles = [8]; }
+def V3Write_20c_1V0 : SchedWriteRes<[V3UnitV0]> { let Latency = 20;
+ let ReleaseAtCycles = [20]; }
+def V3Write_2c_1V1 : SchedWriteRes<[V3UnitV1]> { let Latency = 2; }
+def V3Write_2c_1V13 : SchedWriteRes<[V3UnitV13]> { let Latency = 2; }
+def V3Write_3c_1V1 : SchedWriteRes<[V3UnitV1]> { let Latency = 3; }
+def V3Write_3c_1V13 : SchedWriteRes<[V3UnitV13]> { let Latency = 3; }
+def V3Write_4c_1V1 : SchedWriteRes<[V3UnitV1]> { let Latency = 4; }
+def V3Write_6c_1V1 : SchedWriteRes<[V3UnitV1]> { let Latency = 6; }
+def V3Write_10c_1V1 : SchedWriteRes<[V3UnitV1]> { let Latency = 10; }
+def V3Write_6c_1SA : SchedWriteRes<[V3UnitSA]> { let Latency = 6; }
+
+//===----------------------------------------------------------------------===//
+// Define generic 2 micro-op types
+
+def V3Write_1c_1B_1S : SchedWriteRes<[V3UnitB, V3UnitS]> {
+ let Latency = 1;
+ let NumMicroOps = 2;
+}
+
+def V3Write_6c_1M0_1B : SchedWriteRes<[V3UnitM0, V3UnitB]> {
+ let Latency = 6;
+ let NumMicroOps = 2;
+}
+
+def V3Write_9c_1M0_1L : SchedWriteRes<[V3UnitM0, V3UnitL]> {
+ let Latency = 9;
+ let NumMicroOps = 2;
+}
+
+def V3Write_3c_1I_1M : SchedWriteRes<[V3UnitI, V3UnitM]> {
+ let Latency = 3;
+ let NumMicroOps = 2;
+}
+
+def V3Write_1c_2M : SchedWriteRes<[V3UnitM, V3UnitM]> {
+ let Latency = 1;
+ let NumMicroOps = 2;
+}
+
+def V3Write_2c_2M : SchedWriteRes<[V3UnitM, V3UnitM]> {
+ let Latency = 2;
+ let NumMicroOps = 2;
+}
+
+def V3Write_3c_2M : SchedWriteRes<[V3UnitM, V3UnitM]> {
+ let Latency = 3;
+ let NumMicroOps = 2;
+}
+
+def V3Write_4c_2M : SchedWriteRes<[V3UnitM, V3UnitM]> {
+ let Latency = 4;
+ let NumMicroOps = 2;
+}
+
+def V3Write_5c_1L_1I : SchedWriteRes<[V3UnitL, V3UnitI]> {
+ let Latency = 5;
+ let NumMicroOps = 2;
+}
+
+def V3Write_6c_1I_1L : SchedWriteRes<[V3UnitI, V3UnitL]> {
+ let Latency = 6;
+ let NumMicroOps = 2;
+}
+
+def V3Write_7c_1I_1L : SchedWriteRes<[V3UnitI, V3UnitL]> {
+ let Latency = 7;
+ let NumMicroOps = 2;
+}
+
+def V3Write_1c_1SA_1D : SchedWriteRes<[V3UnitSA, V3UnitD]> {
+ let Latency = 1;
+ let NumMicroOps = 2;
+}
+
+def V3Write_5c_1M0_1V : SchedWriteRes<[V3UnitM0, V3UnitV]> {
+ let Latency = 5;
+ let NumMicroOps = 2;
+}
+
+def V3Write_2c_1SA_1V01 : SchedWriteRes<[V3UnitSA, V3UnitV01]> {
+ let Latency = 2;
+ let NumMicroOps = 2;
+}
+
+def V3Write_2c_2V01 : SchedWriteRes<[V3UnitV01, V3UnitV01]> {
+ let Latency = 2;
+ let NumMicroOps = 2;
+}
+
+def V3Write_4c_1SA_1V01 : SchedWriteRes<[V3UnitSA, V3UnitV01]> {
+ let Latency = 4;
+ let NumMicroOps = 2;
+}
+
+def V3Write_5c_1V13_1V : SchedWriteRes<[V3UnitV13, V3UnitV]> {
+ let Latency = 5;
+ let NumMicroOps = 2;
+}
+
+def V3Write_4c_2V0 : SchedWriteRes<[V3UnitV0, V3UnitV0]> {
+ let Latency = 4;
+ let NumMicroOps = 2;
+}
+
+def V3Write_4c_2V02 : SchedWriteRes<[V3UnitV02, V3UnitV02]> {
+ let Latency = 4;
+ let NumMicroOps = 2;
+}
+
+def V3Write_4c_2V : SchedWriteRes<[V3UnitV, V3UnitV]> {
+ let Latency = 4;
+ let NumMicroOps = 2;
+}
+
+def V3Write_6c_2V : SchedWriteRes<[V3UnitV, V3UnitV]> {
+ let Latency = 6;
+ let NumMicroOps = 2;
+}
+
+def V3Write_6c_2L : SchedWriteRes<[V3UnitL, V3UnitL]> {
+ let Latency = 6;
+ let NumMicroOps = 2;
+}
+
+def V3Write_8c_1L_1V : SchedWriteRes<[V3UnitL, V3UnitV]> {
+ let Latency = 8;
+ let NumMicroOps = 2;
+}
+
+def V3Write_4c_1SA_1V : SchedWriteRes<[V3UnitSA, V3UnitV]> {
+ let Latency = 4;
+ let NumMicroOps = 2;
+}
+
+def V3Write_3c_1M0_1M : SchedWriteRes<[V3UnitM0, V3UnitM]> {
+ let Latency = 3;
+ let NumMicroOps = 2;
+}
+
+def V3Write_4c_1M0_1M : SchedWriteRes<[V3UnitM0, V3UnitM]> {
+ let Latency = 4;
+ let NumMicroOps = 2;
+}
+
+def V3Write_1c_1M0_1M : SchedWriteRes<[V3UnitM0, V3UnitM]> {
+ let Latency = 1;
+ let NumMicroOps = 2;
+}
+
+def V3Write_2c_1M0_1M : SchedWriteRes<[V3UnitM0, V3UnitM]> {
+ let Latency = 2;
+ let NumMicroOps = 2;
+}
+
+def V3Write_6c_2V1 : SchedWriteRes<[V3UnitV1, V3UnitV1]> {
+ let Latency = 6;
+ let NumMicroOps = 2;
+}
+
+def V3Write_5c_2V0 : SchedWriteRes<[V3UnitV0, V3UnitV0]> {
+ let Latency = 5;
+ let NumMicroOps = 2;
+}
+
+def V3Write_5c_2V02 : SchedWriteRes<[V3UnitV02, V3UnitV02]> {
+ let Latency = 5;
+ let NumMicroOps = 2;
+}
+
+def V3Write_5c_1V1_1M0 : SchedWriteRes<[V3UnitV1, V3UnitM0]> {
+ let Latency = 5;
+ let NumMicroOps = 2;
+}
+
+def V3Write_6c_1V1_1M0 : SchedWriteRes<[V3UnitV1, V3UnitM0]> {
+ let Latency = 6;
+ let NumMicroOps = 2;
+}
+
+def V3Write_7c_1M0_1V02 : SchedWriteRes<[V3UnitM0, V3UnitV02]> {
+ let Latency = 7;
+ let NumMicroOps = 2;
+}
+
+def V3Write_2c_1V0_1M : SchedWriteRes<[V3UnitV0, V3UnitM]> {
+ let Latency = 2;
+ let NumMicroOps = 2;
+}
+
+def V3Write_3c_1V0_1M : SchedWriteRes<[V3UnitV0, V3UnitM]> {
+ let Latency = 3;
+ let NumMicroOps = 2;
+}
+
+def V3Write_6c_1V_1V13 : SchedWriteRes<[V3UnitV, V3UnitV13]> {
+ let Latency = 6;
+ let NumMicroOps = 2;
+}
+
+def V3Write_6c_1L_1M : SchedWriteRes<[V3UnitL, V3UnitM]> {
+ let Latency = 6;
+ let NumMicroOps = 2;
+}
+
+def V3Write_6c_1L_1I : SchedWriteRes<[V3UnitL, V3UnitI]> {
+ let Latency = 6;
+ let NumMicroOps = 2;
+}
+
+def V3Write_6c_2V13 : SchedWriteRes<[V3UnitV13, V3UnitV13]> {
+ let Latency = 6;
+ let NumMicroOps = 2;
+}
+
+def V3Write_8c_1M0_1V01 : SchedWriteRes<[V3UnitM0, V3UnitV01]> {
+ let Latency = 8;
+ let NumMicroOps = 2;
+}
+
+//===----------------------------------------------------------------------===//
+// Define generic 3 micro-op types
+
+def V3Write_1c_1SA_1D_1I : SchedWriteRes<[V3UnitSA, V3UnitD, V3UnitI]> {
+ let Latency = 1;
+ let NumMicroOps = 3;
+}
+
+def V3Write_2c_1SA_1V01_1I : SchedWriteRes<[V3UnitSA, V3UnitV01, V3UnitI]> {
+ let Latency = 2;
+ let NumMicroOps = 3;
+}
+
+def V3Write_2c_1SA_2V01 : SchedWriteRes<[V3UnitSA, V3UnitV01, V3UnitV01]> {
+ let Latency = 2;
+ let NumMicroOps = 3;
+}
+
+def V3Write_4c_1SA_2V01 : SchedWriteRes<[V3UnitSA, V3UnitV01, V3UnitV01]> {
+ let Latency = 4;
+ let NumMicroOps = 3;
+}
+
+def V3Write_9c_1L_2V : SchedWriteRes<[V3UnitL, V3UnitV, V3UnitV]> {
+ let Latency = 9;
+ let NumMicroOps = 3;
+}
+
+def V3Write_4c_3V : SchedWriteRes<[V3UnitV, V3UnitV, V3UnitV]> {
+ let Latency = 4;
+ let NumMicroOps = 3;
+}
+
+def V3Write_7c_1M_1M0_1V : SchedWriteRes<[V3UnitM, V3UnitM0, V3UnitV]> {
+ let Latency = 7;
+ let NumMicroOps = 3;
+}
+
+def V3Write_2c_1SA_1I_1V01 : SchedWriteRes<[V3UnitSA, V3UnitI, V3UnitV01]> {
+ let Latency = 2;
+ let NumMicroOps = 3;
+}
+
+def V3Write_6c_3L : SchedWriteRes<[V3UnitL, V3UnitL, V3UnitL]> {
+ let Latency = 6;
+ let NumMicroOps = 3;
+}
+
+def V3Write_6c_3V : SchedWriteRes<[V3UnitV, V3UnitV, V3UnitV]> {
+ let Latency = 6;
+ let NumMicroOps = 3;
+}
+
+def V3Write_8c_1L_2V : SchedWriteRes<[V3UnitL, V3UnitV, V3UnitV]> {
+ let Latency = 8;
+ let NumMicroOps = 3;
+}
+
+//===----------------------------------------------------------------------===//
+// Define generic 4 micro-op types
+
+def V3Write_2c_1SA_2V01_1I : SchedWriteRes<[V3UnitSA, V3UnitV01, V3UnitV01,
+ V3UnitI]> {
+ let Latency = 2;
+ let NumMicroOps = 4;
+}
+
+def V3Write_2c_2SA_2V01 : SchedWriteRes<[V3UnitSA, V3UnitSA,
+ V3UnitV01, V3UnitV01]> {
+ let Latency = 2;
+ let NumMicroOps = 4;
+}
+
+def V3Write_4c_2SA_2V01 : SchedWriteRes<[V3UnitSA, V3UnitSA,
+ V3UnitV01, V3UnitV01]> {
+ let Latency = 4;
+ let NumMicroOps = 4;
+}
+
+def V3Write_5c_1I_3L : SchedWriteRes<[V3UnitI, V3UnitL, V3UnitL, V3UnitL]> {
+ let Latency = 5;
+ let NumMicroOps = 4;
+}
+
+def V3Write_6c_4V0 : SchedWriteRes<[V3UnitV0, V3UnitV0, V3UnitV0, V3UnitV0]> {
+ let Latency = 6;
+ let NumMicroOps = 4;
+}
+
+def V3Write_8c_4V : SchedWriteRes<[V3UnitV, V3UnitV, V3UnitV, V3UnitV]> {
+ let Latency = 8;
+ let NumMicroOps = 4;
+}
+
+def V3Write_6c_2V_2V13 : SchedWriteRes<[V3UnitV, V3UnitV, V3UnitV13,
+ V3UnitV13]> {
+ let Latency = 6;
+ let NumMicroOps = 4;
+}
+
+def V3Write_8c_2V_2V13 : SchedWriteRes<[V3UnitV, V3UnitV, V3UnitV13,
+ V3UnitV13]> {
+ let Latency = 8;
+ let NumMicroOps = 4;
+}
+
+def V3Write_6c_4V02 : SchedWriteRes<[V3UnitV02, V3UnitV02, V3UnitV02,
+ V3UnitV02]> {
+ let Latency = 6;
+ let NumMicroOps = 4;
+}
+
+def V3Write_6c_4V : SchedWriteRes<[V3UnitV, V3UnitV, V3UnitV, V3UnitV]> {
+ let Latency = 6;
+ let NumMicroOps = 4;
+}
+
+def V3Write_8c_2L_2V : SchedWriteRes<[V3UnitL, V3UnitL, V3UnitV, V3UnitV]> {
+ let Latency = 8;
+ let NumMicroOps = 4;
+}
+
+def V3Write_9c_2L_2V : SchedWriteRes<[V3UnitL, V3UnitL, V3UnitV, V3UnitV]> {
+ let Latency = 9;
+ let NumMicroOps = 4;
+}
+
+def V3Write_2c_2SA_2V : SchedWriteRes<[V3UnitSA, V3UnitSA, V3UnitV,
+ V3UnitV]> {
+ let Latency = 2;
+ let NumMicroOps = 4;
+}
+
+def V3Write_4c_2SA_2V : SchedWriteRes<[V3UnitSA, V3UnitSA, V3UnitV,
+ V3UnitV]> {
+ let Latency = 4;
+ let NumMicroOps = 4;
+}
+
+def V3Write_8c_2M0_2V02 : SchedWriteRes<[V3UnitM0, V3UnitM0, V3UnitV02,
+ V3UnitV02]> {
+ let Latency = 8;
+ let NumMicroOps = 4;
+}
+
+def V3Write_8c_2V_2V1 : SchedWriteRes<[V3UnitV, V3UnitV, V3UnitV1,
+ V3UnitV1]> {
+ let Latency = 8;
+ let NumMicroOps = 4;
+}
+
+def V3Write_4c_2M0_2M : SchedWriteRes<[V3UnitM0, V3UnitM0, V3UnitM,
+ V3UnitM]> {
+ let Latency = 4;
+ let NumMicroOps = 4;
+}
+
+def V3Write_5c_2M0_2M : SchedWriteRes<[V3UnitM0, V3UnitM0, V3UnitM,
+ V3UnitM]> {
+ let Latency = 5;
+ let NumMicroOps = 4;
+}
+
+def V3Write_6c_2I_2L : SchedWriteRes<[V3UnitI, V3UnitI, V3UnitL, V3UnitL]> {
+ let Latency = 6;
+ let NumMicroOps = 4;
+}
+
+def V3Write_7c_4L : SchedWriteRes<[V3UnitL, V3UnitL, V3UnitL, V3UnitL]> {
+ let Latency = 7;
+ let NumMicroOps = 4;
+}
+
+def V3Write_6c_1SA_3V01 : SchedWriteRes<[V3UnitSA, V3UnitV01, V3UnitV01,
+ V3UnitV01]> {
+ let Latency = 6;
+ let NumMicroOps = 4;
+}
+
+//===----------------------------------------------------------------------===//
+// Define generic 5 micro-op types
+
+def V3Write_2c_1SA_2V01_2I : SchedWriteRes<[V3UnitSA, V3UnitV01, V3UnitV01,
+ V3UnitI, V3UnitI]> {
+ let Latency = 2;
+ let NumMicroOps = 5;
+}
+
+def V3Write_8c_2L_3V : SchedWriteRes<[V3UnitL, V3UnitL, V3UnitV, V3UnitV,
+ V3UnitV]> {
+ let Latency = 8;
+ let NumMicroOps = 5;
+}
+
+def V3Write_9c_1L_4V : SchedWriteRes<[V3UnitL, V3UnitV, V3UnitV, V3UnitV,
+ V3UnitV]> {
+ let Latency = 9;
+ let NumMicroOps = 5;
+}
+
+def V3Write_10c_1L_4V : SchedWriteRes<[V3UnitL, V3UnitV, V3UnitV, V3UnitV,
+ V3UnitV]> {
+ let Latency = 10;
+ let NumMicroOps = 5;
+}
+
+def V3Write_6c_5V : SchedWriteRes<[V3UnitV, V3UnitV, V3UnitV, V3UnitV,
+ V3UnitV]> {
+ let Latency = 6;
+ let NumMicroOps = 5;
+}
+
+//===----------------------------------------------------------------------===//
+// Define generic 6 micro-op types
+
+def V3Write_8c_3L_3V : SchedWriteRes<[V3UnitL, V3UnitL, V3UnitL,
+ V3UnitV, V3UnitV, V3UnitV]> {
+ let Latency = 8;
+ let NumMicroOps = 6;
+}
+
+def V3Write_9c_3L_3V : SchedWriteRes<[V3UnitL, V3UnitL, V3UnitL,
+ V3UnitV, V3UnitV, V3UnitV]> {
+ let Latency = 9;
+ let NumMicroOps = 6;
+}
+
+def V3Write_9c_2L_4V : SchedWriteRes<[V3UnitL, V3UnitL, V3UnitV,
+ V3UnitV, V3UnitV, V3UnitV]> {
+ let Latency = 9;
+ let NumMicroOps = 6;
+}
+
+def V3Write_9c_2L_2V_2I : SchedWriteRes<[V3UnitL, V3UnitL, V3UnitV,
+ V3UnitV, V3UnitI, V3UnitI]> {
+ let Latency = 9;
+ let NumMicroOps = 6;
+}
+
+def V3Write_9c_2V_4V13 : SchedWriteRes<[V3UnitV, V3UnitV, V3UnitV13,
+ V3UnitV13, V3UnitV13, V3UnitV13]> {
+ let Latency = 9;
+ let NumMicroOps = 6;
+}
+
+def V3Write_2c_3SA_3V : SchedWriteRes<[V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitV, V3UnitV, V3UnitV]> {
+ let Latency = 2;
+ let NumMicroOps = 6;
+}
+
+def V3Write_4c_2SA_4V01 : SchedWriteRes<[V3UnitSA, V3UnitSA, V3UnitV01,
+ V3UnitV01, V3UnitV01, V3UnitV01]> {
+ let Latency = 4;
+ let NumMicroOps = 6;
+}
+
+def V3Write_5c_2SA_4V01 : SchedWriteRes<[V3UnitSA, V3UnitSA, V3UnitV01,
+ V3UnitV01, V3UnitV01, V3UnitV01]> {
+ let Latency = 5;
+ let NumMicroOps = 6;
+}
+
+def V3Write_2c_3SA_3V01 : SchedWriteRes<[V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitV01, V3UnitV01, V3UnitV01]> {
+ let Latency = 2;
+ let NumMicroOps = 6;
+}
+
+def V3Write_4c_2SA_2I_2V01 : SchedWriteRes<[V3UnitSA, V3UnitSA, V3UnitI,
+ V3UnitI, V3UnitV01, V3UnitV01]> {
+ let Latency = 4;
+ let NumMicroOps = 6;
+}
+
+//===----------------------------------------------------------------------===//
+// Define generic 7 micro-op types
+
+def V3Write_8c_3L_4V : SchedWriteRes<[V3UnitL, V3UnitL, V3UnitL,
+ V3UnitV, V3UnitV, V3UnitV, V3UnitV]> {
+ let Latency = 8;
+ let NumMicroOps = 7;
+}
+
+//===----------------------------------------------------------------------===//
+// Define generic 8 micro-op types
+
+def V3Write_2c_4SA_4V : SchedWriteRes<[V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitV, V3UnitV, V3UnitV,
+ V3UnitV]> {
+ let Latency = 2;
+ let NumMicroOps = 8;
+}
+
+def V3Write_2c_4SA_4V01 : SchedWriteRes<[V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01]> {
+ let Latency = 2;
+ let NumMicroOps = 8;
+}
+
+def V3Write_4c_4SA_4V01 : SchedWriteRes<[V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01]> {
+ let Latency = 4;
+ let NumMicroOps = 8;
+}
+
+def V3Write_6c_2SA_6V01 : SchedWriteRes<[V3UnitSA, V3UnitSA, V3UnitV01,
+ V3UnitV01, V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01]> {
+ let Latency = 6;
+ let NumMicroOps = 8;
+}
+
+def V3Write_8c_4L_4V : SchedWriteRes<[V3UnitL, V3UnitL, V3UnitL, V3UnitL,
+ V3UnitV, V3UnitV, V3UnitV, V3UnitV]> {
+ let Latency = 8;
+ let NumMicroOps = 8;
+}
+
+//===----------------------------------------------------------------------===//
+// Define generic 9 micro-op types
+
+def V3Write_6c_3SA_6V01 : SchedWriteRes<[V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitV01, V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01, V3UnitV01]> {
+ let Latency = 6;
+ let NumMicroOps = 9;
+}
+
+def V3Write_10c_1L_8V : SchedWriteRes<[V3UnitL, V3UnitV, V3UnitV, V3UnitV,
+ V3UnitV, V3UnitV, V3UnitV, V3UnitV,
+ V3UnitV]> {
+ let Latency = 10;
+ let NumMicroOps = 9;
+}
+
+def V3Write_10c_3V_3L_3I : SchedWriteRes<[V3UnitV, V3UnitV, V3UnitV,
+ V3UnitL, V3UnitL, V3UnitL,
+ V3UnitI, V3UnitI, V3UnitI]> {
+ let Latency = 10;
+ let NumMicroOps = 9;
+}
+
+//===----------------------------------------------------------------------===//
+// Define generic 10 micro-op types
+
+def V3Write_9c_6L_4V : SchedWriteRes<[V3UnitL, V3UnitL, V3UnitL, V3UnitL,
+ V3UnitL, V3UnitL, V3UnitV, V3UnitV,
+ V3UnitV, V3UnitV]> {
+ let Latency = 9;
+ let NumMicroOps = 10;
+}
+
+//===----------------------------------------------------------------------===//
+// Define generic 12 micro-op types
+
+def V3Write_5c_4SA_8V01 : SchedWriteRes<[V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01, V3UnitV01]> {
+ let Latency = 5;
+ let NumMicroOps = 12;
+}
+
+def V3Write_9c_4L_8V : SchedWriteRes<[V3UnitL, V3UnitL, V3UnitL,
+ V3UnitL, V3UnitV, V3UnitV,
+ V3UnitV, V3UnitV, V3UnitV,
+ V3UnitV, V3UnitV, V3UnitV]> {
+ let Latency = 9;
+ let NumMicroOps = 12;
+}
+
+def V3Write_10c_4L_8V : SchedWriteRes<[V3UnitL, V3UnitL, V3UnitL,
+ V3UnitL, V3UnitV, V3UnitV,
+ V3UnitV, V3UnitV, V3UnitV,
+ V3UnitV, V3UnitV, V3UnitV]> {
+ let Latency = 10;
+ let NumMicroOps = 12;
+}
+
+//===----------------------------------------------------------------------===//
+// Define generic 16 micro-op types
+
+def V3Write_7c_4SA_12V01 : SchedWriteRes<[V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01, V3UnitV01,
+ V3UnitV01]> {
+ let Latency = 7;
+ let NumMicroOps = 16;
+}
+
+def V3Write_10c_4L_8V_4I : SchedWriteRes<[V3UnitL, V3UnitL, V3UnitL,
+ V3UnitL, V3UnitV, V3UnitV,
+ V3UnitV, V3UnitV, V3UnitV,
+ V3UnitV, V3UnitV, V3UnitV,
+ V3UnitI, V3UnitI, V3UnitI,
+ V3UnitI]> {
+ let Latency = 10;
+ let NumMicroOps = 16;
+}
+
+//===----------------------------------------------------------------------===//
+// Define generic 18 micro-op types
+
+def V3Write_7c_9SA_9V01 : SchedWriteRes<[V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitV01, V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01, V3UnitV01]> {
+ let Latency = 7;
+ let NumMicroOps = 18;
+}
+
+//===----------------------------------------------------------------------===//
+// Define generic 27 micro-op types
+
+def V3Write_7c_9SA_9I_9V01 : SchedWriteRes<[V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitI, V3UnitI, V3UnitI,
+ V3UnitI, V3UnitI, V3UnitI,
+ V3UnitI, V3UnitI, V3UnitI,
+ V3UnitV01, V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01,
+ V3UnitV01]> {
+ let Latency = 7;
+ let NumMicroOps = 27;
+}
+
+//===----------------------------------------------------------------------===//
+// Define generic 36 micro-op types
+
+def V3Write_11c_18SA_18V01 : SchedWriteRes<[V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitSA, V3UnitSA,
+ V3UnitV01, V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01,
+ V3UnitV01]> {
+ let Latency = 11;
+ let NumMicroOps = 36;
+}
+
+//===----------------------------------------------------------------------===//
+// Define generic 54 micro-op types
+
+def V3Write_11c_18SA_18I_18V01 : SchedWriteRes<[V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitSA,
+ V3UnitSA, V3UnitSA,
+ V3UnitI, V3UnitI, V3UnitI,
+ V3UnitI, V3UnitI, V3UnitI,
+ V3UnitI, V3UnitI, V3UnitI,
+ V3UnitI, V3UnitI, V3UnitI,
+ V3UnitI, V3UnitI, V3UnitI,
+ V3UnitI, V3UnitI, V3UnitI,
+ V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01,
+ V3UnitV01, V3UnitV01]> {
+ let Latency = 11;
+ let NumMicroOps = 54;
+}
+
+//===----------------------------------------------------------------------===//
+// Define predicate-controlled types
+
+def V3Write_ArithI : SchedWriteVariant<[
+ SchedVar<IsCheapLSL, [V3Write_1c_1I]>,
+ SchedVar<NoSchedPred, [V3Write_2c_1M]>]>;
+
+def V3Write_Logical : SchedWriteVariant<[
+ SchedVar<NeoverseNoLSL, [V3Write_1c_1I_1Flg]>,
+ SchedVar<NoSchedPred, [V3Write_2c_1M_1Flg]>]>;
+
+def V3Write_Extr : SchedWriteVariant<[
+ SchedVar<IsRORImmIdiomPred, [V3Write_1c_1I]>,
+ SchedVar<NoSchedPred, [V3Write_3c_1I_1M]>]>;
+
+def V3Write_LdrHQ : SchedWriteVariant<[
+ SchedVar<NeoverseHQForm, [V3Write_7c_1I_1L]>,
+ SchedVar<NoSchedPred, [V3Write_6c_1L]>]>;
+
+def V3Write_StrHQ : SchedWriteVariant<[
+ SchedVar<NeoverseHQForm, [V3Write_2c_1SA_1V01_1I]>,
+ SchedVar<NoSchedPred, [V3Write_2c_1SA_1V01]>]>;
+
+def V3Write_0or1c_1I : SchedWriteVariant<[
+ SchedVar<NeoverseZeroMove, [V3Write_0c]>,
+ SchedVar<NoSchedPred, [V3Write_1c_1I]>]>;
+
+def V3Write_0or2c_1V : SchedWriteVariant<[
+ SchedVar<NeoverseZeroMove, [V3Write_0c]>,
+ SchedVar<NoSchedPred, [V3Write_2c_1V]>]>;
+
+def V3Write_0or3c_1M0 : SchedWriteVariant<[
+ SchedVar<NeoverseZeroMove, [V3Write_0c]>,
+ SchedVar<NoSchedPred, [V3Write_3c_1M0]>]>;
+
+def V3Write_2or3c_1M : SchedWriteVariant<[
+ SchedVar<NeoversePdIsPg, [V3Write_3c_1M]>,
+ SchedVar<NoSchedPred, [V3Write_2c_1M]>]>;
+
+def V3Write_1or2c_1M : SchedWriteVariant<[
+ SchedVar<NeoversePdIsPg, [V3Write_2c_1M]>,
+ SchedVar<NoSchedPred, [V3Write_1c_1M]>]>;
+
+def V3Write_3or4c_1M0_1M : SchedWriteVariant<[
+ SchedVar<NeoversePdIsPg, [V3Write_4c_1M0_1M]>,
+ SchedVar<NoSchedPred, [V3Write_3c_1M0_1M]>]>;
+
+def V3Write_2or3c_1V0 : SchedWriteVariant<[
+ SchedVar<NeoversePdIsPg, [V3Write_3c_1V0]>,
+ SchedVar<NoSchedPred, [V3Write_2c_1V0]>]>;
+
+def V3Write_2or3c_1V0_1M : SchedWriteVariant<[
+ SchedVar<NeoversePdIsPg, [V3Write_3c_1V0_1M]>,
+ SchedVar<NoSchedPred, [V3Write_2c_1V0_1M]>]>;
+
+def V3Write_IncDec : SchedWriteVariant<[
+ SchedVar<NeoverseCheapIncDec, [V3Write_1c_1I]>,
+ SchedVar<NoSchedPred, [V3Write_2c_1M]>]>;
+
+//===----------------------------------------------------------------------===//
+// Define forwarded types
+
+// NOTE: SOG, p. 16, n. 2: Accumulator forwarding is not supported for
+// consumers of 64 bit multiply high operations?
+def V3Wr_IM : SchedWriteRes<[V3UnitM]> { let Latency = 2; }
+
+def V3Wr_FMA : SchedWriteRes<[V3UnitV]> { let Latency = 4; }
+def V3Rd_FMA : SchedReadAdvance<2, [WriteFMul, V3Wr_FMA]>;
+
+def V3Wr_VA : SchedWriteRes<[V3UnitV]> { let Latency = 4; }
+def V3Rd_VA : SchedReadAdvance<3, [V3Wr_VA]>;
+
+def V3Wr_VDOT : SchedWriteRes<[V3UnitV]> { let Latency = 3; }
+def V3Rd_VDOT : SchedReadAdvance<2, [V3Wr_VDOT]>;
+
+def V3Wr_VMMA : SchedWriteRes<[V3UnitV]> { let Latency = 3; }
+def V3Rd_VMMA : SchedReadAdvance<2, [V3Wr_VMMA]>;
+
+def V3Wr_VMA : SchedWriteRes<[V3UnitV02]> { let Latency = 4; }
+def V3Rd_VMA : SchedReadAdvance<3, [V3Wr_VMA]>;
+
+def V3Wr_VMAH : SchedWriteRes<[V3UnitV02, V3UnitV02]> { let Latency = 4; }
+def V3Rd_VMAH : SchedReadAdvance<2, [V3Wr_VMAH]>;
+
+def V3Wr_VMAL : SchedWriteRes<[V3UnitV02]> { let Latency = 4; }
+def V3Rd_VMAL : SchedReadAdvance<3, [V3Wr_VMAL]>;
+
+def V3Wr_VPA : SchedWriteRes<[V3UnitV]> { let Latency = 4; }
+def V3Rd_VPA : SchedReadAdvance<3, [V3Wr_VPA]>;
+
+def V3Wr_VSA : SchedWriteRes<[V3UnitV]> { let Latency = 4; }
+def V3Rd_VSA : SchedReadAdvance<3, [V3Wr_VSA]>;
+
+def V3Wr_VFCMA : SchedWriteRes<[V3UnitV]> { let Latency = 4; }
+def V3Rd_VFCMA : SchedReadAdvance<2, [V3Wr_VFCMA]>;
+
+def V3Wr_VFM : SchedWriteRes<[V3UnitV]> { let Latency = 3; }
+def V3Wr_VFMA : SchedWriteRes<[V3UnitV]> { let Latency = 4; }
+def V3Rd_VFMA : SchedReadAdvance<2, [V3Wr_VFM, V3Wr_VFMA]>;
+
+def V3Wr_VFMAL : SchedWriteRes<[V3UnitV]> { let Latency = 4; }
+def V3Rd_VFMAL : SchedReadAdvance<2, [V3Wr_VFMAL]>;
+
+def V3Wr_VBFDOT : SchedWriteRes<[V3UnitV]> { let Latency = 5; }
+def V3Rd_VBFDOT : SchedReadAdvance<2, [V3Wr_VBFDOT]>;
+def V3Wr_VBFMMA : SchedWriteRes<[V3UnitV]> { let Latency = 6; }
+def V3Rd_VBFMMA : SchedReadAdvance<2, [V3Wr_VBFMMA]>;
+def V3Wr_VBFMAL : SchedWriteRes<[V3UnitV]> { let Latency = 5; }
+def V3Rd_VBFMAL : SchedReadAdvance<3, [V3Wr_VBFMAL]>;
+
+def V3Wr_CRC : SchedWriteRes<[V3UnitM0]> { let Latency = 2; }
+def V3Rd_CRC : SchedReadAdvance<1, [V3Wr_CRC]>;
+
+def V3Wr_ZA : SchedWriteRes<[V3UnitV]> { let Latency = 4; }
+def V3Rd_ZA : SchedReadAdvance<3, [V3Wr_ZA]>;
+def V3Wr_ZPA : SchedWriteRes<[V3UnitV]> { let Latency = 4; }
+def V3Rd_ZPA : SchedReadAdvance<3, [V3Wr_ZPA]>;
+def V3Wr_ZSA : SchedWriteRes<[V3UnitV13]> { let Latency = 4; }
+def V3Rd_ZSA : SchedReadAdvance<3, [V3Wr_ZSA]>;
+
+def V3Wr_ZDOTB : SchedWriteRes<[V3UnitV]> { let Latency = 3; }
+def V3Rd_ZDOTB : SchedReadAdvance<2, [V3Wr_ZDOTB]>;
+def V3Wr_ZDOTH : SchedWriteRes<[V3UnitV02]> { let Latency = 4; }
+def V3Rd_ZDOTH : SchedReadAdvance<3, [V3Wr_ZDOTH]>;
+
+// NOTE: SOG p. 43: Complex multiply-add B, H, S element size: How to reduce
+// throughput to 1 in case of forwarding?
+def V3Wr_ZCMABHS : SchedWriteRes<[V3UnitV02]> { let Latency = 4; }
+def V3Rd_ZCMABHS : SchedReadAdvance<3, [V3Wr_ZCMABHS]>;
+def V3Wr_ZCMAD : SchedWriteRes<[V3UnitV02, V3UnitV02]> { let Latency = 5; }
+def V3Rd_ZCMAD : SchedReadAdvance<2, [V3Wr_ZCMAD]>;
+
+def V3Wr_ZMMA : SchedWriteRes<[V3UnitV]> { let Latency = 3; }
+def V3Rd_ZMMA : SchedReadAdvance<2, [V3Wr_ZMMA]>;
+
+def V3Wr_ZMABHS : SchedWriteRes<[V3UnitV02, V3UnitV02]> { let Latency = 4; }
+def V3Rd_ZMABHS : SchedReadAdvance<3, [V3Wr_ZMABHS]>;
+def V3Wr_ZMAD : SchedWriteRes<[V3UnitV02, V3UnitV02]> { let Latency = 5; }
+def V3Rd_ZMAD : SchedReadAdvance<2, [V3Wr_ZMAD]>;
+
+def V3Wr_ZMAL : SchedWriteRes<[V3UnitV02]> { let Latency = 4; }
+def V3Rd_ZMAL : SchedReadAdvance<3, [V3Wr_ZMAL]>;
+
+def V3Wr_ZMASQL : SchedWriteRes<[V3UnitV02]> { let Latency = 4; }
+def V3Wr_ZMASQBHS : SchedWriteRes<[V3UnitV02]> { let Latency = 4; }
+def V3Wr_ZMASQD : SchedWriteRes<[V3UnitV02, V3UnitV02]> { let Latency = 5; }
+def V3Rd_ZMASQ : SchedReadAdvance<2, [V3Wr_ZMASQL, V3Wr_ZMASQBHS,
+ V3Wr_ZMASQD]>;
+
+def V3Wr_ZFCMA : SchedWriteRes<[V3UnitV]> { let Latency = 5; }
+def V3Rd_ZFCMA : SchedReadAdvance<3, [V3Wr_ZFCMA]>;
+
+def V3Wr_ZFMA : SchedWriteRes<[V3UnitV]> { let Latency = 4; }
+def V3Rd_ZFMA : SchedReadAdvance<2, [V3Wr_ZFMA]>;
+
+def V3Wr_ZFMAL : SchedWriteRes<[V3UnitV]> { let Latency = 4; }
+def V3Rd_ZFMAL : SchedReadAdvance<2, [V3Wr_ZFMAL]>;
+
+def V3Wr_ZBFDOT : SchedWriteRes<[V3UnitV]> { let Latency = 5; }
+def V3Rd_ZBFDOT : SchedReadAdvance<2, [V3Wr_ZBFDOT]>;
+def V3Wr_ZBFMMA : SchedWriteRes<[V3UnitV]> { let Latency = 6; }
+def V3Rd_ZBFMMA : SchedReadAdvance<2, [V3Wr_ZBFMMA]>;
+def V3Wr_ZBFMAL : SchedWriteRes<[V3UnitV]> { let Latency = 5; }
+def V3Rd_ZBFMAL : SchedReadAdvance<3, [V3Wr_ZBFMAL]>;
+
+//===----------------------------------------------------------------------===//
+// Define types with long resource cycles (rc)
+
+def V3Write_6c_1V1_5rc : SchedWriteRes<[V3UnitV1]> { let Latency = 6; let ReleaseAtCycles = [ 5]; }
+def V3Write_9c_1V1_2rc : SchedWriteRes<[V3UnitV1]> { let Latency = 9; let ReleaseAtCycles = [ 2]; }
+def V3Write_9c_1V1_4rc : SchedWriteRes<[V3UnitV1]> { let Latency = 9; let ReleaseAtCycles = [ 4]; }
+def V3Write_10c_1V1_9rc : SchedWriteRes<[V3UnitV1]> { let Latency = 10; let ReleaseAtCycles = [ 9]; }
+def V3Write_11c_1V1_4rc : SchedWriteRes<[V3UnitV1]> { let Latency = 11; let ReleaseAtCycles = [ 4]; }
+def V3Write_13c_1V1_8rc : SchedWriteRes<[V3UnitV1]> { let Latency = 13; let ReleaseAtCycles = [8]; }
+def V3Write_14c_1V1_2rc : SchedWriteRes<[V3UnitV1]> { let Latency = 14; let ReleaseAtCycles = [2]; }
+
+// Miscellaneous
+// -----------------------------------------------------------------------------
+
+def : InstRW<[WriteI], (instrs COPY)>;
+
+// §3.3 Branch instructions
+// -----------------------------------------------------------------------------
+
+// Branch, immed
+// Compare and branch
+def : SchedAlias<WriteBr, V3Write_1c_1B>;
+
+// Branch, register
+def : SchedAlias<WriteBrReg, V3Write_1c_1B>;
+
+// Branch and link, immed
+// Branch and link, register
+def : InstRW<[V3Write_1c_1B_1S], (instrs BL, BLR)>;
+
+// §3.4 Arithmetic and Logical Instructions
+// -----------------------------------------------------------------------------
+
+// ALU, basic
+def : SchedAlias<WriteI, V3Write_1c_1I>;
+
+// ALU, basic, flagset
+def : InstRW<[V3Write_1c_1I_1Flg],
+ (instregex "^(ADD|SUB)S[WX]r[ir]$",
+ "^(ADC|SBC)S[WX]r$",
+ "^ANDS[WX]ri$",
+ "^(AND|BIC)S[WX]rr$")>;
+def : InstRW<[V3Write_0or1c_1I], (instregex "^MOVZ[WX]i$")>;
+
+// ALU, extend and shift
+def : SchedAlias<WriteIEReg, V3Write_2c_1M>;
+
+// Arithmetic, LSL shift, shift <= 4
+// Arithmetic, flagset, LSL shift, shift <= 4
+// Arithmetic, LSR/ASR/ROR shift or LSL shift > 4
+def : SchedAlias<WriteISReg, V3Write_ArithI>;
+def : InstRW<[V3Write_ArithI],
+ (instregex "^(ADD|SUB)S[WX]rs$")>;
+
+// Arithmetic, immediate to logical address tag
+def : InstRW<[V3Write_2c_1M], (instrs ADDG, SUBG)>;
+
+// Conditional compare
+def : InstRW<[V3Write_1c_1I_1Flg], (instregex "^CCM[NP][WX][ir]")>;
+
+// Convert floating-point condition flags
+// Flag manipulation instructions
+def : WriteRes<WriteSys, []> { let Latency = 1; }
+
+// Insert Random Tags
+def : InstRW<[V3Write_2c_1M], (instrs IRG, IRGstack)>;
+
+// Insert Tag Mask
+// Subtract Pointer
+def : InstRW<[V3Write_1c_1I], (instrs GMI, SUBP)>;
+
+// Subtract Pointer, flagset
+def : InstRW<[V3Write_1c_1I_1Flg], (instrs SUBPS)>;
+
+// Logical, shift, no flagset
+def : InstRW<[V3Write_1c_1I], (instregex "^(AND|BIC|EON|EOR|ORN)[WX]rs$")>;
+def : InstRW<[V3Write_0or1c_1I], (instregex "^ORR[WX]rs$")>;
+
+// Logical, shift, flagset
+def : InstRW<[V3Write_Logical], (instregex "^(AND|BIC)S[WX]rs$")>;
+
+// Move and shift instructions
+// -----------------------------------------------------------------------------
+
+def : SchedAlias<WriteImm, V3Write_1c_1I>;
+
+// §3.5 Divide and multiply instructions
+// -----------------------------------------------------------------------------
+
+// SDIV, UDIV
+def : SchedAlias<WriteID32, V3Write_12c_1M0>;
+def : SchedAlias<WriteID64, V3Write_20c_1M0>;
+
+def : SchedAlias<WriteIM32, V3Write_2c_1M>;
+def : SchedAlias<WriteIM64, V3Write_2c_1M>;
+
+// Multiply
+// Multiply accumulate, W-form
+// Multiply accumulate, X-form
+def : InstRW<[V3Wr_IM], (instregex "^M(ADD|SUB)[WX]rrr$")>;
+
+// Multiply accumulate long
+// Multiply long
+def : InstRW<[V3Wr_IM], (instregex "^(S|U)M(ADD|SUB)Lrrr$")>;
+
+// Multiply high
+def : InstRW<[V3Write_3c_1M], (instrs SMULHrr, UMULHrr)>;
+
+// §3.6 Pointer Authentication Instructions (v8.3 PAC)
+// -----------------------------------------------------------------------------
+
+// Authenticate data address
+// Authenticate instruction address
+// Compute pointer authentication code for data address
+// Compute pointer authentication code, using generic key
+// Compute pointer authentication code for instruction address
+def : InstRW<[V3Write_4c_1M0], (instregex "^AUT", "^PAC")>;
+
+// Branch and link, register, with pointer authentication
+// Branch, register, with pointer authentication
+// Branch, return, with pointer authentication
+def : InstRW<[V3Write_6c_1M0_1B], (instrs BLRAA, BLRAAZ, BLRAB, BLRABZ, BRAA,
+ BRAAZ, BRAB, BRABZ, RETAA, RETAB,
+ ERETAA, ERETAB)>;
+
+
+// Load register, with pointer authentication
+def : InstRW<[V3Write_9c_1M0_1L], (instregex "^LDRA[AB](indexed|writeback)")>;
+
+// Strip pointer authentication code
+def : InstRW<[V3Write_2c_1M0], (instrs XPACD, XPACI, XPACLRI)>;
+
+// §3.7 Miscellaneous data-processing instructions
+// -----------------------------------------------------------------------------
+
+// Address generation
+def : InstRW<[V3Write_1c_1I], (instrs ADR, ADRP)>;
+
+// Bitfield extract, one reg
+// Bitfield extract, two regs
+def : SchedAlias<WriteExtr, V3Write_Extr>;
+def : InstRW<[V3Write_Extr], (instrs EXTRWrri, EXTRXrri)>;
+
+// Bitfield move, basic
+def : SchedAlias<WriteIS, V3Write_1c_1I>;
+
+// Bitfield move, insert
+def : InstRW<[V3Write_2c_1M], (instregex "^BFM[WX]ri$")>;
+
+// §3.8 Load instructions
+// -----------------------------------------------------------------------------
+
+// NOTE: SOG p. 19: Throughput of LDN?P X-form should be 2, but reported as 3.
+
+def : SchedAlias<WriteLD, V3Write_4c_1L>;
+def : SchedAlias<WriteLDIdx, V3Write_4c_1L>;
+
+// Load register, literal
+def : InstRW<[V3Write_5c_1L_1I], (instrs LDRWl, LDRXl, LDRSWl, PRFMl)>;
+
+// Load pair, signed immed offset, signed words
+def : InstRW<[V3Write_5c_1I_3L, WriteLDHi], (instrs LDPSWi)>;
+
+// Load pair, immed post-index or immed pre-index, signed words
+def : InstRW<[WriteAdr, V3Write_5c_1I_3L, WriteLDHi],
+ (instregex "^LDPSW(post|pre)$")>;
+
+// §3.9 Store instructions
+// -----------------------------------------------------------------------------
+
+// NOTE: SOG, p. 20: Unsure if STRH uses pipeline I.
+
+def : SchedAlias<WriteST, V3Write_1c_1SA_1D>;
+def : SchedAlias<WriteSTIdx, V3Write_1c_1SA_1D>;
+def : SchedAlias<WriteSTP, V3Write_1c_1SA_1D>;
+def : SchedAlias<WriteAdr, V3Write_1c_1I>;
+
+// §3.10 Tag load instructions
+// -----------------------------------------------------------------------------
+
+// Load allocation tag
+// Load multiple allocation tags
+def : InstRW<[V3Write_4c_1L], (instrs LDG, LDGM)>;
+
+// §3.11 Tag store instructions
+// -----------------------------------------------------------------------------
+
+// Store allocation tags to one or two granules, post-index
+// Store allocation tags to one or two granules, pre-index
+// Store allocation tag to one or two granules, zeroing, post-index
+// Store Allocation Tag to one or two granules, zeroing, pre-index
+// Store allocation tag and reg pair to memory, post-Index
+// Store allocation tag and reg pair to memory, pre-Index
+def : InstRW<[V3Write_1c_1SA_1D_1I], (instrs STGPreIndex, STGPostIndex,
+ ST2GPreIndex, ST2GPostIndex,
+ STZGPreIndex, STZGPostIndex,
+ STZ2GPreIndex, STZ2GPostIndex,
+ STGPpre, STGPpost)>;
+
+// Store allocation tags to one or two granules, signed offset
+// Store allocation tag to two granules, zeroing, signed offset
+// Store allocation tag and reg pair to memory, signed offset
+// Store multiple allocation tags
+def : InstRW<[V3Write_1c_1SA_1D], (instrs STGi, ST2Gi, STZGi,
+ STZ2Gi, STGPi, STGM, STZGM)>;
+
+// §3.12 FP data processing instructions
+// -----------------------------------------------------------------------------
+
+// FP absolute value
+// FP arithmetic
+// FP min/max
+// FP negate
+// FP select
+def : SchedAlias<WriteF, V3Write_2c_1V>;
+
+// FP compare
+def : SchedAlias<WriteFCmp, V3Write_2c_1V0>;
+
+// FP divide, square root
+def : SchedAlias<WriteFDiv, V3Write_6c_1V1>;
+
+// FP divide, H-form
+def : InstRW<[V3Write_6c_1V1], (instrs FDIVHrr)>;
+// FP divide, S-form
+def : InstRW<[V3Write_8c_1V1], (instrs FDIVSrr)>;
----------------
simonwallis2 wrote:
OK I removed ReleaseAtCycles = [2] which is what was making the throughput of fdivs 2.00.
https://github.com/llvm/llvm-project/pull/163932
More information about the llvm-commits
mailing list