[asan] Add a flag to control asm instrumentation.
[oota-llvm.git] / lib / Target / X86 / X86ScheduleSLM.td
1 //=- X86ScheduleSLM.td - X86 Silvermont Scheduling -----------*- tablegen -*-=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the machine model for Intel Silvermont to support
11 // instruction scheduling and other instruction cost heuristics.
12 //
13 //===----------------------------------------------------------------------===//
14
15 def SLMModel : SchedMachineModel {
16   // All x86 instructions are modeled as a single micro-op, and SLM can decode 2
17   // instructions per cycle.
18   let IssueWidth = 2;
19   let MicroOpBufferSize = 32; // Based on the reorder buffer.
20   let LoadLatency = 3;
21   let MispredictPenalty = 10;
22
23   // FIXME: SSE4 is unimplemented. This flag is set to allow
24   // the scheduler to assign a default model to unrecognized opcodes.
25   let CompleteModel = 0;
26 }
27
28 let SchedModel = SLMModel in {
29
30 // Silvermont has 5 reservation stations for micro-ops
31
32 def IEC_RSV0 : ProcResource<1>;
33 def IEC_RSV1 : ProcResource<1>;
34 def FPC_RSV0 : ProcResource<1> { let BufferSize = 1; }
35 def FPC_RSV1 : ProcResource<1> { let BufferSize = 1; }
36 def MEC_RSV  : ProcResource<1>;
37
38 // Many micro-ops are capable of issuing on multiple ports.
39 def IEC_RSV01  : ProcResGroup<[IEC_RSV0, IEC_RSV1]>;
40 def FPC_RSV01  : ProcResGroup<[FPC_RSV0, FPC_RSV1]>;
41
42 def SMDivider      : ProcResource<1>;
43 def SMFPMultiplier : ProcResource<1>;
44 def SMFPDivider    : ProcResource<1>;
45
46 // Loads are 3 cycles, so ReadAfterLd registers needn't be available until 3
47 // cycles after the memory operand.
48 def : ReadAdvance<ReadAfterLd, 3>;
49
50 // Many SchedWrites are defined in pairs with and without a folded load.
51 // Instructions with folded loads are usually micro-fused, so they only appear
52 // as two micro-ops when queued in the reservation station.
53 // This multiclass defines the resource usage for variants with and without
54 // folded loads.
55 multiclass SMWriteResPair<X86FoldableSchedWrite SchedRW,
56                           ProcResourceKind ExePort,
57                           int Lat> {
58   // Register variant is using a single cycle on ExePort.
59   def : WriteRes<SchedRW, [ExePort]> { let Latency = Lat; }
60
61   // Memory variant also uses a cycle on MEC_RSV and adds 3 cycles to the
62   // latency.
63   def : WriteRes<SchedRW.Folded, [MEC_RSV, ExePort]> {
64      let Latency = !add(Lat, 3);
65   }
66 }
67
68 // A folded store needs a cycle on MEC_RSV for the store data, but it does not
69 // need an extra port cycle to recompute the address.
70 def : WriteRes<WriteRMW, [MEC_RSV]>;
71
72 def : WriteRes<WriteStore, [IEC_RSV01, MEC_RSV]>;
73 def : WriteRes<WriteLoad,  [MEC_RSV]> { let Latency = 3; }
74 def : WriteRes<WriteMove,  [IEC_RSV01]>;
75 def : WriteRes<WriteZero,  []>;
76
77 defm : SMWriteResPair<WriteALU,   IEC_RSV01, 1>;
78 defm : SMWriteResPair<WriteIMul,  IEC_RSV1,  3>;
79 defm : SMWriteResPair<WriteShift, IEC_RSV0,  1>;
80 defm : SMWriteResPair<WriteJump,  IEC_RSV1,   1>;
81
82 // This is for simple LEAs with one or two input operands.
83 // The complex ones can only execute on port 1, and they require two cycles on
84 // the port to read all inputs. We don't model that.
85 def : WriteRes<WriteLEA, [IEC_RSV1]>;
86
87 // This is quite rough, latency depends on the dividend.
88 def : WriteRes<WriteIDiv, [IEC_RSV01, SMDivider]> {
89   let Latency = 25;
90   let ResourceCycles = [1, 25];
91 }
92 def : WriteRes<WriteIDivLd, [MEC_RSV, IEC_RSV01, SMDivider]> {
93   let Latency = 29;
94   let ResourceCycles = [1, 1, 25];
95 }
96
97 // Scalar and vector floating point.
98 defm : SMWriteResPair<WriteFAdd,   FPC_RSV1, 3>;
99 defm : SMWriteResPair<WriteFRcp,   FPC_RSV0, 5>;
100 defm : SMWriteResPair<WriteFSqrt,  FPC_RSV0, 15>;
101 defm : SMWriteResPair<WriteCvtF2I, FPC_RSV01, 4>;
102 defm : SMWriteResPair<WriteCvtI2F, FPC_RSV01, 4>;
103 defm : SMWriteResPair<WriteCvtF2F, FPC_RSV01, 4>;
104 defm : SMWriteResPair<WriteFShuffle,  FPC_RSV0,  1>;
105 defm : SMWriteResPair<WriteFBlend,  FPC_RSV0,  1>;
106
107 // This is quite rough, latency depends on precision
108 def : WriteRes<WriteFMul, [FPC_RSV0, SMFPMultiplier]> {
109   let Latency = 5;
110   let ResourceCycles = [1, 2];
111 }
112 def : WriteRes<WriteFMulLd, [MEC_RSV, FPC_RSV0, SMFPMultiplier]> {
113   let Latency = 8;
114   let ResourceCycles = [1, 1, 2];
115 }
116
117 def : WriteRes<WriteFDiv, [FPC_RSV0, SMFPDivider]> {
118   let Latency = 34;
119   let ResourceCycles = [1, 34];
120 }
121 def : WriteRes<WriteFDivLd, [MEC_RSV, FPC_RSV0, SMFPDivider]> {
122   let Latency = 37;
123   let ResourceCycles = [1, 1, 34];
124 }
125
126 // Vector integer operations.
127 defm : SMWriteResPair<WriteVecShift, FPC_RSV0,  1>;
128 defm : SMWriteResPair<WriteVecLogic, FPC_RSV01, 1>;
129 defm : SMWriteResPair<WriteVecALU,   FPC_RSV01,  1>;
130 defm : SMWriteResPair<WriteVecIMul,  FPC_RSV0,   4>;
131 defm : SMWriteResPair<WriteShuffle,  FPC_RSV0,  1>;
132 defm : SMWriteResPair<WriteBlend,  FPC_RSV0,  1>;
133 defm : SMWriteResPair<WriteMPSAD,  FPC_RSV0,  7>;
134
135 // String instructions.
136 // Packed Compare Implicit Length Strings, Return Mask
137 def : WriteRes<WritePCmpIStrM, [FPC_RSV0]> {
138   let Latency = 13;
139   let ResourceCycles = [13];
140 }
141 def : WriteRes<WritePCmpIStrMLd, [FPC_RSV0, MEC_RSV]> {
142   let Latency = 13;
143   let ResourceCycles = [13, 1];
144 }
145
146 // Packed Compare Explicit Length Strings, Return Mask
147 def : WriteRes<WritePCmpEStrM, [FPC_RSV0]> {
148   let Latency = 17;
149   let ResourceCycles = [17];
150 }
151 def : WriteRes<WritePCmpEStrMLd, [FPC_RSV0, MEC_RSV]> {
152   let Latency = 17;
153   let ResourceCycles = [17, 1];
154 }
155
156 // Packed Compare Implicit Length Strings, Return Index
157 def : WriteRes<WritePCmpIStrI, [FPC_RSV0]> {
158   let Latency = 17;
159   let ResourceCycles = [17];
160 }
161 def : WriteRes<WritePCmpIStrILd, [FPC_RSV0, MEC_RSV]> {
162   let Latency = 17;
163   let ResourceCycles = [17, 1];
164 }
165
166 // Packed Compare Explicit Length Strings, Return Index
167 def : WriteRes<WritePCmpEStrI, [FPC_RSV0]> {
168   let Latency = 21;
169   let ResourceCycles = [21];
170 }
171 def : WriteRes<WritePCmpEStrILd, [FPC_RSV0, MEC_RSV]> {
172   let Latency = 21;
173   let ResourceCycles = [21, 1];
174 }
175
176 // AES Instructions.
177 def : WriteRes<WriteAESDecEnc, [FPC_RSV0]> {
178   let Latency = 8;
179   let ResourceCycles = [5];
180 }
181 def : WriteRes<WriteAESDecEncLd, [FPC_RSV0, MEC_RSV]> {
182   let Latency = 8;
183   let ResourceCycles = [5, 1];
184 }
185
186 def : WriteRes<WriteAESIMC, [FPC_RSV0]> {
187   let Latency = 8;
188   let ResourceCycles = [5];
189 }
190 def : WriteRes<WriteAESIMCLd, [FPC_RSV0, MEC_RSV]> {
191   let Latency = 8;
192   let ResourceCycles = [5, 1];
193 }
194
195 def : WriteRes<WriteAESKeyGen, [FPC_RSV0]> {
196   let Latency = 8;
197   let ResourceCycles = [5];
198 }
199 def : WriteRes<WriteAESKeyGenLd, [FPC_RSV0, MEC_RSV]> {
200   let Latency = 8;
201   let ResourceCycles = [5, 1];
202 }
203
204 // Carry-less multiplication instructions.
205 def : WriteRes<WriteCLMul, [FPC_RSV0]> {
206   let Latency = 10;
207   let ResourceCycles = [10];
208 }
209 def : WriteRes<WriteCLMulLd, [FPC_RSV0, MEC_RSV]> {
210   let Latency = 10;
211   let ResourceCycles = [10, 1];
212 }
213
214
215 def : WriteRes<WriteSystem,     [FPC_RSV0]> { let Latency = 100; }
216 def : WriteRes<WriteMicrocoded, [FPC_RSV0]> { let Latency = 100; }
217 def : WriteRes<WriteFence, [MEC_RSV]>;
218 def : WriteRes<WriteNop, []>;
219
220 // AVX is not supported on that architecture, but we should define the basic
221 // scheduling resources anyway.
222 def  : WriteRes<WriteIMulH, [FPC_RSV0]>;
223 defm : SMWriteResPair<WriteVarBlend, FPC_RSV0, 1>;
224 defm : SMWriteResPair<WriteFVarBlend, FPC_RSV0, 1>;
225 defm : SMWriteResPair<WriteFShuffle256, FPC_RSV0,  1>;
226 defm : SMWriteResPair<WriteShuffle256, FPC_RSV0,  1>;
227 defm : SMWriteResPair<WriteVarVecShift, FPC_RSV0,  1>;
228 } // SchedModel