forked from OSchip/llvm-project
606 lines
27 KiB
TableGen
606 lines
27 KiB
TableGen
//=- X86ScheduleBtVer2.td - X86 BtVer2 (Jaguar) Scheduling ---*- tablegen -*-=//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines the machine model for AMD btver2 (Jaguar) to support
|
|
// instruction scheduling and other instruction cost heuristics. Based off AMD Software
|
|
// Optimization Guide for AMD Family 16h Processors & Instruction Latency appendix.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
def BtVer2Model : SchedMachineModel {
|
|
// All x86 instructions are modeled as a single micro-op, and btver2 can
|
|
// decode 2 instructions per cycle.
|
|
let IssueWidth = 2;
|
|
let MicroOpBufferSize = 64; // Retire Control Unit
|
|
let LoadLatency = 5; // FPU latency (worse case cf Integer 3 cycle latency)
|
|
let HighLatency = 25;
|
|
let MispredictPenalty = 14; // Minimum branch misdirection penalty
|
|
let PostRAScheduler = 1;
|
|
|
|
// FIXME: SSE4/AVX is unimplemented. This flag is set to allow
|
|
// the scheduler to assign a default model to unrecognized opcodes.
|
|
let CompleteModel = 0;
|
|
}
|
|
|
|
let SchedModel = BtVer2Model in {
|
|
|
|
// Jaguar can issue up to 6 micro-ops in one cycle
|
|
def JALU0 : ProcResource<1>; // Integer Pipe0: integer ALU0 (also handle FP->INT jam)
|
|
def JALU1 : ProcResource<1>; // Integer Pipe1: integer ALU1/MUL/DIV
|
|
def JLAGU : ProcResource<1>; // Integer Pipe2: LAGU
|
|
def JSAGU : ProcResource<1>; // Integer Pipe3: SAGU (also handles 3-operand LEA)
|
|
def JFPU0 : ProcResource<1>; // Vector/FPU Pipe0: VALU0/VIMUL/FPA
|
|
def JFPU1 : ProcResource<1>; // Vector/FPU Pipe1: VALU1/STC/FPM
|
|
|
|
// The Integer PRF for Jaguar is 64 entries, and it holds the architectural and
|
|
// speculative version of the 64-bit integer registers.
|
|
// Reference: www.realworldtech.com/jaguar/4/
|
|
def IntegerPRF : RegisterFile<64, [GR8, GR16, GR32, GR64, CCR]>;
|
|
|
|
// The Jaguar FP Retire Queue renames SIMD and FP uOps onto a pool of 72 SSE
|
|
// registers. Operations on 256-bit data types are cracked into two COPs.
|
|
// Reference: www.realworldtech.com/jaguar/4/
|
|
def FpuPRF: RegisterFile<72, [VR64, VR128, VR256], [1, 1, 2]>;
|
|
|
|
// The retire control unit (RCU) can track up to 64 macro-ops in-flight. It can
|
|
// retire up to two macro-ops per cycle.
|
|
// Reference: "Software Optimization Guide for AMD Family 16h Processors"
|
|
def RCU : RetireControlUnit<64, 2>;
|
|
|
|
// Integer Pipe Scheduler
|
|
def JALU01 : ProcResGroup<[JALU0, JALU1]> {
|
|
let BufferSize=20;
|
|
}
|
|
|
|
// AGU Pipe Scheduler
|
|
def JLSAGU : ProcResGroup<[JLAGU, JSAGU]> {
|
|
let BufferSize=12;
|
|
}
|
|
|
|
// Fpu Pipe Scheduler
|
|
def JFPU01 : ProcResGroup<[JFPU0, JFPU1]> {
|
|
let BufferSize=18;
|
|
}
|
|
|
|
// Functional units
|
|
def JDiv : ProcResource<1>; // integer division
|
|
def JMul : ProcResource<1>; // integer multiplication
|
|
def JVALU0 : ProcResource<1>; // vector integer
|
|
def JVALU1 : ProcResource<1>; // vector integer
|
|
def JVIMUL : ProcResource<1>; // vector integer multiplication
|
|
def JSTC : ProcResource<1>; // vector store/convert
|
|
def JFPM : ProcResource<1>; // FP multiplication
|
|
def JFPA : ProcResource<1>; // FP addition
|
|
|
|
// Functional unit groups
|
|
def JFPX : ProcResGroup<[JFPA, JFPM]>;
|
|
def JVALU : ProcResGroup<[JVALU0, JVALU1]>;
|
|
|
|
// Integer loads are 3 cycles, so ReadAfterLd registers needn't be available until 3
|
|
// cycles after the memory operand.
|
|
def : ReadAdvance<ReadAfterLd, 3>;
|
|
|
|
// Many SchedWrites are defined in pairs with and without a folded load.
|
|
// Instructions with folded loads are usually micro-fused, so they only appear
|
|
// as two micro-ops when dispatched by the schedulers.
|
|
// This multiclass defines the resource usage for variants with and without
|
|
// folded loads.
|
|
multiclass JWriteResIntPair<X86FoldableSchedWrite SchedRW,
|
|
list<ProcResourceKind> ExePorts,
|
|
int Lat, list<int> Res = [], int UOps = 1> {
|
|
// Register variant is using a single cycle on ExePort.
|
|
def : WriteRes<SchedRW, ExePorts> {
|
|
let Latency = Lat;
|
|
let ResourceCycles = Res;
|
|
let NumMicroOps = UOps;
|
|
}
|
|
|
|
// Memory variant also uses a cycle on JLAGU and adds 3 cycles to the
|
|
// latency.
|
|
def : WriteRes<SchedRW.Folded, !listconcat([JLAGU], ExePorts)> {
|
|
let Latency = !add(Lat, 3);
|
|
let ResourceCycles = !if(!empty(Res), [], !listconcat([1], Res));
|
|
let NumMicroOps = UOps;
|
|
}
|
|
}
|
|
|
|
multiclass JWriteResFpuPair<X86FoldableSchedWrite SchedRW,
|
|
list<ProcResourceKind> ExePorts,
|
|
int Lat, list<int> Res = [], int UOps = 1> {
|
|
// Register variant is using a single cycle on ExePort.
|
|
def : WriteRes<SchedRW, ExePorts> {
|
|
let Latency = Lat;
|
|
let ResourceCycles = Res;
|
|
let NumMicroOps = UOps;
|
|
}
|
|
|
|
// Memory variant also uses a cycle on JLAGU and adds 5 cycles to the
|
|
// latency.
|
|
def : WriteRes<SchedRW.Folded, !listconcat([JLAGU], ExePorts)> {
|
|
let Latency = !add(Lat, 5);
|
|
let ResourceCycles = !if(!empty(Res), [], !listconcat([1], Res));
|
|
let NumMicroOps = UOps;
|
|
}
|
|
}
|
|
|
|
multiclass JWriteResYMMPair<X86FoldableSchedWrite SchedRW,
|
|
list<ProcResourceKind> ExePorts,
|
|
int Lat, list<int> Res = [2], int UOps = 2> {
|
|
// Register variant is using a single cycle on ExePort.
|
|
def : WriteRes<SchedRW, ExePorts> {
|
|
let Latency = Lat;
|
|
let ResourceCycles = Res;
|
|
let NumMicroOps = UOps;
|
|
}
|
|
|
|
// Memory variant also uses 2 cycles on JLAGU and adds 5 cycles to the
|
|
// latency.
|
|
def : WriteRes<SchedRW.Folded, !listconcat([JLAGU], ExePorts)> {
|
|
let Latency = !add(Lat, 5);
|
|
let ResourceCycles = !listconcat([2], Res);
|
|
let NumMicroOps = UOps;
|
|
}
|
|
}
|
|
|
|
// A folded store needs a cycle on the SAGU for the store data.
|
|
def : WriteRes<WriteRMW, [JSAGU]>;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Arithmetic.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
defm : JWriteResIntPair<WriteALU, [JALU01], 1>;
|
|
defm : JWriteResIntPair<WriteIMul, [JALU1, JMul], 3, [1, 1], 2>; // i8/i16/i32 multiplication
|
|
defm : JWriteResIntPair<WriteIMul64, [JALU1, JMul], 6, [1, 4], 2>; // i64 multiplication
|
|
defm : X86WriteRes<WriteIMulH, [JALU1], 6, [4], 1>;
|
|
|
|
defm : JWriteResIntPair<WriteDiv8, [JALU1, JDiv], 12, [1, 12], 1>;
|
|
defm : JWriteResIntPair<WriteDiv16, [JALU1, JDiv], 17, [1, 17], 2>;
|
|
defm : JWriteResIntPair<WriteDiv32, [JALU1, JDiv], 25, [1, 25], 2>;
|
|
defm : JWriteResIntPair<WriteDiv64, [JALU1, JDiv], 41, [1, 41], 2>;
|
|
defm : JWriteResIntPair<WriteIDiv8, [JALU1, JDiv], 12, [1, 12], 1>;
|
|
defm : JWriteResIntPair<WriteIDiv16, [JALU1, JDiv], 17, [1, 17], 2>;
|
|
defm : JWriteResIntPair<WriteIDiv32, [JALU1, JDiv], 25, [1, 25], 2>;
|
|
defm : JWriteResIntPair<WriteIDiv64, [JALU1, JDiv], 41, [1, 41], 2>;
|
|
|
|
defm : JWriteResIntPair<WriteCRC32, [JALU01], 3, [4], 3>;
|
|
|
|
defm : JWriteResIntPair<WriteCMOV, [JALU01], 1>; // Conditional move.
|
|
def : WriteRes<WriteSETCC, [JALU01]>; // Setcc.
|
|
def : WriteRes<WriteSETCCStore, [JALU01,JSAGU]>;
|
|
|
|
// This is for simple LEAs with one or two input operands.
|
|
// FIXME: SAGU 3-operand LEA
|
|
def : WriteRes<WriteLEA, [JALU01]>;
|
|
|
|
// Bit counts.
|
|
defm : JWriteResIntPair<WriteBitScan, [JALU01], 5, [4], 8>;
|
|
defm : JWriteResIntPair<WritePOPCNT, [JALU01], 1>;
|
|
defm : JWriteResIntPair<WriteLZCNT, [JALU01], 1>;
|
|
defm : JWriteResIntPair<WriteTZCNT, [JALU01], 2, [2]>;
|
|
|
|
// BMI1 BEXTR, BMI2 BZHI
|
|
defm : JWriteResIntPair<WriteBEXTR, [JALU01], 1>;
|
|
defm : JWriteResIntPair<WriteBZHI, [JALU01], 1>; // NOTE: Doesn't exist on Jaguar.
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Integer shifts and rotates.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
defm : JWriteResIntPair<WriteShift, [JALU01], 1>;
|
|
|
|
def JWriteSHLDrri : SchedWriteRes<[JALU01]> {
|
|
let Latency = 3;
|
|
let ResourceCycles = [6];
|
|
let NumMicroOps = 6;
|
|
}
|
|
def: InstRW<[JWriteSHLDrri], (instrs SHLD16rri8, SHLD32rri8, SHLD64rri8,
|
|
SHRD16rri8, SHRD32rri8, SHRD64rri8)>;
|
|
|
|
def JWriteSHLDrrCL : SchedWriteRes<[JALU01]> {
|
|
let Latency = 4;
|
|
let ResourceCycles = [8];
|
|
let NumMicroOps = 7;
|
|
}
|
|
def: InstRW<[JWriteSHLDrrCL], (instrs SHLD16rrCL, SHLD32rrCL, SHLD64rrCL,
|
|
SHRD16rrCL, SHRD32rrCL, SHRD64rrCL)>;
|
|
|
|
def JWriteSHLDm : SchedWriteRes<[JLAGU, JALU01]> {
|
|
let Latency = 9;
|
|
let ResourceCycles = [1, 22];
|
|
let NumMicroOps = 8;
|
|
}
|
|
def: InstRW<[JWriteSHLDm],(instrs SHLD16mri8, SHLD32mri8, SHLD64mri8,
|
|
SHLD16mrCL, SHLD32mrCL, SHLD64mrCL,
|
|
SHRD16mri8, SHRD32mri8, SHRD64mri8,
|
|
SHRD16mrCL, SHRD32mrCL, SHRD64mrCL)>;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Loads, stores, and moves, not folded with other operations.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
def : WriteRes<WriteLoad, [JLAGU]> { let Latency = 5; }
|
|
def : WriteRes<WriteStore, [JSAGU]>;
|
|
def : WriteRes<WriteMove, [JALU01]>;
|
|
|
|
// Load/store MXCSR.
|
|
// FIXME: These are copy and pasted from WriteLoad/Store.
|
|
def : WriteRes<WriteLDMXCSR, [JLAGU]> { let Latency = 5; }
|
|
def : WriteRes<WriteSTMXCSR, [JSAGU]>;
|
|
|
|
// Treat misc copies as a move.
|
|
def : InstRW<[WriteMove], (instrs COPY)>;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Idioms that clear a register, like xorps %xmm0, %xmm0.
|
|
// These can often bypass execution ports completely.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
def : WriteRes<WriteZero, []>;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Branches don't produce values, so they have no latency, but they still
|
|
// consume resources. Indirect branches can fold loads.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
defm : JWriteResIntPair<WriteJump, [JALU01], 1>;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Special case scheduling classes.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
def : WriteRes<WriteSystem, [JALU01]> { let Latency = 100; }
|
|
def : WriteRes<WriteMicrocoded, [JALU01]> { let Latency = 100; }
|
|
def : WriteRes<WriteFence, [JSAGU]>;
|
|
|
|
// Nops don't have dependencies, so there's no actual latency, but we set this
|
|
// to '1' to tell the scheduler that the nop uses an ALU slot for a cycle.
|
|
def : WriteRes<WriteNop, [JALU01]> { let Latency = 1; }
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Floating point. This covers both scalar and vector operations.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
defm : X86WriteRes<WriteFLoad, [JLAGU, JFPU01, JFPX], 5, [1, 1, 1], 1>;
|
|
defm : X86WriteRes<WriteFMaskedLoad, [JLAGU, JFPU01, JFPX], 6, [1, 1, 2], 1>;
|
|
defm : X86WriteRes<WriteFMaskedLoadY, [JLAGU, JFPU01, JFPX], 6, [2, 2, 4], 2>;
|
|
|
|
defm : X86WriteRes<WriteFStore, [JSAGU, JFPU1, JSTC], 1, [1, 1, 1], 1>;
|
|
defm : X86WriteRes<WriteFMaskedStore, [JSAGU, JFPU01, JFPX], 6, [1, 1, 4], 1>;
|
|
defm : X86WriteRes<WriteFMaskedStoreY, [JSAGU, JFPU01, JFPX], 6, [2, 2, 4], 2>;
|
|
|
|
def : WriteRes<WriteFMove, [JFPU01, JFPX]>;
|
|
def : WriteRes<WriteEMMS, [JFPU01, JFPX]> { let Latency = 2; }
|
|
|
|
defm : JWriteResFpuPair<WriteFAdd, [JFPU0, JFPA], 3>;
|
|
defm : JWriteResFpuPair<WriteFAddX, [JFPU0, JFPA], 3>;
|
|
defm : JWriteResYMMPair<WriteFAddY, [JFPU0, JFPA], 3, [2,2], 2>;
|
|
defm : JWriteResFpuPair<WriteFAdd64, [JFPU0, JFPA], 3>;
|
|
defm : JWriteResFpuPair<WriteFAdd64X, [JFPU0, JFPA], 3>;
|
|
defm : JWriteResYMMPair<WriteFAdd64Y, [JFPU0, JFPA], 3, [2,2], 2>;
|
|
defm : JWriteResFpuPair<WriteFCmp, [JFPU0, JFPA], 2>;
|
|
defm : JWriteResFpuPair<WriteFCmpX, [JFPU0, JFPA], 2>;
|
|
defm : JWriteResYMMPair<WriteFCmpY, [JFPU0, JFPA], 2, [2,2], 2>;
|
|
defm : JWriteResFpuPair<WriteFCmp64, [JFPU0, JFPA], 2>;
|
|
defm : JWriteResFpuPair<WriteFCmp64X, [JFPU0, JFPA], 2>;
|
|
defm : JWriteResYMMPair<WriteFCmp64Y, [JFPU0, JFPA], 2, [2,2], 2>;
|
|
defm : JWriteResFpuPair<WriteFCom, [JFPU0, JFPA, JALU0], 3>;
|
|
defm : JWriteResFpuPair<WriteFMul, [JFPU1, JFPM], 2>;
|
|
defm : JWriteResFpuPair<WriteFMulX, [JFPU1, JFPM], 2>;
|
|
defm : JWriteResYMMPair<WriteFMulY, [JFPU1, JFPM], 2, [2,2], 2>;
|
|
defm : JWriteResFpuPair<WriteFMul64, [JFPU1, JFPM], 4, [1,2]>;
|
|
defm : JWriteResFpuPair<WriteFMul64X, [JFPU1, JFPM], 4, [1,2]>;
|
|
defm : JWriteResYMMPair<WriteFMul64Y, [JFPU1, JFPM], 4, [2,4], 2>;
|
|
defm : JWriteResFpuPair<WriteFMA, [JFPU1, JFPM], 2>; // NOTE: Doesn't exist on Jaguar.
|
|
defm : JWriteResFpuPair<WriteFMAX, [JFPU1, JFPM], 2>; // NOTE: Doesn't exist on Jaguar.
|
|
defm : JWriteResFpuPair<WriteFMAY, [JFPU1, JFPM], 2>; // NOTE: Doesn't exist on Jaguar.
|
|
defm : JWriteResFpuPair<WriteDPPD, [JFPU1, JFPM, JFPA], 9, [1, 3, 3], 3>;
|
|
defm : JWriteResFpuPair<WriteDPPS, [JFPU1, JFPM, JFPA], 11, [1, 3, 3], 5>;
|
|
defm : JWriteResYMMPair<WriteDPPSY, [JFPU1, JFPM, JFPA], 12, [2, 6, 6], 10>;
|
|
defm : JWriteResFpuPair<WriteFRcp, [JFPU1, JFPM], 2>;
|
|
defm : JWriteResFpuPair<WriteFRcpX, [JFPU1, JFPM], 2>;
|
|
defm : JWriteResYMMPair<WriteFRcpY, [JFPU1, JFPM], 2, [2,2], 2>;
|
|
defm : JWriteResFpuPair<WriteFRsqrt, [JFPU1, JFPM], 2>;
|
|
defm : JWriteResFpuPair<WriteFRsqrtX, [JFPU1, JFPM], 2>;
|
|
defm : JWriteResYMMPair<WriteFRsqrtY, [JFPU1, JFPM], 2, [2,2], 2>;
|
|
defm : JWriteResFpuPair<WriteFDiv, [JFPU1, JFPM], 19, [1, 19]>;
|
|
defm : JWriteResFpuPair<WriteFDivX, [JFPU1, JFPM], 19, [1, 19]>;
|
|
defm : JWriteResYMMPair<WriteFDivY, [JFPU1, JFPM], 38, [2, 38], 2>;
|
|
defm : JWriteResYMMPair<WriteFDivZ, [JFPU1, JFPM], 38, [2, 38], 2>;
|
|
defm : JWriteResFpuPair<WriteFDiv64, [JFPU1, JFPM], 19, [1, 19]>;
|
|
defm : JWriteResFpuPair<WriteFDiv64X, [JFPU1, JFPM], 19, [1, 19]>;
|
|
defm : JWriteResYMMPair<WriteFDiv64Y, [JFPU1, JFPM], 38, [2, 38], 2>;
|
|
defm : JWriteResYMMPair<WriteFDiv64Z, [JFPU1, JFPM], 38, [2, 38], 2>;
|
|
defm : JWriteResFpuPair<WriteFSqrt, [JFPU1, JFPM], 21, [1, 21]>;
|
|
defm : JWriteResFpuPair<WriteFSqrtX, [JFPU1, JFPM], 21, [1, 21]>;
|
|
defm : JWriteResYMMPair<WriteFSqrtY, [JFPU1, JFPM], 42, [2, 42], 2>;
|
|
defm : JWriteResYMMPair<WriteFSqrtZ, [JFPU1, JFPM], 42, [2, 42], 2>;
|
|
defm : JWriteResFpuPair<WriteFSqrt64, [JFPU1, JFPM], 27, [1, 27]>;
|
|
defm : JWriteResFpuPair<WriteFSqrt64X, [JFPU1, JFPM], 27, [1, 27]>;
|
|
defm : JWriteResYMMPair<WriteFSqrt64Y, [JFPU1, JFPM], 54, [2, 54], 2>;
|
|
defm : JWriteResYMMPair<WriteFSqrt64Z, [JFPU1, JFPM], 54, [2, 54], 2>;
|
|
defm : JWriteResFpuPair<WriteFSqrt80, [JFPU1, JFPM], 35, [1, 35]>;
|
|
defm : JWriteResFpuPair<WriteFSign, [JFPU1, JFPM], 2>;
|
|
defm : JWriteResFpuPair<WriteFRnd, [JFPU1, JSTC], 3>;
|
|
defm : JWriteResYMMPair<WriteFRndY, [JFPU1, JSTC], 3, [2,2], 2>;
|
|
defm : JWriteResFpuPair<WriteFLogic, [JFPU01, JFPX], 1>;
|
|
defm : JWriteResYMMPair<WriteFLogicY, [JFPU01, JFPX], 1, [2, 2], 2>;
|
|
defm : JWriteResFpuPair<WriteFTest, [JFPU0, JFPA, JALU0], 3>;
|
|
defm : JWriteResYMMPair<WriteFTestY , [JFPU01, JFPX, JFPA, JALU0], 4, [2, 2, 2, 1], 3>;
|
|
defm : JWriteResFpuPair<WriteFShuffle, [JFPU01, JFPX], 1>;
|
|
defm : JWriteResYMMPair<WriteFShuffleY, [JFPU01, JFPX], 1, [2, 2], 2>;
|
|
defm : JWriteResFpuPair<WriteFVarShuffle, [JFPU01, JFPX], 2, [1, 4], 3>;
|
|
defm : JWriteResYMMPair<WriteFVarShuffleY,[JFPU01, JFPX], 3, [2, 6], 6>;
|
|
defm : JWriteResFpuPair<WriteFBlend, [JFPU01, JFPX], 1>;
|
|
defm : JWriteResYMMPair<WriteFBlendY, [JFPU01, JFPX], 1, [2, 2], 2>;
|
|
defm : JWriteResFpuPair<WriteFVarBlend, [JFPU01, JFPX], 2, [1, 4], 3>;
|
|
defm : JWriteResYMMPair<WriteFVarBlendY, [JFPU01, JFPX], 3, [2, 6], 6>;
|
|
defm : JWriteResFpuPair<WriteFShuffle256, [JFPU01, JFPX], 1>;
|
|
defm : JWriteResFpuPair<WriteFVarShuffle256, [JFPU01, JFPX], 1>; // NOTE: Doesn't exist on Jaguar.
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Conversions.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
defm : JWriteResFpuPair<WriteCvtF2I, [JFPU1, JSTC], 3>; // Float -> Integer.
|
|
defm : JWriteResFpuPair<WriteCvtI2F, [JFPU1, JSTC], 3>; // Integer -> Float.
|
|
defm : JWriteResFpuPair<WriteCvtF2F, [JFPU1, JSTC], 3>; // Float -> Float size conversion.
|
|
def : WriteRes<WriteCvtF2FSt, [JFPU1, JSTC, JSAGU]> { let Latency = 4; }
|
|
|
|
def JWriteCVTF2F : SchedWriteRes<[JFPU1, JSTC]> {
|
|
let Latency = 7;
|
|
let ResourceCycles = [1, 2];
|
|
let NumMicroOps = 2;
|
|
}
|
|
def : InstRW<[JWriteCVTF2F], (instregex "(V)?CVTS(D|S)2S(D|S)rr")>;
|
|
|
|
def JWriteCVTF2FLd : SchedWriteRes<[JLAGU, JFPU1, JSTC]> {
|
|
let Latency = 12;
|
|
let ResourceCycles = [1, 1, 2];
|
|
let NumMicroOps = 2;
|
|
}
|
|
def : InstRW<[JWriteCVTF2FLd], (instregex "(V)?CVTS(D|S)2S(D|S)rm")>;
|
|
|
|
def JWriteCVTF2SI : SchedWriteRes<[JFPU1, JSTC, JFPA, JALU0]> {
|
|
let Latency = 7;
|
|
let NumMicroOps = 2;
|
|
}
|
|
def : InstRW<[JWriteCVTF2SI], (instregex "(V)?CVT(T?)S(D|S)2SI(64)?rr")>;
|
|
|
|
def JWriteCVTF2SILd : SchedWriteRes<[JLAGU, JFPU1, JSTC, JFPA, JALU0]> {
|
|
let Latency = 12;
|
|
let NumMicroOps = 2;
|
|
}
|
|
def : InstRW<[JWriteCVTF2SILd], (instregex "(V)?CVT(T?)S(D|S)2SI(64)?rm")>;
|
|
|
|
// FIXME: f+3 ST, LD+STC latency
|
|
def JWriteCVTSI2F : SchedWriteRes<[JFPU1, JSTC]> {
|
|
let Latency = 9;
|
|
let NumMicroOps = 2;
|
|
}
|
|
def : InstRW<[JWriteCVTSI2F], (instregex "(V)?CVTSI(64)?2S(D|S)rr")>;
|
|
|
|
def JWriteCVTSI2FLd : SchedWriteRes<[JLAGU, JFPU1, JSTC]> {
|
|
let Latency = 14;
|
|
let NumMicroOps = 2;
|
|
}
|
|
def : InstRW<[JWriteCVTSI2FLd], (instregex "(V)?CVTSI(64)?2S(D|S)rm")>;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Vector integer operations.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
defm : X86WriteRes<WriteVecLoad, [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>;
|
|
defm : X86WriteRes<WriteVecMaskedLoad, [JLAGU, JFPU01, JVALU], 6, [1, 1, 2], 1>;
|
|
defm : X86WriteRes<WriteVecMaskedLoadY, [JLAGU, JFPU01, JVALU], 6, [2, 2, 4], 2>;
|
|
|
|
defm : X86WriteRes<WriteVecStore, [JSAGU, JFPU1, JSTC], 1, [1, 1, 1], 1>;
|
|
defm : X86WriteRes<WriteVecMaskedStore, [JSAGU, JFPU01, JVALU], 6, [1, 1, 4], 1>;
|
|
defm : X86WriteRes<WriteVecMaskedStoreY, [JSAGU, JFPU01, JVALU], 6, [2, 2, 4], 2>;
|
|
|
|
def : WriteRes<WriteVecMove, [JFPU01, JVALU]>;
|
|
|
|
defm : JWriteResFpuPair<WriteVecALU, [JFPU01, JVALU], 1>;
|
|
defm : JWriteResFpuPair<WriteVecALUY, [JFPU01, JVALU], 1>;
|
|
defm : JWriteResFpuPair<WriteVecShift, [JFPU01, JVALU], 1>;
|
|
defm : JWriteResFpuPair<WriteVecShiftX, [JFPU01, JVALU], 1>;
|
|
defm : JWriteResFpuPair<WriteVecShiftY, [JFPU01, JVALU], 1>;
|
|
defm : JWriteResFpuPair<WriteVecShiftImm, [JFPU01, JVALU], 1>;
|
|
defm : JWriteResFpuPair<WriteVecShiftImmX,[JFPU01, JVALU], 1>;
|
|
defm : JWriteResFpuPair<WriteVecShiftImmY,[JFPU01, JVALU], 1>;
|
|
defm : JWriteResFpuPair<WriteVecIMul, [JFPU0, JVIMUL], 2>;
|
|
defm : JWriteResFpuPair<WriteVecIMulX, [JFPU0, JVIMUL], 2>;
|
|
defm : JWriteResFpuPair<WriteVecIMulY, [JFPU0, JVIMUL], 2>;
|
|
defm : JWriteResFpuPair<WritePMULLD, [JFPU0, JFPU01, JVIMUL, JVALU], 4, [2, 1, 2, 1], 3>;
|
|
defm : JWriteResFpuPair<WritePMULLDY, [JFPU0, JFPU01, JVIMUL, JVALU], 4, [2, 1, 2, 1], 3>;
|
|
defm : JWriteResFpuPair<WriteMPSAD, [JFPU0, JVIMUL], 3, [1, 2]>;
|
|
defm : JWriteResFpuPair<WriteMPSADY, [JFPU0, JVIMUL], 3, [1, 2]>;
|
|
defm : JWriteResFpuPair<WritePSADBW, [JFPU01, JVALU], 2>;
|
|
defm : JWriteResFpuPair<WritePSADBWY, [JFPU01, JVALU], 2>;
|
|
defm : JWriteResFpuPair<WritePHMINPOS, [JFPU0, JVALU], 2>;
|
|
defm : JWriteResFpuPair<WriteShuffle, [JFPU01, JVALU], 1>;
|
|
defm : JWriteResFpuPair<WriteShuffleY, [JFPU01, JVALU], 1>;
|
|
defm : JWriteResFpuPair<WriteVarShuffle, [JFPU01, JVALU], 2, [1, 4], 3>;
|
|
defm : JWriteResFpuPair<WriteVarShuffleY, [JFPU01, JVALU], 2, [1, 4], 3>;
|
|
defm : JWriteResFpuPair<WriteBlend, [JFPU01, JVALU], 1>;
|
|
defm : JWriteResFpuPair<WriteBlendY, [JFPU01, JVALU], 1>;
|
|
defm : JWriteResFpuPair<WriteVarBlend, [JFPU01, JVALU], 2, [1, 4], 3>;
|
|
defm : JWriteResFpuPair<WriteVarBlendY, [JFPU01, JVALU], 2, [1, 4], 3>;
|
|
defm : JWriteResFpuPair<WriteVecLogic, [JFPU01, JVALU], 1>;
|
|
defm : JWriteResFpuPair<WriteVecLogicY, [JFPU01, JVALU], 1>; // NOTE: Doesn't exist on Jaguar.
|
|
defm : JWriteResFpuPair<WriteVecTest, [JFPU0, JFPA, JALU0], 3>;
|
|
defm : JWriteResYMMPair<WriteVecTestY , [JFPU01, JFPX, JFPA, JALU0], 4, [2, 2, 2, 1], 3>;
|
|
defm : JWriteResFpuPair<WriteShuffle256, [JFPU01, JVALU], 1>;
|
|
defm : JWriteResFpuPair<WriteVarShuffle256, [JFPU01, JVALU], 1>; // NOTE: Doesn't exist on Jaguar.
|
|
defm : JWriteResFpuPair<WriteVarVecShift, [JFPU01, JVALU], 1>; // NOTE: Doesn't exist on Jaguar.
|
|
defm : JWriteResFpuPair<WriteVarVecShiftY,[JFPU01, JVALU], 1>; // NOTE: Doesn't exist on Jaguar.
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Vector insert/extract operations.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
defm : JWriteResFpuPair<WriteVecInsert, [JFPU01, JVALU], 1>;
|
|
def : WriteRes<WriteVecExtract, [JFPU0, JFPA, JALU0]> { let Latency = 3; }
|
|
def : WriteRes<WriteVecExtractSt, [JFPU1, JSTC, JSAGU]> { let Latency = 3; }
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// SSE42 String instructions.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
defm : JWriteResFpuPair<WritePCmpIStrI, [JFPU1, JVALU1, JFPA, JALU0], 7, [1, 2, 1, 1], 3>;
|
|
defm : JWriteResFpuPair<WritePCmpIStrM, [JFPU1, JVALU1, JFPA, JALU0], 8, [1, 2, 1, 1], 3>;
|
|
defm : JWriteResFpuPair<WritePCmpEStrI, [JFPU1, JSAGU, JLAGU, JVALU, JVALU1, JFPA, JALU0], 14, [1, 2, 2, 6, 4, 1, 1], 9>;
|
|
defm : JWriteResFpuPair<WritePCmpEStrM, [JFPU1, JSAGU, JLAGU, JVALU, JVALU1, JFPA, JALU0], 14, [1, 2, 2, 6, 4, 1, 1], 9>;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// MOVMSK Instructions.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
def : WriteRes<WriteFMOVMSK, [JFPU0, JFPA, JALU0]> { let Latency = 3; }
|
|
def : WriteRes<WriteVecMOVMSK, [JFPU0, JFPA, JALU0]> { let Latency = 3; }
|
|
def : WriteRes<WriteVecMOVMSKY, [JFPU0, JFPA, JALU0]> { let Latency = 3; }
|
|
def : WriteRes<WriteMMXMOVMSK, [JFPU0, JFPA, JALU0]> { let Latency = 3; }
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// AES Instructions.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
defm : JWriteResFpuPair<WriteAESIMC, [JFPU0, JVIMUL], 2>;
|
|
defm : JWriteResFpuPair<WriteAESKeyGen, [JFPU0, JVIMUL], 2>;
|
|
defm : JWriteResFpuPair<WriteAESDecEnc, [JFPU0, JVIMUL], 3, [1, 1], 2>;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Horizontal add/sub instructions.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
defm : JWriteResFpuPair<WriteFHAdd, [JFPU0, JFPA], 3>;
|
|
defm : JWriteResYMMPair<WriteFHAddY, [JFPU0, JFPA], 3, [2,2], 2>;
|
|
defm : JWriteResFpuPair<WritePHAdd, [JFPU01, JVALU], 1>;
|
|
defm : JWriteResFpuPair<WritePHAddY, [JFPU01, JVALU], 1>;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Carry-less multiplication instructions.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
defm : JWriteResFpuPair<WriteCLMul, [JFPU0, JVIMUL], 2>;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// SSE4A instructions.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
def JWriteINSERTQ: SchedWriteRes<[JFPU01, JVALU]> {
|
|
let Latency = 2;
|
|
let ResourceCycles = [1, 4];
|
|
}
|
|
def : InstRW<[JWriteINSERTQ], (instrs INSERTQ, INSERTQI)>;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// F16C instructions.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
def JWriteCVTPS2PHY: SchedWriteRes<[JFPU1, JSTC, JFPX]> {
|
|
let Latency = 6;
|
|
let ResourceCycles = [2, 2, 2];
|
|
let NumMicroOps = 3;
|
|
}
|
|
def : InstRW<[JWriteCVTPS2PHY], (instrs VCVTPS2PHYrr)>;
|
|
|
|
def JWriteCVTPS2PHYSt: SchedWriteRes<[JFPU1, JSTC, JFPX, JSAGU]> {
|
|
let Latency = 7;
|
|
let ResourceCycles = [2, 2, 2, 1];
|
|
let NumMicroOps = 3;
|
|
}
|
|
def : InstRW<[JWriteCVTPS2PHYSt], (instrs VCVTPS2PHYmr)>;
|
|
|
|
def JWriteCVTPH2PSY: SchedWriteRes<[JFPU1, JSTC]> {
|
|
let Latency = 3;
|
|
let ResourceCycles = [2, 2];
|
|
let NumMicroOps = 2;
|
|
}
|
|
def : InstRW<[JWriteCVTPH2PSY], (instrs VCVTPH2PSYrr)>;
|
|
|
|
def JWriteCVTPH2PSYLd: SchedWriteRes<[JLAGU, JFPU1, JSTC]> {
|
|
let Latency = 8;
|
|
let ResourceCycles = [1, 2, 2];
|
|
let NumMicroOps = 2;
|
|
}
|
|
def : InstRW<[JWriteCVTPH2PSYLd], (instrs VCVTPH2PSYrm)>;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// AVX instructions.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
def JWriteVCVTY: SchedWriteRes<[JFPU1, JSTC]> {
|
|
let Latency = 3;
|
|
let ResourceCycles = [2, 2];
|
|
let NumMicroOps = 2;
|
|
}
|
|
def : InstRW<[JWriteVCVTY], (instrs VCVTDQ2PDYrr, VCVTDQ2PSYrr,
|
|
VCVTPS2DQYrr, VCVTTPS2DQYrr)>;
|
|
|
|
def JWriteVCVTYLd: SchedWriteRes<[JLAGU, JFPU1, JSTC]> {
|
|
let Latency = 8;
|
|
let ResourceCycles = [2, 2, 2];
|
|
let NumMicroOps = 2;
|
|
}
|
|
def : InstRW<[JWriteVCVTYLd, ReadAfterLd], (instrs VCVTDQ2PDYrm, VCVTDQ2PSYrm,
|
|
VCVTPS2DQYrm, VCVTTPS2DQYrm)>;
|
|
|
|
def JWriteVMOVNTDQSt: SchedWriteRes<[JFPU1, JSTC, JSAGU]> {
|
|
let Latency = 2;
|
|
}
|
|
def : InstRW<[JWriteVMOVNTDQSt], (instrs MOVNTDQmr, VMOVNTDQmr)>;
|
|
|
|
def JWriteMOVNTSt: SchedWriteRes<[JFPU1, JSTC, JSAGU]> {
|
|
let Latency = 3;
|
|
}
|
|
def : InstRW<[JWriteMOVNTSt], (instrs MOVNTPDmr, MOVNTPSmr, MOVNTSD, MOVNTSS, VMOVNTPDmr, VMOVNTPSmr)>;
|
|
|
|
def JWriteVMOVNTPYSt: SchedWriteRes<[JFPU1, JSTC, JSAGU]> {
|
|
let Latency = 3;
|
|
let ResourceCycles = [2, 2, 2];
|
|
}
|
|
def : InstRW<[JWriteVMOVNTPYSt], (instrs VMOVNTDQYmr, VMOVNTPDYmr, VMOVNTPSYmr)>;
|
|
|
|
def JWriteVCVTPDY: SchedWriteRes<[JFPU1, JSTC, JFPX]> {
|
|
let Latency = 6;
|
|
let ResourceCycles = [2, 2, 4];
|
|
let NumMicroOps = 3;
|
|
}
|
|
def : InstRW<[JWriteVCVTPDY], (instrs VCVTPD2DQYrr, VCVTTPD2DQYrr, VCVTPD2PSYrr)>;
|
|
|
|
def JWriteVCVTPDYLd: SchedWriteRes<[JLAGU, JFPU1, JSTC, JFPX]> {
|
|
let Latency = 11;
|
|
let ResourceCycles = [2, 2, 2, 4];
|
|
let NumMicroOps = 3;
|
|
}
|
|
def : InstRW<[JWriteVCVTPDYLd, ReadAfterLd], (instrs VCVTPD2DQYrm, VCVTTPD2DQYrm, VCVTPD2PSYrm)>;
|
|
|
|
def JWriteVBROADCASTYLd: SchedWriteRes<[JLAGU, JFPU01, JFPX]> {
|
|
let Latency = 6;
|
|
let ResourceCycles = [1, 2, 4];
|
|
let NumMicroOps = 2;
|
|
}
|
|
def : InstRW<[JWriteVBROADCASTYLd, ReadAfterLd], (instrs VBROADCASTSDYrm,
|
|
VBROADCASTSSYrm)>;
|
|
|
|
def JWriteJVZEROALL: SchedWriteRes<[]> {
|
|
let Latency = 90;
|
|
let NumMicroOps = 73;
|
|
}
|
|
def : InstRW<[JWriteJVZEROALL], (instrs VZEROALL)>;
|
|
|
|
def JWriteJVZEROUPPER: SchedWriteRes<[]> {
|
|
let Latency = 46;
|
|
let NumMicroOps = 37;
|
|
}
|
|
def : InstRW<[JWriteJVZEROUPPER], (instrs VZEROUPPER)>;
|
|
} // SchedModel
|
|
|