deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / src / compiler / ia32 / instruction-selector-ia32.cc
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-selector-impl.h"
6 #include "src/compiler/node-matchers.h"
7 #include "src/compiler/node-properties.h"
8
9 namespace v8 {
10 namespace internal {
11 namespace compiler {
12
13 // Adds IA32-specific methods for generating operands.
14 class IA32OperandGenerator FINAL : public OperandGenerator {
15  public:
16   explicit IA32OperandGenerator(InstructionSelector* selector)
17       : OperandGenerator(selector) {}
18
19   InstructionOperand UseByteRegister(Node* node) {
20     // TODO(titzer): encode byte register use constraints.
21     return UseFixed(node, edx);
22   }
23
24   InstructionOperand DefineAsByteRegister(Node* node) {
25     // TODO(titzer): encode byte register def constraints.
26     return DefineAsRegister(node);
27   }
28
29   bool CanBeImmediate(Node* node) {
30     switch (node->opcode()) {
31       case IrOpcode::kInt32Constant:
32       case IrOpcode::kNumberConstant:
33       case IrOpcode::kExternalConstant:
34         return true;
35       case IrOpcode::kHeapConstant: {
36         // Constants in new space cannot be used as immediates in V8 because
37         // the GC does not scan code objects when collecting the new generation.
38         Unique<HeapObject> value = OpParameter<Unique<HeapObject> >(node);
39         Isolate* isolate = value.handle()->GetIsolate();
40         return !isolate->heap()->InNewSpace(*value.handle());
41       }
42       default:
43         return false;
44     }
45   }
46
47   AddressingMode GenerateMemoryOperandInputs(Node* index, int scale, Node* base,
48                                              Node* displacement_node,
49                                              InstructionOperand inputs[],
50                                              size_t* input_count) {
51     AddressingMode mode = kMode_MRI;
52     int32_t displacement = (displacement_node == NULL)
53                                ? 0
54                                : OpParameter<int32_t>(displacement_node);
55     if (base != NULL) {
56       if (base->opcode() == IrOpcode::kInt32Constant) {
57         displacement += OpParameter<int32_t>(base);
58         base = NULL;
59       }
60     }
61     if (base != NULL) {
62       inputs[(*input_count)++] = UseRegister(base);
63       if (index != NULL) {
64         DCHECK(scale >= 0 && scale <= 3);
65         inputs[(*input_count)++] = UseRegister(index);
66         if (displacement != 0) {
67           inputs[(*input_count)++] = TempImmediate(displacement);
68           static const AddressingMode kMRnI_modes[] = {kMode_MR1I, kMode_MR2I,
69                                                        kMode_MR4I, kMode_MR8I};
70           mode = kMRnI_modes[scale];
71         } else {
72           static const AddressingMode kMRn_modes[] = {kMode_MR1, kMode_MR2,
73                                                       kMode_MR4, kMode_MR8};
74           mode = kMRn_modes[scale];
75         }
76       } else {
77         if (displacement == 0) {
78           mode = kMode_MR;
79         } else {
80           inputs[(*input_count)++] = TempImmediate(displacement);
81           mode = kMode_MRI;
82         }
83       }
84     } else {
85       DCHECK(scale >= 0 && scale <= 3);
86       if (index != NULL) {
87         inputs[(*input_count)++] = UseRegister(index);
88         if (displacement != 0) {
89           inputs[(*input_count)++] = TempImmediate(displacement);
90           static const AddressingMode kMnI_modes[] = {kMode_MRI, kMode_M2I,
91                                                       kMode_M4I, kMode_M8I};
92           mode = kMnI_modes[scale];
93         } else {
94           static const AddressingMode kMn_modes[] = {kMode_MR, kMode_M2,
95                                                      kMode_M4, kMode_M8};
96           mode = kMn_modes[scale];
97         }
98       } else {
99         inputs[(*input_count)++] = TempImmediate(displacement);
100         return kMode_MI;
101       }
102     }
103     return mode;
104   }
105
106   AddressingMode GetEffectiveAddressMemoryOperand(Node* node,
107                                                   InstructionOperand inputs[],
108                                                   size_t* input_count) {
109     BaseWithIndexAndDisplacement32Matcher m(node, true);
110     DCHECK(m.matches());
111     if ((m.displacement() == NULL || CanBeImmediate(m.displacement()))) {
112       return GenerateMemoryOperandInputs(m.index(), m.scale(), m.base(),
113                                          m.displacement(), inputs, input_count);
114     } else {
115       inputs[(*input_count)++] = UseRegister(node->InputAt(0));
116       inputs[(*input_count)++] = UseRegister(node->InputAt(1));
117       return kMode_MR1;
118     }
119   }
120
121   bool CanBeBetterLeftOperand(Node* node) const {
122     return !selector()->IsLive(node);
123   }
124 };
125
126
127 static void VisitRRFloat64(InstructionSelector* selector,
128                            InstructionCode opcode, Node* node) {
129   IA32OperandGenerator g(selector);
130   selector->Emit(opcode, g.DefineAsRegister(node),
131                  g.UseRegister(node->InputAt(0)));
132 }
133
134
135 void InstructionSelector::VisitLoad(Node* node) {
136   MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
137   MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
138
139   ArchOpcode opcode;
140   switch (rep) {
141     case kRepFloat32:
142       opcode = kIA32Movss;
143       break;
144     case kRepFloat64:
145       opcode = kIA32Movsd;
146       break;
147     case kRepBit:  // Fall through.
148     case kRepWord8:
149       opcode = typ == kTypeInt32 ? kIA32Movsxbl : kIA32Movzxbl;
150       break;
151     case kRepWord16:
152       opcode = typ == kTypeInt32 ? kIA32Movsxwl : kIA32Movzxwl;
153       break;
154     case kRepTagged:  // Fall through.
155     case kRepWord32:
156       opcode = kIA32Movl;
157       break;
158     default:
159       UNREACHABLE();
160       return;
161   }
162
163   IA32OperandGenerator g(this);
164   InstructionOperand outputs[1];
165   outputs[0] = g.DefineAsRegister(node);
166   InstructionOperand inputs[3];
167   size_t input_count = 0;
168   AddressingMode mode =
169       g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
170   InstructionCode code = opcode | AddressingModeField::encode(mode);
171   Emit(code, 1, outputs, input_count, inputs);
172 }
173
174
175 void InstructionSelector::VisitStore(Node* node) {
176   IA32OperandGenerator g(this);
177   Node* base = node->InputAt(0);
178   Node* index = node->InputAt(1);
179   Node* value = node->InputAt(2);
180
181   StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
182   MachineType rep = RepresentationOf(store_rep.machine_type());
183   if (store_rep.write_barrier_kind() == kFullWriteBarrier) {
184     DCHECK_EQ(kRepTagged, rep);
185     // TODO(dcarney): refactor RecordWrite function to take temp registers
186     //                and pass them here instead of using fixed regs
187     // TODO(dcarney): handle immediate indices.
188     InstructionOperand temps[] = {g.TempRegister(ecx), g.TempRegister(edx)};
189     Emit(kIA32StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, ebx),
190          g.UseFixed(index, ecx), g.UseFixed(value, edx), arraysize(temps),
191          temps);
192     return;
193   }
194   DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
195
196   ArchOpcode opcode;
197   switch (rep) {
198     case kRepFloat32:
199       opcode = kIA32Movss;
200       break;
201     case kRepFloat64:
202       opcode = kIA32Movsd;
203       break;
204     case kRepBit:  // Fall through.
205     case kRepWord8:
206       opcode = kIA32Movb;
207       break;
208     case kRepWord16:
209       opcode = kIA32Movw;
210       break;
211     case kRepTagged:  // Fall through.
212     case kRepWord32:
213       opcode = kIA32Movl;
214       break;
215     default:
216       UNREACHABLE();
217       return;
218   }
219
220   InstructionOperand val;
221   if (g.CanBeImmediate(value)) {
222     val = g.UseImmediate(value);
223   } else if (rep == kRepWord8 || rep == kRepBit) {
224     val = g.UseByteRegister(value);
225   } else {
226     val = g.UseRegister(value);
227   }
228
229   InstructionOperand inputs[4];
230   size_t input_count = 0;
231   AddressingMode mode =
232       g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
233   InstructionCode code = opcode | AddressingModeField::encode(mode);
234   inputs[input_count++] = val;
235   Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs);
236 }
237
238
239 void InstructionSelector::VisitCheckedLoad(Node* node) {
240   MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
241   MachineType typ = TypeOf(OpParameter<MachineType>(node));
242   IA32OperandGenerator g(this);
243   Node* const buffer = node->InputAt(0);
244   Node* const offset = node->InputAt(1);
245   Node* const length = node->InputAt(2);
246   ArchOpcode opcode;
247   switch (rep) {
248     case kRepWord8:
249       opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8;
250       break;
251     case kRepWord16:
252       opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16;
253       break;
254     case kRepWord32:
255       opcode = kCheckedLoadWord32;
256       break;
257     case kRepFloat32:
258       opcode = kCheckedLoadFloat32;
259       break;
260     case kRepFloat64:
261       opcode = kCheckedLoadFloat64;
262       break;
263     default:
264       UNREACHABLE();
265       return;
266   }
267   InstructionOperand offset_operand = g.UseRegister(offset);
268   InstructionOperand length_operand =
269       g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
270   if (g.CanBeImmediate(buffer)) {
271     Emit(opcode | AddressingModeField::encode(kMode_MRI),
272          g.DefineAsRegister(node), offset_operand, length_operand,
273          offset_operand, g.UseImmediate(buffer));
274   } else {
275     Emit(opcode | AddressingModeField::encode(kMode_MR1),
276          g.DefineAsRegister(node), offset_operand, length_operand,
277          g.UseRegister(buffer), offset_operand);
278   }
279 }
280
281
282 void InstructionSelector::VisitCheckedStore(Node* node) {
283   MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
284   IA32OperandGenerator g(this);
285   Node* const buffer = node->InputAt(0);
286   Node* const offset = node->InputAt(1);
287   Node* const length = node->InputAt(2);
288   Node* const value = node->InputAt(3);
289   ArchOpcode opcode;
290   switch (rep) {
291     case kRepWord8:
292       opcode = kCheckedStoreWord8;
293       break;
294     case kRepWord16:
295       opcode = kCheckedStoreWord16;
296       break;
297     case kRepWord32:
298       opcode = kCheckedStoreWord32;
299       break;
300     case kRepFloat32:
301       opcode = kCheckedStoreFloat32;
302       break;
303     case kRepFloat64:
304       opcode = kCheckedStoreFloat64;
305       break;
306     default:
307       UNREACHABLE();
308       return;
309   }
310   InstructionOperand value_operand =
311       g.CanBeImmediate(value)
312           ? g.UseImmediate(value)
313           : ((rep == kRepWord8 || rep == kRepBit) ? g.UseByteRegister(value)
314                                                   : g.UseRegister(value));
315   InstructionOperand offset_operand = g.UseRegister(offset);
316   InstructionOperand length_operand =
317       g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
318   if (g.CanBeImmediate(buffer)) {
319     Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
320          offset_operand, length_operand, value_operand, offset_operand,
321          g.UseImmediate(buffer));
322   } else {
323     Emit(opcode | AddressingModeField::encode(kMode_MR1), g.NoOutput(),
324          offset_operand, length_operand, value_operand, g.UseRegister(buffer),
325          offset_operand);
326   }
327 }
328
329
330 // Shared routine for multiple binary operations.
331 static void VisitBinop(InstructionSelector* selector, Node* node,
332                        InstructionCode opcode, FlagsContinuation* cont) {
333   IA32OperandGenerator g(selector);
334   Int32BinopMatcher m(node);
335   Node* left = m.left().node();
336   Node* right = m.right().node();
337   InstructionOperand inputs[4];
338   size_t input_count = 0;
339   InstructionOperand outputs[2];
340   size_t output_count = 0;
341
342   // TODO(turbofan): match complex addressing modes.
343   if (left == right) {
344     // If both inputs refer to the same operand, enforce allocating a register
345     // for both of them to ensure that we don't end up generating code like
346     // this:
347     //
348     //   mov eax, [ebp-0x10]
349     //   add eax, [ebp-0x10]
350     //   jo label
351     InstructionOperand const input = g.UseRegister(left);
352     inputs[input_count++] = input;
353     inputs[input_count++] = input;
354   } else if (g.CanBeImmediate(right)) {
355     inputs[input_count++] = g.UseRegister(left);
356     inputs[input_count++] = g.UseImmediate(right);
357   } else {
358     if (node->op()->HasProperty(Operator::kCommutative) &&
359         g.CanBeBetterLeftOperand(right)) {
360       std::swap(left, right);
361     }
362     inputs[input_count++] = g.UseRegister(left);
363     inputs[input_count++] = g.Use(right);
364   }
365
366   if (cont->IsBranch()) {
367     inputs[input_count++] = g.Label(cont->true_block());
368     inputs[input_count++] = g.Label(cont->false_block());
369   }
370
371   outputs[output_count++] = g.DefineSameAsFirst(node);
372   if (cont->IsSet()) {
373     outputs[output_count++] = g.DefineAsByteRegister(cont->result());
374   }
375
376   DCHECK_NE(0u, input_count);
377   DCHECK_NE(0u, output_count);
378   DCHECK_GE(arraysize(inputs), input_count);
379   DCHECK_GE(arraysize(outputs), output_count);
380
381   selector->Emit(cont->Encode(opcode), output_count, outputs, input_count,
382                  inputs);
383 }
384
385
386 // Shared routine for multiple binary operations.
387 static void VisitBinop(InstructionSelector* selector, Node* node,
388                        InstructionCode opcode) {
389   FlagsContinuation cont;
390   VisitBinop(selector, node, opcode, &cont);
391 }
392
393
394 void InstructionSelector::VisitWord32And(Node* node) {
395   VisitBinop(this, node, kIA32And);
396 }
397
398
399 void InstructionSelector::VisitWord32Or(Node* node) {
400   VisitBinop(this, node, kIA32Or);
401 }
402
403
404 void InstructionSelector::VisitWord32Xor(Node* node) {
405   IA32OperandGenerator g(this);
406   Int32BinopMatcher m(node);
407   if (m.right().Is(-1)) {
408     Emit(kIA32Not, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()));
409   } else {
410     VisitBinop(this, node, kIA32Xor);
411   }
412 }
413
414
415 // Shared routine for multiple shift operations.
416 static inline void VisitShift(InstructionSelector* selector, Node* node,
417                               ArchOpcode opcode) {
418   IA32OperandGenerator g(selector);
419   Node* left = node->InputAt(0);
420   Node* right = node->InputAt(1);
421
422   if (g.CanBeImmediate(right)) {
423     selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
424                    g.UseImmediate(right));
425   } else {
426     selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
427                    g.UseFixed(right, ecx));
428   }
429 }
430
431
432 namespace {
433
434 void VisitMulHigh(InstructionSelector* selector, Node* node,
435                   ArchOpcode opcode) {
436   IA32OperandGenerator g(selector);
437   selector->Emit(opcode, g.DefineAsFixed(node, edx),
438                  g.UseFixed(node->InputAt(0), eax),
439                  g.UseUniqueRegister(node->InputAt(1)));
440 }
441
442
443 void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
444   IA32OperandGenerator g(selector);
445   InstructionOperand temps[] = {g.TempRegister(edx)};
446   selector->Emit(opcode, g.DefineAsFixed(node, eax),
447                  g.UseFixed(node->InputAt(0), eax),
448                  g.UseUnique(node->InputAt(1)), arraysize(temps), temps);
449 }
450
451
452 void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
453   IA32OperandGenerator g(selector);
454   selector->Emit(opcode, g.DefineAsFixed(node, edx),
455                  g.UseFixed(node->InputAt(0), eax),
456                  g.UseUnique(node->InputAt(1)));
457 }
458
459 void EmitLea(InstructionSelector* selector, Node* result, Node* index,
460              int scale, Node* base, Node* displacement) {
461   IA32OperandGenerator g(selector);
462   InstructionOperand inputs[4];
463   size_t input_count = 0;
464   AddressingMode mode = g.GenerateMemoryOperandInputs(
465       index, scale, base, displacement, inputs, &input_count);
466
467   DCHECK_NE(0u, input_count);
468   DCHECK_GE(arraysize(inputs), input_count);
469
470   InstructionOperand outputs[1];
471   outputs[0] = g.DefineAsRegister(result);
472
473   InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea;
474
475   selector->Emit(opcode, 1, outputs, input_count, inputs);
476 }
477
478 }  // namespace
479
480
481 void InstructionSelector::VisitWord32Shl(Node* node) {
482   Int32ScaleMatcher m(node, true);
483   if (m.matches()) {
484     Node* index = node->InputAt(0);
485     Node* base = m.power_of_two_plus_one() ? index : NULL;
486     EmitLea(this, node, index, m.scale(), base, NULL);
487     return;
488   }
489   VisitShift(this, node, kIA32Shl);
490 }
491
492
493 void InstructionSelector::VisitWord32Shr(Node* node) {
494   VisitShift(this, node, kIA32Shr);
495 }
496
497
498 void InstructionSelector::VisitWord32Sar(Node* node) {
499   VisitShift(this, node, kIA32Sar);
500 }
501
502
503 void InstructionSelector::VisitWord32Ror(Node* node) {
504   VisitShift(this, node, kIA32Ror);
505 }
506
507
508 void InstructionSelector::VisitWord32Clz(Node* node) {
509   IA32OperandGenerator g(this);
510   Emit(kIA32Lzcnt, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
511 }
512
513
514 void InstructionSelector::VisitInt32Add(Node* node) {
515   IA32OperandGenerator g(this);
516
517   // Try to match the Add to a lea pattern
518   BaseWithIndexAndDisplacement32Matcher m(node);
519   if (m.matches() &&
520       (m.displacement() == NULL || g.CanBeImmediate(m.displacement()))) {
521     InstructionOperand inputs[4];
522     size_t input_count = 0;
523     AddressingMode mode = g.GenerateMemoryOperandInputs(
524         m.index(), m.scale(), m.base(), m.displacement(), inputs, &input_count);
525
526     DCHECK_NE(0u, input_count);
527     DCHECK_GE(arraysize(inputs), input_count);
528
529     InstructionOperand outputs[1];
530     outputs[0] = g.DefineAsRegister(node);
531
532     InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea;
533     Emit(opcode, 1, outputs, input_count, inputs);
534     return;
535   }
536
537   // No lea pattern match, use add
538   VisitBinop(this, node, kIA32Add);
539 }
540
541
542 void InstructionSelector::VisitInt32Sub(Node* node) {
543   IA32OperandGenerator g(this);
544   Int32BinopMatcher m(node);
545   if (m.left().Is(0)) {
546     Emit(kIA32Neg, g.DefineSameAsFirst(node), g.Use(m.right().node()));
547   } else {
548     VisitBinop(this, node, kIA32Sub);
549   }
550 }
551
552
553 void InstructionSelector::VisitInt32Mul(Node* node) {
554   Int32ScaleMatcher m(node, true);
555   if (m.matches()) {
556     Node* index = node->InputAt(0);
557     Node* base = m.power_of_two_plus_one() ? index : NULL;
558     EmitLea(this, node, index, m.scale(), base, NULL);
559     return;
560   }
561   IA32OperandGenerator g(this);
562   Node* left = node->InputAt(0);
563   Node* right = node->InputAt(1);
564   if (g.CanBeImmediate(right)) {
565     Emit(kIA32Imul, g.DefineAsRegister(node), g.Use(left),
566          g.UseImmediate(right));
567   } else {
568     if (g.CanBeBetterLeftOperand(right)) {
569       std::swap(left, right);
570     }
571     Emit(kIA32Imul, g.DefineSameAsFirst(node), g.UseRegister(left),
572          g.Use(right));
573   }
574 }
575
576
577 void InstructionSelector::VisitInt32MulHigh(Node* node) {
578   VisitMulHigh(this, node, kIA32ImulHigh);
579 }
580
581
582 void InstructionSelector::VisitUint32MulHigh(Node* node) {
583   VisitMulHigh(this, node, kIA32UmulHigh);
584 }
585
586
587 void InstructionSelector::VisitInt32Div(Node* node) {
588   VisitDiv(this, node, kIA32Idiv);
589 }
590
591
592 void InstructionSelector::VisitUint32Div(Node* node) {
593   VisitDiv(this, node, kIA32Udiv);
594 }
595
596
597 void InstructionSelector::VisitInt32Mod(Node* node) {
598   VisitMod(this, node, kIA32Idiv);
599 }
600
601
602 void InstructionSelector::VisitUint32Mod(Node* node) {
603   VisitMod(this, node, kIA32Udiv);
604 }
605
606
607 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
608   IA32OperandGenerator g(this);
609   Emit(kSSECvtss2sd, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
610 }
611
612
613 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
614   IA32OperandGenerator g(this);
615   Emit(kSSEInt32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
616 }
617
618
619 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
620   IA32OperandGenerator g(this);
621   Emit(kSSEUint32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
622 }
623
624
625 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
626   IA32OperandGenerator g(this);
627   Emit(kSSEFloat64ToInt32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
628 }
629
630
631 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
632   IA32OperandGenerator g(this);
633   Emit(kSSEFloat64ToUint32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
634 }
635
636
637 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
638   IA32OperandGenerator g(this);
639   Emit(kSSECvtsd2ss, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
640 }
641
642
643 void InstructionSelector::VisitFloat64Add(Node* node) {
644   IA32OperandGenerator g(this);
645   if (IsSupported(AVX)) {
646     Emit(kAVXFloat64Add, g.DefineAsRegister(node),
647          g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
648   } else {
649     Emit(kSSEFloat64Add, g.DefineSameAsFirst(node),
650          g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
651   }
652 }
653
654
655 void InstructionSelector::VisitFloat64Sub(Node* node) {
656   IA32OperandGenerator g(this);
657   Float64BinopMatcher m(node);
658   if (m.left().IsMinusZero() && m.right().IsFloat64RoundDown() &&
659       CanCover(m.node(), m.right().node())) {
660     if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat64Sub &&
661         CanCover(m.right().node(), m.right().InputAt(0))) {
662       Float64BinopMatcher mright0(m.right().InputAt(0));
663       if (mright0.left().IsMinusZero()) {
664         Emit(kSSEFloat64Round | MiscField::encode(kRoundUp),
665              g.DefineAsRegister(node), g.UseRegister(mright0.right().node()));
666         return;
667       }
668     }
669   }
670   if (IsSupported(AVX)) {
671     Emit(kAVXFloat64Sub, g.DefineAsRegister(node),
672          g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
673   } else {
674     Emit(kSSEFloat64Sub, g.DefineSameAsFirst(node),
675          g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
676   }
677 }
678
679
680 void InstructionSelector::VisitFloat64Mul(Node* node) {
681   IA32OperandGenerator g(this);
682   if (IsSupported(AVX)) {
683     Emit(kAVXFloat64Mul, g.DefineAsRegister(node),
684          g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
685   } else {
686     Emit(kSSEFloat64Mul, g.DefineSameAsFirst(node),
687          g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
688   }
689 }
690
691
692 void InstructionSelector::VisitFloat64Div(Node* node) {
693   IA32OperandGenerator g(this);
694   if (IsSupported(AVX)) {
695     Emit(kAVXFloat64Div, g.DefineAsRegister(node),
696          g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
697   } else {
698     Emit(kSSEFloat64Div, g.DefineSameAsFirst(node),
699          g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
700   }
701 }
702
703
704 void InstructionSelector::VisitFloat64Mod(Node* node) {
705   IA32OperandGenerator g(this);
706   InstructionOperand temps[] = {g.TempRegister(eax)};
707   Emit(kSSEFloat64Mod, g.DefineSameAsFirst(node),
708        g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), 1,
709        temps);
710 }
711
712
713 void InstructionSelector::VisitFloat64Max(Node* node) {
714   IA32OperandGenerator g(this);
715   if (IsSupported(AVX)) {
716     Emit(kAVXFloat64Max, g.DefineAsRegister(node),
717          g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
718   } else {
719     Emit(kSSEFloat64Max, g.DefineSameAsFirst(node),
720          g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
721   }
722 }
723
724
725 void InstructionSelector::VisitFloat64Min(Node* node) {
726   IA32OperandGenerator g(this);
727   if (IsSupported(AVX)) {
728     Emit(kAVXFloat64Min, g.DefineAsRegister(node),
729          g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
730   } else {
731     Emit(kSSEFloat64Min, g.DefineSameAsFirst(node),
732          g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
733   }
734 }
735
736
737 void InstructionSelector::VisitFloat64Sqrt(Node* node) {
738   IA32OperandGenerator g(this);
739   Emit(kSSEFloat64Sqrt, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
740 }
741
742
743 void InstructionSelector::VisitFloat64RoundDown(Node* node) {
744   VisitRRFloat64(this, kSSEFloat64Round | MiscField::encode(kRoundDown), node);
745 }
746
747
748 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
749   VisitRRFloat64(this, kSSEFloat64Round | MiscField::encode(kRoundToZero),
750                  node);
751 }
752
753
754 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
755   UNREACHABLE();
756 }
757
758
759 void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
760   IA32OperandGenerator g(this);
761   const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
762
763   FrameStateDescriptor* frame_state_descriptor = NULL;
764
765   if (descriptor->NeedsFrameState()) {
766     frame_state_descriptor =
767         GetFrameStateDescriptor(node->InputAt(descriptor->InputCount()));
768   }
769
770   CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
771
772   // Compute InstructionOperands for inputs and outputs.
773   InitializeCallBuffer(node, &buffer, true, true);
774
775   // Push any stack arguments.
776   for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend();
777        ++i) {
778     // TODO(titzer): handle pushing double parameters.
779     InstructionOperand value =
780         g.CanBeImmediate(*i) ? g.UseImmediate(*i) : IsSupported(ATOM)
781                                                         ? g.UseRegister(*i)
782                                                         : g.Use(*i);
783     Emit(kIA32Push, g.NoOutput(), value);
784   }
785
786   // Pass label of exception handler block.
787   CallDescriptor::Flags flags = descriptor->flags();
788   if (handler != nullptr) {
789     flags |= CallDescriptor::kHasExceptionHandler;
790     buffer.instruction_args.push_back(g.Label(handler));
791   }
792
793   // Select the appropriate opcode based on the call type.
794   InstructionCode opcode;
795   switch (descriptor->kind()) {
796     case CallDescriptor::kCallCodeObject: {
797       opcode = kArchCallCodeObject;
798       break;
799     }
800     case CallDescriptor::kCallJSFunction:
801       opcode = kArchCallJSFunction;
802       break;
803     default:
804       UNREACHABLE();
805       return;
806   }
807   opcode |= MiscField::encode(flags);
808
809   // Emit the call instruction.
810   InstructionOperand* first_output =
811       buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
812   Instruction* call_instr =
813       Emit(opcode, buffer.outputs.size(), first_output,
814            buffer.instruction_args.size(), &buffer.instruction_args.front());
815   call_instr->MarkAsCall();
816 }
817
818
819 namespace {
820
821 // Shared routine for multiple compare operations.
822 void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
823                   InstructionOperand left, InstructionOperand right,
824                   FlagsContinuation* cont) {
825   IA32OperandGenerator g(selector);
826   if (cont->IsBranch()) {
827     selector->Emit(cont->Encode(opcode), g.NoOutput(), left, right,
828                    g.Label(cont->true_block()), g.Label(cont->false_block()));
829   } else {
830     DCHECK(cont->IsSet());
831     selector->Emit(cont->Encode(opcode), g.DefineAsByteRegister(cont->result()),
832                    left, right);
833   }
834 }
835
836
837 // Shared routine for multiple compare operations.
838 void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
839                   Node* left, Node* right, FlagsContinuation* cont,
840                   bool commutative) {
841   IA32OperandGenerator g(selector);
842   if (commutative && g.CanBeBetterLeftOperand(right)) {
843     std::swap(left, right);
844   }
845   VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont);
846 }
847
848
849 // Shared routine for multiple float64 compare operations (inputs commuted).
850 void VisitFloat64Compare(InstructionSelector* selector, Node* node,
851                          FlagsContinuation* cont) {
852   Node* const left = node->InputAt(0);
853   Node* const right = node->InputAt(1);
854   VisitCompare(selector, kSSEFloat64Cmp, right, left, cont, false);
855 }
856
857
858 // Shared routine for multiple word compare operations.
859 void VisitWordCompare(InstructionSelector* selector, Node* node,
860                       InstructionCode opcode, FlagsContinuation* cont) {
861   IA32OperandGenerator g(selector);
862   Node* const left = node->InputAt(0);
863   Node* const right = node->InputAt(1);
864
865   // Match immediates on left or right side of comparison.
866   if (g.CanBeImmediate(right)) {
867     VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), cont);
868   } else if (g.CanBeImmediate(left)) {
869     if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute();
870     VisitCompare(selector, opcode, g.Use(right), g.UseImmediate(left), cont);
871   } else {
872     VisitCompare(selector, opcode, left, right, cont,
873                  node->op()->HasProperty(Operator::kCommutative));
874   }
875 }
876
877
878 void VisitWordCompare(InstructionSelector* selector, Node* node,
879                       FlagsContinuation* cont) {
880   IA32OperandGenerator g(selector);
881   Int32BinopMatcher m(node);
882   if (m.left().IsLoad() && m.right().IsLoadStackPointer()) {
883     LoadMatcher<ExternalReferenceMatcher> mleft(m.left().node());
884     ExternalReference js_stack_limit =
885         ExternalReference::address_of_stack_limit(selector->isolate());
886     if (mleft.object().Is(js_stack_limit) && mleft.index().Is(0)) {
887       // Compare(Load(js_stack_limit), LoadStackPointer)
888       if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute();
889       InstructionCode opcode = cont->Encode(kIA32StackCheck);
890       if (cont->IsBranch()) {
891         selector->Emit(opcode, g.NoOutput(), g.Label(cont->true_block()),
892                        g.Label(cont->false_block()));
893       } else {
894         DCHECK(cont->IsSet());
895         selector->Emit(opcode, g.DefineAsRegister(cont->result()));
896       }
897       return;
898     }
899   }
900   VisitWordCompare(selector, node, kIA32Cmp, cont);
901 }
902
903
904 // Shared routine for word comparison with zero.
905 void VisitWordCompareZero(InstructionSelector* selector, Node* user,
906                           Node* value, FlagsContinuation* cont) {
907   // Try to combine the branch with a comparison.
908   while (selector->CanCover(user, value)) {
909     switch (value->opcode()) {
910       case IrOpcode::kWord32Equal: {
911         // Try to combine with comparisons against 0 by simply inverting the
912         // continuation.
913         Int32BinopMatcher m(value);
914         if (m.right().Is(0)) {
915           user = value;
916           value = m.left().node();
917           cont->Negate();
918           continue;
919         }
920         cont->OverwriteAndNegateIfEqual(kEqual);
921         return VisitWordCompare(selector, value, cont);
922       }
923       case IrOpcode::kInt32LessThan:
924         cont->OverwriteAndNegateIfEqual(kSignedLessThan);
925         return VisitWordCompare(selector, value, cont);
926       case IrOpcode::kInt32LessThanOrEqual:
927         cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
928         return VisitWordCompare(selector, value, cont);
929       case IrOpcode::kUint32LessThan:
930         cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
931         return VisitWordCompare(selector, value, cont);
932       case IrOpcode::kUint32LessThanOrEqual:
933         cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
934         return VisitWordCompare(selector, value, cont);
935       case IrOpcode::kFloat64Equal:
936         cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
937         return VisitFloat64Compare(selector, value, cont);
938       case IrOpcode::kFloat64LessThan:
939         cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThan);
940         return VisitFloat64Compare(selector, value, cont);
941       case IrOpcode::kFloat64LessThanOrEqual:
942         cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual);
943         return VisitFloat64Compare(selector, value, cont);
944       case IrOpcode::kProjection:
945         // Check if this is the overflow output projection of an
946         // <Operation>WithOverflow node.
947         if (ProjectionIndexOf(value->op()) == 1u) {
948           // We cannot combine the <Operation>WithOverflow with this branch
949           // unless the 0th projection (the use of the actual value of the
950           // <Operation> is either NULL, which means there's no use of the
951           // actual value, or was already defined, which means it is scheduled
952           // *AFTER* this branch).
953           Node* const node = value->InputAt(0);
954           Node* const result = NodeProperties::FindProjection(node, 0);
955           if (result == NULL || selector->IsDefined(result)) {
956             switch (node->opcode()) {
957               case IrOpcode::kInt32AddWithOverflow:
958                 cont->OverwriteAndNegateIfEqual(kOverflow);
959                 return VisitBinop(selector, node, kIA32Add, cont);
960               case IrOpcode::kInt32SubWithOverflow:
961                 cont->OverwriteAndNegateIfEqual(kOverflow);
962                 return VisitBinop(selector, node, kIA32Sub, cont);
963               default:
964                 break;
965             }
966           }
967         }
968         break;
969       case IrOpcode::kInt32Sub:
970         return VisitWordCompare(selector, value, cont);
971       case IrOpcode::kWord32And:
972         return VisitWordCompare(selector, value, kIA32Test, cont);
973       default:
974         break;
975     }
976     break;
977   }
978
979   // Continuation could not be combined with a compare, emit compare against 0.
980   IA32OperandGenerator g(selector);
981   VisitCompare(selector, kIA32Cmp, g.Use(value), g.TempImmediate(0), cont);
982 }
983
984 }  // namespace
985
986
987 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
988                                       BasicBlock* fbranch) {
989   FlagsContinuation cont(kNotEqual, tbranch, fbranch);
990   VisitWordCompareZero(this, branch, branch->InputAt(0), &cont);
991 }
992
993
994 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
995   IA32OperandGenerator g(this);
996   InstructionOperand value_operand = g.UseRegister(node->InputAt(0));
997
998   // Emit either ArchTableSwitch or ArchLookupSwitch.
999   size_t table_space_cost = 4 + sw.value_range;
1000   size_t table_time_cost = 3;
1001   size_t lookup_space_cost = 3 + 2 * sw.case_count;
1002   size_t lookup_time_cost = sw.case_count;
1003   if (sw.case_count > 4 &&
1004       table_space_cost + 3 * table_time_cost <=
1005           lookup_space_cost + 3 * lookup_time_cost &&
1006       sw.min_value > std::numeric_limits<int32_t>::min()) {
1007     InstructionOperand index_operand = value_operand;
1008     if (sw.min_value) {
1009       index_operand = g.TempRegister();
1010       Emit(kIA32Lea | AddressingModeField::encode(kMode_MRI), index_operand,
1011            value_operand, g.TempImmediate(-sw.min_value));
1012     }
1013     // Generate a table lookup.
1014     return EmitTableSwitch(sw, index_operand);
1015   }
1016
1017   // Generate a sequence of conditional jumps.
1018   return EmitLookupSwitch(sw, value_operand);
1019 }
1020
1021
1022 void InstructionSelector::VisitWord32Equal(Node* const node) {
1023   FlagsContinuation cont(kEqual, node);
1024   Int32BinopMatcher m(node);
1025   if (m.right().Is(0)) {
1026     return VisitWordCompareZero(this, m.node(), m.left().node(), &cont);
1027   }
1028   VisitWordCompare(this, node, &cont);
1029 }
1030
1031
1032 void InstructionSelector::VisitInt32LessThan(Node* node) {
1033   FlagsContinuation cont(kSignedLessThan, node);
1034   VisitWordCompare(this, node, &cont);
1035 }
1036
1037
1038 void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
1039   FlagsContinuation cont(kSignedLessThanOrEqual, node);
1040   VisitWordCompare(this, node, &cont);
1041 }
1042
1043
1044 void InstructionSelector::VisitUint32LessThan(Node* node) {
1045   FlagsContinuation cont(kUnsignedLessThan, node);
1046   VisitWordCompare(this, node, &cont);
1047 }
1048
1049
1050 void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
1051   FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
1052   VisitWordCompare(this, node, &cont);
1053 }
1054
1055
1056 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
1057   if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
1058     FlagsContinuation cont(kOverflow, ovf);
1059     return VisitBinop(this, node, kIA32Add, &cont);
1060   }
1061   FlagsContinuation cont;
1062   VisitBinop(this, node, kIA32Add, &cont);
1063 }
1064
1065
1066 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
1067   if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
1068     FlagsContinuation cont(kOverflow, ovf);
1069     return VisitBinop(this, node, kIA32Sub, &cont);
1070   }
1071   FlagsContinuation cont;
1072   VisitBinop(this, node, kIA32Sub, &cont);
1073 }
1074
1075
1076 void InstructionSelector::VisitFloat64Equal(Node* node) {
1077   FlagsContinuation cont(kUnorderedEqual, node);
1078   VisitFloat64Compare(this, node, &cont);
1079 }
1080
1081
1082 void InstructionSelector::VisitFloat64LessThan(Node* node) {
1083   FlagsContinuation cont(kUnsignedGreaterThan, node);
1084   VisitFloat64Compare(this, node, &cont);
1085 }
1086
1087
1088 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
1089   FlagsContinuation cont(kUnsignedGreaterThanOrEqual, node);
1090   VisitFloat64Compare(this, node, &cont);
1091 }
1092
1093
1094 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
1095   IA32OperandGenerator g(this);
1096   Emit(kSSEFloat64ExtractLowWord32, g.DefineAsRegister(node),
1097        g.Use(node->InputAt(0)));
1098 }
1099
1100
1101 void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) {
1102   IA32OperandGenerator g(this);
1103   Emit(kSSEFloat64ExtractHighWord32, g.DefineAsRegister(node),
1104        g.Use(node->InputAt(0)));
1105 }
1106
1107
1108 void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) {
1109   IA32OperandGenerator g(this);
1110   Node* left = node->InputAt(0);
1111   Node* right = node->InputAt(1);
1112   Float64Matcher mleft(left);
1113   if (mleft.HasValue() && (bit_cast<uint64_t>(mleft.Value()) >> 32) == 0u) {
1114     Emit(kSSEFloat64LoadLowWord32, g.DefineAsRegister(node), g.Use(right));
1115     return;
1116   }
1117   Emit(kSSEFloat64InsertLowWord32, g.DefineSameAsFirst(node),
1118        g.UseRegister(left), g.Use(right));
1119 }
1120
1121
1122 void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) {
1123   IA32OperandGenerator g(this);
1124   Node* left = node->InputAt(0);
1125   Node* right = node->InputAt(1);
1126   Emit(kSSEFloat64InsertHighWord32, g.DefineSameAsFirst(node),
1127        g.UseRegister(left), g.Use(right));
1128 }
1129
1130
1131 // static
1132 MachineOperatorBuilder::Flags
1133 InstructionSelector::SupportedMachineOperatorFlags() {
1134   MachineOperatorBuilder::Flags flags =
1135       MachineOperatorBuilder::kFloat64Max |
1136       MachineOperatorBuilder::kFloat64Min |
1137       MachineOperatorBuilder::kWord32ShiftIsSafe;
1138   if (CpuFeatures::IsSupported(SSE4_1)) {
1139     flags |= MachineOperatorBuilder::kFloat64RoundDown |
1140              MachineOperatorBuilder::kFloat64RoundTruncate;
1141   }
1142   return flags;
1143 }
1144
1145 }  // namespace compiler
1146 }  // namespace internal
1147 }  // namespace v8