1 //=- X86SchedSandyBridge.td - X86 Sandy Bridge Scheduling ----*- tablegen -*-=//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines the machine model for Sandy Bridge to support instruction
10 // scheduling and other instruction cost heuristics.
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`.
16 //===----------------------------------------------------------------------===//
18 def 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.
23 let MicroOpBufferSize = 168; // Based on the reorder buffer.
25 let MispredictPenalty = 16;
27 // Based on the LSD (loop-stream detector) queue size.
28 let LoopMicroOpBufferSize = 28;
30 // This flag is set to allow the scheduler to assign
31 // a default model to unrecognized opcodes.
32 let CompleteModel = 0;
35 let SchedModel = SandyBridgeModel in {
37 // Sandy Bridge can issue micro-ops to 6 different ports in one cycle.
39 // Ports 0, 1, and 5 handle all computation.
40 def SBPort0 : ProcResource<1>;
41 def SBPort1 : ProcResource<1>;
42 def SBPort5 : ProcResource<1>;
44 // Ports 2 and 3 are identical. They handle loads and the address half of
46 def SBPort23 : ProcResource<2>;
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
51 def SBPort4 : ProcResource<1>;
53 // Many micro-ops are capable of issuing on multiple ports.
54 def SBPort01 : ProcResGroup<[SBPort0, SBPort1]>;
55 def SBPort05 : ProcResGroup<[SBPort0, SBPort5]>;
56 def SBPort15 : ProcResGroup<[SBPort1, SBPort5]>;
57 def SBPort015 : ProcResGroup<[SBPort0, SBPort1, SBPort5]>;
59 // 54 Entry Unified Scheduler
60 def SBPortAny : ProcResGroup<[SBPort0, SBPort1, SBPort23, SBPort4, SBPort5]> {
64 // Integer division issued on port 0.
65 def SBDivider : ProcResource<1>;
66 // FP division and sqrt on port 0.
67 def SBFPDivider : ProcResource<1>;
69 // Integer loads are 5 cycles, so ReadAfterLd registers needn't be available until 5
70 // cycles after the memory operand.
71 def : ReadAdvance<ReadAfterLd, 5>;
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.
75 def : ReadAdvance<ReadAfterVecLd, 5>;
76 def : ReadAdvance<ReadAfterVecXLd, 6>;
77 def : ReadAdvance<ReadAfterVecYLd, 7>;
79 def : ReadAdvance<ReadInt2Fpu, 0>;
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
86 multiclass SBWriteResPair<X86FoldableSchedWrite SchedRW,
87 list<ProcResourceKind> ExePorts,
88 int Lat, list<int> Res = [1], int UOps = 1,
90 // Register variant is using a single cycle on ExePort.
91 def : WriteRes<SchedRW, ExePorts> {
93 let ResourceCycles = Res;
94 let NumMicroOps = UOps;
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);
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.
108 def : WriteRes<WriteRMW, [SBPort23,SBPort4]>;
110 def : WriteRes<WriteStore, [SBPort23, SBPort4]>;
111 def : WriteRes<WriteStoreNT, [SBPort23, SBPort4]>;
112 def : WriteRes<WriteLoad, [SBPort23]> { let Latency = 5; }
113 def : WriteRes<WriteMove, [SBPort015]>;
114 def : WriteRes<WriteZero, []>;
117 defm : SBWriteResPair<WriteALU, [SBPort015], 1>;
118 defm : SBWriteResPair<WriteADC, [SBPort05,SBPort015], 2, [1,1], 2>;
120 defm : SBWriteResPair<WriteIMul8, [SBPort1], 3>;
121 defm : SBWriteResPair<WriteIMul16, [SBPort1,SBPort05,SBPort015], 4, [1,1,2], 4>;
122 defm : X86WriteRes<WriteIMul16Imm, [SBPort1,SBPort015], 4, [1,1], 2>;
123 defm : X86WriteRes<WriteIMul16ImmLd, [SBPort1,SBPort015,SBPort23], 8, [1,1,1], 3>;
124 defm : SBWriteResPair<WriteIMul16Reg, [SBPort1], 3>;
125 defm : SBWriteResPair<WriteIMul32, [SBPort1,SBPort05,SBPort015], 4, [1,1,1], 3>;
126 defm : SBWriteResPair<WriteIMul32Imm, [SBPort1], 3>;
127 defm : SBWriteResPair<WriteIMul32Reg, [SBPort1], 3>;
128 defm : SBWriteResPair<WriteIMul64, [SBPort1,SBPort0], 4, [1,1], 2>;
129 defm : SBWriteResPair<WriteIMul64Imm, [SBPort1], 3>;
130 defm : SBWriteResPair<WriteIMul64Reg, [SBPort1], 3>;
131 def : WriteRes<WriteIMulH, []> { let Latency = 3; }
133 defm : X86WriteRes<WriteXCHG, [SBPort015], 2, [3], 3>;
134 defm : X86WriteRes<WriteBSWAP32, [SBPort1], 1, [1], 1>;
135 defm : X86WriteRes<WriteBSWAP64, [SBPort1, SBPort05], 2, [1,1], 2>;
136 defm : X86WriteRes<WriteCMPXCHG, [SBPort05, SBPort015], 5, [1,3], 4>;
137 defm : X86WriteRes<WriteCMPXCHGRMW,[SBPort015, SBPort5, SBPort23, SBPort4], 8, [1, 2, 2, 1], 6>;
139 defm : SBWriteResPair<WriteDiv8, [SBPort0, SBDivider], 25, [1, 10]>;
140 defm : SBWriteResPair<WriteDiv16, [SBPort0, SBDivider], 25, [1, 10]>;
141 defm : SBWriteResPair<WriteDiv32, [SBPort0, SBDivider], 25, [1, 10]>;
142 defm : SBWriteResPair<WriteDiv64, [SBPort0, SBDivider], 25, [1, 10]>;
143 defm : SBWriteResPair<WriteIDiv8, [SBPort0, SBDivider], 25, [1, 10]>;
144 defm : SBWriteResPair<WriteIDiv16, [SBPort0, SBDivider], 25, [1, 10]>;
145 defm : SBWriteResPair<WriteIDiv32, [SBPort0, SBDivider], 25, [1, 10]>;
146 defm : SBWriteResPair<WriteIDiv64, [SBPort0, SBDivider], 25, [1, 10]>;
149 defm : X86WriteRes<WriteSHDrri, [SBPort05, SBPort015], 2, [1, 1], 2>;
150 defm : X86WriteRes<WriteSHDrrcl,[SBPort05, SBPort015], 4, [3, 1], 4>;
151 defm : X86WriteRes<WriteSHDmri, [SBPort4,SBPort23,SBPort05,SBPort015], 8, [1, 2, 1, 1], 5>;
152 defm : X86WriteRes<WriteSHDmrcl,[SBPort4,SBPort23,SBPort05,SBPort015], 10, [1, 2, 3, 1], 7>;
154 defm : SBWriteResPair<WriteShift, [SBPort05], 1>;
155 defm : SBWriteResPair<WriteShiftCL, [SBPort05], 3, [3], 3>;
156 defm : SBWriteResPair<WriteRotate, [SBPort05], 2, [2], 2>;
157 defm : SBWriteResPair<WriteRotateCL, [SBPort05], 3, [3], 3>;
159 defm : SBWriteResPair<WriteJump, [SBPort5], 1>;
160 defm : SBWriteResPair<WriteCRC32, [SBPort1], 3, [1], 1, 5>;
162 defm : SBWriteResPair<WriteCMOV, [SBPort05,SBPort015], 2, [1,1], 2>; // Conditional move.
163 defm : SBWriteResPair<WriteCMOV2, [SBPort05,SBPort015], 3, [2,1], 3>; // Conditional (CF + ZF flag) move.
164 defm : X86WriteRes<WriteFCMOV, [SBPort5,SBPort05], 3, [2,1], 3>; // x87 conditional move.
165 def : WriteRes<WriteSETCC, [SBPort05]>; // Setcc.
166 def : WriteRes<WriteSETCCStore, [SBPort05,SBPort4,SBPort23]> {
171 defm : X86WriteRes<WriteLAHFSAHF, [SBPort05], 1, [1], 1>;
172 defm : X86WriteRes<WriteBitTest, [SBPort05], 1, [1], 1>;
173 defm : X86WriteRes<WriteBitTestImmLd, [SBPort05,SBPort23], 6, [1,1], 2>;
174 //defm : X86WriteRes<WriteBitTestRegLd, [SBPort05,SBPort23], 6, [1,1], 2>;
175 defm : X86WriteRes<WriteBitTestSet, [SBPort05], 1, [1], 1>;
176 defm : X86WriteRes<WriteBitTestSetImmLd, [SBPort05,SBPort23], 6, [1,1], 3>;
177 defm : X86WriteRes<WriteBitTestSetRegLd, [SBPort05,SBPort23,SBPort5,SBPort015], 8, [1,1,1,1], 5>;
179 // This is for simple LEAs with one or two input operands.
180 // The complex ones can only execute on port 1, and they require two cycles on
181 // the port to read all inputs. We don't model that.
182 def : WriteRes<WriteLEA, [SBPort01]>;
185 defm : SBWriteResPair<WriteBSF, [SBPort1], 3, [1], 1, 5>;
186 defm : SBWriteResPair<WriteBSR, [SBPort1], 3, [1], 1, 5>;
187 defm : SBWriteResPair<WriteLZCNT, [SBPort1], 3, [1], 1, 5>;
188 defm : SBWriteResPair<WriteTZCNT, [SBPort1], 3, [1], 1, 5>;
189 defm : SBWriteResPair<WritePOPCNT, [SBPort1], 3, [1], 1, 6>;
191 // BMI1 BEXTR/BLS, BMI2 BZHI
192 // NOTE: These don't exist on Sandy Bridge. Ports are guesses.
193 defm : SBWriteResPair<WriteBEXTR, [SBPort05,SBPort1], 2, [1,1], 2>;
194 defm : SBWriteResPair<WriteBLS, [SBPort015], 1>;
195 defm : SBWriteResPair<WriteBZHI, [SBPort1], 1>;
197 // Scalar and vector floating point.
198 defm : X86WriteRes<WriteFLD0, [SBPort5], 1, [1], 1>;
199 defm : X86WriteRes<WriteFLD1, [SBPort0,SBPort5], 1, [1,1], 2>;
200 defm : X86WriteRes<WriteFLDC, [SBPort0,SBPort1], 1, [1,1], 2>;
201 defm : X86WriteRes<WriteFLoad, [SBPort23], 5, [1], 1>;
202 defm : X86WriteRes<WriteFLoadX, [SBPort23], 6, [1], 1>;
203 defm : X86WriteRes<WriteFLoadY, [SBPort23], 7, [1], 1>;
204 defm : X86WriteRes<WriteFMaskedLoad, [SBPort23,SBPort05], 8, [1,2], 3>;
205 defm : X86WriteRes<WriteFMaskedLoadY, [SBPort23,SBPort05], 9, [1,2], 3>;
206 defm : X86WriteRes<WriteFStore, [SBPort23,SBPort4], 1, [1,1], 1>;
207 defm : X86WriteRes<WriteFStoreX, [SBPort23,SBPort4], 1, [1,1], 1>;
208 defm : X86WriteRes<WriteFStoreY, [SBPort23,SBPort4], 1, [1,1], 1>;
209 defm : X86WriteRes<WriteFStoreNT, [SBPort23,SBPort4], 1, [1,1], 1>;
210 defm : X86WriteRes<WriteFStoreNTX, [SBPort23,SBPort4], 1, [1,1], 1>;
211 defm : X86WriteRes<WriteFStoreNTY, [SBPort23,SBPort4], 1, [1,1], 1>;
212 defm : X86WriteRes<WriteFMaskedStore, [SBPort4,SBPort01,SBPort23], 5, [1,1,1], 3>;
213 defm : X86WriteRes<WriteFMaskedStoreY, [SBPort4,SBPort01,SBPort23], 5, [1,1,1], 3>;
214 defm : X86WriteRes<WriteFMove, [SBPort5], 1, [1], 1>;
215 defm : X86WriteRes<WriteFMoveX, [SBPort5], 1, [1], 1>;
216 defm : X86WriteRes<WriteFMoveY, [SBPort5], 1, [1], 1>;
217 defm : X86WriteRes<WriteEMMS, [SBPort015], 31, [31], 31>;
219 defm : SBWriteResPair<WriteFAdd, [SBPort1], 3, [1], 1, 6>;
220 defm : SBWriteResPair<WriteFAddX, [SBPort1], 3, [1], 1, 6>;
221 defm : SBWriteResPair<WriteFAddY, [SBPort1], 3, [1], 1, 7>;
222 defm : SBWriteResPair<WriteFAddZ, [SBPort1], 3, [1], 1, 7>; // Unsupported = 1
223 defm : SBWriteResPair<WriteFAdd64, [SBPort1], 3, [1], 1, 6>;
224 defm : SBWriteResPair<WriteFAdd64X, [SBPort1], 3, [1], 1, 6>;
225 defm : SBWriteResPair<WriteFAdd64Y, [SBPort1], 3, [1], 1, 7>;
226 defm : SBWriteResPair<WriteFAdd64Z, [SBPort1], 3, [1], 1, 7>; // Unsupported = 1
228 defm : SBWriteResPair<WriteFCmp, [SBPort1], 3, [1], 1, 6>;
229 defm : SBWriteResPair<WriteFCmpX, [SBPort1], 3, [1], 1, 6>;
230 defm : SBWriteResPair<WriteFCmpY, [SBPort1], 3, [1], 1, 7>;
231 defm : SBWriteResPair<WriteFCmpZ, [SBPort1], 3, [1], 1, 7>; // Unsupported = 1
232 defm : SBWriteResPair<WriteFCmp64, [SBPort1], 3, [1], 1, 6>;
233 defm : SBWriteResPair<WriteFCmp64X, [SBPort1], 3, [1], 1, 6>;
234 defm : SBWriteResPair<WriteFCmp64Y, [SBPort1], 3, [1], 1, 7>;
235 defm : SBWriteResPair<WriteFCmp64Z, [SBPort1], 3, [1], 1, 7>; // Unsupported = 1
237 defm : SBWriteResPair<WriteFCom, [SBPort1], 3>;
239 defm : SBWriteResPair<WriteFMul, [SBPort0], 5, [1], 1, 6>;
240 defm : SBWriteResPair<WriteFMulX, [SBPort0], 5, [1], 1, 6>;
241 defm : SBWriteResPair<WriteFMulY, [SBPort0], 5, [1], 1, 7>;
242 defm : SBWriteResPair<WriteFMulZ, [SBPort0], 5, [1], 1, 7>; // Unsupported = 1
243 defm : SBWriteResPair<WriteFMul64, [SBPort0], 5, [1], 1, 6>;
244 defm : SBWriteResPair<WriteFMul64X, [SBPort0], 5, [1], 1, 6>;
245 defm : SBWriteResPair<WriteFMul64Y, [SBPort0], 5, [1], 1, 7>;
246 defm : SBWriteResPair<WriteFMul64Z, [SBPort0], 5, [1], 1, 7>; // Unsupported = 1
248 defm : SBWriteResPair<WriteFDiv, [SBPort0,SBFPDivider], 14, [1,14], 1, 6>;
249 defm : SBWriteResPair<WriteFDivX, [SBPort0,SBFPDivider], 14, [1,14], 1, 6>;
250 defm : SBWriteResPair<WriteFDivY, [SBPort0,SBPort05,SBFPDivider], 29, [2,1,28], 3, 7>;
251 defm : SBWriteResPair<WriteFDivZ, [SBPort0,SBPort05,SBFPDivider], 29, [2,1,28], 3, 7>; // Unsupported = 1
252 defm : SBWriteResPair<WriteFDiv64, [SBPort0,SBFPDivider], 22, [1,22], 1, 6>;
253 defm : SBWriteResPair<WriteFDiv64X, [SBPort0,SBFPDivider], 22, [1,22], 1, 6>;
254 defm : SBWriteResPair<WriteFDiv64Y, [SBPort0,SBPort05,SBFPDivider], 45, [2,1,44], 3, 7>;
255 defm : SBWriteResPair<WriteFDiv64Z, [SBPort0,SBPort05,SBFPDivider], 45, [2,1,44], 3, 7>; // Unsupported = 1
257 defm : SBWriteResPair<WriteFRcp, [SBPort0], 5, [1], 1, 6>;
258 defm : SBWriteResPair<WriteFRcpX, [SBPort0], 5, [1], 1, 6>;
259 defm : SBWriteResPair<WriteFRcpY, [SBPort0,SBPort05], 7, [2,1], 3, 7>;
260 defm : SBWriteResPair<WriteFRcpZ, [SBPort0,SBPort05], 7, [2,1], 3, 7>; // Unsupported = 1
262 defm : SBWriteResPair<WriteFRsqrt, [SBPort0], 5, [1], 1, 6>;
263 defm : SBWriteResPair<WriteFRsqrtX,[SBPort0], 5, [1], 1, 6>;
264 defm : SBWriteResPair<WriteFRsqrtY,[SBPort0,SBPort05], 7, [2,1], 3, 7>;
265 defm : SBWriteResPair<WriteFRsqrtZ,[SBPort0,SBPort05], 7, [2,1], 3, 7>; // Unsupported = 1
267 defm : SBWriteResPair<WriteFSqrt, [SBPort0,SBFPDivider], 14, [1,14], 1, 6>;
268 defm : SBWriteResPair<WriteFSqrtX, [SBPort0,SBFPDivider], 14, [1,14], 1, 6>;
269 defm : SBWriteResPair<WriteFSqrtY, [SBPort0,SBPort05,SBFPDivider], 29, [2,1,28], 3, 7>;
270 defm : SBWriteResPair<WriteFSqrtZ, [SBPort0,SBPort05,SBFPDivider], 29, [2,1,28], 3, 7>; // Unsupported = 1
271 defm : SBWriteResPair<WriteFSqrt64, [SBPort0,SBFPDivider], 21, [1,21], 1, 6>;
272 defm : SBWriteResPair<WriteFSqrt64X, [SBPort0,SBFPDivider], 21, [1,21], 1, 6>;
273 defm : SBWriteResPair<WriteFSqrt64Y, [SBPort0,SBPort05,SBFPDivider], 45, [2,1,44], 3, 7>;
274 defm : SBWriteResPair<WriteFSqrt64Z, [SBPort0,SBPort05,SBFPDivider], 45, [2,1,44], 3, 7>; // Unsupported = 1
275 defm : SBWriteResPair<WriteFSqrt80, [SBPort0,SBFPDivider], 24, [1,24], 1, 6>;
277 defm : SBWriteResPair<WriteDPPD, [SBPort0,SBPort1,SBPort5], 9, [1,1,1], 3, 6>;
278 defm : SBWriteResPair<WriteDPPS, [SBPort0,SBPort1,SBPort5], 12, [1,2,1], 4, 6>;
279 defm : SBWriteResPair<WriteDPPSY, [SBPort0,SBPort1,SBPort5], 12, [1,2,1], 4, 7>;
280 defm : SBWriteResPair<WriteDPPSZ, [SBPort0,SBPort1,SBPort5], 12, [1,2,1], 4, 7>; // Unsupported = 1
281 defm : SBWriteResPair<WriteFSign, [SBPort5], 1>;
282 defm : SBWriteResPair<WriteFRnd, [SBPort1], 3, [1], 1, 6>;
283 defm : SBWriteResPair<WriteFRndY, [SBPort1], 3, [1], 1, 7>;
284 defm : SBWriteResPair<WriteFRndZ, [SBPort1], 3, [1], 1, 7>; // Unsupported = 1
285 defm : SBWriteResPair<WriteFLogic, [SBPort5], 1, [1], 1, 6>;
286 defm : SBWriteResPair<WriteFLogicY, [SBPort5], 1, [1], 1, 7>;
287 defm : SBWriteResPair<WriteFLogicZ, [SBPort5], 1, [1], 1, 7>; // Unsupported = 1
288 defm : SBWriteResPair<WriteFTest, [SBPort0], 1, [1], 1, 6>;
289 defm : SBWriteResPair<WriteFTestY, [SBPort0], 1, [1], 1, 7>;
290 defm : SBWriteResPair<WriteFTestZ, [SBPort0], 1, [1], 1, 7>; // Unsupported = 1
291 defm : SBWriteResPair<WriteFShuffle, [SBPort5], 1, [1], 1, 6>;
292 defm : SBWriteResPair<WriteFShuffleY,[SBPort5], 1, [1], 1, 7>;
293 defm : SBWriteResPair<WriteFShuffleZ,[SBPort5], 1, [1], 1, 7>; // Unsupported = 1
294 defm : SBWriteResPair<WriteFVarShuffle, [SBPort5], 1, [1], 1, 6>;
295 defm : SBWriteResPair<WriteFVarShuffleY,[SBPort5], 1, [1], 1, 7>;
296 defm : SBWriteResPair<WriteFVarShuffleZ,[SBPort5], 1, [1], 1, 7>; // Unsupported = 1
297 defm : SBWriteResPair<WriteFBlend, [SBPort05], 1, [1], 1, 6>;
298 defm : SBWriteResPair<WriteFBlendY, [SBPort05], 1, [1], 1, 7>;
299 defm : SBWriteResPair<WriteFBlendZ, [SBPort05], 1, [1], 1, 7>; // Unsupported = 1
300 defm : SBWriteResPair<WriteFVarBlend, [SBPort05], 2, [2], 2, 6>;
301 defm : SBWriteResPair<WriteFVarBlendY,[SBPort05], 2, [2], 2, 7>;
302 defm : SBWriteResPair<WriteFVarBlendZ,[SBPort05], 2, [2], 2, 7>; // Unsupported = 1
304 // Conversion between integer and float.
305 defm : SBWriteResPair<WriteCvtSS2I, [SBPort0,SBPort1], 5, [1,1], 2>;
306 defm : SBWriteResPair<WriteCvtPS2I, [SBPort1], 3, [1], 1, 6>;
307 defm : SBWriteResPair<WriteCvtPS2IY, [SBPort1], 3, [1], 1, 7>;
308 defm : SBWriteResPair<WriteCvtPS2IZ, [SBPort1], 3, [1], 1, 7>; // Unsupported = 1
309 defm : SBWriteResPair<WriteCvtSD2I, [SBPort0,SBPort1], 5, [1,1], 2>;
310 defm : SBWriteResPair<WriteCvtPD2I, [SBPort1,SBPort5], 4, [1,1], 2, 6>;
311 defm : X86WriteRes<WriteCvtPD2IY, [SBPort1,SBPort5], 4, [1,1], 2>;
312 defm : X86WriteRes<WriteCvtPD2IZ, [SBPort1,SBPort5], 4, [1,1], 2>; // Unsupported = 1
313 defm : X86WriteRes<WriteCvtPD2IYLd, [SBPort1,SBPort5,SBPort23], 11, [1,1,1], 3>;
314 defm : X86WriteRes<WriteCvtPD2IZLd, [SBPort1,SBPort5,SBPort23], 11, [1,1,1], 3>; // Unsupported = 1
316 defm : X86WriteRes<WriteCvtI2SS, [SBPort1,SBPort5], 5, [1,2], 3>;
317 defm : X86WriteRes<WriteCvtI2SSLd, [SBPort1,SBPort5,SBPort23], 10, [1,1,1], 3>;
318 defm : SBWriteResPair<WriteCvtI2PS, [SBPort1], 3, [1], 1, 6>;
319 defm : SBWriteResPair<WriteCvtI2PSY, [SBPort1], 3, [1], 1, 7>;
320 defm : SBWriteResPair<WriteCvtI2PSZ, [SBPort1], 3, [1], 1, 7>; // Unsupported = 1
321 defm : X86WriteRes<WriteCvtI2SD, [SBPort1,SBPort5], 4, [1,1], 2>;
322 defm : X86WriteRes<WriteCvtI2PD, [SBPort1,SBPort5], 4, [1,1], 2>;
323 defm : X86WriteRes<WriteCvtI2PDY, [SBPort1,SBPort5], 4, [1,1], 2>;
324 defm : X86WriteRes<WriteCvtI2PDZ, [SBPort1,SBPort5], 4, [1,1], 2>; // Unsupported = 1
325 defm : X86WriteRes<WriteCvtI2SDLd, [SBPort1,SBPort23], 9, [1,1], 2>;
326 defm : X86WriteRes<WriteCvtI2PDLd, [SBPort1,SBPort5,SBPort23], 10, [1,1,1], 3>;
327 defm : X86WriteRes<WriteCvtI2PDYLd, [SBPort1,SBPort5,SBPort23], 10, [1,1,1], 3>;
328 defm : X86WriteRes<WriteCvtI2PDZLd, [SBPort1,SBPort5,SBPort23], 10, [1,1,1], 3>; // Unsupported = 1
330 defm : SBWriteResPair<WriteCvtSS2SD, [SBPort0], 1, [1], 1, 6>;
331 defm : X86WriteRes<WriteCvtPS2PD, [SBPort0,SBPort5], 2, [1,1], 2>;
332 defm : X86WriteRes<WriteCvtPS2PDY, [SBPort0,SBPort5], 2, [1,1], 2>;
333 defm : X86WriteRes<WriteCvtPS2PDZ, [SBPort0,SBPort5], 2, [1,1], 2>; // Unsupported = 1
334 defm : X86WriteRes<WriteCvtPS2PDLd, [SBPort0,SBPort23], 7, [1,1], 2>;
335 defm : X86WriteRes<WriteCvtPS2PDYLd, [SBPort0,SBPort23], 7, [1,1], 2>;
336 defm : X86WriteRes<WriteCvtPS2PDZLd, [SBPort0,SBPort23], 7, [1,1], 2>; // Unsupported = 1
337 defm : SBWriteResPair<WriteCvtSD2SS, [SBPort1,SBPort5], 4, [1,1], 2, 6>;
338 defm : SBWriteResPair<WriteCvtPD2PS, [SBPort1,SBPort5], 4, [1,1], 2, 6>;
339 defm : SBWriteResPair<WriteCvtPD2PSY, [SBPort1,SBPort5], 4, [1,1], 2, 7>;
340 defm : SBWriteResPair<WriteCvtPD2PSZ, [SBPort1,SBPort5], 4, [1,1], 2, 7>; // Unsupported = 1
342 defm : SBWriteResPair<WriteCvtPH2PS, [SBPort1], 3>;
343 defm : SBWriteResPair<WriteCvtPH2PSY, [SBPort1], 3>;
344 defm : SBWriteResPair<WriteCvtPH2PSZ, [SBPort1], 3>; // Unsupported = 1
346 defm : X86WriteRes<WriteCvtPS2PH, [SBPort1], 3, [1], 1>;
347 defm : X86WriteRes<WriteCvtPS2PHY, [SBPort1], 3, [1], 1>;
348 defm : X86WriteRes<WriteCvtPS2PHZ, [SBPort1], 3, [1], 1>; // Unsupported = 1
349 defm : X86WriteRes<WriteCvtPS2PHSt, [SBPort1, SBPort23, SBPort4], 4, [1,1,1], 1>;
350 defm : X86WriteRes<WriteCvtPS2PHYSt, [SBPort1, SBPort23, SBPort4], 4, [1,1,1], 1>;
351 defm : X86WriteRes<WriteCvtPS2PHZSt, [SBPort1, SBPort23, SBPort4], 4, [1,1,1], 1>; // Unsupported = 1
353 // Vector integer operations.
354 defm : X86WriteRes<WriteVecLoad, [SBPort23], 5, [1], 1>;
355 defm : X86WriteRes<WriteVecLoadX, [SBPort23], 6, [1], 1>;
356 defm : X86WriteRes<WriteVecLoadY, [SBPort23], 7, [1], 1>;
357 defm : X86WriteRes<WriteVecLoadNT, [SBPort23], 6, [1], 1>;
358 defm : X86WriteRes<WriteVecLoadNTY, [SBPort23], 7, [1], 1>;
359 defm : X86WriteRes<WriteVecMaskedLoad, [SBPort23,SBPort05], 8, [1,2], 3>;
360 defm : X86WriteRes<WriteVecMaskedLoadY, [SBPort23,SBPort05], 9, [1,2], 3>;
361 defm : X86WriteRes<WriteVecStore, [SBPort23,SBPort4], 1, [1,1], 1>;
362 defm : X86WriteRes<WriteVecStoreX, [SBPort23,SBPort4], 1, [1,1], 1>;
363 defm : X86WriteRes<WriteVecStoreY, [SBPort23,SBPort4], 1, [1,1], 1>;
364 defm : X86WriteRes<WriteVecStoreNT, [SBPort23,SBPort4], 1, [1,1], 1>;
365 defm : X86WriteRes<WriteVecStoreNTY, [SBPort23,SBPort4], 1, [1,1], 1>;
366 defm : X86WriteRes<WriteVecMaskedStore, [SBPort4,SBPort01,SBPort23], 5, [1,1,1], 3>;
367 defm : X86WriteRes<WriteVecMaskedStoreY, [SBPort4,SBPort01,SBPort23], 5, [1,1,1], 3>;
368 defm : X86WriteRes<WriteVecMove, [SBPort05], 1, [1], 1>;
369 defm : X86WriteRes<WriteVecMoveX, [SBPort015], 1, [1], 1>;
370 defm : X86WriteRes<WriteVecMoveY, [SBPort05], 1, [1], 1>;
371 defm : X86WriteRes<WriteVecMoveToGpr, [SBPort0], 2, [1], 1>;
372 defm : X86WriteRes<WriteVecMoveFromGpr, [SBPort5], 1, [1], 1>;
374 defm : SBWriteResPair<WriteVecLogic, [SBPort015], 1, [1], 1, 5>;
375 defm : SBWriteResPair<WriteVecLogicX,[SBPort015], 1, [1], 1, 6>;
376 defm : SBWriteResPair<WriteVecLogicY,[SBPort015], 1, [1], 1, 7>;
377 defm : SBWriteResPair<WriteVecLogicZ,[SBPort015], 1, [1], 1, 7>; // Unsupported = 1
378 defm : SBWriteResPair<WriteVecTest, [SBPort0,SBPort5], 2, [1,1], 2, 6>;
379 defm : SBWriteResPair<WriteVecTestY, [SBPort0,SBPort5], 2, [1,1], 2, 7>;
380 defm : SBWriteResPair<WriteVecTestZ, [SBPort0,SBPort5], 2, [1,1], 2, 7>; // Unsupported = 1
381 defm : SBWriteResPair<WriteVecALU, [SBPort1], 3, [1], 1, 5>;
382 defm : SBWriteResPair<WriteVecALUX, [SBPort15], 1, [1], 1, 6>;
383 defm : SBWriteResPair<WriteVecALUY, [SBPort15], 1, [1], 1, 7>;
384 defm : SBWriteResPair<WriteVecALUZ, [SBPort15], 1, [1], 1, 7>; // Unsupported = 1
385 defm : SBWriteResPair<WriteVecIMul, [SBPort0], 5, [1], 1, 5>;
386 defm : SBWriteResPair<WriteVecIMulX, [SBPort0], 5, [1], 1, 6>;
387 defm : SBWriteResPair<WriteVecIMulY, [SBPort0], 5, [1], 1, 7>;
388 defm : SBWriteResPair<WriteVecIMulZ, [SBPort0], 5, [1], 1, 7>; // Unsupported = 1
389 defm : SBWriteResPair<WritePMULLD, [SBPort0], 5, [1], 1, 6>;
390 defm : SBWriteResPair<WritePMULLDY, [SBPort0], 5, [1], 1, 7>; // TODO this is probably wrong for 256/512-bit for the "generic" model
391 defm : SBWriteResPair<WritePMULLDZ, [SBPort0], 5, [1], 1, 7>; // Unsupported = 1
392 defm : SBWriteResPair<WriteShuffle, [SBPort5], 1, [1], 1, 5>;
393 defm : SBWriteResPair<WriteShuffleX, [SBPort15], 1, [1], 1, 6>;
394 defm : SBWriteResPair<WriteShuffleY, [SBPort5], 1, [1], 1, 7>;
395 defm : SBWriteResPair<WriteShuffleZ, [SBPort5], 1, [1], 1, 7>; // Unsupported = 1
396 defm : SBWriteResPair<WriteVarShuffle, [SBPort15], 1, [1], 1, 5>;
397 defm : SBWriteResPair<WriteVarShuffleX, [SBPort15], 1, [1], 1, 6>;
398 defm : SBWriteResPair<WriteVarShuffleY, [SBPort15], 1, [1], 1, 7>;
399 defm : SBWriteResPair<WriteVarShuffleZ, [SBPort15], 1, [1], 1, 7>; // Unsupported = 1
400 defm : SBWriteResPair<WriteBlend, [SBPort15], 1, [1], 1, 6>;
401 defm : SBWriteResPair<WriteBlendY, [SBPort15], 1, [1], 1, 7>;
402 defm : SBWriteResPair<WriteBlendZ, [SBPort15], 1, [1], 1, 7>; // Unsupported = 1
403 defm : SBWriteResPair<WriteVarBlend, [SBPort15], 2, [2], 2, 6>;
404 defm : SBWriteResPair<WriteVarBlendY,[SBPort15], 2, [2], 2, 7>;
405 defm : SBWriteResPair<WriteVarBlendZ,[SBPort15], 2, [2], 2, 7>; // Unsupported = 1
406 defm : SBWriteResPair<WriteMPSAD, [SBPort0, SBPort15], 7, [1,2], 3, 6>;
407 defm : SBWriteResPair<WriteMPSADY, [SBPort0, SBPort15], 7, [1,2], 3, 7>;
408 defm : SBWriteResPair<WriteMPSADZ, [SBPort0, SBPort15], 7, [1,2], 3, 7>; // Unsupported = 1
409 defm : SBWriteResPair<WritePSADBW, [SBPort0], 5, [1], 1, 5>;
410 defm : SBWriteResPair<WritePSADBWX, [SBPort0], 5, [1], 1, 6>;
411 defm : SBWriteResPair<WritePSADBWY, [SBPort0], 5, [1], 1, 7>;
412 defm : SBWriteResPair<WritePSADBWZ, [SBPort0], 5, [1], 1, 7>; // Unsupported = 1
413 defm : SBWriteResPair<WritePHMINPOS, [SBPort0], 5, [1], 1, 6>;
415 // Vector integer shifts.
416 defm : SBWriteResPair<WriteVecShift, [SBPort5], 1, [1], 1, 5>;
417 defm : SBWriteResPair<WriteVecShiftX, [SBPort0,SBPort15], 2, [1,1], 2, 6>;
418 defm : SBWriteResPair<WriteVecShiftY, [SBPort0,SBPort15], 4, [1,1], 2, 7>;
419 defm : SBWriteResPair<WriteVecShiftZ, [SBPort0,SBPort15], 4, [1,1], 2, 7>; // Unsupported = 1
420 defm : SBWriteResPair<WriteVecShiftImm, [SBPort5], 1, [1], 1, 5>;
421 defm : SBWriteResPair<WriteVecShiftImmX, [SBPort0], 1, [1], 1, 6>;
422 defm : SBWriteResPair<WriteVecShiftImmY, [SBPort0], 1, [1], 1, 7>;
423 defm : SBWriteResPair<WriteVecShiftImmZ, [SBPort0], 1, [1], 1, 7>; // Unsupported = 1
424 defm : SBWriteResPair<WriteVarVecShift, [SBPort0], 1, [1], 1, 6>;
425 defm : SBWriteResPair<WriteVarVecShiftY, [SBPort0], 1, [1], 1, 7>;
426 defm : SBWriteResPair<WriteVarVecShiftZ, [SBPort0], 1, [1], 1, 7>; // Unsupported = 1
428 // Vector insert/extract operations.
429 def : WriteRes<WriteVecInsert, [SBPort5,SBPort15]> {
433 def : WriteRes<WriteVecInsertLd, [SBPort23,SBPort15]> {
438 def : WriteRes<WriteVecExtract, [SBPort0,SBPort15]> {
442 def : WriteRes<WriteVecExtractSt, [SBPort4,SBPort23,SBPort15]> {
447 ////////////////////////////////////////////////////////////////////////////////
448 // Horizontal add/sub instructions.
449 ////////////////////////////////////////////////////////////////////////////////
451 defm : SBWriteResPair<WriteFHAdd, [SBPort1,SBPort5], 5, [1,2], 3, 6>;
452 defm : SBWriteResPair<WriteFHAddY, [SBPort1,SBPort5], 5, [1,2], 3, 7>;
453 defm : SBWriteResPair<WriteFHAddZ, [SBPort1,SBPort5], 5, [1,2], 3, 7>; // Unsupported = 1
454 defm : SBWriteResPair<WritePHAdd, [SBPort15], 3, [3], 3, 5>;
455 defm : SBWriteResPair<WritePHAddX, [SBPort15], 3, [3], 3, 6>;
456 defm : SBWriteResPair<WritePHAddY, [SBPort15], 3, [3], 3, 7>;
457 defm : SBWriteResPair<WritePHAddZ, [SBPort15], 3, [3], 3, 7>; // Unsupported = 1
459 ////////////////////////////////////////////////////////////////////////////////
460 // String instructions.
461 ////////////////////////////////////////////////////////////////////////////////
463 // Packed Compare Implicit Length Strings, Return Mask
464 def : WriteRes<WritePCmpIStrM, [SBPort0]> {
467 let ResourceCycles = [3];
469 def : WriteRes<WritePCmpIStrMLd, [SBPort0, SBPort23]> {
472 let ResourceCycles = [3,1];
475 // Packed Compare Explicit Length Strings, Return Mask
476 def : WriteRes<WritePCmpEStrM, [SBPort015]> {
478 let ResourceCycles = [8];
480 def : WriteRes<WritePCmpEStrMLd, [SBPort015, SBPort23]> {
482 let ResourceCycles = [7, 1];
485 // Packed Compare Implicit Length Strings, Return Index
486 def : WriteRes<WritePCmpIStrI, [SBPort0]> {
489 let ResourceCycles = [3];
491 def : WriteRes<WritePCmpIStrILd, [SBPort0,SBPort23]> {
494 let ResourceCycles = [3,1];
497 // Packed Compare Explicit Length Strings, Return Index
498 def : WriteRes<WritePCmpEStrI, [SBPort015]> {
500 let ResourceCycles = [8];
502 def : WriteRes<WritePCmpEStrILd, [SBPort015, SBPort23]> {
504 let ResourceCycles = [7, 1];
507 // MOVMSK Instructions.
508 def : WriteRes<WriteFMOVMSK, [SBPort0]> { let Latency = 2; }
509 def : WriteRes<WriteVecMOVMSK, [SBPort0]> { let Latency = 2; }
510 def : WriteRes<WriteVecMOVMSKY, [SBPort0]> { let Latency = 2; }
511 def : WriteRes<WriteMMXMOVMSK, [SBPort0]> { let Latency = 1; }
514 def : WriteRes<WriteAESDecEnc, [SBPort5,SBPort015]> {
517 let ResourceCycles = [1,1];
519 def : WriteRes<WriteAESDecEncLd, [SBPort5,SBPort23,SBPort015]> {
522 let ResourceCycles = [1,1,1];
525 def : WriteRes<WriteAESIMC, [SBPort5]> {
528 let ResourceCycles = [2];
530 def : WriteRes<WriteAESIMCLd, [SBPort5,SBPort23]> {
533 let ResourceCycles = [2,1];
536 def : WriteRes<WriteAESKeyGen, [SBPort015]> {
538 let ResourceCycles = [11];
540 def : WriteRes<WriteAESKeyGenLd, [SBPort015, SBPort23]> {
542 let ResourceCycles = [10, 1];
545 // Carry-less multiplication instructions.
546 def : WriteRes<WriteCLMul, [SBPort015]> {
548 let ResourceCycles = [18];
550 def : WriteRes<WriteCLMulLd, [SBPort015, SBPort23]> {
552 let ResourceCycles = [17, 1];
556 // FIXME: This is probably wrong. Only STMXCSR should require Port4.
557 def : WriteRes<WriteLDMXCSR, [SBPort0,SBPort4,SBPort5,SBPort23]> { let Latency = 5; let NumMicroOps = 4; let ResourceCycles = [1,1,1,1]; }
558 def : WriteRes<WriteSTMXCSR, [SBPort0,SBPort4,SBPort5,SBPort23]> { let Latency = 5; let NumMicroOps = 4; let ResourceCycles = [1,1,1,1]; }
560 def : WriteRes<WriteSystem, [SBPort015]> { let Latency = 100; }
561 def : WriteRes<WriteMicrocoded, [SBPort015]> { let Latency = 100; }
562 def : WriteRes<WriteFence, [SBPort23, SBPort4]>;
563 def : WriteRes<WriteNop, []>;
565 // AVX2/FMA is not supported on that architecture, but we should define the basic
566 // scheduling resources anyway.
567 defm : SBWriteResPair<WriteFShuffle256, [SBPort5], 1, [1], 1, 7>;
568 defm : SBWriteResPair<WriteFVarShuffle256, [SBPort5], 1, [1], 1, 7>;
569 defm : SBWriteResPair<WriteShuffle256, [SBPort5], 1, [1], 1, 7>;
570 defm : SBWriteResPair<WriteVarShuffle256, [SBPort5], 1, [1], 1, 7>;
571 defm : SBWriteResPair<WriteFMA, [SBPort01], 5>;
572 defm : SBWriteResPair<WriteFMAX, [SBPort01], 5>;
573 defm : SBWriteResPair<WriteFMAY, [SBPort01], 5>;
574 defm : SBWriteResPair<WriteFMAZ, [SBPort01], 5>; // Unsupported = 1
576 // Remaining SNB instrs.
578 def SBWriteResGroup1 : SchedWriteRes<[SBPort1]> {
581 let ResourceCycles = [1];
583 def: InstRW<[SBWriteResGroup1], (instrs COMP_FST0r,
588 def SBWriteResGroup2 : SchedWriteRes<[SBPort5]> {
591 let ResourceCycles = [1];
593 def: InstRW<[SBWriteResGroup2], (instrs FDECSTP, FINCSTP, FFREE, FFREEP, FNOP,
594 LD_Frr, ST_Frr, ST_FPrr)>;
595 def: InstRW<[SBWriteResGroup2], (instrs LOOP, LOOPE, LOOPNE)>; // FIXME: This seems wrong compared to other Intel CPUs.
596 def: InstRW<[SBWriteResGroup2], (instrs RETQ)>;
598 def SBWriteResGroup4 : SchedWriteRes<[SBPort05]> {
601 let ResourceCycles = [1];
603 def: InstRW<[SBWriteResGroup4], (instrs CDQ, CQO)>;
605 def SBWriteResGroup5 : SchedWriteRes<[SBPort15]> {
608 let ResourceCycles = [1];
610 def: InstRW<[SBWriteResGroup5], (instrs MMX_PABSBrr,
619 def SBWriteResGroup9 : SchedWriteRes<[SBPort05]> {
622 let ResourceCycles = [2];
624 def: InstRW<[SBWriteResGroup9], (instregex "SET(A|BE)r")>;
626 def SBWriteResGroup11 : SchedWriteRes<[SBPort015]> {
629 let ResourceCycles = [2];
631 def: InstRW<[SBWriteResGroup11], (instrs SCASB,
636 def SBWriteResGroup12 : SchedWriteRes<[SBPort0,SBPort1]> {
639 let ResourceCycles = [1,1];
641 def: InstRW<[SBWriteResGroup12], (instregex "(V?)(U?)COMI(SD|SS)rr")>;
643 def SBWriteResGroup15 : SchedWriteRes<[SBPort0,SBPort015]> {
646 let ResourceCycles = [1,1];
648 def: InstRW<[SBWriteResGroup15], (instrs CWD,
651 def SBWriteResGroup18 : SchedWriteRes<[SBPort5,SBPort015]> {
654 let ResourceCycles = [1,1];
656 def: InstRW<[SBWriteResGroup18], (instrs JCXZ, JECXZ, JRCXZ,
659 def SBWriteResGroup21 : SchedWriteRes<[SBPort1]> {
662 let ResourceCycles = [1];
664 def: InstRW<[SBWriteResGroup21], (instrs PUSHFS64)>;
666 def SBWriteResGroup22 : SchedWriteRes<[SBPort0,SBPort5]> {
669 let ResourceCycles = [1,1];
671 def: InstRW<[SBWriteResGroup22], (instregex "(V?)EXTRACTPSrr")>;
673 def SBWriteResGroup23 : SchedWriteRes<[SBPort05]> {
676 let ResourceCycles = [3];
678 def: InstRW<[SBWriteResGroup23], (instregex "RCL(8|16|32|64)r1",
679 "RCR(8|16|32|64)r1")>;
681 def SBWriteResGroup25_1 : SchedWriteRes<[SBPort23,SBPort015]> {
684 let ResourceCycles = [1,2];
686 def: InstRW<[SBWriteResGroup25_1], (instrs LEAVE, LEAVE64)>;
688 def SBWriteResGroup26_2 : SchedWriteRes<[SBPort0,SBPort1,SBPort5]> {
691 let ResourceCycles = [1,1,1];
693 def: InstRW<[SBWriteResGroup26_2], (instrs COM_FIPr, COM_FIr, UCOM_FIPr, UCOM_FIr)>;
695 def SBWriteResGroup29 : SchedWriteRes<[SBPort1,SBPort015]> {
698 let ResourceCycles = [1,1];
700 def: InstRW<[SBWriteResGroup29], (instrs MOV64sr)>;
702 def SBWriteResGroup29_2 : SchedWriteRes<[SBPort5,SBPort015]> {
705 let ResourceCycles = [1,3];
707 def: InstRW<[SBWriteResGroup29_2], (instrs PAUSE)>;
709 def SBWriteResGroup30 : SchedWriteRes<[SBPort0]> {
712 let ResourceCycles = [1];
715 def SBWriteResGroup31 : SchedWriteRes<[SBPort23]> {
718 let ResourceCycles = [1];
720 def: InstRW<[SBWriteResGroup31], (instregex "MOVSX(16|32|64)rm(8|16|32)",
721 "MOVZX(16|32|64)rm(8|16)")>;
723 def SBWriteResGroup76 : SchedWriteRes<[SBPort05]> {
726 let ResourceCycles = [8];
728 def: InstRW<[SBWriteResGroup76], (instregex "RCL(8|16|32|64)r(i|CL)",
729 "RCR(8|16|32|64)r(i|CL)")>;
731 def SBWriteResGroup33 : SchedWriteRes<[SBPort4,SBPort23]> {
734 let ResourceCycles = [1,1];
736 def: InstRW<[SBWriteResGroup33], (instregex "PUSH(16r|32r|64r|64i8)")>;
738 def SBWriteResGroup35 : SchedWriteRes<[SBPort1,SBPort5]> {
741 let ResourceCycles = [1,2];
743 def: InstRW<[SBWriteResGroup35], (instrs CLI)>;
745 def SBWriteResGroup35_2 : SchedWriteRes<[SBPort1,SBPort4,SBPort23]> {
748 let ResourceCycles = [1,1,1];
750 def: InstRW<[SBWriteResGroup35_2], (instrs PUSHGS64)>;
751 def: InstRW<[SBWriteResGroup35_2], (instregex "ISTT_FP(16|32|64)m")>;
753 def SBWriteResGroup36 : SchedWriteRes<[SBPort4,SBPort5,SBPort23]> {
756 let ResourceCycles = [1,1,1];
758 def: InstRW<[SBWriteResGroup36], (instrs CALL64pcrel32)>;
759 def: InstRW<[SBWriteResGroup36], (instregex "CALL(16|32|64)r",
762 def SBWriteResGroup40 : SchedWriteRes<[SBPort4,SBPort23,SBPort015]> {
765 let ResourceCycles = [1,1,1];
767 def: InstRW<[SBWriteResGroup40], (instrs STOSB, STOSL, STOSQ, STOSW)>;
769 def SBWriteResGroup41 : SchedWriteRes<[SBPort5,SBPort015]> {
772 let ResourceCycles = [1,3];
774 def: InstRW<[SBWriteResGroup41], (instrs FNINIT)>;
776 def SBWriteResGroup43 : SchedWriteRes<[SBPort4,SBPort23,SBPort05]> {
779 let ResourceCycles = [1,1,2];
781 def: InstRW<[SBWriteResGroup43], (instregex "SET(A|BE)m")>;
783 def SBWriteResGroup45 : SchedWriteRes<[SBPort0,SBPort4,SBPort23,SBPort15]> {
786 let ResourceCycles = [1,1,1,1];
788 def: InstRW<[SBWriteResGroup45], (instregex "(V?)PEXTR(D|Q)mr",
791 def SBWriteResGroup46 : SchedWriteRes<[SBPort4,SBPort5,SBPort01,SBPort23]> {
794 let ResourceCycles = [1,1,1,1];
796 def: InstRW<[SBWriteResGroup46], (instregex "CLFLUSH")>;
798 def SBWriteResGroup47 : SchedWriteRes<[SBPort4,SBPort5,SBPort01,SBPort23]> {
801 let ResourceCycles = [1,2,1,1];
803 def: InstRW<[SBWriteResGroup47], (instregex "FXRSTOR")>;
805 def SBWriteResGroup48 : SchedWriteRes<[SBPort23]> {
808 let ResourceCycles = [1];
810 def: InstRW<[SBWriteResGroup48], (instrs MMX_MOVD64from64rm,
812 def: InstRW<[SBWriteResGroup48], (instregex "POP(16|32|64)r",
822 def SBWriteResGroup49 : SchedWriteRes<[SBPort5,SBPort23]> {
825 let ResourceCycles = [1,1];
827 def: InstRW<[SBWriteResGroup49], (instrs MOV16sm)>;
829 def SBWriteResGroup51 : SchedWriteRes<[SBPort23,SBPort15]> {
832 let ResourceCycles = [1,1];
834 def: InstRW<[SBWriteResGroup51], (instrs MMX_PABSBrm,
842 def SBWriteResGroup52 : SchedWriteRes<[SBPort23,SBPort015]> {
845 let ResourceCycles = [1,1];
847 def: InstRW<[SBWriteResGroup52], (instrs LODSL, LODSQ)>;
849 def SBWriteResGroup53 : SchedWriteRes<[SBPort4,SBPort23]> {
852 let ResourceCycles = [1,2];
854 def: InstRW<[SBWriteResGroup53], (instregex "ST_F(32|64)m",
855 "ST_FP(32|64|80)m")>;
857 def SBWriteResGroup54 : SchedWriteRes<[SBPort23]> {
860 let ResourceCycles = [1];
862 def: InstRW<[SBWriteResGroup54], (instrs VBROADCASTSDYrm,
868 def SBWriteResGroup58 : SchedWriteRes<[SBPort23,SBPort05]> {
871 let ResourceCycles = [1,1];
873 def: InstRW<[SBWriteResGroup58], (instrs VINSERTF128rm)>;
875 def SBWriteResGroup59 : SchedWriteRes<[SBPort23,SBPort15]> {
878 let ResourceCycles = [1,1];
880 def: InstRW<[SBWriteResGroup59], (instrs MMX_PADDQirm)>;
882 def SBWriteResGroup62 : SchedWriteRes<[SBPort5,SBPort23]> {
885 let ResourceCycles = [2,1];
887 def: InstRW<[SBWriteResGroup62], (instrs VERRm, VERWm)>;
889 def SBWriteResGroup63 : SchedWriteRes<[SBPort23,SBPort015]> {
892 let ResourceCycles = [1,2];
894 def: InstRW<[SBWriteResGroup63], (instrs LODSB, LODSW)>;
896 def SBWriteResGroup64 : SchedWriteRes<[SBPort5,SBPort01,SBPort23]> {
899 let ResourceCycles = [1,1,1];
901 def: InstRW<[SBWriteResGroup64], (instrs FARJMP64)>;
903 def SBWriteResGroup66 : SchedWriteRes<[SBPort0,SBPort4,SBPort23]> {
906 let ResourceCycles = [1,1,2];
908 def: InstRW<[SBWriteResGroup66], (instrs FNSTSWm)>;
910 def SBWriteResGroup67 : SchedWriteRes<[SBPort1,SBPort5,SBPort015]> {
913 let ResourceCycles = [1,2,1];
915 def: InstRW<[SBWriteResGroup67], (instregex "SLDT(16|32|64)r",
918 def SBWriteResGroup68 : SchedWriteRes<[SBPort4,SBPort5,SBPort23]> {
921 let ResourceCycles = [1,1,2];
923 def: InstRW<[SBWriteResGroup68], (instrs FNSTCW16m)>;
924 def: InstRW<[SBWriteResGroup68], (instregex "CALL(16|32|64)m")>;
926 def SBWriteResGroup69 : SchedWriteRes<[SBPort4,SBPort23,SBPort05]> {
929 let ResourceCycles = [1,2,1];
931 def: InstRW<[SBWriteResGroup69], (instregex "SAR(8|16|32|64)m(1|i)",
932 "SHL(8|16|32|64)m(1|i)",
933 "SHR(8|16|32|64)m(1|i)")>;
935 def SBWriteResGroup77 : SchedWriteRes<[SBPort0,SBPort1,SBPort23]> {
938 let ResourceCycles = [1,1,1];
940 def: InstRW<[SBWriteResGroup77], (instregex "(V?)(U?)COMI(SD|SS)rm")>;
942 def SBWriteResGroup81 : SchedWriteRes<[SBPort4, SBPort23, SBPort015]> {
945 let ResourceCycles = [1, 2, 1];
947 def: InstRW<[SBWriteResGroup81], (instregex "CMPXCHG(8|16)B")>;
949 def SBWriteResGroup83 : SchedWriteRes<[SBPort23,SBPort015]> {
952 let ResourceCycles = [2,3];
954 def: InstRW<[SBWriteResGroup83], (instrs CMPSB,
959 def SBWriteResGroup84 : SchedWriteRes<[SBPort4,SBPort5,SBPort23]> {
962 let ResourceCycles = [1,2,2];
964 def: InstRW<[SBWriteResGroup84], (instrs FLDCW16m)>;
966 def SBWriteResGroup85 : SchedWriteRes<[SBPort4,SBPort23,SBPort05]> {
969 let ResourceCycles = [1,2,2];
971 def: InstRW<[SBWriteResGroup85], (instregex "ROL(8|16|32|64)m(1|i)",
972 "ROR(8|16|32|64)m(1|i)")>;
974 def SBWriteResGroup86 : SchedWriteRes<[SBPort4,SBPort23,SBPort015]> {
977 let ResourceCycles = [1,2,2];
979 def: InstRW<[SBWriteResGroup86], (instrs MOVSB, MOVSL, MOVSQ, MOVSW)>;
980 def: InstRW<[SBWriteResGroup86], (instregex "XADD(8|16|32|64)rm")>;
982 def SBWriteResGroup87 : SchedWriteRes<[SBPort4,SBPort5,SBPort01,SBPort23]> {
985 let ResourceCycles = [1,1,1,2];
987 def: InstRW<[SBWriteResGroup87], (instrs FARCALL64)>;
989 def SBWriteResGroup93 : SchedWriteRes<[SBPort0,SBPort1,SBPort23]> {
992 let ResourceCycles = [1,1,1];
994 def: InstRW<[SBWriteResGroup93], (instregex "CVT(T?)(SD|SS)2SI(64)?rm")>;
996 def SBWriteResGroup95 : SchedWriteRes<[SBPort5,SBPort01,SBPort23]> {
999 let ResourceCycles = [1,1,1];
1001 def: InstRW<[SBWriteResGroup95], (instregex "LD_F(32|64|80)m")>;
1003 def SBWriteResGroup97 : SchedWriteRes<[SBPort1,SBPort4,SBPort23]> {
1005 let NumMicroOps = 4;
1006 let ResourceCycles = [1,1,2];
1008 def: InstRW<[SBWriteResGroup97], (instregex "IST_F(16|32)m",
1009 "IST_FP(16|32|64)m")>;
1011 def SBWriteResGroup97_2 : SchedWriteRes<[SBPort4,SBPort23,SBPort05]> {
1013 let NumMicroOps = 6;
1014 let ResourceCycles = [1,2,3];
1016 def: InstRW<[SBWriteResGroup97_2], (instregex "ROL(8|16|32|64)mCL",
1017 "ROR(8|16|32|64)mCL",
1018 "SAR(8|16|32|64)mCL",
1019 "SHL(8|16|32|64)mCL",
1020 "SHR(8|16|32|64)mCL")>;
1022 def SBWriteResGroup98 : SchedWriteRes<[SBPort4,SBPort23,SBPort015]> {
1024 let NumMicroOps = 6;
1025 let ResourceCycles = [1,2,3];
1027 def: SchedAlias<WriteADCRMW, SBWriteResGroup98>;
1029 def SBWriteResGroup99 : SchedWriteRes<[SBPort4,SBPort23,SBPort05,SBPort015]> {
1031 let NumMicroOps = 6;
1032 let ResourceCycles = [1,2,2,1];
1034 def: InstRW<[SBWriteResGroup99, ReadAfterLd], (instrs ADC8mr, ADC16mr, ADC32mr, ADC64mr,
1035 SBB8mr, SBB16mr, SBB32mr, SBB64mr)>;
1037 def SBWriteResGroup100 : SchedWriteRes<[SBPort4,SBPort5,SBPort23,SBPort05,SBPort015]> {
1039 let NumMicroOps = 6;
1040 let ResourceCycles = [1,1,2,1,1];
1042 def : SchedAlias<WriteBitTestRegLd, SBWriteResGroup100>; // TODO - this is incorrect - no RMW
1044 def SBWriteResGroup101 : SchedWriteRes<[SBPort1,SBPort23]> {
1046 let NumMicroOps = 2;
1047 let ResourceCycles = [1,1];
1049 def: InstRW<[SBWriteResGroup101], (instregex "(ADD|SUB|SUBR)_F(32|64)m",
1050 "ILD_F(16|32|64)m")>;
1052 def SBWriteResGroup104 : SchedWriteRes<[SBPort0,SBPort23]> {
1054 let NumMicroOps = 2;
1055 let ResourceCycles = [1,1];
1057 def: InstRW<[SBWriteResGroup104], (instregex "(V?)PCMPGTQrm")>;
1059 def SBWriteResGroup106 : SchedWriteRes<[SBPort1,SBPort23]> {
1061 let NumMicroOps = 3;
1062 let ResourceCycles = [2,1];
1064 def: InstRW<[SBWriteResGroup106], (instregex "FICOM(P?)(16|32)m")>;
1066 def SBWriteResGroup108 : SchedWriteRes<[SBPort05,SBPort23]> {
1068 let NumMicroOps = 11;
1069 let ResourceCycles = [7,4];
1071 def: InstRW<[SBWriteResGroup108], (instregex "RCL(8|16|32|64)m",
1072 "RCR(8|16|32|64)m")>;
1074 def SBWriteResGroup111 : SchedWriteRes<[SBPort0,SBPort23]> {
1076 let NumMicroOps = 2;
1077 let ResourceCycles = [1,1];
1079 def: InstRW<[SBWriteResGroup111], (instregex "MUL_F(32|64)m")>;
1081 def SBWriteResGroup114 : SchedWriteRes<[SBPort1,SBPort23]> {
1083 let NumMicroOps = 3;
1084 let ResourceCycles = [2,1];
1086 def: InstRW<[SBWriteResGroup114], (instregex "(ADD|SUB|SUBR)_FI(16|32)m")>;
1088 def SBWriteResGroup119 : SchedWriteRes<[SBPort0,SBPort1,SBPort23]> {
1090 let NumMicroOps = 3;
1091 let ResourceCycles = [1,1,1];
1093 def: InstRW<[SBWriteResGroup119], (instregex "MUL_FI(16|32)m")>;
1095 def SBWriteResGroup130 : SchedWriteRes<[SBPort0,SBPort23]> {
1097 let NumMicroOps = 2;
1098 let ResourceCycles = [1,1];
1100 def: InstRW<[SBWriteResGroup130], (instregex "DIV(R?)_F(32|64)m")>;
1102 def SBWriteResGroup131 : SchedWriteRes<[SBPort0,SBPort1,SBPort23]> {
1104 let NumMicroOps = 3;
1105 let ResourceCycles = [1,1,1];
1107 def: InstRW<[SBWriteResGroup131], (instregex "DIV(R?)_FI(16|32)m")>;
1109 def SBWriteResGroupVzeroall : SchedWriteRes<[SBPort5]> {
1111 let NumMicroOps = 20;
1112 let ResourceCycles = [2];
1114 def: InstRW<[SBWriteResGroupVzeroall], (instrs VZEROALL)>;
1116 def SBWriteResGroupVzeroupper : SchedWriteRes<[]> {
1118 let NumMicroOps = 4;
1119 let ResourceCycles = [];
1121 def: InstRW<[SBWriteResGroupVzeroupper], (instrs VZEROUPPER)>;
1123 def: InstRW<[WriteZero], (instrs CLC)>;
1125 // Intruction variants handled by the renamer. These might not need execution
1126 // ports in certain conditions.
1127 // See Agner's Fog "The microarchitecture of Intel, AMD and VIA CPUs",
1128 // section "Sandy Bridge and Ivy Bridge Pipeline" > "Register allocation and
1130 // These can be investigated with llvm-exegesis, e.g.
1131 // echo 'pxor %mm0, %mm0' | /tmp/llvm-exegesis -mode=uops -snippets-file=-
1132 // echo 'vxorpd %xmm0, %xmm0, %xmm1' | /tmp/llvm-exegesis -mode=uops -snippets-file=-
1134 def SBWriteZeroLatency : SchedWriteRes<[]> {
1138 def SBWriteZeroIdiom : SchedWriteVariant<[
1139 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [SBWriteZeroLatency]>,
1140 SchedVar<NoSchedPred, [WriteALU]>
1142 def : InstRW<[SBWriteZeroIdiom], (instrs SUB32rr, SUB64rr,
1145 def SBWriteFZeroIdiom : SchedWriteVariant<[
1146 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [SBWriteZeroLatency]>,
1147 SchedVar<NoSchedPred, [WriteFLogic]>
1149 def : InstRW<[SBWriteFZeroIdiom], (instrs XORPSrr, VXORPSrr, XORPDrr,
1152 def SBWriteVZeroIdiomLogicX : SchedWriteVariant<[
1153 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [SBWriteZeroLatency]>,
1154 SchedVar<NoSchedPred, [WriteVecLogicX]>
1156 def : InstRW<[SBWriteVZeroIdiomLogicX], (instrs PXORrr, VPXORrr)>;
1158 def SBWriteVZeroIdiomALUX : SchedWriteVariant<[
1159 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [SBWriteZeroLatency]>,
1160 SchedVar<NoSchedPred, [WriteVecALUX]>
1162 def : InstRW<[SBWriteVZeroIdiomALUX], (instrs PSUBBrr, VPSUBBrr,
1166 PCMPGTBrr, VPCMPGTBrr,
1167 PCMPGTDrr, VPCMPGTDrr,
1168 PCMPGTWrr, VPCMPGTWrr)>;
1170 def SBWriteVZeroIdiomPCMPGTQ : SchedWriteVariant<[
1171 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [SBWriteZeroLatency]>,
1172 SchedVar<NoSchedPred, [SBWriteResGroup30]>
1174 def : InstRW<[SBWriteVZeroIdiomPCMPGTQ], (instrs PCMPGTQrr, VPCMPGTQrr)>;