1958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Copyright 2014 the V8 project authors. All rights reserved.
2958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Use of this source code is governed by a BSD-style license that can be
3958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// found in the LICENSE file.
4958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/base/adapters.h"
6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/base/bits.h"
7958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/instruction-selector-impl.h"
8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/node-matchers.h"
9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/node-properties.h"
10958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
11958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace v8 {
12958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace internal {
13958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace compiler {
14958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
15958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define TRACE_UNIMPL() \
16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  PrintF("UNIMPLEMENTED instr_sel: %s at line %d\n", __FUNCTION__, __LINE__)
17958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
18958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define TRACE() PrintF("instr_sel: %s at line %d\n", __FUNCTION__, __LINE__)
19958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
20958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
21958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Adds Mips-specific methods for generating InstructionOperands.
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass MipsOperandGenerator final : public OperandGenerator {
23958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public:
24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  explicit MipsOperandGenerator(InstructionSelector* selector)
25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      : OperandGenerator(selector) {}
26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand UseOperand(Node* node, InstructionCode opcode) {
28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (CanBeImmediate(node, opcode)) {
29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return UseImmediate(node);
30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return UseRegister(node);
32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
34c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // Use the zero register if the node has the immediate value zero, otherwise
35c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // assign a register.
36c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  InstructionOperand UseRegisterOrImmediateZero(Node* node) {
37c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if ((IsIntegerConstant(node) && (GetIntegerConstantValue(node) == 0)) ||
38c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        (IsFloatConstant(node) &&
39c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch         (bit_cast<int64_t>(GetFloatConstantValue(node)) == V8_INT64_C(0)))) {
40c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      return UseImmediate(node);
41c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
42c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return UseRegister(node);
43c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
44c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
45c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  bool IsIntegerConstant(Node* node) {
46c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return (node->opcode() == IrOpcode::kInt32Constant);
47c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
48c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
49c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int64_t GetIntegerConstantValue(Node* node) {
50c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    DCHECK(node->opcode() == IrOpcode::kInt32Constant);
51c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return OpParameter<int32_t>(node);
52c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
53c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
54c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  bool IsFloatConstant(Node* node) {
55c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return (node->opcode() == IrOpcode::kFloat32Constant) ||
56c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch           (node->opcode() == IrOpcode::kFloat64Constant);
57c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
58c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
59c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  double GetFloatConstantValue(Node* node) {
60c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (node->opcode() == IrOpcode::kFloat32Constant) {
61c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      return OpParameter<float>(node);
62c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
63c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    DCHECK_EQ(IrOpcode::kFloat64Constant, node->opcode());
64c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return OpParameter<double>(node);
65c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
66c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
67958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool CanBeImmediate(Node* node, InstructionCode opcode) {
68958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Int32Matcher m(node);
69958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (!m.HasValue()) return false;
70958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    int32_t value = m.Value();
71958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    switch (ArchOpcodeField::decode(opcode)) {
72958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMipsShl:
73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMipsSar:
74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMipsShr:
75958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return is_uint5(value);
76c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kMipsAdd:
77c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kMipsAnd:
78c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kMipsOr:
79c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kMipsTst:
80c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kMipsSub:
81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMipsXor:
82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return is_uint16(value);
83c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kMipsLb:
84c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kMipsLbu:
85c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kMipsSb:
86c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kMipsLh:
87c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kMipsLhu:
88c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kMipsSh:
89c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kMipsLw:
90c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kMipsSw:
91c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kMipsLwc1:
92c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kMipsSwc1:
93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMipsLdc1:
94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMipsSdc1:
95c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kCheckedLoadInt8:
96c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kCheckedLoadUint8:
97c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kCheckedLoadInt16:
98c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kCheckedLoadUint16:
99c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kCheckedLoadWord32:
100c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kCheckedStoreWord8:
101c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kCheckedStoreWord16:
102c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kCheckedStoreWord32:
103c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kCheckedLoadFloat32:
104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kCheckedLoadFloat64:
105c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case kCheckedStoreFloat32:
106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kCheckedStoreFloat64:
107c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        // true even for 32b values, offsets > 16b
108c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        // are handled in assembler-mips.cc
109c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        return is_int32(value);
110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      default:
111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return is_int16(value);
112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private:
116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool ImmediateFitsAddrMode1Instruction(int32_t imm) const {
117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    TRACE_UNIMPL();
118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return false;
119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic void VisitRRR(InstructionSelector* selector, ArchOpcode opcode,
124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                     Node* node) {
125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(selector);
126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  selector->Emit(opcode, g.DefineAsRegister(node),
127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                 g.UseRegister(node->InputAt(0)),
128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                 g.UseRegister(node->InputAt(1)));
129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic void VisitRR(InstructionSelector* selector, ArchOpcode opcode,
133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                    Node* node) {
134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(selector);
135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  selector->Emit(opcode, g.DefineAsRegister(node),
136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                 g.UseRegister(node->InputAt(0)));
137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic void VisitRRO(InstructionSelector* selector, ArchOpcode opcode,
141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                     Node* node) {
142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(selector);
143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  selector->Emit(opcode, g.DefineAsRegister(node),
144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                 g.UseRegister(node->InputAt(0)),
145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                 g.UseOperand(node->InputAt(1), opcode));
146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
148c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochbool TryMatchImmediate(InstructionSelector* selector,
149c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                       InstructionCode* opcode_return, Node* node,
150c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                       size_t* input_count_return, InstructionOperand* inputs) {
151c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  MipsOperandGenerator g(selector);
152c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (g.CanBeImmediate(node, *opcode_return)) {
153c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    *opcode_return |= AddressingModeField::encode(kMode_MRI);
154c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    inputs[0] = g.UseImmediate(node);
155c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    *input_count_return = 1;
156c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return true;
157c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
158c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return false;
159c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic void VisitBinop(InstructionSelector* selector, Node* node,
162c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                       InstructionCode opcode, bool has_reverse_opcode,
163c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                       InstructionCode reverse_opcode,
164c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                       FlagsContinuation* cont) {
165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(selector);
166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Int32BinopMatcher m(node);
167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand inputs[4];
168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t input_count = 0;
169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand outputs[2];
170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t output_count = 0;
171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
172c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (TryMatchImmediate(selector, &opcode, m.right().node(), &input_count,
173c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                        &inputs[1])) {
174c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    inputs[0] = g.UseRegister(m.left().node());
175c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    input_count++;
17662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (has_reverse_opcode &&
17762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             TryMatchImmediate(selector, &reverse_opcode, m.left().node(),
17862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                               &input_count, &inputs[1])) {
179c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    inputs[0] = g.UseRegister(m.right().node());
180c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    opcode = reverse_opcode;
181c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    input_count++;
182c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else {
183c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    inputs[input_count++] = g.UseRegister(m.left().node());
184c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    inputs[input_count++] = g.UseOperand(m.right().node(), opcode);
185c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (cont->IsBranch()) {
188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    inputs[input_count++] = g.Label(cont->true_block());
189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    inputs[input_count++] = g.Label(cont->false_block());
19062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (cont->IsTrap()) {
19162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    inputs[input_count++] = g.TempImmediate(cont->trap_id());
192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (cont->IsDeoptimize()) {
195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // If we can deoptimize as a result of the binop, we need to make sure that
196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // the deopt inputs are not overwritten by the binop result. One way
197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // to achieve that is to declare the output register as same-as-first.
198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    outputs[output_count++] = g.DefineSameAsFirst(node);
199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    outputs[output_count++] = g.DefineAsRegister(node);
201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (cont->IsSet()) {
203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    outputs[output_count++] = g.DefineAsRegister(cont->result());
204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_NE(0u, input_count);
207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_NE(0u, output_count);
208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK_GE(arraysize(inputs), input_count);
209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK_GE(arraysize(outputs), output_count);
210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  opcode = cont->Encode(opcode);
2123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (cont->IsDeoptimize()) {
2133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
21462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             cont->kind(), cont->reason(), cont->frame_state());
2153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else {
2163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    selector->Emit(opcode, output_count, outputs, input_count, inputs);
2173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
220c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstatic void VisitBinop(InstructionSelector* selector, Node* node,
221c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                       InstructionCode opcode, bool has_reverse_opcode,
222c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                       InstructionCode reverse_opcode) {
223c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  FlagsContinuation cont;
224c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  VisitBinop(selector, node, opcode, has_reverse_opcode, reverse_opcode, &cont);
225c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
226c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
227c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstatic void VisitBinop(InstructionSelector* selector, Node* node,
228c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                       InstructionCode opcode, FlagsContinuation* cont) {
229c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  VisitBinop(selector, node, opcode, false, kArchNop, cont);
230c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic void VisitBinop(InstructionSelector* selector, Node* node,
233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                       InstructionCode opcode) {
234c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  VisitBinop(selector, node, opcode, false, kArchNop);
235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitLoad(Node* node) {
239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LoadRepresentation load_rep = LoadRepresentationOf(node->op());
240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(this);
241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* base = node->InputAt(0);
242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* index = node->InputAt(1);
243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ArchOpcode opcode = kArchNop;
245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (load_rep.representation()) {
246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat32:
247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode = kMipsLwc1;
248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat64:
250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode = kMipsLdc1;
251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kBit:  // Fall through.
253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord8:
254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      opcode = load_rep.IsUnsigned() ? kMipsLbu : kMipsLb;
255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord16:
257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      opcode = load_rep.IsUnsigned() ? kMipsLhu : kMipsLh;
258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
259f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTaggedSigned:   // Fall through.
260f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTaggedPointer:  // Fall through.
261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kTagged:  // Fall through.
262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord32:
263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode = kMipsLw;
264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
265109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case MachineRepresentation::kWord64:   // Fall through.
266109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case MachineRepresentation::kSimd128:  // Fall through.
26762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x4:  // Fall through.
26862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x8:  // Fall through.
26962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x16:  // Fall through.
270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kNone:
271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      UNREACHABLE();
272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return;
273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (g.CanBeImmediate(index, opcode)) {
276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Emit(opcode | AddressingModeField::encode(kMode_MRI),
277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier         g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand addr_reg = g.TempRegister();
280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier         g.UseRegister(index), g.UseRegister(base));
282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Emit desired load opcode, using temp addr_reg.
283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Emit(opcode | AddressingModeField::encode(kMode_MRI),
284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier         g.DefineAsRegister(node), addr_reg, g.TempImmediate(0));
285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
288f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid InstructionSelector::VisitProtectedLoad(Node* node) {
289f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // TODO(eholk)
290f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  UNIMPLEMENTED();
291f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitStore(Node* node) {
294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(this);
295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* base = node->InputAt(0);
296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* index = node->InputAt(1);
297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* value = node->InputAt(2);
298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  StoreRepresentation store_rep = StoreRepresentationOf(node->op());
300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MachineRepresentation rep = store_rep.representation();
302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // TODO(mips): I guess this could be done in a better way.
304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (write_barrier_kind != kNoWriteBarrier) {
305f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK(CanBeTaggedPointer(rep));
306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand inputs[3];
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    size_t input_count = 0;
308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    inputs[input_count++] = g.UseUniqueRegister(base);
309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    inputs[input_count++] = g.UseUniqueRegister(index);
3103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    inputs[input_count++] = g.UseUniqueRegister(value);
311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny;
312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (write_barrier_kind) {
313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kNoWriteBarrier:
314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UNREACHABLE();
315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMapWriteBarrier:
317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        record_write_mode = RecordWriteMode::kValueIsMap;
318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kPointerWriteBarrier:
320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        record_write_mode = RecordWriteMode::kValueIsPointer;
321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kFullWriteBarrier:
323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        record_write_mode = RecordWriteMode::kValueIsAny;
324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    size_t const temp_count = arraysize(temps);
328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionCode code = kArchStoreWithWriteBarrier;
329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    code |= MiscField::encode(static_cast<int>(record_write_mode));
330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ArchOpcode opcode = kArchNop;
333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (rep) {
334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kFloat32:
335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        opcode = kMipsSwc1;
336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kFloat64:
338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        opcode = kMipsSdc1;
339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kBit:  // Fall through.
341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kWord8:
342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        opcode = kMipsSb;
343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kWord16:
345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        opcode = kMipsSh;
346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
347f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case MachineRepresentation::kTaggedSigned:   // Fall through.
348f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case MachineRepresentation::kTaggedPointer:  // Fall through.
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kTagged:  // Fall through.
350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kWord32:
351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        opcode = kMipsSw;
352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
353109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      case MachineRepresentation::kWord64:   // Fall through.
354109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      case MachineRepresentation::kSimd128:  // Fall through.
35562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      case MachineRepresentation::kSimd1x4:  // Fall through.
35662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      case MachineRepresentation::kSimd1x8:  // Fall through.
35762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      case MachineRepresentation::kSimd1x16:  // Fall through.
358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kNone:
359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UNREACHABLE();
360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return;
361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (g.CanBeImmediate(index, opcode)) {
364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
365c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch           g.UseRegister(base), g.UseImmediate(index),
366c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch           g.UseRegisterOrImmediateZero(value));
367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand addr_reg = g.TempRegister();
369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           g.UseRegister(index), g.UseRegister(base));
371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Emit desired store opcode, using temp addr_reg.
372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
373c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch           addr_reg, g.TempImmediate(0), g.UseRegisterOrImmediateZero(value));
374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
37862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InstructionSelector::VisitProtectedStore(Node* node) {
37962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // TODO(eholk)
38062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  UNIMPLEMENTED();
38162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitWord32And(Node* node) {
384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MipsOperandGenerator g(this);
385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Int32BinopMatcher m(node);
386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (m.left().IsWord32Shr() && CanCover(node, m.left().node()) &&
387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      m.right().HasValue()) {
388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint32_t mask = m.right().Value();
389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint32_t mask_width = base::bits::CountPopulation32(mask);
390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint32_t mask_msb = base::bits::CountLeadingZeros32(mask);
391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if ((mask_width != 0) && (mask_msb + mask_width == 32)) {
392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The mask must be contiguous, and occupy the least-significant bits.
393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_EQ(0u, base::bits::CountTrailingZeros32(mask));
394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Select Ext for And(Shr(x, imm), mask) where the mask is in the least
396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // significant bits.
397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Int32BinopMatcher mleft(m.left().node());
398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (mleft.right().HasValue()) {
399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Any shift value can match; int32 shifts use `value % 32`.
400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        uint32_t lsb = mleft.right().Value() & 0x1f;
401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Ext cannot extract bits past the register size, however since
403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // shifting the original value would have introduced some zeros we can
404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // still use Ext with a smaller mask and the remaining bits will be
405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // zeros.
406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (lsb + mask_width > 32) mask_width = 32 - lsb;
407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
40862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        if (lsb == 0 && mask_width == 32) {
40962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(mleft.left().node()));
41062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        } else {
41162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          Emit(kMipsExt, g.DefineAsRegister(node),
41262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch               g.UseRegister(mleft.left().node()), g.TempImmediate(lsb),
41362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch               g.TempImmediate(mask_width));
41462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        }
415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return;
416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Other cases fall through to the normal And operation.
418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (m.right().HasValue()) {
421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint32_t mask = m.right().Value();
422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint32_t shift = base::bits::CountPopulation32(~mask);
423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint32_t msb = base::bits::CountLeadingZeros32(~mask);
424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (shift != 0 && shift != 32 && msb + shift == 32) {
425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Insert zeros for (x >> K) << K => x & ~(2^K - 1) expression reduction
426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // and remove constant loading of invereted mask.
427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Emit(kMipsIns, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           g.TempImmediate(0), g.TempImmediate(shift));
429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
432c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  VisitBinop(this, node, kMipsAnd, true, kMipsAnd);
433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitWord32Or(Node* node) {
437c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  VisitBinop(this, node, kMipsOr, true, kMipsOr);
438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitWord32Xor(Node* node) {
442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Int32BinopMatcher m(node);
443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (m.left().IsWord32Or() && CanCover(node, m.left().node()) &&
444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      m.right().Is(-1)) {
445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Int32BinopMatcher mleft(m.left().node());
446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!mleft.right().HasValue()) {
447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MipsOperandGenerator g(this);
448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Emit(kMipsNor, g.DefineAsRegister(node),
449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           g.UseRegister(mleft.left().node()),
450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           g.UseRegister(mleft.right().node()));
451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (m.right().Is(-1)) {
455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Use Nor for bit negation and eliminate constant loading for xori.
456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MipsOperandGenerator g(this);
457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Emit(kMipsNor, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         g.TempImmediate(0));
459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
461c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  VisitBinop(this, node, kMipsXor, true, kMipsXor);
462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
463958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitWord32Shl(Node* node) {
466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Int32BinopMatcher m(node);
467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (m.left().IsWord32And() && CanCover(node, m.left().node()) &&
468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      m.right().IsInRange(1, 31)) {
469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MipsOperandGenerator g(this);
470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Int32BinopMatcher mleft(m.left().node());
471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Match Word32Shl(Word32And(x, mask), imm) to Shl where the mask is
472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // contiguous, and the shift immediate non-zero.
473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (mleft.right().HasValue()) {
474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint32_t mask = mleft.right().Value();
475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint32_t mask_width = base::bits::CountPopulation32(mask);
476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint32_t mask_msb = base::bits::CountLeadingZeros32(mask);
477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if ((mask_width != 0) && (mask_msb + mask_width == 32)) {
478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        uint32_t shift = m.right().Value();
479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK_EQ(0u, base::bits::CountTrailingZeros32(mask));
480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK_NE(0u, shift);
481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if ((shift + mask_width) >= 32) {
482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // If the mask is contiguous and reaches or extends beyond the top
483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // bit, only the shift is needed.
484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Emit(kMipsShl, g.DefineAsRegister(node),
485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               g.UseRegister(mleft.left().node()),
486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               g.UseImmediate(m.right().node()));
487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return;
488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitRRO(this, kMipsShl, node);
493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitWord32Shr(Node* node) {
497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Int32BinopMatcher m(node);
498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (m.left().IsWord32And() && m.right().HasValue()) {
499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    uint32_t lsb = m.right().Value() & 0x1f;
500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Int32BinopMatcher mleft(m.left().node());
501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (mleft.right().HasValue()) {
502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Select Ext for Shr(And(x, mask), imm) where the result of the mask is
503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // shifted into the least-significant bits.
504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint32_t mask = (mleft.right().Value() >> lsb) << lsb;
505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      unsigned mask_width = base::bits::CountPopulation32(mask);
506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      unsigned mask_msb = base::bits::CountLeadingZeros32(mask);
507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if ((mask_msb + mask_width + lsb) == 32) {
508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        MipsOperandGenerator g(this);
509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK_EQ(lsb, base::bits::CountTrailingZeros32(mask));
510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Emit(kMipsExt, g.DefineAsRegister(node),
511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             g.UseRegister(mleft.left().node()), g.TempImmediate(lsb),
512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             g.TempImmediate(mask_width));
513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return;
514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
517958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitRRO(this, kMipsShr, node);
518958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
519958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
520958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
521958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitWord32Sar(Node* node) {
522f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Int32BinopMatcher m(node);
523f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (m.left().IsWord32Shl() && CanCover(node, m.left().node())) {
524f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Int32BinopMatcher mleft(m.left().node());
525f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (m.right().HasValue() && mleft.right().HasValue()) {
526f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      MipsOperandGenerator g(this);
527f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      uint32_t sar = m.right().Value();
528f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      uint32_t shl = mleft.right().Value();
529f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if ((sar == shl) && (sar == 16)) {
530f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        Emit(kMipsSeh, g.DefineAsRegister(node),
531f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch             g.UseRegister(mleft.left().node()));
532f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        return;
533f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      } else if ((sar == shl) && (sar == 24)) {
534f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        Emit(kMipsSeb, g.DefineAsRegister(node),
535f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch             g.UseRegister(mleft.left().node()));
536f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        return;
537f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
538f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
539f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
540958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitRRO(this, kMipsSar, node);
541958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
542958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
543bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochstatic void VisitInt32PairBinop(InstructionSelector* selector,
544c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                InstructionCode pair_opcode,
545c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                InstructionCode single_opcode, Node* node) {
546bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  MipsOperandGenerator g(selector);
5473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
548c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* projection1 = NodeProperties::FindProjection(node, 1);
549c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
550c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (projection1) {
551c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // We use UseUniqueRegister here to avoid register sharing with the output
552c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // register.
553c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    InstructionOperand inputs[] = {g.UseUniqueRegister(node->InputAt(0)),
554c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                   g.UseUniqueRegister(node->InputAt(1)),
555c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                   g.UseUniqueRegister(node->InputAt(2)),
556c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                   g.UseUniqueRegister(node->InputAt(3))};
557bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
558c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    InstructionOperand outputs[] = {
559c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        g.DefineAsRegister(node),
560c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        g.DefineAsRegister(NodeProperties::FindProjection(node, 1))};
561c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    selector->Emit(pair_opcode, 2, outputs, 4, inputs);
562c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else {
563c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // The high word of the result is not used, so we emit the standard 32 bit
564c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // instruction.
565c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    selector->Emit(single_opcode, g.DefineSameAsFirst(node),
566c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                   g.UseRegister(node->InputAt(0)),
567c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                   g.UseRegister(node->InputAt(2)));
568c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
569bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
570bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
571bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitInt32PairAdd(Node* node) {
572c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  VisitInt32PairBinop(this, kMipsAddPair, kMipsAdd, node);
573bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
574bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
575bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitInt32PairSub(Node* node) {
576c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  VisitInt32PairBinop(this, kMipsSubPair, kMipsSub, node);
577bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
578bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
579bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitInt32PairMul(Node* node) {
580c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  VisitInt32PairBinop(this, kMipsMulPair, kMipsMul, node);
581bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
582bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
583bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch// Shared routine for multiple shift operations.
584bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochstatic void VisitWord32PairShift(InstructionSelector* selector,
585bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                 InstructionCode opcode, Node* node) {
586bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  MipsOperandGenerator g(selector);
587bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Int32Matcher m(node->InputAt(2));
588bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  InstructionOperand shift_operand;
589bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (m.HasValue()) {
590bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    shift_operand = g.UseImmediate(m.node());
591bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else {
592bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    shift_operand = g.UseUniqueRegister(m.node());
593bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
594bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
595bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // We use UseUniqueRegister here to avoid register sharing with the output
596bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // register.
597bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  InstructionOperand inputs[] = {g.UseUniqueRegister(node->InputAt(0)),
598bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                 g.UseUniqueRegister(node->InputAt(1)),
599bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                 shift_operand};
600bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
601c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Node* projection1 = NodeProperties::FindProjection(node, 1);
602c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
603c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  InstructionOperand outputs[2];
604c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  InstructionOperand temps[1];
605c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int32_t output_count = 0;
606c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int32_t temp_count = 0;
607bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
608c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  outputs[output_count++] = g.DefineAsRegister(node);
609c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (projection1) {
610c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    outputs[output_count++] = g.DefineAsRegister(projection1);
611c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else {
612c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    temps[temp_count++] = g.TempRegister();
613c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
614c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
615c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  selector->Emit(opcode, output_count, outputs, 3, inputs, temp_count, temps);
6163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
6173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
618bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitWord32PairShl(Node* node) {
619bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  VisitWord32PairShift(this, kMipsShlPair, node);
620bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
6213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
622bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitWord32PairShr(Node* node) {
623bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  VisitWord32PairShift(this, kMipsShrPair, node);
624bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
6253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
626bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitWord32PairSar(Node* node) {
627bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  VisitWord32PairShift(this, kMipsSarPair, node);
628bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
629958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
630958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitWord32Ror(Node* node) {
631958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitRRO(this, kMipsRor, node);
632958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
633958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
634958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitWord32Clz(Node* node) {
636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRR(this, kMipsClz, node);
637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
640109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InstructionSelector::VisitWord32ReverseBits(Node* node) { UNREACHABLE(); }
641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
642f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitWord64ReverseBytes(Node* node) { UNREACHABLE(); }
643f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
644f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitWord32ReverseBytes(Node* node) {
645f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  MipsOperandGenerator g(this);
646f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Emit(kMipsByteSwap32, g.DefineAsRegister(node),
647f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch       g.UseRegister(node->InputAt(0)));
648f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
650109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InstructionSelector::VisitWord32Ctz(Node* node) {
651109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  MipsOperandGenerator g(this);
652109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Emit(kMipsCtz, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
653109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
654109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
655109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
656109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InstructionSelector::VisitWord32Popcnt(Node* node) {
657109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  MipsOperandGenerator g(this);
658109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Emit(kMipsPopcnt, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
659109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
662958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32Add(Node* node) {
663958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(this);
664bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Int32BinopMatcher m(node);
665bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
666bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Select Lsa for (left + (left_of_right << imm)).
667bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (m.right().opcode() == IrOpcode::kWord32Shl &&
668bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      CanCover(node, m.left().node()) && CanCover(node, m.right().node())) {
669bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Int32BinopMatcher mright(m.right().node());
67062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (mright.right().HasValue() && !m.left().HasValue()) {
671bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      int32_t shift_value = static_cast<int32_t>(mright.right().Value());
672bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      Emit(kMipsLsa, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
673bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch           g.UseRegister(mright.left().node()), g.TempImmediate(shift_value));
674bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      return;
675bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
676bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
677bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
678bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Select Lsa for ((left_of_left << imm) + right).
679bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (m.left().opcode() == IrOpcode::kWord32Shl &&
680bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      CanCover(node, m.right().node()) && CanCover(node, m.left().node())) {
681bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Int32BinopMatcher mleft(m.left().node());
68262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (mleft.right().HasValue() && !m.right().HasValue()) {
683bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      int32_t shift_value = static_cast<int32_t>(mleft.right().Value());
684bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      Emit(kMipsLsa, g.DefineAsRegister(node), g.UseRegister(m.right().node()),
685bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch           g.UseRegister(mleft.left().node()), g.TempImmediate(shift_value));
686bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      return;
687bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
688bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
689958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
690c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  VisitBinop(this, node, kMipsAdd, true, kMipsAdd);
691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
692958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
693958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
694958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32Sub(Node* node) {
695958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitBinop(this, node, kMipsSub);
696958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
697958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
698958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
699958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32Mul(Node* node) {
700958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(this);
701958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Int32BinopMatcher m(node);
702958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (m.right().HasValue() && m.right().Value() > 0) {
703958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    int32_t value = m.right().Value();
704958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (base::bits::IsPowerOfTwo32(value)) {
705958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Emit(kMipsShl | AddressingModeField::encode(kMode_None),
706958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           g.DefineAsRegister(node), g.UseRegister(m.left().node()),
707958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           g.TempImmediate(WhichPowerOf2(value)));
708958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return;
709958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
710958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (base::bits::IsPowerOfTwo32(value - 1)) {
711bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      Emit(kMipsLsa, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
712958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           g.UseRegister(m.left().node()),
713958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           g.TempImmediate(WhichPowerOf2(value - 1)));
714958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return;
715958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
716958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (base::bits::IsPowerOfTwo32(value + 1)) {
717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand temp = g.TempRegister();
718958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Emit(kMipsShl | AddressingModeField::encode(kMode_None), temp,
719958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           g.UseRegister(m.left().node()),
720958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           g.TempImmediate(WhichPowerOf2(value + 1)));
721958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Emit(kMipsSub | AddressingModeField::encode(kMode_None),
722958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           g.DefineAsRegister(node), temp, g.UseRegister(m.left().node()));
723958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return;
724958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
725958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRRR(this, kMipsMul, node);
727958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
728958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
729958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
730958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32MulHigh(Node* node) {
731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRRR(this, kMipsMulHigh, node);
732958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
733958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
734958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
735958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32MulHigh(Node* node) {
736958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(this);
737958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Emit(kMipsMulHighU, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)),
738958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       g.UseRegister(node->InputAt(1)));
739958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
740958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
741958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
742958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32Div(Node* node) {
743958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(this);
744958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Int32BinopMatcher m(node);
745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Emit(kMipsDiv, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
746958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       g.UseRegister(m.right().node()));
747958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
748958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
749958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
750958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32Div(Node* node) {
751958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(this);
752958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Int32BinopMatcher m(node);
753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Emit(kMipsDivU, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
754958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       g.UseRegister(m.right().node()));
755958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
756958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
757958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
758958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32Mod(Node* node) {
759958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(this);
760958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Int32BinopMatcher m(node);
761958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Emit(kMipsMod, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
762958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       g.UseRegister(m.right().node()));
763958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
764958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
765958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
766958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32Mod(Node* node) {
767958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(this);
768958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Int32BinopMatcher m(node);
769958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Emit(kMipsModU, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
770958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       g.UseRegister(m.right().node()));
771958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
772958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
773958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
774958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRR(this, kMipsCvtDS, node);
776958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
777958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
778958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
779109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InstructionSelector::VisitRoundInt32ToFloat32(Node* node) {
780109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  VisitRR(this, kMipsCvtSW, node);
781109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
782109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
783109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
784109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InstructionSelector::VisitRoundUint32ToFloat32(Node* node) {
785109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  VisitRR(this, kMipsCvtSUw, node);
786109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
787109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
788109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
789958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRR(this, kMipsCvtDW, node);
791958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
792958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
793958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
794958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRR(this, kMipsCvtDUw, node);
796958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
797958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
798958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
799109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InstructionSelector::VisitTruncateFloat32ToInt32(Node* node) {
800109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  VisitRR(this, kMipsTruncWS, node);
801109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
802109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
803109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
804109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InstructionSelector::VisitTruncateFloat32ToUint32(Node* node) {
805109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  VisitRR(this, kMipsTruncUwS, node);
806109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
807109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
808109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
809958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(this);
811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* value = node->InputAt(0);
812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Match ChangeFloat64ToInt32(Float64Round##OP) to corresponding instruction
813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // which does rounding and conversion to integer format.
814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CanCover(node, value)) {
815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (value->opcode()) {
816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case IrOpcode::kFloat64RoundDown:
817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Emit(kMipsFloorWD, g.DefineAsRegister(node),
818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             g.UseRegister(value->InputAt(0)));
819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return;
820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case IrOpcode::kFloat64RoundUp:
821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Emit(kMipsCeilWD, g.DefineAsRegister(node),
822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             g.UseRegister(value->InputAt(0)));
823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return;
824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case IrOpcode::kFloat64RoundTiesEven:
825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Emit(kMipsRoundWD, g.DefineAsRegister(node),
826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             g.UseRegister(value->InputAt(0)));
827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return;
828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case IrOpcode::kFloat64RoundTruncate:
829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Emit(kMipsTruncWD, g.DefineAsRegister(node),
830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             g.UseRegister(value->InputAt(0)));
831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return;
832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      default:
833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (value->opcode() == IrOpcode::kChangeFloat32ToFloat64) {
836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Node* next = value->InputAt(0);
837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (CanCover(value, next)) {
838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Match ChangeFloat64ToInt32(ChangeFloat32ToFloat64(Float64Round##OP))
839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        switch (next->opcode()) {
840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          case IrOpcode::kFloat32RoundDown:
841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Emit(kMipsFloorWS, g.DefineAsRegister(node),
842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 g.UseRegister(next->InputAt(0)));
843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            return;
844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          case IrOpcode::kFloat32RoundUp:
845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Emit(kMipsCeilWS, g.DefineAsRegister(node),
846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 g.UseRegister(next->InputAt(0)));
847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            return;
848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          case IrOpcode::kFloat32RoundTiesEven:
849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Emit(kMipsRoundWS, g.DefineAsRegister(node),
850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 g.UseRegister(next->InputAt(0)));
851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            return;
852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          case IrOpcode::kFloat32RoundTruncate:
853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Emit(kMipsTruncWS, g.DefineAsRegister(node),
854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 g.UseRegister(next->InputAt(0)));
855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            return;
856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          default:
857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Emit(kMipsTruncWS, g.DefineAsRegister(node),
858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 g.UseRegister(value->InputAt(0)));
859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            return;
860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Match float32 -> float64 -> int32 representation change path.
863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Emit(kMipsTruncWS, g.DefineAsRegister(node),
864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             g.UseRegister(value->InputAt(0)));
865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return;
866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRR(this, kMipsTruncWD, node);
870958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
871958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
872958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
873958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRR(this, kMipsTruncUwD, node);
875958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
876958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
8773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid InstructionSelector::VisitTruncateFloat64ToUint32(Node* node) {
8783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  VisitRR(this, kMipsTruncUwD, node);
8793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
880958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
881958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
882958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(this);
883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* value = node->InputAt(0);
884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Match TruncateFloat64ToFloat32(ChangeInt32ToFloat64) to corresponding
885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // instruction.
886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CanCover(node, value) &&
887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      value->opcode() == IrOpcode::kChangeInt32ToFloat64) {
888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Emit(kMipsCvtSW, g.DefineAsRegister(node),
889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         g.UseRegister(value->InputAt(0)));
890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRR(this, kMipsCvtSD, node);
893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
895bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitTruncateFloat64ToWord32(Node* node) {
896bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  VisitRR(this, kArchTruncateDoubleToI, node);
897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
899bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitRoundFloat64ToInt32(Node* node) {
900bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  VisitRR(this, kMipsTruncWD, node);
901bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitBitcastFloat32ToInt32(Node* node) {
904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRR(this, kMipsFloat64ExtractLowWord32, node);
905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitBitcastInt32ToFloat32(Node* node) {
909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MipsOperandGenerator g(this);
910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Emit(kMipsFloat64InsertLowWord32, g.DefineAsRegister(node),
911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       ImmediateOperand(ImmediateOperand::INLINE, 0),
912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       g.UseRegister(node->InputAt(0)));
913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Add(Node* node) {
917f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  MipsOperandGenerator g(this);
91862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (IsMipsArchVariant(kMips32r2)) {  // Select Madd.S(z, x, y).
91962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Float32BinopMatcher m(node);
92062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (m.left().IsFloat32Mul() && CanCover(node, m.left().node())) {
92162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // For Add.S(Mul.S(x, y), z):
92262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Float32BinopMatcher mleft(m.left().node());
923f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Emit(kMipsMaddS, g.DefineAsRegister(node),
924f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()),
925f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           g.UseRegister(mleft.right().node()));
926f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return;
927f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
92862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (m.right().IsFloat32Mul() && CanCover(node, m.right().node())) {
92962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // For Add.S(x, Mul.S(y, z)):
93062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Float32BinopMatcher mright(m.right().node());
931f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Emit(kMipsMaddS, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
932f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           g.UseRegister(mright.left().node()),
933f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           g.UseRegister(mright.right().node()));
934f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return;
935f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
936f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRRR(this, kMipsAddS, node);
938958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
939958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
940958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
941958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64Add(Node* node) {
942f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  MipsOperandGenerator g(this);
94362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (IsMipsArchVariant(kMips32r2)) {  // Select Madd.S(z, x, y).
94462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Float64BinopMatcher m(node);
94562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (m.left().IsFloat64Mul() && CanCover(node, m.left().node())) {
94662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // For Add.D(Mul.D(x, y), z):
94762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Float64BinopMatcher mleft(m.left().node());
948f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Emit(kMipsMaddD, g.DefineAsRegister(node),
949f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()),
950f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           g.UseRegister(mleft.right().node()));
951f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return;
952f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
95362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (m.right().IsFloat64Mul() && CanCover(node, m.right().node())) {
95462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // For Add.D(x, Mul.D(y, z)):
95562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Float64BinopMatcher mright(m.right().node());
956f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Emit(kMipsMaddD, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
957f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           g.UseRegister(mright.left().node()),
958f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           g.UseRegister(mright.right().node()));
959f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return;
960f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
961f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
962958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitRRR(this, kMipsAddD, node);
963958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
964958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
965958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Sub(Node* node) {
967f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  MipsOperandGenerator g(this);
96862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (IsMipsArchVariant(kMips32r2)) {  // Select Madd.S(z, x, y).
96962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Float32BinopMatcher m(node);
97062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (m.left().IsFloat32Mul() && CanCover(node, m.left().node())) {
971f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // For Sub.S(Mul.S(x,y), z) select Msub.S(z, x, y).
972f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Float32BinopMatcher mleft(m.left().node());
973f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Emit(kMipsMsubS, g.DefineAsRegister(node),
974f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()),
975f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           g.UseRegister(mleft.right().node()));
976f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return;
977f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
978f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRRR(this, kMipsSubS, node);
980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
982958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64Sub(Node* node) {
983f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  MipsOperandGenerator g(this);
98462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (IsMipsArchVariant(kMips32r2)) {  // Select Madd.S(z, x, y).
98562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Float64BinopMatcher m(node);
98662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (m.left().IsFloat64Mul() && CanCover(node, m.left().node())) {
987f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // For Sub.D(Mul.S(x,y), z) select Msub.D(z, x, y).
988f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Float64BinopMatcher mleft(m.left().node());
989f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Emit(kMipsMsubD, g.DefineAsRegister(node),
990f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()),
991f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           g.UseRegister(mleft.right().node()));
992f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return;
993f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
994f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
995958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitRRR(this, kMipsSubD, node);
996958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
997958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Mul(Node* node) {
999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRRR(this, kMipsMulS, node);
1000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1003958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64Mul(Node* node) {
1004958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitRRR(this, kMipsMulD, node);
1005958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1006958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1007958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Div(Node* node) {
1009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRRR(this, kMipsDivS, node);
1010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1013958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64Div(Node* node) {
1014958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitRRR(this, kMipsDivD, node);
1015958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1016958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1017958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64Mod(Node* node) {
1019958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(this);
1020958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Emit(kMipsModD, g.DefineAsFixed(node, f0), g.UseFixed(node->InputAt(0), f12),
1021958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       g.UseFixed(node->InputAt(1), f14))->MarkAsCall();
1022958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1023958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Max(Node* node) {
1025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MipsOperandGenerator g(this);
1026f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Emit(kMipsFloat32Max, g.DefineAsRegister(node),
1027f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch       g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
1028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64Max(Node* node) {
1031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MipsOperandGenerator g(this);
1032f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Emit(kMipsFloat64Max, g.DefineAsRegister(node),
1033f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch       g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
1034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Min(Node* node) {
1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MipsOperandGenerator g(this);
1038f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Emit(kMipsFloat32Min, g.DefineAsRegister(node),
1039f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch       g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
1040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64Min(Node* node) {
1043958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(this);
1044f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Emit(kMipsFloat64Min, g.DefineAsRegister(node),
1045f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch       g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
1046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Abs(Node* node) {
1050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRR(this, kMipsAbsS, node);
1051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64Abs(Node* node) {
1055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRR(this, kMipsAbsD, node);
1056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Sqrt(Node* node) {
1059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRR(this, kMipsSqrtS, node);
1060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64Sqrt(Node* node) {
1064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRR(this, kMipsSqrtD, node);
1065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32RoundDown(Node* node) {
1069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRR(this, kMipsFloat32RoundDown, node);
1070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64RoundDown(Node* node) {
1074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRR(this, kMipsFloat64RoundDown, node);
1075958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1076958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1077958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32RoundUp(Node* node) {
1079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRR(this, kMipsFloat32RoundUp, node);
1080958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1081958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1082958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64RoundUp(Node* node) {
1084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRR(this, kMipsFloat64RoundUp, node);
1085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32RoundTruncate(Node* node) {
1089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRR(this, kMipsFloat32RoundTruncate, node);
1090958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1091958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1092958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1093958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
1094958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitRR(this, kMipsFloat64RoundTruncate, node);
1095958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1096958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1097958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1098958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
1099958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UNREACHABLE();
1100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32RoundTiesEven(Node* node) {
1104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRR(this, kMipsFloat32RoundTiesEven, node);
1105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
1109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitRR(this, kMipsFloat64RoundTiesEven, node);
1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1112f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitFloat32Neg(Node* node) {
1113f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  VisitRR(this, kMipsNegS, node);
1114f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
111513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
1116f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitFloat64Neg(Node* node) {
1117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  VisitRR(this, kMipsNegD, node);
1118f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
111913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
112013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid InstructionSelector::VisitFloat64Ieee754Binop(Node* node,
112113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                                   InstructionCode opcode) {
112213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  MipsOperandGenerator g(this);
1123f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Emit(opcode, g.DefineAsFixed(node, f0), g.UseFixed(node->InputAt(0), f2),
1124f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch       g.UseFixed(node->InputAt(1), f4))
112513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ->MarkAsCall();
112613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
112713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
112813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid InstructionSelector::VisitFloat64Ieee754Unop(Node* node,
112913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                                  InstructionCode opcode) {
113013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  MipsOperandGenerator g(this);
113113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Emit(opcode, g.DefineAsFixed(node, f0), g.UseFixed(node->InputAt(0), f12))
113213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ->MarkAsCall();
113313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
1134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::EmitPrepareArguments(
1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
1137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* node) {
1138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MipsOperandGenerator g(this);
1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Prepare for C function call.
1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (descriptor->IsCFunctionCall()) {
1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Emit(kArchPrepareCallCFunction |
1143f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch             MiscField::encode(static_cast<int>(descriptor->ParameterCount())),
1144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         0, nullptr, 0, nullptr);
1145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Poke any stack arguments.
1147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int slot = kCArgSlotCount;
1148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (PushParameter input : (*arguments)) {
1149109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (input.node()) {
1150109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        Emit(kMipsStoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
1151109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch             g.TempImmediate(slot << kPointerSizeLog2));
1152109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        ++slot;
1153109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
1154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Possibly align stack here for functions.
1157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int push_count = static_cast<int>(descriptor->StackParameterCount());
1158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (push_count > 0) {
1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Emit(kMipsStackClaim, g.NoOutput(),
1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           g.TempImmediate(push_count << kPointerSizeLog2));
1161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t n = 0; n < arguments->size(); ++n) {
1163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PushParameter input = (*arguments)[n];
1164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (input.node()) {
1165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Emit(kMipsStoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
1166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             g.TempImmediate(n << kPointerSizeLog2));
1167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool InstructionSelector::IsTailCallAddressImmediate() { return false; }
1174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
11753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochint InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; }
1176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitUnalignedLoad(Node* node) {
1178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  UnalignedLoadRepresentation load_rep =
1179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      UnalignedLoadRepresentationOf(node->op());
1180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  MipsOperandGenerator g(this);
1181f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* base = node->InputAt(0);
1182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* index = node->InputAt(1);
1183f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ArchOpcode opcode = kArchNop;
1185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  switch (load_rep.representation()) {
1186f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kBit:  // Fall through.
1187f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kWord8:
1188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      UNREACHABLE();
1189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kWord16:
1191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      opcode = load_rep.IsUnsigned() ? kMipsUlhu : kMipsUlh;
1192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTaggedSigned:   // Fall through.
1194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTaggedPointer:  // Fall through.
1195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTagged:  // Fall through.
1196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kWord32:
1197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      opcode = kMipsUlw;
1198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kFloat32:
1200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      opcode = kMipsUlwc1;
1201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kFloat64:
1203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      opcode = kMipsUldc1;
1204f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kWord64:   // Fall through.
1206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kSimd128:  // Fall through.
120762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x4:  // Fall through.
120862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x8:  // Fall through.
120962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x16:  // Fall through.
1210f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kNone:
1211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      UNREACHABLE();
1212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return;
1213f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1214f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1215f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (g.CanBeImmediate(index, opcode)) {
1216f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Emit(opcode | AddressingModeField::encode(kMode_MRI),
1217f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch         g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
1218f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
1219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    InstructionOperand addr_reg = g.TempRegister();
1220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
1221f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch         g.UseRegister(index), g.UseRegister(base));
1222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // Emit desired load opcode, using temp addr_reg.
1223f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Emit(opcode | AddressingModeField::encode(kMode_MRI),
1224f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch         g.DefineAsRegister(node), addr_reg, g.TempImmediate(0));
1225f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1226f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1227f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1228f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitUnalignedStore(Node* node) {
1229f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  MipsOperandGenerator g(this);
1230f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* base = node->InputAt(0);
1231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* index = node->InputAt(1);
1232f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* value = node->InputAt(2);
1233f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1234f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  UnalignedStoreRepresentation rep = UnalignedStoreRepresentationOf(node->op());
1235f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1236f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // TODO(mips): I guess this could be done in a better way.
1237f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ArchOpcode opcode = kArchNop;
1238f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  switch (rep) {
1239f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kFloat32:
1240f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      opcode = kMipsUswc1;
1241f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1242f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kFloat64:
1243f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      opcode = kMipsUsdc1;
1244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1245f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kBit:  // Fall through.
1246f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kWord8:
1247f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      UNREACHABLE();
1248f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1249f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kWord16:
1250f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      opcode = kMipsUsh;
1251f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1252f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTaggedSigned:   // Fall through.
1253f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTaggedPointer:  // Fall through.
1254f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTagged:  // Fall through.
1255f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kWord32:
1256f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      opcode = kMipsUsw;
1257f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1258f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kWord64:   // Fall through.
1259f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kSimd128:  // Fall through.
126062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x4:  // Fall through.
126162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x8:  // Fall through.
126262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x16:  // Fall through.
1263f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kNone:
1264f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      UNREACHABLE();
1265f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return;
1266f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1267f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1268f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (g.CanBeImmediate(index, opcode)) {
1269f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
1270c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch         g.UseRegister(base), g.UseImmediate(index),
1271c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch         g.UseRegisterOrImmediateZero(value));
1272f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
1273f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    InstructionOperand addr_reg = g.TempRegister();
1274f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
1275f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch         g.UseRegister(index), g.UseRegister(base));
1276f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // Emit desired store opcode, using temp addr_reg.
1277f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
1278c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch         addr_reg, g.TempImmediate(0), g.UseRegisterOrImmediateZero(value));
1279f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1280f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1281f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitCheckedLoad(Node* node) {
1283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op());
1284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(this);
1285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* const buffer = node->InputAt(0);
1286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* const offset = node->InputAt(1);
1287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* const length = node->InputAt(2);
1288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ArchOpcode opcode = kArchNop;
1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (load_rep.representation()) {
1290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord8:
1291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8;
1292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord16:
1294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16;
1295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord32:
1297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode = kCheckedLoadWord32;
1298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat32:
1300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode = kCheckedLoadFloat32;
1301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat64:
1303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode = kCheckedLoadFloat64;
1304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1305109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case MachineRepresentation::kBit:      // Fall through.
1306f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTaggedSigned:   // Fall through.
1307f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTaggedPointer:  // Fall through.
1308109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case MachineRepresentation::kTagged:   // Fall through.
1309109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case MachineRepresentation::kWord64:   // Fall through.
1310109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case MachineRepresentation::kSimd128:  // Fall through.
131162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x4:  // Fall through.
131262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x8:  // Fall through.
131362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x16:  // Fall through.
1314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kNone:
1315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      UNREACHABLE();
1316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return;
1317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
1319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          ? g.UseImmediate(offset)
1320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          : g.UseRegister(offset);
1321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
1323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          ? g.CanBeImmediate(length, opcode)
1324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                ? g.UseImmediate(length)
1325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                : g.UseRegister(length)
1326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          : g.UseRegister(length);
1327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Emit(opcode | AddressingModeField::encode(kMode_MRI),
1329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       g.DefineAsRegister(node), offset_operand, length_operand,
1330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       g.UseRegister(buffer));
1331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitCheckedStore(Node* node) {
1335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MachineRepresentation rep = CheckedStoreRepresentationOf(node->op());
1336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(this);
1337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* const buffer = node->InputAt(0);
1338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* const offset = node->InputAt(1);
1339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* const length = node->InputAt(2);
1340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* const value = node->InputAt(3);
1341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ArchOpcode opcode = kArchNop;
1342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  switch (rep) {
1343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord8:
1344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode = kCheckedStoreWord8;
1345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord16:
1347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode = kCheckedStoreWord16;
1348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord32:
1350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode = kCheckedStoreWord32;
1351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat32:
1353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode = kCheckedStoreFloat32;
1354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat64:
1356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode = kCheckedStoreFloat64;
1357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    default:
1359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      UNREACHABLE();
1360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return;
1361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
1363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          ? g.UseImmediate(offset)
1364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          : g.UseRegister(offset);
1365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
1367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          ? g.CanBeImmediate(length, opcode)
1368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                ? g.UseImmediate(length)
1369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                : g.UseRegister(length)
1370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          : g.UseRegister(length);
1371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
1373c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch       offset_operand, length_operand, g.UseRegisterOrImmediateZero(value),
1374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       g.UseRegister(buffer));
1375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace {
1379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Shared routine for multiple compare operations.
1380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
1381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         InstructionOperand left, InstructionOperand right,
1382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                         FlagsContinuation* cont) {
1383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(selector);
1384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  opcode = cont->Encode(opcode);
1385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (cont->IsBranch()) {
1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    selector->Emit(opcode, g.NoOutput(), left, right,
1387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   g.Label(cont->true_block()), g.Label(cont->false_block()));
13883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else if (cont->IsDeoptimize()) {
138962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(),
139062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             cont->reason(), cont->frame_state());
139162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (cont->IsSet()) {
1392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
139362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else {
139462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK(cont->IsTrap());
139562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    selector->Emit(opcode, g.NoOutput(), left, right,
139662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                   g.TempImmediate(cont->trap_id()));
1397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Shared routine for multiple float32 compare operations.
1402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitFloat32Compare(InstructionSelector* selector, Node* node,
1403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         FlagsContinuation* cont) {
1404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MipsOperandGenerator g(selector);
1405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Float32BinopMatcher m(node);
1406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand lhs, rhs;
1407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  lhs = m.left().IsZero() ? g.UseImmediate(m.left().node())
1409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                          : g.UseRegister(m.left().node());
1410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rhs = m.right().IsZero() ? g.UseImmediate(m.right().node())
1411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           : g.UseRegister(m.right().node());
1412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitCompare(selector, kMipsCmpS, lhs, rhs, cont);
1413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Shared routine for multiple float64 compare operations.
1417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitFloat64Compare(InstructionSelector* selector, Node* node,
1418958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                         FlagsContinuation* cont) {
1419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(selector);
1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Float64BinopMatcher m(node);
1421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand lhs, rhs;
1422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  lhs = m.left().IsZero() ? g.UseImmediate(m.left().node())
1424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                          : g.UseRegister(m.left().node());
1425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rhs = m.right().IsZero() ? g.UseImmediate(m.right().node())
1426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           : g.UseRegister(m.right().node());
1427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitCompare(selector, kMipsCmpD, lhs, rhs, cont);
1428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Shared routine for multiple word compare operations.
1432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitWordCompare(InstructionSelector* selector, Node* node,
1433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                      InstructionCode opcode, FlagsContinuation* cont,
1434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                      bool commutative) {
1435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(selector);
1436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* left = node->InputAt(0);
1437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* right = node->InputAt(1);
1438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Match immediates on left or right side of comparison.
1440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (g.CanBeImmediate(right, opcode)) {
1441c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (opcode == kMipsTst) {
1442c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right),
1443c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                   cont);
1444c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    } else {
1445c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      switch (cont->condition()) {
1446c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        case kEqual:
1447c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        case kNotEqual:
1448c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          if (cont->IsSet()) {
1449c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            VisitCompare(selector, opcode, g.UseRegister(left),
1450c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         g.UseImmediate(right), cont);
1451c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          } else {
1452c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            VisitCompare(selector, opcode, g.UseRegister(left),
1453c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         g.UseRegister(right), cont);
1454c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          }
1455c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          break;
1456c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        case kSignedLessThan:
1457c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        case kSignedGreaterThanOrEqual:
1458c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        case kUnsignedLessThan:
1459c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        case kUnsignedGreaterThanOrEqual:
1460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          VisitCompare(selector, opcode, g.UseRegister(left),
1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       g.UseImmediate(right), cont);
1462c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          break;
1463c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        default:
1464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          VisitCompare(selector, opcode, g.UseRegister(left),
1465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       g.UseRegister(right), cont);
1466c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
1467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else if (g.CanBeImmediate(left, opcode)) {
1469958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (!commutative) cont->Commute();
1470c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (opcode == kMipsTst) {
1471c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left),
1472c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                   cont);
1473c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    } else {
1474c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      switch (cont->condition()) {
1475c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        case kEqual:
1476c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        case kNotEqual:
1477c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          if (cont->IsSet()) {
1478c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            VisitCompare(selector, opcode, g.UseRegister(right),
1479c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         g.UseImmediate(left), cont);
1480c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          } else {
1481c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            VisitCompare(selector, opcode, g.UseRegister(right),
1482c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                         g.UseRegister(left), cont);
1483c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          }
1484c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          break;
1485c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        case kSignedLessThan:
1486c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        case kSignedGreaterThanOrEqual:
1487c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        case kUnsignedLessThan:
1488c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        case kUnsignedGreaterThanOrEqual:
1489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          VisitCompare(selector, opcode, g.UseRegister(right),
1490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       g.UseImmediate(left), cont);
1491c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          break;
1492c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        default:
1493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          VisitCompare(selector, opcode, g.UseRegister(right),
1494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       g.UseRegister(left), cont);
1495c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
1496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
1498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right),
1499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                 cont);
1500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1501958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1502958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1503958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1504958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitWordCompare(InstructionSelector* selector, Node* node,
1505958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                      FlagsContinuation* cont) {
1506958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitWordCompare(selector, node, kMipsCmp, cont, false);
1507958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1508958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Shared routine for word comparisons against zero.
1510958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitWordCompareZero(InstructionSelector* selector, Node* user,
1511958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                          Node* value, FlagsContinuation* cont) {
1512c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // Try to combine with comparisons against 0 by simply inverting the branch.
1513c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  while (value->opcode() == IrOpcode::kWord32Equal &&
1514c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch         selector->CanCover(user, value)) {
1515c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Int32BinopMatcher m(value);
1516c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (!m.right().Is(0)) break;
1517c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1518c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    user = value;
1519c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    value = m.left().node();
1520c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    cont->Negate();
1521c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
1522c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1523c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (selector->CanCover(user, value)) {
1524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    switch (value->opcode()) {
1525c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case IrOpcode::kWord32Equal:
1526958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        cont->OverwriteAndNegateIfEqual(kEqual);
1527958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return VisitWordCompare(selector, value, cont);
1528958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kInt32LessThan:
1529958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        cont->OverwriteAndNegateIfEqual(kSignedLessThan);
1530958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return VisitWordCompare(selector, value, cont);
1531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kInt32LessThanOrEqual:
1532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
1533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return VisitWordCompare(selector, value, cont);
1534958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kUint32LessThan:
1535958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
1536958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return VisitWordCompare(selector, value, cont);
1537958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kUint32LessThanOrEqual:
1538958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
1539958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return VisitWordCompare(selector, value, cont);
1540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case IrOpcode::kFloat32Equal:
1541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        cont->OverwriteAndNegateIfEqual(kEqual);
1542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return VisitFloat32Compare(selector, value, cont);
1543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case IrOpcode::kFloat32LessThan:
1544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
1545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return VisitFloat32Compare(selector, value, cont);
1546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case IrOpcode::kFloat32LessThanOrEqual:
1547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
1548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return VisitFloat32Compare(selector, value, cont);
1549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kFloat64Equal:
1550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        cont->OverwriteAndNegateIfEqual(kEqual);
1551958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return VisitFloat64Compare(selector, value, cont);
1552958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kFloat64LessThan:
1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
1554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return VisitFloat64Compare(selector, value, cont);
1555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kFloat64LessThanOrEqual:
1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
1557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return VisitFloat64Compare(selector, value, cont);
1558958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kProjection:
1559958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // Check if this is the overflow output projection of an
1560958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // <Operation>WithOverflow node.
1561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (ProjectionIndexOf(value->op()) == 1u) {
1562958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          // We cannot combine the <Operation>WithOverflow with this branch
1563958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          // unless the 0th projection (the use of the actual value of the
1564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // <Operation> is either nullptr, which means there's no use of the
1565958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          // actual value, or was already defined, which means it is scheduled
1566958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          // *AFTER* this branch).
1567958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          Node* const node = value->InputAt(0);
1568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Node* const result = NodeProperties::FindProjection(node, 0);
1569958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          if (!result || selector->IsDefined(result)) {
1570958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            switch (node->opcode()) {
1571958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              case IrOpcode::kInt32AddWithOverflow:
1572958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                cont->OverwriteAndNegateIfEqual(kOverflow);
1573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                return VisitBinop(selector, node, kMipsAddOvf, cont);
1574958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              case IrOpcode::kInt32SubWithOverflow:
1575958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                cont->OverwriteAndNegateIfEqual(kOverflow);
1576958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                return VisitBinop(selector, node, kMipsSubOvf, cont);
1577f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              case IrOpcode::kInt32MulWithOverflow:
1578f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                cont->OverwriteAndNegateIfEqual(kOverflow);
1579f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                return VisitBinop(selector, node, kMipsMulOvf, cont);
1580958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              default:
1581958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                break;
1582958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            }
1583958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          }
1584958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
1585958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
1586958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kWord32And:
1587958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return VisitWordCompare(selector, value, kMipsTst, cont, true);
1588958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      default:
1589958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
1590958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1591958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1592958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1593958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Continuation could not be combined with a compare, emit compare against 0.
1594958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandGenerator g(selector);
1595958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  InstructionCode const opcode = cont->Encode(kMipsCmp);
1596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand const value_operand = g.UseRegister(value);
1597958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (cont->IsBranch()) {
1598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0),
1599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   g.Label(cont->true_block()), g.Label(cont->false_block()));
16003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else if (cont->IsDeoptimize()) {
16013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    selector->EmitDeoptimize(opcode, g.NoOutput(), value_operand,
160262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             g.TempImmediate(0), cont->kind(), cont->reason(),
1603f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                             cont->frame_state());
160462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (cont->IsSet()) {
1605958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand,
1606958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                   g.TempImmediate(0));
160762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else {
160862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK(cont->IsTrap());
160962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0),
161062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                   g.TempImmediate(cont->trap_id()));
1611958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1612958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1613958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
16143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}  // namespace
1615958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
1617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                      BasicBlock* fbranch) {
1618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  FlagsContinuation cont(kNotEqual, tbranch, fbranch);
1619958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitWordCompareZero(this, branch, branch->InputAt(0), &cont);
1620958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
16223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid InstructionSelector::VisitDeoptimizeIf(Node* node) {
162362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
1624f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
162562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      kNotEqual, p.kind(), p.reason(), node->InputAt(1));
16263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  VisitWordCompareZero(this, node, node->InputAt(0), &cont);
16273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
16283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
16293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid InstructionSelector::VisitDeoptimizeUnless(Node* node) {
163062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
1631f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
163262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      kEqual, p.kind(), p.reason(), node->InputAt(1));
163362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  VisitWordCompareZero(this, node, node->InputAt(0), &cont);
163462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
163562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
163662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InstructionSelector::VisitTrapIf(Node* node, Runtime::FunctionId func_id) {
163762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  FlagsContinuation cont =
163862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      FlagsContinuation::ForTrap(kNotEqual, func_id, node->InputAt(1));
163962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  VisitWordCompareZero(this, node, node->InputAt(0), &cont);
164062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
164162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
164262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InstructionSelector::VisitTrapUnless(Node* node,
164362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                          Runtime::FunctionId func_id) {
164462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  FlagsContinuation cont =
164562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      FlagsContinuation::ForTrap(kEqual, func_id, node->InputAt(1));
16463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  VisitWordCompareZero(this, node, node->InputAt(0), &cont);
16473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
1648958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
1650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MipsOperandGenerator g(this);
1651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand value_operand = g.UseRegister(node->InputAt(0));
1652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Emit either ArchTableSwitch or ArchLookupSwitch.
1654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t table_space_cost = 9 + sw.value_range;
1655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t table_time_cost = 3;
1656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t lookup_space_cost = 2 + 2 * sw.case_count;
1657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t lookup_time_cost = sw.case_count;
1658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (sw.case_count > 0 &&
1659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      table_space_cost + 3 * table_time_cost <=
1660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          lookup_space_cost + 3 * lookup_time_cost &&
1661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      sw.min_value > std::numeric_limits<int32_t>::min()) {
1662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand index_operand = value_operand;
1663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (sw.min_value) {
1664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      index_operand = g.TempRegister();
1665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Emit(kMipsSub, index_operand, value_operand,
1666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           g.TempImmediate(sw.min_value));
1667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Generate a table lookup.
1669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return EmitTableSwitch(sw, index_operand);
1670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Generate a sequence of conditional jumps.
1673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return EmitLookupSwitch(sw, value_operand);
1674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitWord32Equal(Node* const node) {
16783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
1679958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Int32BinopMatcher m(node);
1680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (m.right().Is(0)) {
1681958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return VisitWordCompareZero(this, m.node(), m.left().node(), &cont);
1682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1683958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitWordCompare(this, node, &cont);
1684958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1685958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1686958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32LessThan(Node* node) {
16883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
1689958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitWordCompare(this, node, &cont);
1690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1692958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1693958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
16943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont =
16953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
1696958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitWordCompare(this, node, &cont);
1697958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1698958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1699958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1700958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32LessThan(Node* node) {
17013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
1702958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitWordCompare(this, node, &cont);
1703958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1704958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1705958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1706958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
17073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont =
17083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
1709958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitWordCompare(this, node, &cont);
1710958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1711958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1712958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1713958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
1714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
17153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
1716958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return VisitBinop(this, node, kMipsAddOvf, &cont);
1717958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1718958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  FlagsContinuation cont;
1719958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitBinop(this, node, kMipsAddOvf, &cont);
1720958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1721958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1722958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1723958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
1724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
17253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
1726958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return VisitBinop(this, node, kMipsSubOvf, &cont);
1727958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1728958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  FlagsContinuation cont;
1729958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitBinop(this, node, kMipsSubOvf, &cont);
1730958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1731958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1732f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitInt32MulWithOverflow(Node* node) {
1733f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
1734f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
1735f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return VisitBinop(this, node, kMipsMulOvf, &cont);
1736f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1737f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FlagsContinuation cont;
1738f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  VisitBinop(this, node, kMipsMulOvf, &cont);
1739f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1740958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Equal(Node* node) {
17423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
1743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitFloat32Compare(this, node, &cont);
1744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32LessThan(Node* node) {
17483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
1749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitFloat32Compare(this, node, &cont);
1750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
17543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont =
17553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
1756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitFloat32Compare(this, node, &cont);
1757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1760958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64Equal(Node* node) {
17613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
1762958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitFloat64Compare(this, node, &cont);
1763958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1764958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1765958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1766958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64LessThan(Node* node) {
17673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
1768958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitFloat64Compare(this, node, &cont);
1769958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1770958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1771958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1772958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
17733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont =
17743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
1775958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitFloat64Compare(this, node, &cont);
1776958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1777958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1778958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
1780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MipsOperandGenerator g(this);
1781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Emit(kMipsFloat64ExtractLowWord32, g.DefineAsRegister(node),
1782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       g.UseRegister(node->InputAt(0)));
1783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) {
1787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MipsOperandGenerator g(this);
1788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Emit(kMipsFloat64ExtractHighWord32, g.DefineAsRegister(node),
1789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       g.UseRegister(node->InputAt(0)));
1790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64InsertLowWord32(Node* node) {
1794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MipsOperandGenerator g(this);
1795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* left = node->InputAt(0);
1796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* right = node->InputAt(1);
1797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Emit(kMipsFloat64InsertLowWord32, g.DefineSameAsFirst(node),
1798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       g.UseRegister(left), g.UseRegister(right));
1799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64InsertHighWord32(Node* node) {
1803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MipsOperandGenerator g(this);
1804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* left = node->InputAt(0);
1805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* right = node->InputAt(1);
1806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Emit(kMipsFloat64InsertHighWord32, g.DefineSameAsFirst(node),
1807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       g.UseRegister(left), g.UseRegister(right));
1808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
181013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid InstructionSelector::VisitFloat64SilenceNaN(Node* node) {
181113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  MipsOperandGenerator g(this);
181213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Node* left = node->InputAt(0);
181313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  InstructionOperand temps[] = {g.TempRegister()};
181413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Emit(kMipsFloat64SilenceNaN, g.DefineSameAsFirst(node), g.UseRegister(left),
181513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch       arraysize(temps), temps);
181613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
181713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
1818bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitAtomicLoad(Node* node) {
1819bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  LoadRepresentation load_rep = LoadRepresentationOf(node->op());
1820bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  MipsOperandGenerator g(this);
1821bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* base = node->InputAt(0);
1822bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* index = node->InputAt(1);
1823bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  ArchOpcode opcode = kArchNop;
1824bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  switch (load_rep.representation()) {
1825bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case MachineRepresentation::kWord8:
1826bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      opcode = load_rep.IsSigned() ? kAtomicLoadInt8 : kAtomicLoadUint8;
1827bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
1828bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case MachineRepresentation::kWord16:
1829bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      opcode = load_rep.IsSigned() ? kAtomicLoadInt16 : kAtomicLoadUint16;
1830bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
1831bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case MachineRepresentation::kWord32:
1832bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      opcode = kAtomicLoadWord32;
1833bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
1834bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    default:
1835bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      UNREACHABLE();
1836bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      return;
1837bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
1838c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1839bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (g.CanBeImmediate(index, opcode)) {
1840bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Emit(opcode | AddressingModeField::encode(kMode_MRI),
1841bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
1842bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else {
1843bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    InstructionOperand addr_reg = g.TempRegister();
1844bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
1845bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         g.UseRegister(index), g.UseRegister(base));
1846bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // Emit desired load opcode, using temp addr_reg.
1847bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Emit(opcode | AddressingModeField::encode(kMode_MRI),
1848bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         g.DefineAsRegister(node), addr_reg, g.TempImmediate(0));
1849bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
1850bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
1851bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1852bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitAtomicStore(Node* node) {
1853bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  MachineRepresentation rep = AtomicStoreRepresentationOf(node->op());
1854bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  MipsOperandGenerator g(this);
1855bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* base = node->InputAt(0);
1856bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* index = node->InputAt(1);
1857bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* value = node->InputAt(2);
1858bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  ArchOpcode opcode = kArchNop;
1859bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  switch (rep) {
1860bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case MachineRepresentation::kWord8:
1861bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      opcode = kAtomicStoreWord8;
1862bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
1863bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case MachineRepresentation::kWord16:
1864bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      opcode = kAtomicStoreWord16;
1865bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
1866bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case MachineRepresentation::kWord32:
1867bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      opcode = kAtomicStoreWord32;
1868bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
1869bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    default:
1870bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      UNREACHABLE();
1871bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      return;
1872bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
1873bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1874bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (g.CanBeImmediate(index, opcode)) {
1875bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
1876c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch         g.UseRegister(base), g.UseImmediate(index),
1877c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch         g.UseRegisterOrImmediateZero(value));
1878bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else {
1879bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    InstructionOperand addr_reg = g.TempRegister();
1880bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
1881bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         g.UseRegister(index), g.UseRegister(base));
1882bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // Emit desired store opcode, using temp addr_reg.
1883bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
1884c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch         addr_reg, g.TempImmediate(0), g.UseRegisterOrImmediateZero(value));
1885bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
1886bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
1887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1888958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// static
1889958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierMachineOperatorBuilder::Flags
1890958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierInstructionSelector::SupportedMachineOperatorFlags() {
1891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags;
1892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
1893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      IsFp64Mode()) {
1894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    flags |= MachineOperatorBuilder::kFloat64RoundDown |
1895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             MachineOperatorBuilder::kFloat64RoundUp |
1896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             MachineOperatorBuilder::kFloat64RoundTruncate |
1897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             MachineOperatorBuilder::kFloat64RoundTiesEven;
1898958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1899f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1900109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return flags | MachineOperatorBuilder::kWord32Ctz |
1901109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch         MachineOperatorBuilder::kWord32Popcnt |
1902109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch         MachineOperatorBuilder::kInt32DivIsSafe |
1903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         MachineOperatorBuilder::kUint32DivIsSafe |
1904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         MachineOperatorBuilder::kWord32ShiftIsSafe |
1905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         MachineOperatorBuilder::kFloat32RoundDown |
1906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         MachineOperatorBuilder::kFloat32RoundUp |
1907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         MachineOperatorBuilder::kFloat32RoundTruncate |
1908f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch         MachineOperatorBuilder::kFloat32RoundTiesEven |
1909f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch         MachineOperatorBuilder::kWord32ReverseBytes |
1910f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch         MachineOperatorBuilder::kWord64ReverseBytes;
1911958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1912958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
191313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// static
191413e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochMachineOperatorBuilder::AlignmentRequirements
191513e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochInstructionSelector::AlignmentRequirements() {
191613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (IsMipsArchVariant(kMips32r6)) {
191713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return MachineOperatorBuilder::AlignmentRequirements::
191813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        FullUnalignedAccessSupport();
191913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  } else {
192013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    DCHECK(IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r1) ||
192113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch           IsMipsArchVariant(kMips32r2));
192213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return MachineOperatorBuilder::AlignmentRequirements::
192313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        NoUnalignedAccessSupport();
192413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
192513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
192613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
1927958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace compiler
1928958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace internal
1929958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace v8
1930