summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/ia32/instruction-scheduler-ia32.cc
blob: 07d42bc6143887ed63ed085811264ea0ea87b617 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/compiler/instruction-scheduler.h"

namespace v8 {
namespace internal {
namespace compiler {

bool InstructionScheduler::SchedulerSupported() { return true; }


int InstructionScheduler::GetTargetInstructionFlags(
    const Instruction* instr) const {
  switch (instr->arch_opcode()) {
    case kIA32Add:
    case kIA32And:
    case kIA32Cmp:
    case kIA32Cmp16:
    case kIA32Cmp8:
    case kIA32Test:
    case kIA32Test16:
    case kIA32Test8:
    case kIA32Or:
    case kIA32Xor:
    case kIA32Sub:
    case kIA32Imul:
    case kIA32ImulHigh:
    case kIA32UmulHigh:
    case kIA32Not:
    case kIA32Neg:
    case kIA32Shl:
    case kIA32Shr:
    case kIA32Sar:
    case kIA32AddPair:
    case kIA32SubPair:
    case kIA32MulPair:
    case kIA32ShlPair:
    case kIA32ShrPair:
    case kIA32SarPair:
    case kIA32Ror:
    case kIA32Lzcnt:
    case kIA32Tzcnt:
    case kIA32Popcnt:
    case kIA32Bswap:
    case kIA32Lea:
    case kSSEFloat32Cmp:
    case kSSEFloat32Add:
    case kSSEFloat32Sub:
    case kSSEFloat32Mul:
    case kSSEFloat32Div:
    case kSSEFloat32Abs:
    case kSSEFloat32Neg:
    case kSSEFloat32Sqrt:
    case kSSEFloat32Round:
    case kSSEFloat64Cmp:
    case kSSEFloat64Add:
    case kSSEFloat64Sub:
    case kSSEFloat64Mul:
    case kSSEFloat64Div:
    case kSSEFloat64Mod:
    case kSSEFloat32Max:
    case kSSEFloat64Max:
    case kSSEFloat32Min:
    case kSSEFloat64Min:
    case kSSEFloat64Abs:
    case kSSEFloat64Neg:
    case kSSEFloat64Sqrt:
    case kSSEFloat64Round:
    case kSSEFloat32ToFloat64:
    case kSSEFloat64ToFloat32:
    case kSSEFloat32ToInt32:
    case kSSEFloat32ToUint32:
    case kSSEFloat64ToInt32:
    case kSSEFloat64ToUint32:
    case kSSEInt32ToFloat32:
    case kSSEUint32ToFloat32:
    case kSSEInt32ToFloat64:
    case kSSEUint32ToFloat64:
    case kSSEFloat64ExtractLowWord32:
    case kSSEFloat64ExtractHighWord32:
    case kSSEFloat64InsertLowWord32:
    case kSSEFloat64InsertHighWord32:
    case kSSEFloat64LoadLowWord32:
    case kSSEFloat64SilenceNaN:
    case kAVXFloat32Add:
    case kAVXFloat32Sub:
    case kAVXFloat32Mul:
    case kAVXFloat32Div:
    case kAVXFloat64Add:
    case kAVXFloat64Sub:
    case kAVXFloat64Mul:
    case kAVXFloat64Div:
    case kAVXFloat64Abs:
    case kAVXFloat64Neg:
    case kAVXFloat32Abs:
    case kAVXFloat32Neg:
    case kIA32BitcastFI:
    case kIA32BitcastIF:
    case kSSEF32x4Splat:
    case kAVXF32x4Splat:
    case kSSEF32x4ExtractLane:
    case kAVXF32x4ExtractLane:
    case kSSEF32x4ReplaceLane:
    case kAVXF32x4ReplaceLane:
    case kIA32F32x4SConvertI32x4:
    case kSSEF32x4UConvertI32x4:
    case kAVXF32x4UConvertI32x4:
    case kSSEF32x4Abs:
    case kAVXF32x4Abs:
    case kSSEF32x4Neg:
    case kAVXF32x4Neg:
    case kIA32F32x4RecipApprox:
    case kIA32F32x4RecipSqrtApprox:
    case kSSEF32x4Add:
    case kAVXF32x4Add:
    case kSSEF32x4AddHoriz:
    case kAVXF32x4AddHoriz:
    case kSSEF32x4Sub:
    case kAVXF32x4Sub:
    case kSSEF32x4Mul:
    case kAVXF32x4Mul:
    case kSSEF32x4Min:
    case kAVXF32x4Min:
    case kSSEF32x4Max:
    case kAVXF32x4Max:
    case kSSEF32x4Eq:
    case kAVXF32x4Eq:
    case kSSEF32x4Ne:
    case kAVXF32x4Ne:
    case kSSEF32x4Lt:
    case kAVXF32x4Lt:
    case kSSEF32x4Le:
    case kAVXF32x4Le:
    case kIA32I32x4Splat:
    case kIA32I32x4ExtractLane:
    case kSSEI32x4ReplaceLane:
    case kAVXI32x4ReplaceLane:
    case kSSEI32x4SConvertF32x4:
    case kAVXI32x4SConvertF32x4:
    case kIA32I32x4SConvertI16x8Low:
    case kIA32I32x4SConvertI16x8High:
    case kIA32I32x4Neg:
    case kSSEI32x4Shl:
    case kAVXI32x4Shl:
    case kSSEI32x4ShrS:
    case kAVXI32x4ShrS:
    case kSSEI32x4Add:
    case kAVXI32x4Add:
    case kSSEI32x4AddHoriz:
    case kAVXI32x4AddHoriz:
    case kSSEI32x4Sub:
    case kAVXI32x4Sub:
    case kSSEI32x4Mul:
    case kAVXI32x4Mul:
    case kSSEI32x4MinS:
    case kAVXI32x4MinS:
    case kSSEI32x4MaxS:
    case kAVXI32x4MaxS:
    case kSSEI32x4Eq:
    case kAVXI32x4Eq:
    case kSSEI32x4Ne:
    case kAVXI32x4Ne:
    case kSSEI32x4GtS:
    case kAVXI32x4GtS:
    case kSSEI32x4GeS:
    case kAVXI32x4GeS:
    case kSSEI32x4UConvertF32x4:
    case kAVXI32x4UConvertF32x4:
    case kIA32I32x4UConvertI16x8Low:
    case kIA32I32x4UConvertI16x8High:
    case kSSEI32x4ShrU:
    case kAVXI32x4ShrU:
    case kSSEI32x4MinU:
    case kAVXI32x4MinU:
    case kSSEI32x4MaxU:
    case kAVXI32x4MaxU:
    case kSSEI32x4GtU:
    case kAVXI32x4GtU:
    case kSSEI32x4GeU:
    case kAVXI32x4GeU:
    case kIA32I16x8Splat:
    case kIA32I16x8ExtractLane:
    case kSSEI16x8ReplaceLane:
    case kAVXI16x8ReplaceLane:
    case kIA32I16x8SConvertI8x16Low:
    case kIA32I16x8SConvertI8x16High:
    case kIA32I16x8Neg:
    case kSSEI16x8Shl:
    case kAVXI16x8Shl:
    case kSSEI16x8ShrS:
    case kAVXI16x8ShrS:
    case kSSEI16x8SConvertI32x4:
    case kAVXI16x8SConvertI32x4:
    case kSSEI16x8Add:
    case kAVXI16x8Add:
    case kSSEI16x8AddSaturateS:
    case kAVXI16x8AddSaturateS:
    case kSSEI16x8AddHoriz:
    case kAVXI16x8AddHoriz:
    case kSSEI16x8Sub:
    case kAVXI16x8Sub:
    case kSSEI16x8SubSaturateS:
    case kAVXI16x8SubSaturateS:
    case kSSEI16x8Mul:
    case kAVXI16x8Mul:
    case kSSEI16x8MinS:
    case kAVXI16x8MinS:
    case kSSEI16x8MaxS:
    case kAVXI16x8MaxS:
    case kSSEI16x8Eq:
    case kAVXI16x8Eq:
    case kSSEI16x8Ne:
    case kAVXI16x8Ne:
    case kSSEI16x8GtS:
    case kAVXI16x8GtS:
    case kSSEI16x8GeS:
    case kAVXI16x8GeS:
    case kIA32I16x8UConvertI8x16Low:
    case kIA32I16x8UConvertI8x16High:
    case kSSEI16x8ShrU:
    case kAVXI16x8ShrU:
    case kSSEI16x8UConvertI32x4:
    case kAVXI16x8UConvertI32x4:
    case kSSEI16x8AddSaturateU:
    case kAVXI16x8AddSaturateU:
    case kSSEI16x8SubSaturateU:
    case kAVXI16x8SubSaturateU:
    case kSSEI16x8MinU:
    case kAVXI16x8MinU:
    case kSSEI16x8MaxU:
    case kAVXI16x8MaxU:
    case kSSEI16x8GtU:
    case kAVXI16x8GtU:
    case kSSEI16x8GeU:
    case kAVXI16x8GeU:
    case kIA32I8x16Splat:
    case kIA32I8x16ExtractLane:
    case kSSEI8x16ReplaceLane:
    case kAVXI8x16ReplaceLane:
    case kSSEI8x16SConvertI16x8:
    case kAVXI8x16SConvertI16x8:
    case kIA32I8x16Neg:
    case kSSEI8x16Shl:
    case kAVXI8x16Shl:
    case kIA32I8x16ShrS:
    case kSSEI8x16Add:
    case kAVXI8x16Add:
    case kSSEI8x16AddSaturateS:
    case kAVXI8x16AddSaturateS:
    case kSSEI8x16Sub:
    case kAVXI8x16Sub:
    case kSSEI8x16SubSaturateS:
    case kAVXI8x16SubSaturateS:
    case kSSEI8x16Mul:
    case kAVXI8x16Mul:
    case kSSEI8x16MinS:
    case kAVXI8x16MinS:
    case kSSEI8x16MaxS:
    case kAVXI8x16MaxS:
    case kSSEI8x16Eq:
    case kAVXI8x16Eq:
    case kSSEI8x16Ne:
    case kAVXI8x16Ne:
    case kSSEI8x16GtS:
    case kAVXI8x16GtS:
    case kSSEI8x16GeS:
    case kAVXI8x16GeS:
    case kSSEI8x16UConvertI16x8:
    case kAVXI8x16UConvertI16x8:
    case kSSEI8x16AddSaturateU:
    case kAVXI8x16AddSaturateU:
    case kSSEI8x16SubSaturateU:
    case kAVXI8x16SubSaturateU:
    case kIA32I8x16ShrU:
    case kSSEI8x16MinU:
    case kAVXI8x16MinU:
    case kSSEI8x16MaxU:
    case kAVXI8x16MaxU:
    case kSSEI8x16GtU:
    case kAVXI8x16GtU:
    case kSSEI8x16GeU:
    case kAVXI8x16GeU:
    case kIA32S128Zero:
    case kSSES128Not:
    case kAVXS128Not:
    case kSSES128And:
    case kAVXS128And:
    case kSSES128Or:
    case kAVXS128Or:
    case kSSES128Xor:
    case kAVXS128Xor:
    case kSSES128Select:
    case kAVXS128Select:
    case kIA32S8x16Shuffle:
    case kIA32S32x4Swizzle:
    case kIA32S32x4Shuffle:
    case kIA32S16x8Blend:
    case kIA32S16x8HalfShuffle1:
    case kIA32S16x8HalfShuffle2:
    case kIA32S8x16Alignr:
    case kIA32S16x8Dup:
    case kIA32S8x16Dup:
    case kSSES16x8UnzipHigh:
    case kAVXS16x8UnzipHigh:
    case kSSES16x8UnzipLow:
    case kAVXS16x8UnzipLow:
    case kSSES8x16UnzipHigh:
    case kAVXS8x16UnzipHigh:
    case kSSES8x16UnzipLow:
    case kAVXS8x16UnzipLow:
    case kIA32S64x2UnpackHigh:
    case kIA32S32x4UnpackHigh:
    case kIA32S16x8UnpackHigh:
    case kIA32S8x16UnpackHigh:
    case kIA32S64x2UnpackLow:
    case kIA32S32x4UnpackLow:
    case kIA32S16x8UnpackLow:
    case kIA32S8x16UnpackLow:
    case kSSES8x16TransposeLow:
    case kAVXS8x16TransposeLow:
    case kSSES8x16TransposeHigh:
    case kAVXS8x16TransposeHigh:
    case kSSES8x8Reverse:
    case kAVXS8x8Reverse:
    case kSSES8x4Reverse:
    case kAVXS8x4Reverse:
    case kSSES8x2Reverse:
    case kAVXS8x2Reverse:
    case kIA32S1x4AnyTrue:
    case kIA32S1x4AllTrue:
    case kIA32S1x8AnyTrue:
    case kIA32S1x8AllTrue:
    case kIA32S1x16AnyTrue:
    case kIA32S1x16AllTrue:
      return (instr->addressing_mode() == kMode_None)
          ? kNoOpcodeFlags
          : kIsLoadOperation | kHasSideEffect;

    case kIA32Idiv:
    case kIA32Udiv:
      return (instr->addressing_mode() == kMode_None)
                 ? kMayNeedDeoptOrTrapCheck
                 : kMayNeedDeoptOrTrapCheck | kIsLoadOperation | kHasSideEffect;

    case kIA32Movsxbl:
    case kIA32Movzxbl:
    case kIA32Movb:
    case kIA32Movsxwl:
    case kIA32Movzxwl:
    case kIA32Movw:
    case kIA32Movl:
    case kIA32Movss:
    case kIA32Movsd:
    case kIA32Movdqu:
      // Moves are used for memory load/store operations.
      return instr->HasOutput() ? kIsLoadOperation : kHasSideEffect;

    case kIA32StackCheck:
    case kIA32Peek:
      return kIsLoadOperation;

    case kIA32Push:
    case kIA32PushFloat32:
    case kIA32PushFloat64:
    case kIA32PushSimd128:
    case kIA32Poke:
    case kLFence:
      return kHasSideEffect;

    case kIA32Word32AtomicPairLoad:
      return kIsLoadOperation;

    case kIA32Word32AtomicPairStore:
    case kIA32Word32AtomicPairAdd:
    case kIA32Word32AtomicPairSub:
    case kIA32Word32AtomicPairAnd:
    case kIA32Word32AtomicPairOr:
    case kIA32Word32AtomicPairXor:
    case kIA32Word32AtomicPairExchange:
    case kIA32Word32AtomicPairCompareExchange:
    case kIA32Word64AtomicNarrowAddUint8:
    case kIA32Word64AtomicNarrowAddUint16:
    case kIA32Word64AtomicNarrowAddUint32:
    case kIA32Word64AtomicNarrowSubUint8:
    case kIA32Word64AtomicNarrowSubUint16:
    case kIA32Word64AtomicNarrowSubUint32:
    case kIA32Word64AtomicNarrowAndUint8:
    case kIA32Word64AtomicNarrowAndUint16:
    case kIA32Word64AtomicNarrowAndUint32:
    case kIA32Word64AtomicNarrowOrUint8:
    case kIA32Word64AtomicNarrowOrUint16:
    case kIA32Word64AtomicNarrowOrUint32:
    case kIA32Word64AtomicNarrowXorUint8:
    case kIA32Word64AtomicNarrowXorUint16:
    case kIA32Word64AtomicNarrowXorUint32:
    case kIA32Word64AtomicNarrowExchangeUint8:
    case kIA32Word64AtomicNarrowExchangeUint16:
    case kIA32Word64AtomicNarrowExchangeUint32:
    case kIA32Word64AtomicNarrowCompareExchangeUint8:
    case kIA32Word64AtomicNarrowCompareExchangeUint16:
    case kIA32Word64AtomicNarrowCompareExchangeUint32:
      return kHasSideEffect;

#define CASE(Name) case k##Name:
    COMMON_ARCH_OPCODE_LIST(CASE)
#undef CASE
      // Already covered in architecture independent code.
      UNREACHABLE();
  }

  UNREACHABLE();
}


int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
  // Basic latency modeling for ia32 instructions. They have been determined
  // in an empirical way.
  switch (instr->arch_opcode()) {
    case kSSEFloat64Mul:
      return 5;
    case kIA32Imul:
    case kIA32ImulHigh:
      return 5;
    case kSSEFloat32Cmp:
    case kSSEFloat64Cmp:
      return 9;
    case kSSEFloat32Add:
    case kSSEFloat32Sub:
    case kSSEFloat32Abs:
    case kSSEFloat32Neg:
    case kSSEFloat64Add:
    case kSSEFloat64Sub:
    case kSSEFloat64Max:
    case kSSEFloat64Min:
    case kSSEFloat64Abs:
    case kSSEFloat64Neg:
      return 5;
    case kSSEFloat32Mul:
      return 4;
    case kSSEFloat32ToFloat64:
    case kSSEFloat64ToFloat32:
      return 6;
    case kSSEFloat32Round:
    case kSSEFloat64Round:
    case kSSEFloat32ToInt32:
    case kSSEFloat64ToInt32:
      return 8;
    case kSSEFloat32ToUint32:
      return 21;
    case kSSEFloat64ToUint32:
      return 15;
    case kIA32Idiv:
      return 33;
    case kIA32Udiv:
      return 26;
    case kSSEFloat32Div:
      return 35;
    case kSSEFloat64Div:
      return 63;
    case kSSEFloat32Sqrt:
    case kSSEFloat64Sqrt:
      return 25;
    case kSSEFloat64Mod:
      return 50;
    case kArchTruncateDoubleToI:
      return 9;
    default:
      return 1;
  }
}

}  // namespace compiler
}  // namespace internal
}  // namespace v8