xref: /netbsd-src/external/apache2/llvm/dist/llvm/lib/Target/X86/X86SchedSandyBridge.td (revision 82d56013d7b633d116a93943de88e08335357a7c)
1//=- X86SchedSandyBridge.td - X86 Sandy Bridge Scheduling ----*- tablegen -*-=//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the machine model for Sandy Bridge to support instruction
10// scheduling and other instruction cost heuristics.
11//
12// Note that we define some instructions here that are not supported by SNB,
13// but we still have to define them because SNB is the default subtarget for
14// X86. These instructions are tagged with a comment `Unsupported = 1`.
15//
16//===----------------------------------------------------------------------===//
17
18def SandyBridgeModel : SchedMachineModel {
19  // All x86 instructions are modeled as a single micro-op, and SB can decode 4
20  // instructions per cycle.
21  // FIXME: Identify instructions that aren't a single fused micro-op.
22  let IssueWidth = 4;
23  let MicroOpBufferSize = 168; // Based on the reorder buffer.
24  let LoadLatency = 5;
25  let MispredictPenalty = 16;
26
27  // Based on the LSD (loop-stream detector) queue size.
28  let LoopMicroOpBufferSize = 28;
29
30  // This flag is set to allow the scheduler to assign
31  // a default model to unrecognized opcodes.
32  let CompleteModel = 0;
33}
34
35let SchedModel = SandyBridgeModel in {
36
37// Sandy Bridge can issue micro-ops to 6 different ports in one cycle.
38
39// Ports 0, 1, and 5 handle all computation.
40def SBPort0 : ProcResource<1>;
41def SBPort1 : ProcResource<1>;
42def SBPort5 : ProcResource<1>;
43
44// Ports 2 and 3 are identical. They handle loads and the address half of
45// stores.
46def SBPort23 : ProcResource<2>;
47
48// Port 4 gets the data half of stores. Store data can be available later than
49// the store address, but since we don't model the latency of stores, we can
50// ignore that.
51def SBPort4 : ProcResource<1>;
52
53// Many micro-ops are capable of issuing on multiple ports.
54def SBPort01  : ProcResGroup<[SBPort0, SBPort1]>;
55def SBPort05  : ProcResGroup<[SBPort0, SBPort5]>;
56def SBPort15  : ProcResGroup<[SBPort1, SBPort5]>;
57def SBPort015 : ProcResGroup<[SBPort0, SBPort1, SBPort5]>;
58
59// 54 Entry Unified Scheduler
60def SBPortAny : ProcResGroup<[SBPort0, SBPort1, SBPort23, SBPort4, SBPort5]> {
61  let BufferSize=54;
62}
63
64// Integer division issued on port 0.
65def SBDivider : ProcResource<1>;
66// FP division and sqrt on port 0.
67def SBFPDivider : ProcResource<1>;
68
69// Integer loads are 5 cycles, so ReadAfterLd registers needn't be available until 5
70// cycles after the memory operand.
71def : ReadAdvance<ReadAfterLd, 5>;
72
73// Vector loads are 5/6/7 cycles, so ReadAfterVec*Ld registers needn't be available
74// until 5/6/7 cycles after the memory operand.
75def : ReadAdvance<ReadAfterVecLd, 5>;
76def : ReadAdvance<ReadAfterVecXLd, 6>;
77def : ReadAdvance<ReadAfterVecYLd, 7>;
78
79def : ReadAdvance<ReadInt2Fpu, 0>;
80
81// Many SchedWrites are defined in pairs with and without a folded load.
82// Instructions with folded loads are usually micro-fused, so they only appear
83// as two micro-ops when queued in the reservation station.
84// This multiclass defines the resource usage for variants with and without
85// folded loads.
86multiclass SBWriteResPair<X86FoldableSchedWrite SchedRW,
87                          list<ProcResourceKind> ExePorts,
88                          int Lat, list<int> Res = [1], int UOps = 1,
89                          int LoadLat = 5> {
90  // Register variant is using a single cycle on ExePort.
91  def : WriteRes<SchedRW, ExePorts> {
92    let Latency = Lat;
93    let ResourceCycles = Res;
94    let NumMicroOps = UOps;
95  }
96
97  // Memory variant also uses a cycle on port 2/3 and adds LoadLat cycles to
98  // the latency (default = 5).
99  def : WriteRes<SchedRW.Folded, !listconcat([SBPort23], ExePorts)> {
100    let Latency = !add(Lat, LoadLat);
101    let ResourceCycles = !listconcat([1], Res);
102    let NumMicroOps = !add(UOps, 1);
103  }
104}
105
106// A folded store needs a cycle on port 4 for the store data, and an extra port
107// 2/3 cycle to recompute the address.
108def : WriteRes<WriteRMW, [SBPort23,SBPort4]>;
109
110def : WriteRes<WriteStore,   [SBPort23, SBPort4]>;
111def : WriteRes<WriteStoreNT, [SBPort23, SBPort4]>;
112def : WriteRes<WriteLoad,    [SBPort23]> { let Latency = 5; }
113def : WriteRes<WriteMove,    [SBPort015]>;
114def : WriteRes<WriteZero,    []>;
115
116// Arithmetic.
117defm : SBWriteResPair<WriteALU,    [SBPort015], 1>;
118defm : SBWriteResPair<WriteADC,    [SBPort05,SBPort015], 2, [1,1], 2>;
119
120defm : SBWriteResPair<WriteIMul8,     [SBPort1],   3>;
121defm : SBWriteResPair<WriteIMul16,    [SBPort1,SBPort05,SBPort015], 4, [1,1,2], 4>;
122defm : X86WriteRes<WriteIMul16Imm,    [SBPort1,SBPort015], 4, [1,1], 2>;
123defm : X86WriteRes<WriteIMul16ImmLd,  [SBPort1,SBPort015,SBPort23], 8, [1,1,1], 3>;
124defm : SBWriteResPair<WriteIMul16Reg, [SBPort1],   3>;
125defm : SBWriteResPair<WriteIMul32,    [SBPort1,SBPort05,SBPort015], 4, [1,1,1], 3>;
126defm : SBWriteResPair<WriteIMul32Imm, [SBPort1],   3>;
127defm : SBWriteResPair<WriteIMul32Reg, [SBPort1],   3>;
128defm : SBWriteResPair<WriteIMul64,    [SBPort1,SBPort0], 4, [1,1], 2>;
129defm : SBWriteResPair<WriteIMul64Imm, [SBPort1],   3>;
130defm : SBWriteResPair<WriteIMul64Reg, [SBPort1],   3>;
131def  : WriteRes<WriteIMulH, []> { let Latency = 3; }
132
133defm : X86WriteRes<WriteXCHG,      [SBPort015], 2, [3], 3>;
134defm : X86WriteRes<WriteBSWAP32,   [SBPort1], 1, [1], 1>;
135defm : X86WriteRes<WriteBSWAP64,   [SBPort1, SBPort05], 2, [1,1], 2>;
136defm : X86WriteRes<WriteCMPXCHG,   [SBPort05, SBPort015], 5, [1,3], 4>;
137defm : X86WriteRes<WriteCMPXCHGRMW,[SBPort015, SBPort5, SBPort23, SBPort4], 8, [1, 2, 2, 1], 6>;
138
139defm : SBWriteResPair<WriteDiv8,   [SBPort0, SBDivider], 25, [1, 10]>;
140defm : SBWriteResPair<WriteDiv16,  [SBPort0, SBDivider], 25, [1, 10]>;
141defm : SBWriteResPair<WriteDiv32,  [SBPort0, SBDivider], 25, [1, 10]>;
142defm : SBWriteResPair<WriteDiv64,  [SBPort0, SBDivider], 25, [1, 10]>;
143defm : SBWriteResPair<WriteIDiv8,  [SBPort0, SBDivider], 25, [1, 10]>;
144defm : SBWriteResPair<WriteIDiv16, [SBPort0, SBDivider], 25, [1, 10]>;
145defm : SBWriteResPair<WriteIDiv32, [SBPort0, SBDivider], 25, [1, 10]>;
146defm : SBWriteResPair<WriteIDiv64, [SBPort0, SBDivider], 25, [1, 10]>;
147
148// SHLD/SHRD.
149defm : X86WriteRes<WriteSHDrri, [SBPort05, SBPort015], 2, [1, 1], 2>;
150defm : X86WriteRes<WriteSHDrrcl,[SBPort05, SBPort015], 4, [3, 1], 4>;
151defm : X86WriteRes<WriteSHDmri, [SBPort4,SBPort23,SBPort05,SBPort015], 8, [1, 2, 1, 1], 5>;
152defm : X86WriteRes<WriteSHDmrcl,[SBPort4,SBPort23,SBPort05,SBPort015], 10, [1, 2, 3, 1], 7>;
153
154defm : SBWriteResPair<WriteShift,    [SBPort05],  1>;
155defm : SBWriteResPair<WriteShiftCL,  [SBPort05],  3, [3], 3>;
156defm : SBWriteResPair<WriteRotate,   [SBPort05],  2, [2], 2>;
157defm : SBWriteResPair<WriteRotateCL, [SBPort05],  3, [3], 3>;
158
159defm : SBWriteResPair<WriteJump,  [SBPort5],   1>;
160defm : SBWriteResPair<WriteCRC32, [SBPort1],   3, [1], 1, 5>;
161
162defm : SBWriteResPair<WriteCMOV,  [SBPort05,SBPort015], 2, [1,1], 2>; // Conditional move.
163defm : X86WriteRes<WriteFCMOV, [SBPort5,SBPort05], 3, [2,1], 3>; // x87 conditional move.
164def  : WriteRes<WriteSETCC, [SBPort05]>; // Setcc.
165def  : WriteRes<WriteSETCCStore, [SBPort05,SBPort4,SBPort23]> {
166  let Latency = 2;
167  let NumMicroOps = 3;
168}
169
170defm : X86WriteRes<WriteLAHFSAHF,        [SBPort05], 1, [1], 1>;
171defm : X86WriteRes<WriteBitTest,         [SBPort05], 1, [1], 1>;
172defm : X86WriteRes<WriteBitTestImmLd,    [SBPort05,SBPort23], 6, [1,1], 2>;
173//defm : X86WriteRes<WriteBitTestRegLd,    [SBPort05,SBPort23], 6, [1,1], 2>;
174defm : X86WriteRes<WriteBitTestSet,      [SBPort05], 1, [1], 1>;
175defm : X86WriteRes<WriteBitTestSetImmLd, [SBPort05,SBPort23], 6, [1,1], 3>;
176defm : X86WriteRes<WriteBitTestSetRegLd, [SBPort05,SBPort23,SBPort5,SBPort015], 8, [1,1,1,1], 5>;
177
178// This is for simple LEAs with one or two input operands.
179// The complex ones can only execute on port 1, and they require two cycles on
180// the port to read all inputs. We don't model that.
181def : WriteRes<WriteLEA, [SBPort01]>;
182
183// Bit counts.
184defm : SBWriteResPair<WriteBSF, [SBPort1], 3, [1], 1, 5>;
185defm : SBWriteResPair<WriteBSR, [SBPort1], 3, [1], 1, 5>;
186defm : SBWriteResPair<WriteLZCNT,          [SBPort1], 3, [1], 1, 5>;
187defm : SBWriteResPair<WriteTZCNT,          [SBPort1], 3, [1], 1, 5>;
188defm : SBWriteResPair<WritePOPCNT,         [SBPort1], 3, [1], 1, 6>;
189
190// BMI1 BEXTR/BLS, BMI2 BZHI
191// NOTE: These don't exist on Sandy Bridge. Ports are guesses.
192defm : SBWriteResPair<WriteBEXTR, [SBPort05,SBPort1], 2, [1,1], 2>;
193defm : SBWriteResPair<WriteBLS,   [SBPort015], 1>;
194defm : SBWriteResPair<WriteBZHI,  [SBPort1], 1>;
195
196// Scalar and vector floating point.
197defm : X86WriteRes<WriteFLD0,          [SBPort5], 1, [1], 1>;
198defm : X86WriteRes<WriteFLD1,          [SBPort0,SBPort5], 1, [1,1], 2>;
199defm : X86WriteRes<WriteFLDC,          [SBPort0,SBPort1], 1, [1,1], 2>;
200defm : X86WriteRes<WriteFLoad,         [SBPort23], 5, [1], 1>;
201defm : X86WriteRes<WriteFLoadX,        [SBPort23], 6, [1], 1>;
202defm : X86WriteRes<WriteFLoadY,        [SBPort23], 7, [1], 1>;
203defm : X86WriteRes<WriteFMaskedLoad,   [SBPort23,SBPort05], 8, [1,2], 3>;
204defm : X86WriteRes<WriteFMaskedLoadY,  [SBPort23,SBPort05], 9, [1,2], 3>;
205defm : X86WriteRes<WriteFStore,        [SBPort23,SBPort4], 1, [1,1], 1>;
206defm : X86WriteRes<WriteFStoreX,       [SBPort23,SBPort4], 1, [1,1], 1>;
207defm : X86WriteRes<WriteFStoreY,       [SBPort23,SBPort4], 1, [1,1], 1>;
208defm : X86WriteRes<WriteFStoreNT,      [SBPort23,SBPort4], 1, [1,1], 1>;
209defm : X86WriteRes<WriteFStoreNTX,     [SBPort23,SBPort4], 1, [1,1], 1>;
210defm : X86WriteRes<WriteFStoreNTY,     [SBPort23,SBPort4], 1, [1,1], 1>;
211
212defm : X86WriteRes<WriteFMaskedStore32,  [SBPort4,SBPort01,SBPort23], 5, [1,1,1], 3>;
213defm : X86WriteRes<WriteFMaskedStore32Y, [SBPort4,SBPort01,SBPort23], 5, [1,1,1], 3>;
214defm : X86WriteRes<WriteFMaskedStore64,  [SBPort4,SBPort01,SBPort23], 5, [1,1,1], 3>;
215defm : X86WriteRes<WriteFMaskedStore64Y, [SBPort4,SBPort01,SBPort23], 5, [1,1,1], 3>;
216
217defm : X86WriteRes<WriteFMove,         [SBPort5], 1, [1], 1>;
218defm : X86WriteRes<WriteFMoveX,        [SBPort5], 1, [1], 1>;
219defm : X86WriteRes<WriteFMoveY,        [SBPort5], 1, [1], 1>;
220defm : X86WriteRes<WriteEMMS,          [SBPort015], 31, [31], 31>;
221
222defm : SBWriteResPair<WriteFAdd,    [SBPort1],  3, [1], 1, 6>;
223defm : SBWriteResPair<WriteFAddX,   [SBPort1],  3, [1], 1, 6>;
224defm : SBWriteResPair<WriteFAddY,   [SBPort1],  3, [1], 1, 7>;
225defm : SBWriteResPair<WriteFAddZ,   [SBPort1],  3, [1], 1, 7>; // Unsupported = 1
226defm : SBWriteResPair<WriteFAdd64,  [SBPort1],  3, [1], 1, 6>;
227defm : SBWriteResPair<WriteFAdd64X, [SBPort1],  3, [1], 1, 6>;
228defm : SBWriteResPair<WriteFAdd64Y, [SBPort1],  3, [1], 1, 7>;
229defm : SBWriteResPair<WriteFAdd64Z, [SBPort1],  3, [1], 1, 7>; // Unsupported = 1
230
231defm : SBWriteResPair<WriteFCmp,    [SBPort1],  3, [1], 1, 6>;
232defm : SBWriteResPair<WriteFCmpX,   [SBPort1],  3, [1], 1, 6>;
233defm : SBWriteResPair<WriteFCmpY,   [SBPort1],  3, [1], 1, 7>;
234defm : SBWriteResPair<WriteFCmpZ,   [SBPort1],  3, [1], 1, 7>; // Unsupported = 1
235defm : SBWriteResPair<WriteFCmp64,  [SBPort1],  3, [1], 1, 6>;
236defm : SBWriteResPair<WriteFCmp64X, [SBPort1],  3, [1], 1, 6>;
237defm : SBWriteResPair<WriteFCmp64Y, [SBPort1],  3, [1], 1, 7>;
238defm : SBWriteResPair<WriteFCmp64Z, [SBPort1],  3, [1], 1, 7>; // Unsupported = 1
239
240defm : SBWriteResPair<WriteFCom,    [SBPort1],  3>;
241defm : SBWriteResPair<WriteFComX,   [SBPort1],  3>;
242
243defm : SBWriteResPair<WriteFMul,    [SBPort0],  5, [1], 1, 6>;
244defm : SBWriteResPair<WriteFMulX,   [SBPort0],  5, [1], 1, 6>;
245defm : SBWriteResPair<WriteFMulY,   [SBPort0],  5, [1], 1, 7>;
246defm : SBWriteResPair<WriteFMulZ,   [SBPort0],  5, [1], 1, 7>; // Unsupported = 1
247defm : SBWriteResPair<WriteFMul64,  [SBPort0],  5, [1], 1, 6>;
248defm : SBWriteResPair<WriteFMul64X, [SBPort0],  5, [1], 1, 6>;
249defm : SBWriteResPair<WriteFMul64Y, [SBPort0],  5, [1], 1, 7>;
250defm : SBWriteResPair<WriteFMul64Z, [SBPort0],  5, [1], 1, 7>; // Unsupported = 1
251
252defm : SBWriteResPair<WriteFDiv,    [SBPort0,SBFPDivider], 14, [1,14], 1, 6>;
253defm : SBWriteResPair<WriteFDivX,   [SBPort0,SBFPDivider], 14, [1,14], 1, 6>;
254defm : SBWriteResPair<WriteFDivY,   [SBPort0,SBPort05,SBFPDivider], 29, [2,1,28], 3, 7>;
255defm : SBWriteResPair<WriteFDivZ,   [SBPort0,SBPort05,SBFPDivider], 29, [2,1,28], 3, 7>; // Unsupported = 1
256defm : SBWriteResPair<WriteFDiv64,  [SBPort0,SBFPDivider], 22, [1,22], 1, 6>;
257defm : SBWriteResPair<WriteFDiv64X, [SBPort0,SBFPDivider], 22, [1,22], 1, 6>;
258defm : SBWriteResPair<WriteFDiv64Y, [SBPort0,SBPort05,SBFPDivider], 45, [2,1,44], 3, 7>;
259defm : SBWriteResPair<WriteFDiv64Z, [SBPort0,SBPort05,SBFPDivider], 45, [2,1,44], 3, 7>; // Unsupported = 1
260
261defm : SBWriteResPair<WriteFRcp,   [SBPort0],  5, [1], 1, 6>;
262defm : SBWriteResPair<WriteFRcpX,  [SBPort0],  5, [1], 1, 6>;
263defm : SBWriteResPair<WriteFRcpY,  [SBPort0,SBPort05],  7, [2,1], 3, 7>;
264defm : SBWriteResPair<WriteFRcpZ,  [SBPort0,SBPort05],  7, [2,1], 3, 7>; // Unsupported = 1
265
266defm : SBWriteResPair<WriteFRsqrt, [SBPort0],  5, [1], 1, 6>;
267defm : SBWriteResPair<WriteFRsqrtX,[SBPort0],  5, [1], 1, 6>;
268defm : SBWriteResPair<WriteFRsqrtY,[SBPort0,SBPort05],  7, [2,1], 3, 7>;
269defm : SBWriteResPair<WriteFRsqrtZ,[SBPort0,SBPort05],  7, [2,1], 3, 7>; // Unsupported = 1
270
271defm : SBWriteResPair<WriteFSqrt,    [SBPort0,SBFPDivider], 14, [1,14], 1, 6>;
272defm : SBWriteResPair<WriteFSqrtX,   [SBPort0,SBFPDivider], 14, [1,14], 1, 6>;
273defm : SBWriteResPair<WriteFSqrtY,   [SBPort0,SBPort05,SBFPDivider], 29, [2,1,28], 3, 7>;
274defm : SBWriteResPair<WriteFSqrtZ,   [SBPort0,SBPort05,SBFPDivider], 29, [2,1,28], 3, 7>; // Unsupported = 1
275defm : SBWriteResPair<WriteFSqrt64,  [SBPort0,SBFPDivider], 21, [1,21], 1, 6>;
276defm : SBWriteResPair<WriteFSqrt64X, [SBPort0,SBFPDivider], 21, [1,21], 1, 6>;
277defm : SBWriteResPair<WriteFSqrt64Y, [SBPort0,SBPort05,SBFPDivider], 45, [2,1,44], 3, 7>;
278defm : SBWriteResPair<WriteFSqrt64Z, [SBPort0,SBPort05,SBFPDivider], 45, [2,1,44], 3, 7>; // Unsupported = 1
279defm : SBWriteResPair<WriteFSqrt80,  [SBPort0,SBFPDivider], 24, [1,24], 1, 6>;
280
281defm : SBWriteResPair<WriteDPPD,   [SBPort0,SBPort1,SBPort5],  9, [1,1,1], 3, 6>;
282defm : SBWriteResPair<WriteDPPS,   [SBPort0,SBPort1,SBPort5], 12, [1,2,1], 4, 6>;
283defm : SBWriteResPair<WriteDPPSY,  [SBPort0,SBPort1,SBPort5], 12, [1,2,1], 4, 7>;
284defm : SBWriteResPair<WriteDPPSZ,  [SBPort0,SBPort1,SBPort5], 12, [1,2,1], 4, 7>; // Unsupported = 1
285defm : SBWriteResPair<WriteFSign,    [SBPort5], 1>;
286defm : SBWriteResPair<WriteFRnd,     [SBPort1], 3, [1], 1, 6>;
287defm : SBWriteResPair<WriteFRndY,    [SBPort1], 3, [1], 1, 7>;
288defm : SBWriteResPair<WriteFRndZ,    [SBPort1], 3, [1], 1, 7>; // Unsupported = 1
289defm : SBWriteResPair<WriteFLogic,   [SBPort5], 1, [1], 1, 6>;
290defm : SBWriteResPair<WriteFLogicY,  [SBPort5], 1, [1], 1, 7>;
291defm : SBWriteResPair<WriteFLogicZ,  [SBPort5], 1, [1], 1, 7>; // Unsupported = 1
292defm : SBWriteResPair<WriteFTest,    [SBPort0], 1, [1], 1, 6>;
293defm : SBWriteResPair<WriteFTestY,   [SBPort0], 1, [1], 1, 7>;
294defm : SBWriteResPair<WriteFTestZ,   [SBPort0], 1, [1], 1, 7>; // Unsupported = 1
295defm : SBWriteResPair<WriteFShuffle, [SBPort5], 1, [1], 1, 6>;
296defm : SBWriteResPair<WriteFShuffleY,[SBPort5], 1, [1], 1, 7>;
297defm : SBWriteResPair<WriteFShuffleZ,[SBPort5], 1, [1], 1, 7>; // Unsupported = 1
298defm : SBWriteResPair<WriteFVarShuffle, [SBPort5], 1, [1], 1, 6>;
299defm : SBWriteResPair<WriteFVarShuffleY,[SBPort5], 1, [1], 1, 7>;
300defm : SBWriteResPair<WriteFVarShuffleZ,[SBPort5], 1, [1], 1, 7>; // Unsupported = 1
301defm : SBWriteResPair<WriteFBlend,    [SBPort05], 1, [1], 1, 6>;
302defm : SBWriteResPair<WriteFBlendY,   [SBPort05], 1, [1], 1, 7>;
303defm : SBWriteResPair<WriteFBlendZ,   [SBPort05], 1, [1], 1, 7>; // Unsupported = 1
304defm : SBWriteResPair<WriteFVarBlend, [SBPort05], 2, [2], 2, 6>;
305defm : SBWriteResPair<WriteFVarBlendY,[SBPort05], 2, [2], 2, 7>;
306defm : SBWriteResPair<WriteFVarBlendZ,[SBPort05], 2, [2], 2, 7>; // Unsupported = 1
307
308// Conversion between integer and float.
309defm : SBWriteResPair<WriteCvtSS2I,   [SBPort0,SBPort1], 5, [1,1], 2>;
310defm : SBWriteResPair<WriteCvtPS2I,           [SBPort1], 3, [1], 1, 6>;
311defm : SBWriteResPair<WriteCvtPS2IY,          [SBPort1], 3, [1], 1, 7>;
312defm : SBWriteResPair<WriteCvtPS2IZ,          [SBPort1], 3, [1], 1, 7>; // Unsupported = 1
313defm : SBWriteResPair<WriteCvtSD2I,   [SBPort0,SBPort1], 5, [1,1], 2>;
314defm : SBWriteResPair<WriteCvtPD2I,   [SBPort1,SBPort5], 4, [1,1], 2, 6>;
315defm : X86WriteRes<WriteCvtPD2IY,     [SBPort1,SBPort5], 4, [1,1], 2>;
316defm : X86WriteRes<WriteCvtPD2IZ,     [SBPort1,SBPort5], 4, [1,1], 2>; // Unsupported = 1
317defm : X86WriteRes<WriteCvtPD2IYLd,   [SBPort1,SBPort5,SBPort23], 11, [1,1,1], 3>;
318defm : X86WriteRes<WriteCvtPD2IZLd,   [SBPort1,SBPort5,SBPort23], 11, [1,1,1], 3>; // Unsupported = 1
319
320defm : X86WriteRes<WriteCvtI2SS,      [SBPort1,SBPort5],  5, [1,2], 3>;
321defm : X86WriteRes<WriteCvtI2SSLd,    [SBPort1,SBPort5,SBPort23], 10, [1,1,1], 3>;
322defm : SBWriteResPair<WriteCvtI2PS,           [SBPort1],  3, [1], 1, 6>;
323defm : SBWriteResPair<WriteCvtI2PSY,          [SBPort1],  3, [1], 1, 7>;
324defm : SBWriteResPair<WriteCvtI2PSZ,          [SBPort1],  3, [1], 1, 7>; // Unsupported = 1
325defm : X86WriteRes<WriteCvtI2SD,      [SBPort1,SBPort5],  4, [1,1], 2>;
326defm : X86WriteRes<WriteCvtI2PD,      [SBPort1,SBPort5],  4, [1,1], 2>;
327defm : X86WriteRes<WriteCvtI2PDY,     [SBPort1,SBPort5],  4, [1,1], 2>;
328defm : X86WriteRes<WriteCvtI2PDZ,     [SBPort1,SBPort5],  4, [1,1], 2>; // Unsupported = 1
329defm : X86WriteRes<WriteCvtI2SDLd,   [SBPort1,SBPort23],  9, [1,1], 2>;
330defm : X86WriteRes<WriteCvtI2PDLd,   [SBPort1,SBPort5,SBPort23], 10, [1,1,1], 3>;
331defm : X86WriteRes<WriteCvtI2PDYLd,  [SBPort1,SBPort5,SBPort23], 10, [1,1,1], 3>;
332defm : X86WriteRes<WriteCvtI2PDZLd,  [SBPort1,SBPort5,SBPort23], 10, [1,1,1], 3>; // Unsupported = 1
333
334defm : SBWriteResPair<WriteCvtSS2SD,  [SBPort0], 1, [1], 1, 6>;
335defm : X86WriteRes<WriteCvtPS2PD,     [SBPort0,SBPort5], 2, [1,1], 2>;
336defm : X86WriteRes<WriteCvtPS2PDY,    [SBPort0,SBPort5], 2, [1,1], 2>;
337defm : X86WriteRes<WriteCvtPS2PDZ,    [SBPort0,SBPort5], 2, [1,1], 2>; // Unsupported = 1
338defm : X86WriteRes<WriteCvtPS2PDLd,  [SBPort0,SBPort23], 7, [1,1], 2>;
339defm : X86WriteRes<WriteCvtPS2PDYLd, [SBPort0,SBPort23], 7, [1,1], 2>;
340defm : X86WriteRes<WriteCvtPS2PDZLd, [SBPort0,SBPort23], 7, [1,1], 2>; // Unsupported = 1
341defm : SBWriteResPair<WriteCvtSD2SS,  [SBPort1,SBPort5], 4, [1,1], 2, 6>;
342defm : SBWriteResPair<WriteCvtPD2PS,  [SBPort1,SBPort5], 4, [1,1], 2, 6>;
343defm : SBWriteResPair<WriteCvtPD2PSY, [SBPort1,SBPort5], 4, [1,1], 2, 7>;
344defm : SBWriteResPair<WriteCvtPD2PSZ, [SBPort1,SBPort5], 4, [1,1], 2, 7>; // Unsupported = 1
345
346defm : SBWriteResPair<WriteCvtPH2PS,  [SBPort1], 3>;
347defm : SBWriteResPair<WriteCvtPH2PSY, [SBPort1], 3>;
348defm : SBWriteResPair<WriteCvtPH2PSZ, [SBPort1], 3>; // Unsupported = 1
349
350defm : X86WriteRes<WriteCvtPS2PH,    [SBPort1], 3, [1], 1>;
351defm : X86WriteRes<WriteCvtPS2PHY,   [SBPort1], 3, [1], 1>;
352defm : X86WriteRes<WriteCvtPS2PHZ,   [SBPort1], 3, [1], 1>; // Unsupported = 1
353defm : X86WriteRes<WriteCvtPS2PHSt,  [SBPort1, SBPort23, SBPort4], 4, [1,1,1], 1>;
354defm : X86WriteRes<WriteCvtPS2PHYSt, [SBPort1, SBPort23, SBPort4], 4, [1,1,1], 1>;
355defm : X86WriteRes<WriteCvtPS2PHZSt, [SBPort1, SBPort23, SBPort4], 4, [1,1,1], 1>; // Unsupported = 1
356
357// Vector integer operations.
358defm : X86WriteRes<WriteVecLoad,         [SBPort23], 5, [1], 1>;
359defm : X86WriteRes<WriteVecLoadX,        [SBPort23], 6, [1], 1>;
360defm : X86WriteRes<WriteVecLoadY,        [SBPort23], 7, [1], 1>;
361defm : X86WriteRes<WriteVecLoadNT,       [SBPort23], 6, [1], 1>;
362defm : X86WriteRes<WriteVecLoadNTY,      [SBPort23], 7, [1], 1>;
363defm : X86WriteRes<WriteVecMaskedLoad,   [SBPort23,SBPort05], 8, [1,2], 3>;
364defm : X86WriteRes<WriteVecMaskedLoadY,  [SBPort23,SBPort05], 9, [1,2], 3>;
365defm : X86WriteRes<WriteVecStore,        [SBPort23,SBPort4], 1, [1,1], 1>;
366defm : X86WriteRes<WriteVecStoreX,       [SBPort23,SBPort4], 1, [1,1], 1>;
367defm : X86WriteRes<WriteVecStoreY,       [SBPort23,SBPort4], 1, [1,1], 1>;
368defm : X86WriteRes<WriteVecStoreNT,      [SBPort23,SBPort4], 1, [1,1], 1>;
369defm : X86WriteRes<WriteVecStoreNTY,     [SBPort23,SBPort4], 1, [1,1], 1>;
370defm : X86WriteRes<WriteVecMaskedStore32,  [SBPort4,SBPort01,SBPort23], 5, [1,1,1], 3>;
371defm : X86WriteRes<WriteVecMaskedStore32Y, [SBPort4,SBPort01,SBPort23], 5, [1,1,1], 3>;
372defm : X86WriteRes<WriteVecMaskedStore64,  [SBPort4,SBPort01,SBPort23], 5, [1,1,1], 3>;
373defm : X86WriteRes<WriteVecMaskedStore64Y, [SBPort4,SBPort01,SBPort23], 5, [1,1,1], 3>;
374defm : X86WriteRes<WriteVecMove,         [SBPort05], 1, [1], 1>;
375defm : X86WriteRes<WriteVecMoveX,        [SBPort015], 1, [1], 1>;
376defm : X86WriteRes<WriteVecMoveY,        [SBPort05], 1, [1], 1>;
377defm : X86WriteRes<WriteVecMoveToGpr,    [SBPort0], 2, [1], 1>;
378defm : X86WriteRes<WriteVecMoveFromGpr,  [SBPort5], 1, [1], 1>;
379
380defm : SBWriteResPair<WriteVecLogic, [SBPort015], 1, [1], 1, 5>;
381defm : SBWriteResPair<WriteVecLogicX,[SBPort015], 1, [1], 1, 6>;
382defm : SBWriteResPair<WriteVecLogicY,[SBPort015], 1, [1], 1, 7>;
383defm : SBWriteResPair<WriteVecLogicZ,[SBPort015], 1, [1], 1, 7>; // Unsupported = 1
384defm : SBWriteResPair<WriteVecTest,  [SBPort0,SBPort5], 2, [1,1], 2, 6>;
385defm : SBWriteResPair<WriteVecTestY, [SBPort0,SBPort5], 2, [1,1], 2, 7>;
386defm : SBWriteResPair<WriteVecTestZ, [SBPort0,SBPort5], 2, [1,1], 2, 7>; // Unsupported = 1
387defm : SBWriteResPair<WriteVecALU,   [SBPort1],  3, [1], 1, 5>;
388defm : SBWriteResPair<WriteVecALUX,  [SBPort15], 1, [1], 1, 6>;
389defm : SBWriteResPair<WriteVecALUY,  [SBPort15], 1, [1], 1, 7>;
390defm : SBWriteResPair<WriteVecALUZ,  [SBPort15], 1, [1], 1, 7>; // Unsupported = 1
391defm : SBWriteResPair<WriteVecIMul,  [SBPort0], 5, [1], 1, 5>;
392defm : SBWriteResPair<WriteVecIMulX, [SBPort0], 5, [1], 1, 6>;
393defm : SBWriteResPair<WriteVecIMulY, [SBPort0], 5, [1], 1, 7>;
394defm : SBWriteResPair<WriteVecIMulZ, [SBPort0], 5, [1], 1, 7>; // Unsupported = 1
395defm : SBWriteResPair<WritePMULLD,   [SBPort0], 5, [1], 1, 6>;
396defm : SBWriteResPair<WritePMULLDY,  [SBPort0], 5, [1], 1, 7>; // TODO this is probably wrong for 256/512-bit for the "generic" model
397defm : SBWriteResPair<WritePMULLDZ,  [SBPort0], 5, [1], 1, 7>;  // Unsupported = 1
398defm : SBWriteResPair<WriteShuffle,  [SBPort5], 1, [1], 1, 5>;
399defm : SBWriteResPair<WriteShuffleX, [SBPort15], 1, [1], 1, 6>;
400defm : SBWriteResPair<WriteShuffleY, [SBPort5], 1, [1], 1, 7>;
401defm : SBWriteResPair<WriteShuffleZ, [SBPort5], 1, [1], 1, 7>; // Unsupported = 1
402defm : SBWriteResPair<WriteVarShuffle,  [SBPort15], 1, [1], 1, 5>;
403defm : SBWriteResPair<WriteVarShuffleX, [SBPort15], 1, [1], 1, 6>;
404defm : SBWriteResPair<WriteVarShuffleY, [SBPort15], 1, [1], 1, 7>;
405defm : SBWriteResPair<WriteVarShuffleZ, [SBPort15], 1, [1], 1, 7>; // Unsupported = 1
406defm : SBWriteResPair<WriteBlend,   [SBPort15], 1, [1], 1, 6>;
407defm : SBWriteResPair<WriteBlendY,  [SBPort15], 1, [1], 1, 7>;
408defm : SBWriteResPair<WriteBlendZ,  [SBPort15], 1, [1], 1, 7>; // Unsupported = 1
409defm : SBWriteResPair<WriteVarBlend, [SBPort15], 2, [2], 2, 6>;
410defm : SBWriteResPair<WriteVarBlendY,[SBPort15], 2, [2], 2, 7>;
411defm : SBWriteResPair<WriteVarBlendZ,[SBPort15], 2, [2], 2, 7>; // Unsupported = 1
412defm : SBWriteResPair<WriteMPSAD,  [SBPort0, SBPort15], 7, [1,2], 3, 6>;
413defm : SBWriteResPair<WriteMPSADY, [SBPort0, SBPort15], 7, [1,2], 3, 7>;
414defm : SBWriteResPair<WriteMPSADZ, [SBPort0, SBPort15], 7, [1,2], 3, 7>; // Unsupported = 1
415defm : SBWriteResPair<WritePSADBW,  [SBPort0], 5, [1], 1, 5>;
416defm : SBWriteResPair<WritePSADBWX, [SBPort0], 5, [1], 1, 6>;
417defm : SBWriteResPair<WritePSADBWY, [SBPort0], 5, [1], 1, 7>;
418defm : SBWriteResPair<WritePSADBWZ, [SBPort0], 5, [1], 1, 7>; // Unsupported = 1
419defm : SBWriteResPair<WritePHMINPOS,  [SBPort0], 5, [1], 1, 6>;
420
421// Vector integer shifts.
422defm : SBWriteResPair<WriteVecShift,     [SBPort5], 1, [1], 1, 5>;
423defm : SBWriteResPair<WriteVecShiftX,    [SBPort0,SBPort15], 2, [1,1], 2, 6>;
424defm : SBWriteResPair<WriteVecShiftY,    [SBPort0,SBPort15], 4, [1,1], 2, 7>;
425defm : SBWriteResPair<WriteVecShiftZ,    [SBPort0,SBPort15], 4, [1,1], 2, 7>; // Unsupported = 1
426defm : SBWriteResPair<WriteVecShiftImm,  [SBPort5], 1, [1], 1, 5>;
427defm : SBWriteResPair<WriteVecShiftImmX, [SBPort0], 1, [1], 1, 6>;
428defm : SBWriteResPair<WriteVecShiftImmY, [SBPort0], 1, [1], 1, 7>;
429defm : SBWriteResPair<WriteVecShiftImmZ, [SBPort0], 1, [1], 1, 7>; // Unsupported = 1
430defm : SBWriteResPair<WriteVarVecShift,  [SBPort0], 1, [1], 1, 6>;
431defm : SBWriteResPair<WriteVarVecShiftY, [SBPort0], 1, [1], 1, 7>;
432defm : SBWriteResPair<WriteVarVecShiftZ, [SBPort0], 1, [1], 1, 7>; // Unsupported = 1
433
434// Vector insert/extract operations.
435def : WriteRes<WriteVecInsert, [SBPort5,SBPort15]> {
436  let Latency = 2;
437  let NumMicroOps = 2;
438}
439def : WriteRes<WriteVecInsertLd, [SBPort23,SBPort15]> {
440  let Latency = 7;
441  let NumMicroOps = 2;
442}
443
444def : WriteRes<WriteVecExtract, [SBPort0,SBPort15]> {
445  let Latency = 3;
446  let NumMicroOps = 2;
447}
448def : WriteRes<WriteVecExtractSt, [SBPort4,SBPort23,SBPort15]> {
449  let Latency = 5;
450  let NumMicroOps = 3;
451}
452
453////////////////////////////////////////////////////////////////////////////////
454// Horizontal add/sub  instructions.
455////////////////////////////////////////////////////////////////////////////////
456
457defm : SBWriteResPair<WriteFHAdd,  [SBPort1,SBPort5], 5, [1,2], 3, 6>;
458defm : SBWriteResPair<WriteFHAddY, [SBPort1,SBPort5], 5, [1,2], 3, 7>;
459defm : SBWriteResPair<WriteFHAddZ, [SBPort1,SBPort5], 5, [1,2], 3, 7>; // Unsupported = 1
460defm : SBWriteResPair<WritePHAdd,  [SBPort15], 3, [3], 3, 5>;
461defm : SBWriteResPair<WritePHAddX, [SBPort15], 3, [3], 3, 6>;
462defm : SBWriteResPair<WritePHAddY, [SBPort15], 3, [3], 3, 7>;
463defm : SBWriteResPair<WritePHAddZ, [SBPort15], 3, [3], 3, 7>; // Unsupported = 1
464
465////////////////////////////////////////////////////////////////////////////////
466// String instructions.
467////////////////////////////////////////////////////////////////////////////////
468
469// Packed Compare Implicit Length Strings, Return Mask
470def : WriteRes<WritePCmpIStrM, [SBPort0]> {
471  let Latency = 11;
472  let NumMicroOps = 3;
473  let ResourceCycles = [3];
474}
475def : WriteRes<WritePCmpIStrMLd, [SBPort0, SBPort23]> {
476  let Latency = 17;
477  let NumMicroOps = 4;
478  let ResourceCycles = [3,1];
479}
480
481// Packed Compare Explicit Length Strings, Return Mask
482def : WriteRes<WritePCmpEStrM, [SBPort015]> {
483  let Latency = 11;
484  let ResourceCycles = [8];
485}
486def : WriteRes<WritePCmpEStrMLd, [SBPort015, SBPort23]> {
487  let Latency = 17;
488  let ResourceCycles = [7, 1];
489}
490
491// Packed Compare Implicit Length Strings, Return Index
492def : WriteRes<WritePCmpIStrI, [SBPort0]> {
493  let Latency = 11;
494  let NumMicroOps = 3;
495  let ResourceCycles = [3];
496}
497def : WriteRes<WritePCmpIStrILd, [SBPort0,SBPort23]> {
498  let Latency = 17;
499  let NumMicroOps = 4;
500  let ResourceCycles = [3,1];
501}
502
503// Packed Compare Explicit Length Strings, Return Index
504def : WriteRes<WritePCmpEStrI, [SBPort015]> {
505  let Latency = 4;
506  let ResourceCycles = [8];
507}
508def : WriteRes<WritePCmpEStrILd, [SBPort015, SBPort23]> {
509  let Latency = 10;
510  let ResourceCycles = [7, 1];
511}
512
513// MOVMSK Instructions.
514def : WriteRes<WriteFMOVMSK,    [SBPort0]> { let Latency = 2; }
515def : WriteRes<WriteVecMOVMSK,  [SBPort0]> { let Latency = 2; }
516def : WriteRes<WriteVecMOVMSKY, [SBPort0]> { let Latency = 2; }
517def : WriteRes<WriteMMXMOVMSK,  [SBPort0]> { let Latency = 1; }
518
519// AES Instructions.
520def : WriteRes<WriteAESDecEnc, [SBPort5,SBPort015]> {
521  let Latency = 7;
522  let NumMicroOps = 2;
523  let ResourceCycles = [1,1];
524}
525def : WriteRes<WriteAESDecEncLd, [SBPort5,SBPort23,SBPort015]> {
526  let Latency = 13;
527  let NumMicroOps = 3;
528  let ResourceCycles = [1,1,1];
529}
530
531def : WriteRes<WriteAESIMC, [SBPort5]> {
532  let Latency = 12;
533  let NumMicroOps = 2;
534  let ResourceCycles = [2];
535}
536def : WriteRes<WriteAESIMCLd, [SBPort5,SBPort23]> {
537  let Latency = 18;
538  let NumMicroOps = 3;
539  let ResourceCycles = [2,1];
540}
541
542def : WriteRes<WriteAESKeyGen, [SBPort015]> {
543  let Latency = 8;
544  let ResourceCycles = [11];
545}
546def : WriteRes<WriteAESKeyGenLd, [SBPort015, SBPort23]> {
547  let Latency = 14;
548  let ResourceCycles = [10, 1];
549}
550
551// Carry-less multiplication instructions.
552def : WriteRes<WriteCLMul, [SBPort015]> {
553  let Latency = 14;
554  let ResourceCycles = [18];
555}
556def : WriteRes<WriteCLMulLd, [SBPort015, SBPort23]> {
557  let Latency = 20;
558  let ResourceCycles = [17, 1];
559}
560
561// Load/store MXCSR.
562// FIXME: This is probably wrong. Only STMXCSR should require Port4.
563def : WriteRes<WriteLDMXCSR, [SBPort0,SBPort4,SBPort5,SBPort23]> { let Latency = 5; let NumMicroOps = 4; let ResourceCycles = [1,1,1,1]; }
564def : WriteRes<WriteSTMXCSR, [SBPort0,SBPort4,SBPort5,SBPort23]> { let Latency = 5; let NumMicroOps = 4; let ResourceCycles = [1,1,1,1]; }
565
566def : WriteRes<WriteSystem,     [SBPort015]> { let Latency = 100; }
567def : WriteRes<WriteMicrocoded, [SBPort015]> { let Latency = 100; }
568def : WriteRes<WriteFence, [SBPort23, SBPort4]>;
569def : WriteRes<WriteNop, []>;
570
571// AVX2/FMA is not supported on that architecture, but we should define the basic
572// scheduling resources anyway.
573defm : SBWriteResPair<WriteFShuffle256, [SBPort5], 1, [1], 1, 7>;
574defm : SBWriteResPair<WriteFVarShuffle256, [SBPort5], 1, [1], 1, 7>;
575defm : SBWriteResPair<WriteShuffle256, [SBPort5], 1, [1], 1, 7>;
576defm : SBWriteResPair<WriteVPMOV256, [SBPort5], 1, [1], 1, 7>;
577defm : SBWriteResPair<WriteVarShuffle256, [SBPort5], 1, [1], 1, 7>;
578defm : SBWriteResPair<WriteFMA,  [SBPort01],  5>;
579defm : SBWriteResPair<WriteFMAX, [SBPort01],  5>;
580defm : SBWriteResPair<WriteFMAY, [SBPort01],  5>;
581defm : SBWriteResPair<WriteFMAZ, [SBPort01],  5>;  // Unsupported = 1
582
583// Remaining SNB instrs.
584
585def SBWriteResGroup1 : SchedWriteRes<[SBPort1]> {
586  let Latency = 1;
587  let NumMicroOps = 1;
588  let ResourceCycles = [1];
589}
590def: InstRW<[SBWriteResGroup1], (instrs COMP_FST0r,
591                                        COM_FST0r,
592                                        UCOM_FPr,
593                                        UCOM_Fr)>;
594
595def SBWriteResGroup2 : SchedWriteRes<[SBPort5]> {
596  let Latency = 1;
597  let NumMicroOps = 1;
598  let ResourceCycles = [1];
599}
600def: InstRW<[SBWriteResGroup2], (instrs FDECSTP, FINCSTP, FFREE, FFREEP, FNOP,
601                                        LD_Frr, ST_Frr, ST_FPrr)>;
602def: InstRW<[SBWriteResGroup2], (instrs LOOP, LOOPE, LOOPNE)>; // FIXME: This seems wrong compared to other Intel CPUs.
603def: InstRW<[SBWriteResGroup2], (instrs RETQ)>;
604
605def SBWriteResGroup4 : SchedWriteRes<[SBPort05]> {
606  let Latency = 1;
607  let NumMicroOps = 1;
608  let ResourceCycles = [1];
609}
610def: InstRW<[SBWriteResGroup4], (instrs CDQ, CQO)>;
611
612def SBWriteResGroup5 : SchedWriteRes<[SBPort15]> {
613  let Latency = 1;
614  let NumMicroOps = 1;
615  let ResourceCycles = [1];
616}
617def: InstRW<[SBWriteResGroup5], (instrs MMX_PABSBrr,
618                                        MMX_PABSDrr,
619                                        MMX_PABSWrr,
620                                        MMX_PADDQirr,
621                                        MMX_PALIGNRrri,
622                                        MMX_PSIGNBrr,
623                                        MMX_PSIGNDrr,
624                                        MMX_PSIGNWrr)>;
625
626def SBWriteResGroup11 : SchedWriteRes<[SBPort015]> {
627  let Latency = 2;
628  let NumMicroOps = 2;
629  let ResourceCycles = [2];
630}
631def: InstRW<[SBWriteResGroup11], (instrs SCASB,
632                                         SCASL,
633                                         SCASQ,
634                                         SCASW)>;
635
636def SBWriteResGroup12 : SchedWriteRes<[SBPort0,SBPort1]> {
637  let Latency = 2;
638  let NumMicroOps = 2;
639  let ResourceCycles = [1,1];
640}
641def: InstRW<[SBWriteResGroup12], (instregex "(V?)(U?)COMI(SD|SS)rr")>;
642
643def SBWriteResGroup15 : SchedWriteRes<[SBPort0,SBPort015]> {
644  let Latency = 2;
645  let NumMicroOps = 2;
646  let ResourceCycles = [1,1];
647}
648def: InstRW<[SBWriteResGroup15], (instrs CWD,
649                                         FNSTSW16r)>;
650
651def SBWriteResGroup18 : SchedWriteRes<[SBPort5,SBPort015]> {
652  let Latency = 2;
653  let NumMicroOps = 2;
654  let ResourceCycles = [1,1];
655}
656def: InstRW<[SBWriteResGroup18], (instrs JCXZ, JECXZ, JRCXZ,
657                                         MMX_MOVDQ2Qrr)>;
658
659def SBWriteResGroup21 : SchedWriteRes<[SBPort1]> {
660  let Latency = 3;
661  let NumMicroOps = 1;
662  let ResourceCycles = [1];
663}
664def: InstRW<[SBWriteResGroup21], (instrs PUSHFS64)>;
665
666def SBWriteResGroup22 : SchedWriteRes<[SBPort0,SBPort5]> {
667  let Latency = 3;
668  let NumMicroOps = 2;
669  let ResourceCycles = [1,1];
670}
671def: InstRW<[SBWriteResGroup22], (instregex "(V?)EXTRACTPSrr")>;
672
673def SBWriteResGroup23 : SchedWriteRes<[SBPort05]> {
674  let Latency = 2;
675  let NumMicroOps = 3;
676  let ResourceCycles = [3];
677}
678def: InstRW<[SBWriteResGroup23], (instregex "RCL(8|16|32|64)r1",
679                                            "RCR(8|16|32|64)r1")>;
680
681def SBWriteResGroup25_1 : SchedWriteRes<[SBPort23,SBPort015]> {
682  let Latency = 7;
683  let NumMicroOps = 3;
684  let ResourceCycles = [1,2];
685}
686def: InstRW<[SBWriteResGroup25_1], (instrs LEAVE, LEAVE64)>;
687
688def SBWriteResGroup26_2 : SchedWriteRes<[SBPort0,SBPort1,SBPort5]> {
689  let Latency = 3;
690  let NumMicroOps = 3;
691  let ResourceCycles = [1,1,1];
692}
693def: InstRW<[SBWriteResGroup26_2], (instrs COM_FIPr, COM_FIr, UCOM_FIPr, UCOM_FIr)>;
694
695def SBWriteResGroup29 : SchedWriteRes<[SBPort1,SBPort015]> {
696  let Latency = 4;
697  let NumMicroOps = 2;
698  let ResourceCycles = [1,1];
699}
700def: InstRW<[SBWriteResGroup29], (instrs MOV64sr)>;
701
702def SBWriteResGroup29_2 : SchedWriteRes<[SBPort5,SBPort015]> {
703  let Latency = 4;
704  let NumMicroOps = 4;
705  let ResourceCycles = [1,3];
706}
707def: InstRW<[SBWriteResGroup29_2], (instrs PAUSE)>;
708
709def SBWriteResGroup31 : SchedWriteRes<[SBPort23]> {
710  let Latency = 5;
711  let NumMicroOps = 1;
712  let ResourceCycles = [1];
713}
714def: InstRW<[SBWriteResGroup31], (instregex "MOVSX(16|32|64)rm(8|16|32)",
715                                            "MOVZX(16|32|64)rm(8|16)")>;
716
717def SBWriteResGroup76 : SchedWriteRes<[SBPort05]> {
718  let Latency = 5;
719  let NumMicroOps = 8;
720  let ResourceCycles = [8];
721}
722def: InstRW<[SBWriteResGroup76], (instregex "RCL(8|16|32|64)r(i|CL)",
723                                            "RCR(8|16|32|64)r(i|CL)")>;
724
725def SBWriteResGroup33 : SchedWriteRes<[SBPort4,SBPort23]> {
726  let Latency = 5;
727  let NumMicroOps = 2;
728  let ResourceCycles = [1,1];
729}
730def: InstRW<[SBWriteResGroup33], (instregex "PUSH(16r|32r|64r|64i8)")>;
731
732def SBWriteResGroup35 : SchedWriteRes<[SBPort1,SBPort5]> {
733  let Latency = 5;
734  let NumMicroOps = 3;
735  let ResourceCycles = [1,2];
736}
737def: InstRW<[SBWriteResGroup35], (instrs CLI)>;
738
739def SBWriteResGroup35_2 : SchedWriteRes<[SBPort1,SBPort4,SBPort23]> {
740  let Latency = 5;
741  let NumMicroOps = 3;
742  let ResourceCycles = [1,1,1];
743}
744def: InstRW<[SBWriteResGroup35_2], (instrs PUSHGS64)>;
745def: InstRW<[SBWriteResGroup35_2], (instregex "ISTT_FP(16|32|64)m")>;
746
747def SBWriteResGroup36 : SchedWriteRes<[SBPort4,SBPort5,SBPort23]> {
748  let Latency = 5;
749  let NumMicroOps = 3;
750  let ResourceCycles = [1,1,1];
751}
752def: InstRW<[SBWriteResGroup36], (instrs CALL64pcrel32)>;
753def: InstRW<[SBWriteResGroup36], (instregex "CALL(16|32|64)r",
754                                            "(V?)EXTRACTPSmr")>;
755
756def SBWriteResGroup40 : SchedWriteRes<[SBPort4,SBPort23,SBPort015]> {
757  let Latency = 5;
758  let NumMicroOps = 3;
759  let ResourceCycles = [1,1,1];
760}
761def: InstRW<[SBWriteResGroup40], (instrs STOSB, STOSL, STOSQ, STOSW)>;
762
763def SBWriteResGroup41 : SchedWriteRes<[SBPort5,SBPort015]> {
764  let Latency = 5;
765  let NumMicroOps = 4;
766  let ResourceCycles = [1,3];
767}
768def: InstRW<[SBWriteResGroup41], (instrs FNINIT)>;
769
770def SBWriteResGroup45 : SchedWriteRes<[SBPort0,SBPort4,SBPort23,SBPort15]> {
771  let Latency = 5;
772  let NumMicroOps = 4;
773  let ResourceCycles = [1,1,1,1];
774}
775def: InstRW<[SBWriteResGroup45], (instregex "(V?)PEXTR(D|Q)mr",
776                                            "PUSHF(16|64)")>;
777
778def SBWriteResGroup46 : SchedWriteRes<[SBPort4,SBPort5,SBPort01,SBPort23]> {
779  let Latency = 5;
780  let NumMicroOps = 4;
781  let ResourceCycles = [1,1,1,1];
782}
783def: InstRW<[SBWriteResGroup46], (instregex "CLFLUSH")>;
784
785def SBWriteResGroup47 : SchedWriteRes<[SBPort4,SBPort5,SBPort01,SBPort23]> {
786  let Latency = 5;
787  let NumMicroOps = 5;
788  let ResourceCycles = [1,2,1,1];
789}
790def: InstRW<[SBWriteResGroup47], (instregex "FXRSTOR")>;
791
792def SBWriteResGroup48 : SchedWriteRes<[SBPort23]> {
793  let Latency = 6;
794  let NumMicroOps = 1;
795  let ResourceCycles = [1];
796}
797def: InstRW<[SBWriteResGroup48], (instrs MMX_MOVD64from64rm,
798                                         VBROADCASTSSrm)>;
799def: InstRW<[SBWriteResGroup48], (instregex "POP(16|32|64)r",
800                                            "(V?)MOV64toPQIrm",
801                                            "(V?)MOVDDUPrm",
802                                            "(V?)MOVDI2PDIrm",
803                                            "(V?)MOVQI2PQIrm",
804                                            "(V?)MOVSDrm",
805                                            "(V?)MOVSHDUPrm",
806                                            "(V?)MOVSLDUPrm",
807                                            "(V?)MOVSSrm")>;
808
809def SBWriteResGroup49 : SchedWriteRes<[SBPort5,SBPort23]> {
810  let Latency = 6;
811  let NumMicroOps = 2;
812  let ResourceCycles = [1,1];
813}
814def: InstRW<[SBWriteResGroup49], (instrs MOV16sm)>;
815
816def SBWriteResGroup51 : SchedWriteRes<[SBPort23,SBPort15]> {
817  let Latency = 6;
818  let NumMicroOps = 2;
819  let ResourceCycles = [1,1];
820}
821def: InstRW<[SBWriteResGroup51], (instrs MMX_PABSBrm,
822                                         MMX_PABSDrm,
823                                         MMX_PABSWrm,
824                                         MMX_PALIGNRrmi,
825                                         MMX_PSIGNBrm,
826                                         MMX_PSIGNDrm,
827                                         MMX_PSIGNWrm)>;
828
829def SBWriteResGroup52 : SchedWriteRes<[SBPort23,SBPort015]> {
830  let Latency = 6;
831  let NumMicroOps = 2;
832  let ResourceCycles = [1,1];
833}
834def: InstRW<[SBWriteResGroup52], (instrs LODSL, LODSQ)>;
835
836def SBWriteResGroup53 : SchedWriteRes<[SBPort4,SBPort23]> {
837  let Latency = 6;
838  let NumMicroOps = 3;
839  let ResourceCycles = [1,2];
840}
841def: InstRW<[SBWriteResGroup53], (instregex "ST_F(32|64)m",
842                                            "ST_FP(32|64|80)m")>;
843
844def SBWriteResGroup54 : SchedWriteRes<[SBPort23]> {
845  let Latency = 7;
846  let NumMicroOps = 1;
847  let ResourceCycles = [1];
848}
849def: InstRW<[SBWriteResGroup54], (instrs VBROADCASTSDYrm,
850                                         VBROADCASTSSYrm,
851                                         VMOVDDUPYrm,
852                                         VMOVSHDUPYrm,
853                                         VMOVSLDUPYrm)>;
854
855def SBWriteResGroup58 : SchedWriteRes<[SBPort23,SBPort05]> {
856  let Latency = 7;
857  let NumMicroOps = 2;
858  let ResourceCycles = [1,1];
859}
860def: InstRW<[SBWriteResGroup58], (instrs VINSERTF128rm)>;
861
862def SBWriteResGroup59 : SchedWriteRes<[SBPort23,SBPort15]> {
863  let Latency = 7;
864  let NumMicroOps = 2;
865  let ResourceCycles = [1,1];
866}
867def: InstRW<[SBWriteResGroup59], (instrs MMX_PADDQirm)>;
868
869def SBWriteResGroup62 : SchedWriteRes<[SBPort5,SBPort23]> {
870  let Latency = 7;
871  let NumMicroOps = 3;
872  let ResourceCycles = [2,1];
873}
874def: InstRW<[SBWriteResGroup62], (instrs VERRm, VERWm)>;
875
876def SBWriteResGroup63 : SchedWriteRes<[SBPort23,SBPort015]> {
877  let Latency = 7;
878  let NumMicroOps = 3;
879  let ResourceCycles = [1,2];
880}
881def: InstRW<[SBWriteResGroup63], (instrs LODSB, LODSW)>;
882
883def SBWriteResGroup64 : SchedWriteRes<[SBPort5,SBPort01,SBPort23]> {
884  let Latency = 7;
885  let NumMicroOps = 3;
886  let ResourceCycles = [1,1,1];
887}
888def: InstRW<[SBWriteResGroup64], (instrs FARJMP64m)>;
889
890def SBWriteResGroup66 : SchedWriteRes<[SBPort0,SBPort4,SBPort23]> {
891  let Latency = 7;
892  let NumMicroOps = 4;
893  let ResourceCycles = [1,1,2];
894}
895def: InstRW<[SBWriteResGroup66], (instrs FNSTSWm)>;
896
897def SBWriteResGroup67 : SchedWriteRes<[SBPort1,SBPort5,SBPort015]> {
898  let Latency = 7;
899  let NumMicroOps = 4;
900  let ResourceCycles = [1,2,1];
901}
902def: InstRW<[SBWriteResGroup67], (instregex "SLDT(16|32|64)r",
903                                            "STR(16|32|64)r")>;
904
905def SBWriteResGroup68 : SchedWriteRes<[SBPort4,SBPort5,SBPort23]> {
906  let Latency = 7;
907  let NumMicroOps = 4;
908  let ResourceCycles = [1,1,2];
909}
910def: InstRW<[SBWriteResGroup68], (instrs FNSTCW16m)>;
911def: InstRW<[SBWriteResGroup68], (instregex "CALL(16|32|64)m")>;
912
913def SBWriteResGroup69 : SchedWriteRes<[SBPort4,SBPort23,SBPort05]> {
914  let Latency = 7;
915  let NumMicroOps = 4;
916  let ResourceCycles = [1,2,1];
917}
918def: InstRW<[SBWriteResGroup69], (instregex "SAR(8|16|32|64)m(1|i)",
919                                            "SHL(8|16|32|64)m(1|i)",
920                                            "SHR(8|16|32|64)m(1|i)")>;
921
922def SBWriteResGroup77 : SchedWriteRes<[SBPort0,SBPort1,SBPort23]> {
923  let Latency = 8;
924  let NumMicroOps = 3;
925  let ResourceCycles = [1,1,1];
926}
927def: InstRW<[SBWriteResGroup77], (instregex "(V?)(U?)COMI(SD|SS)rm")>;
928
929def SBWriteResGroup81 : SchedWriteRes<[SBPort4, SBPort23, SBPort015]> {
930  let Latency = 6;
931  let NumMicroOps = 3;
932  let ResourceCycles = [1, 2, 1];
933}
934def: InstRW<[SBWriteResGroup81], (instregex "CMPXCHG(8|16)B")>;
935
936def SBWriteResGroup83 : SchedWriteRes<[SBPort23,SBPort015]> {
937  let Latency = 8;
938  let NumMicroOps = 5;
939  let ResourceCycles = [2,3];
940}
941def: InstRW<[SBWriteResGroup83], (instrs CMPSB,
942                                         CMPSL,
943                                         CMPSQ,
944                                         CMPSW)>;
945
946def SBWriteResGroup84 : SchedWriteRes<[SBPort4,SBPort5,SBPort23]> {
947  let Latency = 8;
948  let NumMicroOps = 5;
949  let ResourceCycles = [1,2,2];
950}
951def: InstRW<[SBWriteResGroup84], (instrs FLDCW16m)>;
952
953def SBWriteResGroup85 : SchedWriteRes<[SBPort4,SBPort23,SBPort05]> {
954  let Latency = 8;
955  let NumMicroOps = 5;
956  let ResourceCycles = [1,2,2];
957}
958def: InstRW<[SBWriteResGroup85], (instregex "ROL(8|16|32|64)m(1|i)",
959                                            "ROR(8|16|32|64)m(1|i)")>;
960
961def SBWriteResGroup86 : SchedWriteRes<[SBPort4,SBPort23,SBPort015]> {
962  let Latency = 8;
963  let NumMicroOps = 5;
964  let ResourceCycles = [1,2,2];
965}
966def: InstRW<[SBWriteResGroup86], (instrs MOVSB, MOVSL, MOVSQ, MOVSW)>;
967def: InstRW<[SBWriteResGroup86], (instregex "XADD(8|16|32|64)rm")>;
968
969def SBWriteResGroup87 : SchedWriteRes<[SBPort4,SBPort5,SBPort01,SBPort23]> {
970  let Latency = 8;
971  let NumMicroOps = 5;
972  let ResourceCycles = [1,1,1,2];
973}
974def: InstRW<[SBWriteResGroup87], (instrs FARCALL64m)>;
975
976def SBWriteResGroup93 : SchedWriteRes<[SBPort0,SBPort1,SBPort23]> {
977  let Latency = 9;
978  let NumMicroOps = 3;
979  let ResourceCycles = [1,1,1];
980}
981def: InstRW<[SBWriteResGroup93], (instregex "CVT(T?)(SD|SS)2SI(64)?rm")>;
982
983def SBWriteResGroup95 : SchedWriteRes<[SBPort5,SBPort01,SBPort23]> {
984  let Latency = 9;
985  let NumMicroOps = 3;
986  let ResourceCycles = [1,1,1];
987}
988def: InstRW<[SBWriteResGroup95], (instregex "LD_F(32|64|80)m")>;
989
990def SBWriteResGroup97 : SchedWriteRes<[SBPort1,SBPort4,SBPort23]> {
991  let Latency = 9;
992  let NumMicroOps = 4;
993  let ResourceCycles = [1,1,2];
994}
995def: InstRW<[SBWriteResGroup97], (instregex "IST_F(16|32)m",
996                                            "IST_FP(16|32|64)m")>;
997
998def SBWriteResGroup97_2 : SchedWriteRes<[SBPort4,SBPort23,SBPort05]> {
999  let Latency = 9;
1000  let NumMicroOps = 6;
1001  let ResourceCycles = [1,2,3];
1002}
1003def: InstRW<[SBWriteResGroup97_2], (instregex "ROL(8|16|32|64)mCL",
1004                                              "ROR(8|16|32|64)mCL",
1005                                              "SAR(8|16|32|64)mCL",
1006                                              "SHL(8|16|32|64)mCL",
1007                                              "SHR(8|16|32|64)mCL")>;
1008
1009def SBWriteResGroup98 : SchedWriteRes<[SBPort4,SBPort23,SBPort015]> {
1010  let Latency = 9;
1011  let NumMicroOps = 6;
1012  let ResourceCycles = [1,2,3];
1013}
1014def: SchedAlias<WriteADCRMW, SBWriteResGroup98>;
1015
1016def SBWriteResGroup99 : SchedWriteRes<[SBPort4,SBPort23,SBPort05,SBPort015]> {
1017  let Latency = 9;
1018  let NumMicroOps = 6;
1019  let ResourceCycles = [1,2,2,1];
1020}
1021def: InstRW<[SBWriteResGroup99, ReadAfterLd], (instrs ADC8mr, ADC16mr, ADC32mr, ADC64mr,
1022                                                      SBB8mr, SBB16mr, SBB32mr, SBB64mr)>;
1023
1024def SBWriteResGroup100 : SchedWriteRes<[SBPort4,SBPort5,SBPort23,SBPort05,SBPort015]> {
1025  let Latency = 9;
1026  let NumMicroOps = 6;
1027  let ResourceCycles = [1,1,2,1,1];
1028}
1029def : SchedAlias<WriteBitTestRegLd, SBWriteResGroup100>; // TODO - this is incorrect - no RMW
1030
1031def SBWriteResGroup101 : SchedWriteRes<[SBPort1,SBPort23]> {
1032  let Latency = 10;
1033  let NumMicroOps = 2;
1034  let ResourceCycles = [1,1];
1035}
1036def: InstRW<[SBWriteResGroup101], (instregex "(ADD|SUB|SUBR)_F(32|64)m",
1037                                             "ILD_F(16|32|64)m")>;
1038
1039def SBWriteResGroup104 : SchedWriteRes<[SBPort0,SBPort23]> {
1040  let Latency = 11;
1041  let NumMicroOps = 2;
1042  let ResourceCycles = [1,1];
1043}
1044def: InstRW<[SBWriteResGroup104], (instregex "(V?)PCMPGTQrm")>;
1045
1046def SBWriteResGroup106 : SchedWriteRes<[SBPort1,SBPort23]> {
1047  let Latency = 11;
1048  let NumMicroOps = 3;
1049  let ResourceCycles = [2,1];
1050}
1051def: InstRW<[SBWriteResGroup106], (instregex "FICOM(P?)(16|32)m")>;
1052
1053def SBWriteResGroup108 : SchedWriteRes<[SBPort05,SBPort23]> {
1054  let Latency = 11;
1055  let NumMicroOps = 11;
1056  let ResourceCycles = [7,4];
1057}
1058def: InstRW<[SBWriteResGroup108], (instregex "RCL(8|16|32|64)m",
1059                                             "RCR(8|16|32|64)m")>;
1060
1061def SBWriteResGroup111 : SchedWriteRes<[SBPort0,SBPort23]> {
1062  let Latency = 12;
1063  let NumMicroOps = 2;
1064  let ResourceCycles = [1,1];
1065}
1066def: InstRW<[SBWriteResGroup111], (instregex "MUL_F(32|64)m")>;
1067
1068def SBWriteResGroup114 : SchedWriteRes<[SBPort1,SBPort23]> {
1069  let Latency = 13;
1070  let NumMicroOps = 3;
1071  let ResourceCycles = [2,1];
1072}
1073def: InstRW<[SBWriteResGroup114], (instregex "(ADD|SUB|SUBR)_FI(16|32)m")>;
1074
1075def SBWriteResGroup119 : SchedWriteRes<[SBPort0,SBPort1,SBPort23]> {
1076  let Latency = 15;
1077  let NumMicroOps = 3;
1078  let ResourceCycles = [1,1,1];
1079}
1080def: InstRW<[SBWriteResGroup119], (instregex "MUL_FI(16|32)m")>;
1081
1082def SBWriteResGroup130 : SchedWriteRes<[SBPort0,SBPort23]> {
1083  let Latency = 31;
1084  let NumMicroOps = 2;
1085  let ResourceCycles = [1,1];
1086}
1087def: InstRW<[SBWriteResGroup130], (instregex "DIV(R?)_F(32|64)m")>;
1088
1089def SBWriteResGroup131 : SchedWriteRes<[SBPort0,SBPort1,SBPort23]> {
1090  let Latency = 34;
1091  let NumMicroOps = 3;
1092  let ResourceCycles = [1,1,1];
1093}
1094def: InstRW<[SBWriteResGroup131], (instregex "DIV(R?)_FI(16|32)m")>;
1095
1096def SBWriteResGroupVzeroall : SchedWriteRes<[SBPort5]> {
1097  let Latency = 9;
1098  let NumMicroOps = 20;
1099  let ResourceCycles = [2];
1100}
1101def: InstRW<[SBWriteResGroupVzeroall], (instrs VZEROALL)>;
1102
1103def SBWriteResGroupVzeroupper : SchedWriteRes<[]> {
1104  let Latency = 1;
1105  let NumMicroOps = 4;
1106  let ResourceCycles = [];
1107}
1108def: InstRW<[SBWriteResGroupVzeroupper], (instrs VZEROUPPER)>;
1109
1110def: InstRW<[WriteZero], (instrs CLC)>;
1111
1112// Instruction variants handled by the renamer. These might not need execution
1113// ports in certain conditions.
1114// See Agner's Fog "The microarchitecture of Intel, AMD and VIA CPUs",
1115// section "Sandy Bridge and Ivy Bridge Pipeline" > "Register allocation and
1116// renaming".
1117// These can be investigated with llvm-exegesis, e.g.
1118// echo 'pxor %mm0, %mm0' | /tmp/llvm-exegesis -mode=uops -snippets-file=-
1119// echo 'vxorpd %xmm0, %xmm0, %xmm1' | /tmp/llvm-exegesis -mode=uops -snippets-file=-
1120
1121def SBWriteZeroLatency : SchedWriteRes<[]> {
1122  let Latency = 0;
1123}
1124
1125def SBWriteZeroIdiom : SchedWriteVariant<[
1126    SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [SBWriteZeroLatency]>,
1127    SchedVar<NoSchedPred,                          [WriteALU]>
1128]>;
1129def : InstRW<[SBWriteZeroIdiom], (instrs SUB32rr, SUB64rr,
1130                                         XOR32rr, XOR64rr)>;
1131
1132def SBWriteFZeroIdiom : SchedWriteVariant<[
1133    SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [SBWriteZeroLatency]>,
1134    SchedVar<NoSchedPred,                          [WriteFLogic]>
1135]>;
1136def : InstRW<[SBWriteFZeroIdiom], (instrs XORPSrr, VXORPSrr, XORPDrr,
1137                                          VXORPDrr)>;
1138
1139def SBWriteFZeroIdiomY : SchedWriteVariant<[
1140    SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [SBWriteZeroLatency]>,
1141    SchedVar<NoSchedPred,                          [WriteFLogicY]>
1142]>;
1143def : InstRW<[SBWriteFZeroIdiomY], (instrs VXORPSYrr, VXORPDYrr)>;
1144
1145def SBWriteVZeroIdiomLogicX : SchedWriteVariant<[
1146    SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [SBWriteZeroLatency]>,
1147    SchedVar<NoSchedPred,                          [WriteVecLogicX]>
1148]>;
1149def : InstRW<[SBWriteVZeroIdiomLogicX], (instrs PXORrr, VPXORrr)>;
1150
1151def SBWriteVZeroIdiomALUX : SchedWriteVariant<[
1152    SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [SBWriteZeroLatency]>,
1153    SchedVar<NoSchedPred,                          [WriteVecALUX]>
1154]>;
1155def : InstRW<[SBWriteVZeroIdiomALUX], (instrs PSUBBrr, VPSUBBrr,
1156                                              PSUBDrr, VPSUBDrr,
1157                                              PSUBQrr, VPSUBQrr,
1158                                              PSUBWrr, VPSUBWrr,
1159                                              PCMPGTBrr, VPCMPGTBrr,
1160                                              PCMPGTDrr, VPCMPGTDrr,
1161                                              PCMPGTWrr, VPCMPGTWrr)>;
1162
1163def SBWritePCMPGTQ : SchedWriteRes<[SBPort0]> {
1164  let Latency = 5;
1165  let NumMicroOps = 1;
1166  let ResourceCycles = [1];
1167}
1168
1169def SBWriteVZeroIdiomPCMPGTQ : SchedWriteVariant<[
1170    SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [SBWriteZeroLatency]>,
1171    SchedVar<NoSchedPred,                          [SBWritePCMPGTQ]>
1172]>;
1173def : InstRW<[SBWriteVZeroIdiomPCMPGTQ], (instrs PCMPGTQrr, VPCMPGTQrr)>;
1174
1175// CMOVs that use both Z and C flag require an extra uop.
1176def SBWriteCMOVA_CMOVBErr : SchedWriteRes<[SBPort05,SBPort015]> {
1177  let Latency = 3;
1178  let ResourceCycles = [2,1];
1179  let NumMicroOps = 3;
1180}
1181
1182def SBWriteCMOVA_CMOVBErm : SchedWriteRes<[SBPort23,SBPort05,SBPort015]> {
1183  let Latency = 8;
1184  let ResourceCycles = [1,2,1];
1185  let NumMicroOps = 4;
1186}
1187
1188def SBCMOVA_CMOVBErr :  SchedWriteVariant<[
1189  SchedVar<MCSchedPredicate<IsCMOVArr_Or_CMOVBErr>, [SBWriteCMOVA_CMOVBErr]>,
1190  SchedVar<NoSchedPred,                             [WriteCMOV]>
1191]>;
1192
1193def SBCMOVA_CMOVBErm :  SchedWriteVariant<[
1194  SchedVar<MCSchedPredicate<IsCMOVArm_Or_CMOVBErm>, [SBWriteCMOVA_CMOVBErm]>,
1195  SchedVar<NoSchedPred,                             [WriteCMOV.Folded]>
1196]>;
1197
1198def : InstRW<[SBCMOVA_CMOVBErr], (instrs CMOV16rr, CMOV32rr, CMOV64rr)>;
1199def : InstRW<[SBCMOVA_CMOVBErm], (instrs CMOV16rm, CMOV32rm, CMOV64rm)>;
1200
1201// SETCCs that use both Z and C flag require an extra uop.
1202def SBWriteSETA_SETBEr : SchedWriteRes<[SBPort05]> {
1203  let Latency = 2;
1204  let ResourceCycles = [2];
1205  let NumMicroOps = 2;
1206}
1207
1208def SBWriteSETA_SETBEm : SchedWriteRes<[SBPort4,SBPort23,SBPort05]> {
1209  let Latency = 3;
1210  let ResourceCycles = [1,1,2];
1211  let NumMicroOps = 4;
1212}
1213
1214def SBSETA_SETBErr :  SchedWriteVariant<[
1215  SchedVar<MCSchedPredicate<IsSETAr_Or_SETBEr>, [SBWriteSETA_SETBEr]>,
1216  SchedVar<NoSchedPred,                         [WriteSETCC]>
1217]>;
1218
1219def SBSETA_SETBErm :  SchedWriteVariant<[
1220  SchedVar<MCSchedPredicate<IsSETAm_Or_SETBEm>, [SBWriteSETA_SETBEm]>,
1221  SchedVar<NoSchedPred,                         [WriteSETCCStore]>
1222]>;
1223
1224def : InstRW<[SBSETA_SETBErr], (instrs SETCCr)>;
1225def : InstRW<[SBSETA_SETBErm], (instrs SETCCm)>;
1226
1227} // SchedModel
1228