1// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/compiler/instruction-scheduler.h"
6
7namespace v8 {
8namespace internal {
9namespace compiler {
10
11bool InstructionScheduler::SchedulerSupported() { return true; }
12
13
14int InstructionScheduler::GetTargetInstructionFlags(
15    const Instruction* instr) const {
16  switch (instr->arch_opcode()) {
17    case kArm64Add:
18    case kArm64Add32:
19    case kArm64And:
20    case kArm64And32:
21    case kArm64Bic:
22    case kArm64Bic32:
23    case kArm64Clz:
24    case kArm64Clz32:
25    case kArm64Cmp:
26    case kArm64Cmp32:
27    case kArm64Cmn:
28    case kArm64Cmn32:
29    case kArm64Tst:
30    case kArm64Tst32:
31    case kArm64Or:
32    case kArm64Or32:
33    case kArm64Orn:
34    case kArm64Orn32:
35    case kArm64Eor:
36    case kArm64Eor32:
37    case kArm64Eon:
38    case kArm64Eon32:
39    case kArm64Sub:
40    case kArm64Sub32:
41    case kArm64Mul:
42    case kArm64Mul32:
43    case kArm64Smull:
44    case kArm64Umull:
45    case kArm64Madd:
46    case kArm64Madd32:
47    case kArm64Msub:
48    case kArm64Msub32:
49    case kArm64Mneg:
50    case kArm64Mneg32:
51    case kArm64Idiv:
52    case kArm64Idiv32:
53    case kArm64Udiv:
54    case kArm64Udiv32:
55    case kArm64Imod:
56    case kArm64Imod32:
57    case kArm64Umod:
58    case kArm64Umod32:
59    case kArm64Not:
60    case kArm64Not32:
61    case kArm64Lsl:
62    case kArm64Lsl32:
63    case kArm64Lsr:
64    case kArm64Lsr32:
65    case kArm64Asr:
66    case kArm64Asr32:
67    case kArm64Ror:
68    case kArm64Ror32:
69    case kArm64Mov32:
70    case kArm64Sxtb32:
71    case kArm64Sxth32:
72    case kArm64Sxtw:
73    case kArm64Sbfx32:
74    case kArm64Ubfx:
75    case kArm64Ubfx32:
76    case kArm64Ubfiz32:
77    case kArm64Bfi:
78    case kArm64Rbit:
79    case kArm64Rbit32:
80    case kArm64Float32Cmp:
81    case kArm64Float32Add:
82    case kArm64Float32Sub:
83    case kArm64Float32Mul:
84    case kArm64Float32Div:
85    case kArm64Float32Abs:
86    case kArm64Float32Neg:
87    case kArm64Float32Sqrt:
88    case kArm64Float32RoundDown:
89    case kArm64Float32Max:
90    case kArm64Float32Min:
91    case kArm64Float64Cmp:
92    case kArm64Float64Add:
93    case kArm64Float64Sub:
94    case kArm64Float64Mul:
95    case kArm64Float64Div:
96    case kArm64Float64Mod:
97    case kArm64Float64Max:
98    case kArm64Float64Min:
99    case kArm64Float64Abs:
100    case kArm64Float64Neg:
101    case kArm64Float64Sqrt:
102    case kArm64Float64RoundDown:
103    case kArm64Float64RoundTiesAway:
104    case kArm64Float64RoundTruncate:
105    case kArm64Float64RoundTiesEven:
106    case kArm64Float64RoundUp:
107    case kArm64Float32RoundTiesEven:
108    case kArm64Float32RoundTruncate:
109    case kArm64Float32RoundUp:
110    case kArm64Float32ToFloat64:
111    case kArm64Float64ToFloat32:
112    case kArm64Float32ToInt32:
113    case kArm64Float64ToInt32:
114    case kArm64Float32ToUint32:
115    case kArm64Float64ToUint32:
116    case kArm64Float32ToInt64:
117    case kArm64Float64ToInt64:
118    case kArm64Float32ToUint64:
119    case kArm64Float64ToUint64:
120    case kArm64Int32ToFloat32:
121    case kArm64Int32ToFloat64:
122    case kArm64Int64ToFloat32:
123    case kArm64Int64ToFloat64:
124    case kArm64Uint32ToFloat32:
125    case kArm64Uint32ToFloat64:
126    case kArm64Uint64ToFloat32:
127    case kArm64Uint64ToFloat64:
128    case kArm64Float64ExtractLowWord32:
129    case kArm64Float64ExtractHighWord32:
130    case kArm64Float64InsertLowWord32:
131    case kArm64Float64InsertHighWord32:
132    case kArm64Float64MoveU64:
133    case kArm64U64MoveFloat64:
134    case kArm64Float64SilenceNaN:
135      return kNoOpcodeFlags;
136
137    case kArm64TestAndBranch32:
138    case kArm64TestAndBranch:
139    case kArm64CompareAndBranch32:
140    case kArm64CompareAndBranch:
141      return kIsBlockTerminator;
142
143    case kArm64LdrS:
144    case kArm64LdrD:
145    case kArm64Ldrb:
146    case kArm64Ldrsb:
147    case kArm64Ldrh:
148    case kArm64Ldrsh:
149    case kArm64Ldrsw:
150    case kArm64LdrW:
151    case kArm64Ldr:
152      return kIsLoadOperation;
153
154    case kArm64ClaimCSP:
155    case kArm64ClaimJSSP:
156    case kArm64PokeCSP:
157    case kArm64PokeJSSP:
158    case kArm64PokePair:
159    case kArm64StrS:
160    case kArm64StrD:
161    case kArm64Strb:
162    case kArm64Strh:
163    case kArm64StrW:
164    case kArm64Str:
165      return kHasSideEffect;
166
167#define CASE(Name) case k##Name:
168    COMMON_ARCH_OPCODE_LIST(CASE)
169#undef CASE
170      // Already covered in architecture independent code.
171      UNREACHABLE();
172  }
173
174  UNREACHABLE();
175  return kNoOpcodeFlags;
176}
177
178
179int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
180  // Basic latency modeling for arm64 instructions. They have been determined
181  // in an empirical way.
182  switch (instr->arch_opcode()) {
183    case kArm64Add:
184    case kArm64Add32:
185    case kArm64And:
186    case kArm64And32:
187    case kArm64Bic:
188    case kArm64Bic32:
189    case kArm64Cmn:
190    case kArm64Cmn32:
191    case kArm64Cmp:
192    case kArm64Cmp32:
193    case kArm64Eon:
194    case kArm64Eon32:
195    case kArm64Eor:
196    case kArm64Eor32:
197    case kArm64Not:
198    case kArm64Not32:
199    case kArm64Or:
200    case kArm64Or32:
201    case kArm64Orn:
202    case kArm64Orn32:
203    case kArm64Sub:
204    case kArm64Sub32:
205    case kArm64Tst:
206    case kArm64Tst32:
207      if (instr->addressing_mode() != kMode_None) {
208        return 3;
209      } else {
210        return 1;
211      }
212
213    case kArm64Clz:
214    case kArm64Clz32:
215    case kArm64Sbfx32:
216    case kArm64Sxtb32:
217    case kArm64Sxth32:
218    case kArm64Sxtw:
219    case kArm64Ubfiz32:
220    case kArm64Ubfx:
221    case kArm64Ubfx32:
222      return 1;
223
224    case kArm64Lsl:
225    case kArm64Lsl32:
226    case kArm64Lsr:
227    case kArm64Lsr32:
228    case kArm64Asr:
229    case kArm64Asr32:
230    case kArm64Ror:
231    case kArm64Ror32:
232      return 1;
233
234    case kArm64Ldr:
235    case kArm64LdrD:
236    case kArm64LdrS:
237    case kArm64LdrW:
238    case kArm64Ldrb:
239    case kArm64Ldrh:
240    case kArm64Ldrsb:
241    case kArm64Ldrsh:
242    case kArm64Ldrsw:
243      return 11;
244
245    case kCheckedLoadInt8:
246    case kCheckedLoadUint8:
247    case kCheckedLoadInt16:
248    case kCheckedLoadUint16:
249    case kCheckedLoadWord32:
250    case kCheckedLoadWord64:
251    case kCheckedLoadFloat32:
252    case kCheckedLoadFloat64:
253      return 5;
254
255    case kArm64Str:
256    case kArm64StrD:
257    case kArm64StrS:
258    case kArm64StrW:
259    case kArm64Strb:
260    case kArm64Strh:
261      return 1;
262
263    case kCheckedStoreWord8:
264    case kCheckedStoreWord16:
265    case kCheckedStoreWord32:
266    case kCheckedStoreWord64:
267    case kCheckedStoreFloat32:
268    case kCheckedStoreFloat64:
269      return 1;
270
271    case kArm64Madd32:
272    case kArm64Mneg32:
273    case kArm64Msub32:
274    case kArm64Mul32:
275      return 3;
276
277    case kArm64Madd:
278    case kArm64Mneg:
279    case kArm64Msub:
280    case kArm64Mul:
281      return 5;
282
283    case kArm64Idiv32:
284    case kArm64Udiv32:
285      return 12;
286
287    case kArm64Idiv:
288    case kArm64Udiv:
289      return 20;
290
291    case kArm64Float32Add:
292    case kArm64Float32Sub:
293    case kArm64Float64Add:
294    case kArm64Float64Sub:
295      return 5;
296
297    case kArm64Float32Abs:
298    case kArm64Float32Cmp:
299    case kArm64Float32Neg:
300    case kArm64Float64Abs:
301    case kArm64Float64Cmp:
302    case kArm64Float64Neg:
303      return 3;
304
305    case kArm64Float32Div:
306    case kArm64Float32Sqrt:
307      return 12;
308
309    case kArm64Float64Div:
310    case kArm64Float64Sqrt:
311      return 19;
312
313    case kArm64Float32RoundDown:
314    case kArm64Float32RoundTiesEven:
315    case kArm64Float32RoundTruncate:
316    case kArm64Float32RoundUp:
317    case kArm64Float64RoundDown:
318    case kArm64Float64RoundTiesAway:
319    case kArm64Float64RoundTiesEven:
320    case kArm64Float64RoundTruncate:
321    case kArm64Float64RoundUp:
322      return 5;
323
324    case kArm64Float32ToFloat64:
325    case kArm64Float64ToFloat32:
326    case kArm64Float64ToInt32:
327    case kArm64Float64ToUint32:
328    case kArm64Float32ToInt64:
329    case kArm64Float64ToInt64:
330    case kArm64Float32ToUint64:
331    case kArm64Float64ToUint64:
332    case kArm64Int32ToFloat64:
333    case kArm64Int64ToFloat32:
334    case kArm64Int64ToFloat64:
335    case kArm64Uint32ToFloat64:
336    case kArm64Uint64ToFloat32:
337    case kArm64Uint64ToFloat64:
338      return 5;
339
340    default:
341      return 2;
342  }
343}
344
345}  // namespace compiler
346}  // namespace internal
347}  // namespace v8
348