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
5958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/code-generator.h"
6f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/compilation-info.h"
7958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/code-generator-impl.h"
8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/gap-resolver.h"
9958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/node-matchers.h"
10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/osr.h"
11958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/mips/macro-assembler-mips.h"
12958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
13958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace v8 {
14958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace internal {
15958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace compiler {
16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
17958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define __ masm()->
18958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
19958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
20958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// TODO(plind): Possibly avoid using these lithium names.
21958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define kScratchReg kLithiumScratchReg
22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define kScratchReg2 kLithiumScratchReg2
23958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define kScratchDoubleReg kLithiumScratchDouble
24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// TODO(plind): consider renaming these macros.
27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define TRACE_MSG(msg)                                                      \
28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  PrintF("code_gen: \'%s\' in function %s at line %d\n", msg, __FUNCTION__, \
29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier         __LINE__)
30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define TRACE_UNIMPL()                                                       \
32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  PrintF("UNIMPLEMENTED code_generator_mips: %s at line %d\n", __FUNCTION__, \
33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier         __LINE__)
34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Adds Mips-specific methods to convert InstructionOperands.
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass MipsOperandConverter final : public InstructionOperandConverter {
38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public:
39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandConverter(CodeGenerator* gen, Instruction* instr)
40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      : InstructionOperandConverter(gen, instr) {}
41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FloatRegister OutputSingleRegister(size_t index = 0) {
43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return ToSingleRegister(instr_->OutputAt(index));
44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FloatRegister InputSingleRegister(size_t index) {
47958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return ToSingleRegister(instr_->InputAt(index));
48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
49958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
50958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  FloatRegister ToSingleRegister(InstructionOperand* op) {
51958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Single (Float) and Double register namespace is same on MIPS,
52958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // both are typedefs of FPURegister.
53958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return ToDoubleRegister(op);
54958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
55958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
56c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Register InputOrZeroRegister(size_t index) {
57c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (instr_->InputAt(index)->IsImmediate()) {
58c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      DCHECK((InputInt32(index) == 0));
59c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      return zero_reg;
60c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
61c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return InputRegister(index);
62c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
63c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DoubleRegister InputOrZeroDoubleRegister(size_t index) {
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (instr_->InputAt(index)->IsImmediate()) return kDoubleRegZero;
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return InputDoubleRegister(index);
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DoubleRegister InputOrZeroSingleRegister(size_t index) {
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (instr_->InputAt(index)->IsImmediate()) return kDoubleRegZero;
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return InputSingleRegister(index);
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Operand InputImmediate(size_t index) {
77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Constant constant = ToConstant(instr_->InputAt(index));
78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    switch (constant.type()) {
79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case Constant::kInt32:
80958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return Operand(constant.ToInt32());
81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case Constant::kInt64:
82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return Operand(constant.ToInt64());
83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case Constant::kFloat32:
84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return Operand(
85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED));
86958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case Constant::kFloat64:
87958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return Operand(
88958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED));
89958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case Constant::kExternalReference:
90958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case Constant::kHeapObject:
91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // TODO(plind): Maybe we should handle ExtRef & HeapObj here?
92958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        //    maybe not done on arm due to const pool ??
93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case Constant::kRpoNumber:
95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        UNREACHABLE();  // TODO(titzer): RPO immediates on mips?
96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    UNREACHABLE();
99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return Operand(zero_reg);
100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Operand InputOperand(size_t index) {
103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    InstructionOperand* op = instr_->InputAt(index);
104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (op->IsRegister()) {
105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return Operand(ToRegister(op));
106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return InputImmediate(index);
108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MemOperand MemoryOperand(size_t* first_index) {
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const size_t index = *first_index;
112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    switch (AddressingModeField::decode(instr_->opcode())) {
113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_None:
114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_MRI:
116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        *first_index += 2;
117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return MemOperand(InputRegister(index + 0), InputInt32(index + 1));
118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_MRR:
119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // TODO(plind): r6 address mode, to be implemented ...
120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        UNREACHABLE();
121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    UNREACHABLE();
123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return MemOperand(no_reg);
124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MemOperand MemoryOperand(size_t index = 0) { return MemoryOperand(&index); }
127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MemOperand ToMemOperand(InstructionOperand* op) const {
129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NOT_NULL(op);
130bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(op->IsStackSlot() || op->IsFPStackSlot());
1313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return SlotToMemOperand(AllocatedOperand::cast(op)->index());
1323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  MemOperand SlotToMemOperand(int slot) const {
1353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    FrameOffset offset = frame_access_state()->GetFrameOffset(slot);
136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset());
137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic inline bool HasRegisterInput(Instruction* instr, size_t index) {
142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return instr->InputAt(index)->IsRegister();
143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace {
147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineLoadSingle final : public OutOfLineCode {
149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public:
150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  OutOfLineLoadSingle(CodeGenerator* gen, FloatRegister result)
151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      : OutOfLineCode(gen), result_(result) {}
152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Generate() final {
154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ Move(result_, std::numeric_limits<float>::quiet_NaN());
155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private:
158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  FloatRegister const result_;
159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineLoadDouble final : public OutOfLineCode {
163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public:
164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  OutOfLineLoadDouble(CodeGenerator* gen, DoubleRegister result)
165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      : OutOfLineCode(gen), result_(result) {}
166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Generate() final {
168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ Move(result_, std::numeric_limits<double>::quiet_NaN());
169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private:
172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DoubleRegister const result_;
173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineLoadInteger final : public OutOfLineCode {
177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public:
178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  OutOfLineLoadInteger(CodeGenerator* gen, Register result)
179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      : OutOfLineCode(gen), result_(result) {}
180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Generate() final { __ mov(result_, zero_reg); }
182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private:
184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Register const result_;
185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass OutOfLineRound : public OutOfLineCode {
189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public:
190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  OutOfLineRound(CodeGenerator* gen, DoubleRegister result)
191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      : OutOfLineCode(gen), result_(result) {}
192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Generate() final {
194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Handle rounding to zero case where sign has to be preserved.
195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // High bits of double input already in kScratchReg.
196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ dsrl(at, kScratchReg, 31);
197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ dsll(at, at, 31);
198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ mthc1(at, result_);
199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private:
202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DoubleRegister const result_;
203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineRound32 : public OutOfLineCode {
207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public:
208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OutOfLineRound32(CodeGenerator* gen, DoubleRegister result)
209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : OutOfLineCode(gen), result_(result) {}
210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Generate() final {
212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Handle rounding to zero case where sign has to be preserved.
213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // High bits of float input already in kScratchReg.
214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ srl(at, kScratchReg, 31);
215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ sll(at, at, 31);
216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ mtc1(at, result_);
217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DoubleRegister const result_;
221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineRecordWrite final : public OutOfLineCode {
225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public:
226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register index,
227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       Register value, Register scratch0, Register scratch1,
228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       RecordWriteMode mode)
229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : OutOfLineCode(gen),
230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        object_(object),
231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        index_(index),
232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        value_(value),
233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        scratch0_(scratch0),
234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        scratch1_(scratch1),
2353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        mode_(mode),
2363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        must_save_lr_(!gen->frame_access_state()->has_frame()) {}
237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Generate() final {
239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (mode_ > RecordWriteMode::kValueIsPointer) {
240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ JumpIfSmi(value_, exit());
241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
242109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    __ CheckPageFlag(value_, scratch0_,
243109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                     MemoryChunk::kPointersToHereAreInterestingMask, eq,
244109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                     exit());
245109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    RememberedSetAction const remembered_set_action =
246109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET
247109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                             : OMIT_REMEMBERED_SET;
248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SaveFPRegsMode const save_fp_mode =
249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
2503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (must_save_lr_) {
251109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // We need to save and restore ra if the frame was elided.
252109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Push(ra);
253109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_,
255109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                         remembered_set_action, save_fp_mode);
256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ Daddu(scratch1_, object_, index_);
257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ CallStub(&stub);
2583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (must_save_lr_) {
259109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Pop(ra);
260109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register const object_;
265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register const index_;
266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register const value_;
267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register const scratch0_;
268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register const scratch1_;
269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RecordWriteMode const mode_;
2703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool must_save_lr_;
271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochCondition FlagsConditionToConditionCmp(FlagsCondition condition) {
275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (condition) {
276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kEqual:
277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return eq;
278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kNotEqual:
279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return ne;
280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSignedLessThan:
281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return lt;
282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSignedGreaterThanOrEqual:
283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return ge;
284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSignedLessThanOrEqual:
285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return le;
286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSignedGreaterThan:
287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return gt;
288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedLessThan:
289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return lo;
290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedGreaterThanOrEqual:
291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return hs;
292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedLessThanOrEqual:
293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return ls;
294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedGreaterThan:
295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return hi;
296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnorderedEqual:
297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnorderedNotEqual:
298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return kNoCondition;
304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochCondition FlagsConditionToConditionTst(FlagsCondition condition) {
308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (condition) {
309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kNotEqual:
310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return ne;
311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kEqual:
312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return eq;
313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return kNoCondition;
318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochCondition FlagsConditionToConditionOvf(FlagsCondition condition) {
322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (condition) {
323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kOverflow:
324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return ne;
325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kNotOverflow:
326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return eq;
327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return kNoCondition;
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochFPUCondition FlagsConditionToConditionCmpFPU(bool& predicate,
336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                             FlagsCondition condition) {
337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (condition) {
338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kEqual:
339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      predicate = true;
340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return EQ;
341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kNotEqual:
342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      predicate = false;
343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return EQ;
344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedLessThan:
345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      predicate = true;
346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return OLT;
347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedGreaterThanOrEqual:
348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      predicate = false;
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return ULT;
350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedLessThanOrEqual:
351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      predicate = true;
352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return OLE;
353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedGreaterThan:
354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      predicate = false;
355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return ULE;
356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnorderedEqual:
357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnorderedNotEqual:
358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      predicate = true;
359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      predicate = true;
362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return kNoFPUCondition;
366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace
369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr)                         \
371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  do {                                                                        \
372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto result = i.Output##width##Register();                                \
373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto ool = new (zone()) OutOfLineLoad##width(this, result);               \
374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (instr->InputAt(0)->IsRegister()) {                                    \
375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto offset = i.InputRegister(0);                                       \
376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
377bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ And(kScratchReg, offset, Operand(0xffffffff));                       \
378bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ Daddu(kScratchReg, i.InputRegister(2), kScratchReg);                 \
379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ asm_instr(result, MemOperand(kScratchReg, 0));                       \
380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {                                                                  \
381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int offset = static_cast<int>(i.InputOperand(0).immediate());           \
382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset));       \
383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ asm_instr(result, MemOperand(i.InputRegister(2), offset));           \
384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }                                                                         \
385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ bind(ool->exit());                                                     \
386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } while (0)
387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr)                              \
389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  do {                                                                        \
390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto result = i.OutputRegister();                                         \
391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto ool = new (zone()) OutOfLineLoadInteger(this, result);               \
392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (instr->InputAt(0)->IsRegister()) {                                    \
393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto offset = i.InputRegister(0);                                       \
394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
395bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ And(kScratchReg, offset, Operand(0xffffffff));                       \
396bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ Daddu(kScratchReg, i.InputRegister(2), kScratchReg);                 \
397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ asm_instr(result, MemOperand(kScratchReg, 0));                       \
398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {                                                                  \
399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int offset = static_cast<int>(i.InputOperand(0).immediate());           \
400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset));       \
401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ asm_instr(result, MemOperand(i.InputRegister(2), offset));           \
402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }                                                                         \
403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ bind(ool->exit());                                                     \
404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } while (0)
405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
406958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr)                 \
407958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  do {                                                                 \
408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Label done;                                                        \
409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (instr->InputAt(0)->IsRegister()) {                             \
410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto offset = i.InputRegister(0);                                \
411c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      auto value = i.InputOrZero##width##Register(2);                  \
412c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (value.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) {      \
413c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        __ Move(kDoubleRegZero, 0.0);                                  \
414c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }                                                                \
415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
416bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ And(kScratchReg, offset, Operand(0xffffffff));                \
417bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ Daddu(kScratchReg, i.InputRegister(3), kScratchReg);          \
418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ asm_instr(value, MemOperand(kScratchReg, 0));                 \
419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {                                                           \
420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int offset = static_cast<int>(i.InputOperand(0).immediate());    \
421c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      auto value = i.InputOrZero##width##Register(2);                  \
422c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (value.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) {      \
423c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        __ Move(kDoubleRegZero, 0.0);                                  \
424c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }                                                                \
425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Branch(&done, ls, i.InputRegister(1), Operand(offset));       \
426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ asm_instr(value, MemOperand(i.InputRegister(3), offset));     \
427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }                                                                  \
428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ bind(&done);                                                    \
429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } while (0)
430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr)                      \
432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  do {                                                                 \
433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Label done;                                                        \
434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (instr->InputAt(0)->IsRegister()) {                             \
435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto offset = i.InputRegister(0);                                \
436c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      auto value = i.InputOrZeroRegister(2);                           \
437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
438bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ And(kScratchReg, offset, Operand(0xffffffff));                \
439bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ Daddu(kScratchReg, i.InputRegister(3), kScratchReg);          \
440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ asm_instr(value, MemOperand(kScratchReg, 0));                 \
441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {                                                           \
442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int offset = static_cast<int>(i.InputOperand(0).immediate());    \
443c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      auto value = i.InputOrZeroRegister(2);                           \
444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Branch(&done, ls, i.InputRegister(1), Operand(offset));       \
445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ asm_instr(value, MemOperand(i.InputRegister(3), offset));     \
446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }                                                                  \
447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ bind(&done);                                                    \
448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } while (0)
449958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(mode)                                  \
451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kArchVariant == kMips64r6) {                                             \
452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ cfc1(kScratchReg, FCSR);                                                \
453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ li(at, Operand(mode_##mode));                                           \
454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ctc1(at, FCSR);                                                         \
455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ rint_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));             \
456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ctc1(kScratchReg, FCSR);                                                \
457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {                                                                     \
458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto ool = new (zone()) OutOfLineRound(this, i.OutputDoubleRegister());    \
459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Label done;                                                                \
460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ mfhc1(kScratchReg, i.InputDoubleRegister(0));                           \
461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ Ext(at, kScratchReg, HeapNumber::kExponentShift,                        \
462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           HeapNumber::kExponentBits);                                         \
463958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ Branch(USE_DELAY_SLOT, &done, hs, at,                                   \
464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              Operand(HeapNumber::kExponentBias + HeapNumber::kMantissaBits)); \
465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ mov_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));              \
466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ mode##_l_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));         \
467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ dmfc1(at, i.OutputDoubleRegister());                                    \
468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg));        \
469958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister());            \
470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ bind(ool->exit());                                                      \
471958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ bind(&done);                                                            \
472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_ROUND_FLOAT_TO_FLOAT(mode)                                   \
475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kArchVariant == kMips64r6) {                                            \
476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ cfc1(kScratchReg, FCSR);                                               \
477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ li(at, Operand(mode_##mode));                                          \
478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ctc1(at, FCSR);                                                        \
479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ rint_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0));            \
480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ctc1(kScratchReg, FCSR);                                               \
481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {                                                                    \
482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int32_t kFloat32ExponentBias = 127;                                       \
483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int32_t kFloat32MantissaBits = 23;                                        \
484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int32_t kFloat32ExponentBits = 8;                                         \
485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto ool = new (zone()) OutOfLineRound32(this, i.OutputDoubleRegister()); \
486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Label done;                                                               \
487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ mfc1(kScratchReg, i.InputDoubleRegister(0));                           \
488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ Ext(at, kScratchReg, kFloat32MantissaBits, kFloat32ExponentBits);      \
489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ Branch(USE_DELAY_SLOT, &done, hs, at,                                  \
490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              Operand(kFloat32ExponentBias + kFloat32MantissaBits));          \
491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ mov_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0));             \
492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ mode##_w_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0));        \
493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ mfc1(at, i.OutputDoubleRegister());                                    \
494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg));       \
495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ cvt_s_w(i.OutputDoubleRegister(), i.OutputDoubleRegister());           \
496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ bind(ool->exit());                                                     \
497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ bind(&done);                                                           \
498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
500bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#define ASSEMBLE_ATOMIC_LOAD_INTEGER(asm_instr)          \
501bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  do {                                                   \
502bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    __ asm_instr(i.OutputRegister(), i.MemoryOperand()); \
503bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    __ sync();                                           \
504bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } while (0)
505bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
506c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#define ASSEMBLE_ATOMIC_STORE_INTEGER(asm_instr)               \
507c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  do {                                                         \
508c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    __ sync();                                                 \
509c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    __ asm_instr(i.InputOrZeroRegister(2), i.MemoryOperand()); \
510c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    __ sync();                                                 \
511bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } while (0)
512bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
51313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#define ASSEMBLE_IEEE754_BINOP(name)                                          \
51413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  do {                                                                        \
51513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    FrameScope scope(masm(), StackFrame::MANUAL);                             \
51613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ PrepareCallCFunction(0, 2, kScratchReg);                               \
51713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ MovToFloatParameters(i.InputDoubleRegister(0),                         \
51813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                            i.InputDoubleRegister(1));                        \
51913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \
52013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                     0, 2);                                                   \
52113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    /* Move the result in the double result register. */                      \
52213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ MovFromFloatResult(i.OutputDoubleRegister());                          \
52313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  } while (0)
52413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
52513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#define ASSEMBLE_IEEE754_UNOP(name)                                           \
52613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  do {                                                                        \
52713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    FrameScope scope(masm(), StackFrame::MANUAL);                             \
52813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ PrepareCallCFunction(0, 1, kScratchReg);                               \
52913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ MovToFloatParameter(i.InputDoubleRegister(0));                         \
53013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \
53113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                     0, 1);                                                   \
53213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    /* Move the result in the double result register. */                      \
53313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ MovFromFloatResult(i.OutputDoubleRegister());                          \
53413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  } while (0)
53513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
5363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid CodeGenerator::AssembleDeconstructFrame() {
5373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ mov(sp, fp);
5383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ Pop(ra, fp);
5393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
5403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
541f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::AssemblePrepareTailCall() {
5423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (frame_access_state()->has_frame()) {
543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ld(ra, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ld(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  frame_access_state()->SetFrameAccessToSP();
547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
5493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
5503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                                     Register scratch1,
5513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                                     Register scratch2,
5523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                                     Register scratch3) {
5533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
5543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Label done;
5553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
5563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Check if current frame is an arguments adaptor frame.
5573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ ld(scratch3, MemOperand(fp, StandardFrameConstants::kContextOffset));
5583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ Branch(&done, ne, scratch3,
5593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
5603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
5613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Load arguments count from current arguments adaptor frame (note, it
5623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // does not include receiver).
5633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Register caller_args_count_reg = scratch1;
5643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ ld(caller_args_count_reg,
5653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
5663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ SmiUntag(caller_args_count_reg);
5673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
5683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  ParameterCount callee_args_count(args_reg);
5693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
5703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                        scratch3);
5713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ bind(&done);
5723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
574f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace {
575f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
576f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid AdjustStackPointerForTailCall(MacroAssembler* masm,
577f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                   FrameAccessState* state,
578f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                   int new_slot_above_sp,
579f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                   bool allow_shrinkage = true) {
580f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int current_sp_offset = state->GetSPToFPSlotCount() +
581f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                          StandardFrameConstants::kFixedSlotCountAboveFp;
582f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int stack_slot_delta = new_slot_above_sp - current_sp_offset;
583f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (stack_slot_delta > 0) {
584f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    masm->Dsubu(sp, sp, stack_slot_delta * kPointerSize);
585f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    state->IncreaseSPDelta(stack_slot_delta);
586f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else if (allow_shrinkage && stack_slot_delta < 0) {
587f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    masm->Daddu(sp, sp, -stack_slot_delta * kPointerSize);
588f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    state->IncreaseSPDelta(stack_slot_delta);
589f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
590f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
591f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
592f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}  // namespace
593f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
594f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::AssembleTailCallBeforeGap(Instruction* instr,
595f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                              int first_unused_stack_slot) {
596f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  AdjustStackPointerForTailCall(masm(), frame_access_state(),
597f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                first_unused_stack_slot, false);
598f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
599f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
600f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::AssembleTailCallAfterGap(Instruction* instr,
601f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                             int first_unused_stack_slot) {
602f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  AdjustStackPointerForTailCall(masm(), frame_access_state(),
603f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                first_unused_stack_slot);
604f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
605f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
606958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Assembles an instruction after register allocation, producing machine code.
607bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
608bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Instruction* instr) {
609958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandConverter i(this, instr);
610958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  InstructionCode opcode = instr->opcode();
6113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode);
6123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  switch (arch_opcode) {
613958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kArchCallCodeObject: {
614958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      EnsureSpaceForLazyDeopt();
615958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (instr->InputAt(0)->IsImmediate()) {
616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ Call(Handle<Code>::cast(i.InputHeapObject(0)),
617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                RelocInfo::CODE_TARGET);
618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
619958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ daddiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag);
620958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ Call(at);
621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RecordCallPosition(instr);
623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->ClearSPDelta();
624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
6263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kArchTailCallCodeObjectFromJSFunction:
627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchTailCallCodeObject: {
6283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
6293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
6303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                         i.TempRegister(0), i.TempRegister(1),
6313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                         i.TempRegister(2));
6323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(0)->IsImmediate()) {
634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Jump(Handle<Code>::cast(i.InputHeapObject(0)),
635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                RelocInfo::CODE_TARGET);
636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ daddiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag);
638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Jump(at);
639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->ClearSPDelta();
641f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      frame_access_state()->SetFrameAccessToDefault();
642958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
643958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
644bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kArchTailCallAddress: {
645bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      CHECK(!instr->InputAt(0)->IsImmediate());
646bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ Jump(i.InputRegister(0));
647bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      frame_access_state()->ClearSPDelta();
648f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      frame_access_state()->SetFrameAccessToDefault();
649bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
650bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
651958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kArchCallJSFunction: {
652958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      EnsureSpaceForLazyDeopt();
653958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Register func = i.InputRegister(0);
654958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (FLAG_debug_code) {
655958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // Check the function's context matches the context argument.
656958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ ld(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset));
657958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg));
658958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
659958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ ld(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
660958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Call(at);
661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RecordCallPosition(instr);
662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->ClearSPDelta();
663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
665c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case kArchTailCallJSFunctionFromJSFunction: {
666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register func = i.InputRegister(0);
667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code) {
668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Check the function's context matches the context argument.
669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ ld(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset));
670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg));
671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
672c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
673c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                       i.TempRegister(0), i.TempRegister(1),
674c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                       i.TempRegister(2));
675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ ld(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Jump(at);
677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->ClearSPDelta();
678f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      frame_access_state()->SetFrameAccessToDefault();
679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchPrepareCallCFunction: {
682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int const num_parameters = MiscField::decode(instr->opcode());
683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ PrepareCallCFunction(num_parameters, kScratchReg);
684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Frame alignment requires using FP-relative frame addressing.
685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->SetFrameAccessToFP();
686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchPrepareTailCall:
689f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      AssemblePrepareTailCall();
690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchCallCFunction: {
692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int const num_parameters = MiscField::decode(instr->opcode());
693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(0)->IsImmediate()) {
694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ExternalReference ref = i.InputExternalReference(0);
695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ CallCFunction(ref, num_parameters);
696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register func = i.InputRegister(0);
698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ CallCFunction(func, num_parameters);
699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->SetFrameAccessToDefault();
701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->ClearSPDelta();
702958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
703958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
704958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kArchJmp:
705958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      AssembleArchJump(i.InputRpo(0));
706958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchLookupSwitch:
708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AssembleArchLookupSwitch(instr);
709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchTableSwitch:
711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AssembleArchTableSwitch(instr);
712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
71313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kArchDebugBreak:
71413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ stop("kArchDebugBreak");
71513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
71613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kArchComment: {
71713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Address comment_string = i.InputExternalReference(0).address();
71813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ RecordComment(reinterpret_cast<const char*>(comment_string));
71913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
72013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
721958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kArchNop:
722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchThrowTerminator:
723958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // don't emit code for nops.
724958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchDeoptimize: {
726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int deopt_state_id =
727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Deoptimizer::BailoutType bailout_type =
729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Deoptimizer::BailoutType(MiscField::decode(instr->opcode()));
730f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      CodeGenResult result = AssembleDeoptimizerCall(
731f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          deopt_state_id, bailout_type, current_source_position_);
732bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (result != kSuccess) return result;
733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
735958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kArchRet:
736c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      AssembleReturn(instr->InputAt(0));
737958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
738958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kArchStackPointer:
739958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ mov(i.OutputRegister(), sp);
740958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchFramePointer:
742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mov(i.OutputRegister(), fp);
743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
744109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kArchParentFramePointer:
7453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (frame_access_state()->has_frame()) {
746109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ ld(i.OutputRegister(), MemOperand(fp, 0));
747109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      } else {
748109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ mov(i.OutputRegister(), fp);
749109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
750109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
751958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kArchTruncateDoubleToI:
752958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
753958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchStoreWithWriteBarrier: {
755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RecordWriteMode mode =
756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          static_cast<RecordWriteMode>(MiscField::decode(instr->opcode()));
757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register object = i.InputRegister(0);
758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register index = i.InputRegister(1);
759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register value = i.InputRegister(2);
760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register scratch0 = i.TempRegister(0);
761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register scratch1 = i.TempRegister(1);
762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      auto ool = new (zone()) OutOfLineRecordWrite(this, object, index, value,
763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   scratch0, scratch1, mode);
764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Daddu(at, object, index);
765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ sd(value, MemOperand(at));
766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ CheckPageFlag(object, scratch0,
767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       MemoryChunk::kPointersFromHereAreInterestingMask, ne,
768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       ool->entry());
769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ bind(ool->exit());
770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
772109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kArchStackSlot: {
773109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      FrameOffset offset =
774109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          frame_access_state()->GetFrameOffset(i.InputInt32(0));
775109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Daddu(i.OutputRegister(), offset.from_stack_pointer() ? sp : fp,
776109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch               Operand(offset.offset()));
777109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
778109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
779f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Acos:
780f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(acos);
781f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
782f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Acosh:
783f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(acosh);
784f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
785f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Asin:
786f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(asin);
787f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
788f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Asinh:
789f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(asinh);
790f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
79113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Atan:
79213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(atan);
79313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
79413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Atanh:
79513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(atanh);
79613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
797f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Atan2:
798f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_BINOP(atan2);
799f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
80013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Cos:
80113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(cos);
80213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
803f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Cosh:
804f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(cosh);
805f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
80613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Cbrt:
80713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(cbrt);
80813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
80913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Exp:
81013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(exp);
81113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
81213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Expm1:
81313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(expm1);
81413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
81513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Log:
81613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(log);
81713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
81813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Log1p:
81913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(log1p);
82013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
82113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Log2:
82213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(log2);
82313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
82413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Log10:
82513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(log10);
82613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
827f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Pow: {
828f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      MathPowStub stub(isolate(), MathPowStub::DOUBLE);
829f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ CallStub(&stub);
830f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
831f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
83213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Sin:
83313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(sin);
83413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
835f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Sinh:
836f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(sinh);
837f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
83813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Tan:
83913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(tan);
84013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
841f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Tanh:
842f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(tanh);
843f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
844958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Add:
845958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Addu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
846958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
847958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Dadd:
848958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Daddu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
849958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64DaddOvf:
851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Pseudo-instruction used for overflow/branch. No opcode emitted here.
852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
853958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Sub:
854958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Subu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
855958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
856958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Dsub:
857958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Dsubu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
858958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64DsubOvf:
860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Pseudo-instruction used for overflow/branch. No opcode emitted here.
861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
862958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Mul:
863958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Mul(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
864958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
865f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64MulOvf:
866f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Pseudo-instruction used for overflow/branch. No opcode emitted here.
867f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
868958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64MulHigh:
869958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Mulh(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
870958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
871958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64MulHighU:
872958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Mulhu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
873958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64DMulHigh:
875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Dmulh(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
877958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Div:
878958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Div(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (kArchVariant == kMips64r6) {
880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ selnez(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Movz(i.OutputRegister(), i.InputRegister(1), i.InputRegister(1));
883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
884958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
885958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64DivU:
886958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Divu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (kArchVariant == kMips64r6) {
888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ selnez(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Movz(i.OutputRegister(), i.InputRegister(1), i.InputRegister(1));
891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
892958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
893958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Mod:
894958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Mod(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
895958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
896958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64ModU:
897958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Modu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
898958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
899958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Dmul:
900958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Dmul(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
901958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
902958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Ddiv:
903958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Ddiv(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (kArchVariant == kMips64r6) {
905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ selnez(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Movz(i.OutputRegister(), i.InputRegister(1), i.InputRegister(1));
908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
909958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
910958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64DdivU:
911958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Ddivu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (kArchVariant == kMips64r6) {
913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ selnez(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Movz(i.OutputRegister(), i.InputRegister(1), i.InputRegister(1));
916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
917958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
918958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Dmod:
919958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Dmod(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
920958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
921958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64DmodU:
922958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Dmodu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
923958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
924bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kMips64Dlsa:
925bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      DCHECK(instr->InputAt(2)->IsImmediate());
926bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ Dlsa(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
927bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch              i.InputInt8(2));
928bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
929bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kMips64Lsa:
930bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      DCHECK(instr->InputAt(2)->IsImmediate());
931bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ Lsa(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
932bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch             i.InputInt8(2));
933bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
934958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64And:
935958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
936958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
937f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64And32:
938f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (instr->InputAt(1)->IsRegister()) {
939f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
940f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ sll(i.InputRegister(1), i.InputRegister(1), 0x0);
941f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
942f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
943f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
944f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
945f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
946f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
947958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Or:
948958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Or(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
949958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
950f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64Or32:
951f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (instr->InputAt(1)->IsRegister()) {
952f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
953f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ sll(i.InputRegister(1), i.InputRegister(1), 0x0);
954f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Or(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
955f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
956f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
957f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Or(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
958f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
959f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64Nor:
961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(1)->IsRegister()) {
962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Nor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(i.InputOperand(1).immediate() == 0);
965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Nor(i.OutputRegister(), i.InputRegister(0), zero_reg);
966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
968f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64Nor32:
969f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (instr->InputAt(1)->IsRegister()) {
970f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
971f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ sll(i.InputRegister(1), i.InputRegister(1), 0x0);
972f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Nor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
973f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
974f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        DCHECK(i.InputOperand(1).immediate() == 0);
975f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
976f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Nor(i.OutputRegister(), i.InputRegister(0), zero_reg);
977f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
978f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
979958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Xor:
980958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Xor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
981958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
982f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64Xor32:
983f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (instr->InputAt(1)->IsRegister()) {
984f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
985f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ sll(i.InputRegister(1), i.InputRegister(1), 0x0);
986f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Xor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
987f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
988f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
989f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Xor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
990f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
991f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64Clz:
993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Clz(i.OutputRegister(), i.InputRegister(0));
994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64Dclz:
996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ dclz(i.OutputRegister(), i.InputRegister(0));
997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
998109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kMips64Ctz: {
999109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Register reg1 = kScratchReg;
1000109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Register reg2 = kScratchReg2;
1001109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Label skip_for_zero;
1002109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Label end;
1003109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Branch if the operand is zero
1004109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Branch(&skip_for_zero, eq, i.InputRegister(0), Operand(zero_reg));
1005109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Find the number of bits before the last bit set to 1.
1006109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Subu(reg2, zero_reg, i.InputRegister(0));
1007109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ And(reg2, reg2, i.InputRegister(0));
1008109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ clz(reg2, reg2);
1009109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Get the number of bits after the last bit set to 1.
1010109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ li(reg1, 0x1F);
1011109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Subu(i.OutputRegister(), reg1, reg2);
1012109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Branch(&end);
1013109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ bind(&skip_for_zero);
1014109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // If the operand is zero, return word length as the result.
1015109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ li(i.OutputRegister(), 0x20);
1016109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ bind(&end);
1017109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    } break;
1018109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kMips64Dctz: {
1019109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Register reg1 = kScratchReg;
1020109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Register reg2 = kScratchReg2;
1021109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Label skip_for_zero;
1022109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Label end;
1023109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Branch if the operand is zero
1024109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Branch(&skip_for_zero, eq, i.InputRegister(0), Operand(zero_reg));
1025109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Find the number of bits before the last bit set to 1.
1026109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Dsubu(reg2, zero_reg, i.InputRegister(0));
1027109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ And(reg2, reg2, i.InputRegister(0));
1028109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ dclz(reg2, reg2);
1029109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Get the number of bits after the last bit set to 1.
1030109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ li(reg1, 0x3F);
1031109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Subu(i.OutputRegister(), reg1, reg2);
1032109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Branch(&end);
1033109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ bind(&skip_for_zero);
1034109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // If the operand is zero, return word length as the result.
1035109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ li(i.OutputRegister(), 0x40);
1036109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ bind(&end);
1037109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    } break;
1038109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kMips64Popcnt: {
1039109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Register reg1 = kScratchReg;
1040109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Register reg2 = kScratchReg2;
1041109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      uint32_t m1 = 0x55555555;
1042109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      uint32_t m2 = 0x33333333;
1043109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      uint32_t m4 = 0x0f0f0f0f;
1044109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      uint32_t m8 = 0x00ff00ff;
1045109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      uint32_t m16 = 0x0000ffff;
1046109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1047109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Put count of ones in every 2 bits into those 2 bits.
1048109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ li(at, m1);
1049109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ dsrl(reg1, i.InputRegister(0), 1);
1050109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ And(reg2, i.InputRegister(0), at);
1051109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ And(reg1, reg1, at);
1052109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Daddu(reg1, reg1, reg2);
1053109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1054109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Put count of ones in every 4 bits into those 4 bits.
1055109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ li(at, m2);
1056109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ dsrl(reg2, reg1, 2);
1057109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ And(reg2, reg2, at);
1058109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ And(reg1, reg1, at);
1059109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Daddu(reg1, reg1, reg2);
1060109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1061109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Put count of ones in every 8 bits into those 8 bits.
1062109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ li(at, m4);
1063109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ dsrl(reg2, reg1, 4);
1064109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ And(reg2, reg2, at);
1065109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ And(reg1, reg1, at);
1066109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Daddu(reg1, reg1, reg2);
1067109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1068109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Put count of ones in every 16 bits into those 16 bits.
1069109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ li(at, m8);
1070109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ dsrl(reg2, reg1, 8);
1071109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ And(reg2, reg2, at);
1072109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ And(reg1, reg1, at);
1073109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Daddu(reg1, reg1, reg2);
1074109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1075109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Calculate total number of ones.
1076109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ li(at, m16);
1077109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ dsrl(reg2, reg1, 16);
1078109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ And(reg2, reg2, at);
1079109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ And(reg1, reg1, at);
1080109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Daddu(i.OutputRegister(), reg1, reg2);
1081109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    } break;
1082109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kMips64Dpopcnt: {
1083109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Register reg1 = kScratchReg;
1084109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Register reg2 = kScratchReg2;
1085109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      uint64_t m1 = 0x5555555555555555;
1086109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      uint64_t m2 = 0x3333333333333333;
1087109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      uint64_t m4 = 0x0f0f0f0f0f0f0f0f;
1088109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      uint64_t m8 = 0x00ff00ff00ff00ff;
1089109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      uint64_t m16 = 0x0000ffff0000ffff;
1090109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      uint64_t m32 = 0x00000000ffffffff;
1091109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1092109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Put count of ones in every 2 bits into those 2 bits.
1093109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ li(at, m1);
1094109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ dsrl(reg1, i.InputRegister(0), 1);
1095109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ and_(reg2, i.InputRegister(0), at);
1096109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ and_(reg1, reg1, at);
1097109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Daddu(reg1, reg1, reg2);
1098109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1099109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Put count of ones in every 4 bits into those 4 bits.
1100109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ li(at, m2);
1101109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ dsrl(reg2, reg1, 2);
1102109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ and_(reg2, reg2, at);
1103109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ and_(reg1, reg1, at);
1104109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Daddu(reg1, reg1, reg2);
1105109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1106109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Put count of ones in every 8 bits into those 8 bits.
1107109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ li(at, m4);
1108109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ dsrl(reg2, reg1, 4);
1109109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ and_(reg2, reg2, at);
1110109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ and_(reg1, reg1, at);
1111109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Daddu(reg1, reg1, reg2);
1112109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1113109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Put count of ones in every 16 bits into those 16 bits.
1114109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ li(at, m8);
1115109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ dsrl(reg2, reg1, 8);
1116109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ and_(reg2, reg2, at);
1117109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ and_(reg1, reg1, at);
1118109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Daddu(reg1, reg1, reg2);
1119109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1120109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Put count of ones in every 32 bits into those 32 bits.
1121109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ li(at, m16);
1122109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ dsrl(reg2, reg1, 16);
1123109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ and_(reg2, reg2, at);
1124109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ and_(reg1, reg1, at);
1125109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Daddu(reg1, reg1, reg2);
1126109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1127109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Calculate total number of ones.
1128109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ li(at, m32);
1129109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ dsrl32(reg2, reg1, 0);
1130109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ and_(reg2, reg2, at);
1131109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ and_(reg1, reg1, at);
1132109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Daddu(i.OutputRegister(), reg1, reg2);
1133109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    } break;
1134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Shl:
1135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (instr->InputAt(1)->IsRegister()) {
1136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ sllv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
1137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
1138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int64_t imm = i.InputOperand(1).immediate();
1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ sll(i.OutputRegister(), i.InputRegister(0),
1140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               static_cast<uint16_t>(imm));
1141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Shr:
1144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (instr->InputAt(1)->IsRegister()) {
1145f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
1146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ srlv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
1147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
1148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int64_t imm = i.InputOperand(1).immediate();
1149f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
1150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ srl(i.OutputRegister(), i.InputRegister(0),
1151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               static_cast<uint16_t>(imm));
1152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Sar:
1155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (instr->InputAt(1)->IsRegister()) {
1156f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
1157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ srav(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
1158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int64_t imm = i.InputOperand(1).immediate();
1160f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ sll(i.InputRegister(0), i.InputRegister(0), 0x0);
1161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ sra(i.OutputRegister(), i.InputRegister(0),
1162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               static_cast<uint16_t>(imm));
1163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Ext:
1166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Ext(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
1167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier             i.InputInt8(2));
1168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64Ins:
1170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(1)->IsImmediate() && i.InputInt8(1) == 0) {
1171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Ins(i.OutputRegister(), zero_reg, i.InputInt8(1), i.InputInt8(2));
1172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Ins(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
1174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               i.InputInt8(2));
1175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64Dext: {
1178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int16_t pos = i.InputInt8(1);
1179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int16_t size = i.InputInt8(2);
1180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (size > 0 && size <= 32 && pos >= 0 && pos < 32) {
1181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Dext(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
1182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                i.InputInt8(2));
1183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else if (size > 32 && size <= 64 && pos > 0 && pos < 32) {
1184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Dextm(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
1185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 i.InputInt8(2));
1186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(size > 0 && size <= 32 && pos >= 32 && pos < 64);
1188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Dextu(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
1189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 i.InputInt8(2));
1190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64Dins:
1194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(1)->IsImmediate() && i.InputInt8(1) == 0) {
1195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Dins(i.OutputRegister(), zero_reg, i.InputInt8(1), i.InputInt8(2));
1196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Dins(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                i.InputInt8(2));
1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Dshl:
1202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (instr->InputAt(1)->IsRegister()) {
1203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ dsllv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
1204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
1205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int64_t imm = i.InputOperand(1).immediate();
1206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (imm < 32) {
1207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ dsll(i.OutputRegister(), i.InputRegister(0),
1208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  static_cast<uint16_t>(imm));
1209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        } else {
1210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ dsll32(i.OutputRegister(), i.InputRegister(0),
1211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    static_cast<uint16_t>(imm - 32));
1212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
1213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Dshr:
1216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (instr->InputAt(1)->IsRegister()) {
1217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ dsrlv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
1218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
1219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int64_t imm = i.InputOperand(1).immediate();
1220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (imm < 32) {
1221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ dsrl(i.OutputRegister(), i.InputRegister(0),
1222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  static_cast<uint16_t>(imm));
1223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        } else {
1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ dsrl32(i.OutputRegister(), i.InputRegister(0),
1225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    static_cast<uint16_t>(imm - 32));
1226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
1227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Dsar:
1230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (instr->InputAt(1)->IsRegister()) {
1231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ dsrav(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
1232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
1233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int64_t imm = i.InputOperand(1).immediate();
1234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (imm < 32) {
1235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ dsra(i.OutputRegister(), i.InputRegister(0), imm);
1236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        } else {
1237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ dsra32(i.OutputRegister(), i.InputRegister(0), imm - 32);
1238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
1239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Ror:
1242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Ror(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
1243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Dror:
1245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Dror(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
1246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Tst:
1248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // Pseudo-instruction used for cmp/branch. No opcode emitted here.
1249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Cmp:
1251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // Pseudo-instruction used for cmp/branch. No opcode emitted here.
1252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Mov:
1254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // TODO(plind): Should we combine mov/li like this, or use separate instr?
1255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      //    - Also see x64 ASSEMBLE_BINOP & RegisterOrOperandType
1256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (HasRegisterInput(instr, 0)) {
1257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ mov(i.OutputRegister(), i.InputRegister(0));
1258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
1259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ li(i.OutputRegister(), i.InputOperand(0));
1260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64CmpS:
1264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Psuedo-instruction used for FP cmp/branch. No opcode emitted here.
1265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64AddS:
1267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // TODO(plind): add special case: combine mult & add.
1268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ add_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
1269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               i.InputDoubleRegister(1));
1270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64SubS:
1272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ sub_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
1273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               i.InputDoubleRegister(1));
1274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64MulS:
1276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // TODO(plind): add special case: right op is -1.0, see arm port.
1277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mul_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
1278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               i.InputDoubleRegister(1));
1279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64DivS:
1281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ div_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
1282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               i.InputDoubleRegister(1));
1283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64ModS: {
1285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // TODO(bmeurer): We should really get rid of this special instruction,
1286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // and generate a CallAddress instruction instead.
1287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FrameScope scope(masm(), StackFrame::MANUAL);
1288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ PrepareCallCFunction(0, 2, kScratchReg);
1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ MovToFloatParameters(i.InputDoubleRegister(0),
1290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              i.InputDoubleRegister(1));
1291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // TODO(balazs.kilvady): implement mod_two_floats_operation(isolate())
1292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()),
1293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       0, 2);
1294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Move the result in the double result register.
1295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ MovFromFloatResult(i.OutputSingleRegister());
1296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64AbsS:
1299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ abs_s(i.OutputSingleRegister(), i.InputSingleRegister(0));
1300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1301f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64NegS:
1302f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Neg_s(i.OutputSingleRegister(), i.InputSingleRegister(0));
1303f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64SqrtS: {
1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ sqrt_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
1306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64MaxS:
1309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ max_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
1310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               i.InputDoubleRegister(1));
1311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64MinS:
1313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ min_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
1314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               i.InputDoubleRegister(1));
1315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64CmpD:
1317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // Psuedo-instruction used for FP cmp/branch. No opcode emitted here.
1318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64AddD:
1320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // TODO(plind): add special case: combine mult & add.
1321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ add_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
1322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier               i.InputDoubleRegister(1));
1323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64SubD:
1325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ sub_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
1326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier               i.InputDoubleRegister(1));
1327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1328f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case kMips64MaddS:
1329f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      __ madd_s(i.OutputFloatRegister(), i.InputFloatRegister(0),
1330f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                i.InputFloatRegister(1), i.InputFloatRegister(2));
1331f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
1332f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case kMips64MaddD:
1333f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      __ madd_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
1334f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                i.InputDoubleRegister(1), i.InputDoubleRegister(2));
1335f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
1336f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case kMips64MaddfS:
1337f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      __ maddf_s(i.OutputFloatRegister(), i.InputFloatRegister(1),
1338f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                 i.InputFloatRegister(2));
1339f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
1340f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case kMips64MaddfD:
1341f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      __ maddf_d(i.OutputDoubleRegister(), i.InputDoubleRegister(1),
1342f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                 i.InputDoubleRegister(2));
1343f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
1344f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case kMips64MsubS:
1345f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      __ msub_s(i.OutputFloatRegister(), i.InputFloatRegister(0),
1346f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                i.InputFloatRegister(1), i.InputFloatRegister(2));
1347f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
1348f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case kMips64MsubD:
1349f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      __ msub_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
1350f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                i.InputDoubleRegister(1), i.InputDoubleRegister(2));
1351f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
1352f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case kMips64MsubfS:
1353f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      __ msubf_s(i.OutputFloatRegister(), i.InputFloatRegister(1),
1354f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                 i.InputFloatRegister(2));
1355f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
1356f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case kMips64MsubfD:
1357f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      __ msubf_d(i.OutputDoubleRegister(), i.InputDoubleRegister(1),
1358f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                 i.InputDoubleRegister(2));
1359f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
1360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64MulD:
1361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // TODO(plind): add special case: right op is -1.0, see arm port.
1362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ mul_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
1363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier               i.InputDoubleRegister(1));
1364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64DivD:
1366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ div_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
1367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier               i.InputDoubleRegister(1));
1368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64ModD: {
1370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // TODO(bmeurer): We should really get rid of this special instruction,
1371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // and generate a CallAddress instruction instead.
1372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      FrameScope scope(masm(), StackFrame::MANUAL);
1373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ PrepareCallCFunction(0, 2, kScratchReg);
1374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ MovToFloatParameters(i.InputDoubleRegister(0),
1375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                              i.InputDoubleRegister(1));
1376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()),
1377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                       0, 2);
1378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // Move the result in the double result register.
1379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ MovFromFloatResult(i.OutputDoubleRegister());
1380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64AbsD:
1383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ abs_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
1384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1385f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64NegD:
1386f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Neg_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
1387f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64SqrtD: {
1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ sqrt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
1390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64MaxD:
1393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ max_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
1394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               i.InputDoubleRegister(1));
1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64MinD:
1397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ min_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               i.InputDoubleRegister(1));
1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64Float64RoundDown: {
1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(floor);
1402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64Float32RoundDown: {
1405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_ROUND_FLOAT_TO_FLOAT(floor);
1406958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1407958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Float64RoundTruncate: {
1409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(trunc);
1410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64Float32RoundTruncate: {
1413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_ROUND_FLOAT_TO_FLOAT(trunc);
1414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64Float64RoundUp: {
1417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil);
1418958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64Float32RoundUp: {
1421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_ROUND_FLOAT_TO_FLOAT(ceil);
1422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64Float64RoundTiesEven: {
1425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(round);
1426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64Float32RoundTiesEven: {
1429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_ROUND_FLOAT_TO_FLOAT(round);
1430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1432f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64Float32Max: {
1433f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Label compare_nan, done_compare;
1434f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ MaxNaNCheck_s(i.OutputSingleRegister(), i.InputSingleRegister(0),
1435f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                       i.InputSingleRegister(1), &compare_nan);
1436f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Branch(&done_compare);
1437f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&compare_nan);
1438f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Move(i.OutputSingleRegister(),
1439f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              std::numeric_limits<float>::quiet_NaN());
1440f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&done_compare);
1441f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1442f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
1443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64Float64Max: {
1444f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Label compare_nan, done_compare;
1445f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ MaxNaNCheck_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
1446f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                       i.InputDoubleRegister(1), &compare_nan);
1447f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Branch(&done_compare);
1448f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&compare_nan);
1449f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Move(i.OutputDoubleRegister(),
1450f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              std::numeric_limits<double>::quiet_NaN());
1451f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&done_compare);
1452f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1453f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
1454f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64Float32Min: {
1455f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Label compare_nan, done_compare;
1456f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ MinNaNCheck_s(i.OutputSingleRegister(), i.InputSingleRegister(0),
1457f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                       i.InputSingleRegister(1), &compare_nan);
1458f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Branch(&done_compare);
1459f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&compare_nan);
1460f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Move(i.OutputSingleRegister(),
1461f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              std::numeric_limits<float>::quiet_NaN());
1462f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&done_compare);
1463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64Float64Min: {
1466f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Label compare_nan, done_compare;
1467f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ MinNaNCheck_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
1468f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                       i.InputDoubleRegister(1), &compare_nan);
1469f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Branch(&done_compare);
1470f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&compare_nan);
1471f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Move(i.OutputDoubleRegister(),
1472f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              std::numeric_limits<double>::quiet_NaN());
1473f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&done_compare);
1474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1475958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
147613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kMips64Float64SilenceNaN:
147713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ FPUCanonicalizeNaN(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
147813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
1479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64CvtSD:
1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ cvt_s_d(i.OutputSingleRegister(), i.InputDoubleRegister(0));
1481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64CvtDS:
1483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ cvt_d_s(i.OutputDoubleRegister(), i.InputSingleRegister(0));
1484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1485958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64CvtDW: {
1486958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      FPURegister scratch = kScratchDoubleReg;
1487958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ mtc1(i.InputRegister(0), scratch);
1488958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ cvt_d_w(i.OutputDoubleRegister(), scratch);
1489958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1490958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64CvtSW: {
1492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FPURegister scratch = kScratchDoubleReg;
1493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mtc1(i.InputRegister(0), scratch);
1494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ cvt_s_w(i.OutputDoubleRegister(), scratch);
1495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1497109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kMips64CvtSUw: {
1498109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Cvt_s_uw(i.OutputDoubleRegister(), i.InputRegister(0));
1499109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
1500109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
1501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64CvtSL: {
1502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FPURegister scratch = kScratchDoubleReg;
1503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ dmtc1(i.InputRegister(0), scratch);
1504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ cvt_s_l(i.OutputDoubleRegister(), scratch);
1505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64CvtDL: {
1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FPURegister scratch = kScratchDoubleReg;
1509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ dmtc1(i.InputRegister(0), scratch);
1510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ cvt_d_l(i.OutputDoubleRegister(), scratch);
1511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1513958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64CvtDUw: {
1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Cvt_d_uw(i.OutputDoubleRegister(), i.InputRegister(0));
1515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64CvtDUl: {
1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Cvt_d_ul(i.OutputDoubleRegister(), i.InputRegister(0));
1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64CvtSUl: {
1522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Cvt_s_ul(i.OutputDoubleRegister(), i.InputRegister(0));
1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64FloorWD: {
1526958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      FPURegister scratch = kScratchDoubleReg;
1527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ floor_w_d(scratch, i.InputDoubleRegister(0));
1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mfc1(i.OutputRegister(), scratch);
1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64CeilWD: {
1532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FPURegister scratch = kScratchDoubleReg;
1533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ ceil_w_d(scratch, i.InputDoubleRegister(0));
1534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mfc1(i.OutputRegister(), scratch);
1535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64RoundWD: {
1538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FPURegister scratch = kScratchDoubleReg;
1539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ round_w_d(scratch, i.InputDoubleRegister(0));
1540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mfc1(i.OutputRegister(), scratch);
1541958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1542958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1543958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64TruncWD: {
1544958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      FPURegister scratch = kScratchDoubleReg;
1545958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // Other arches use round to zero here, so we follow.
1546958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ trunc_w_d(scratch, i.InputDoubleRegister(0));
1547958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ mfc1(i.OutputRegister(), scratch);
1548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64FloorWS: {
1551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FPURegister scratch = kScratchDoubleReg;
1552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ floor_w_s(scratch, i.InputDoubleRegister(0));
1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mfc1(i.OutputRegister(), scratch);
1554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64CeilWS: {
1557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FPURegister scratch = kScratchDoubleReg;
1558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ ceil_w_s(scratch, i.InputDoubleRegister(0));
1559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mfc1(i.OutputRegister(), scratch);
1560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64RoundWS: {
1563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FPURegister scratch = kScratchDoubleReg;
1564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ round_w_s(scratch, i.InputDoubleRegister(0));
1565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mfc1(i.OutputRegister(), scratch);
1566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64TruncWS: {
1569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FPURegister scratch = kScratchDoubleReg;
1570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ trunc_w_s(scratch, i.InputDoubleRegister(0));
1571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mfc1(i.OutputRegister(), scratch);
1572f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Avoid INT32_MAX as an overflow indicator and use INT32_MIN instead,
1573f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // because INT32_MIN allows easier out-of-bounds detection.
1574f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ addiu(kScratchReg, i.OutputRegister(), 1);
1575f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ slt(kScratchReg2, kScratchReg, i.OutputRegister());
1576f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Movn(i.OutputRegister(), kScratchReg, kScratchReg2);
1577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64TruncLS: {
1580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FPURegister scratch = kScratchDoubleReg;
1581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register tmp_fcsr = kScratchReg;
1582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register result = kScratchReg2;
1583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool load_status = instr->OutputCount() > 1;
1585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (load_status) {
1586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Save FCSR.
1587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ cfc1(tmp_fcsr, FCSR);
1588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Clear FPU flags.
1589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ ctc1(zero_reg, FCSR);
1590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Other arches use round to zero here, so we follow.
1592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ trunc_l_s(scratch, i.InputDoubleRegister(0));
1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ dmfc1(i.OutputRegister(), scratch);
1594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (load_status) {
1595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ cfc1(result, FCSR);
1596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Check for overflow and NaNs.
1597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ andi(result, result,
1598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                (kFCSROverflowFlagMask | kFCSRInvalidOpFlagMask));
1599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Slt(result, zero_reg, result);
1600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ xori(result, result, 1);
1601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ mov(i.OutputRegister(1), result);
1602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Restore FCSR
1603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ ctc1(tmp_fcsr, FCSR);
1604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64TruncLD: {
1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FPURegister scratch = kScratchDoubleReg;
1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register tmp_fcsr = kScratchReg;
1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register result = kScratchReg2;
1611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool load_status = instr->OutputCount() > 1;
1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (load_status) {
1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Save FCSR.
1615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ cfc1(tmp_fcsr, FCSR);
1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Clear FPU flags.
1617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ ctc1(zero_reg, FCSR);
1618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Other arches use round to zero here, so we follow.
1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ trunc_l_d(scratch, i.InputDoubleRegister(0));
1621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ dmfc1(i.OutputRegister(0), scratch);
1622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (load_status) {
1623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ cfc1(result, FCSR);
1624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Check for overflow and NaNs.
1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ andi(result, result,
1626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                (kFCSROverflowFlagMask | kFCSRInvalidOpFlagMask));
1627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Slt(result, zero_reg, result);
1628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ xori(result, result, 1);
1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ mov(i.OutputRegister(1), result);
1630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Restore FCSR
1631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ ctc1(tmp_fcsr, FCSR);
1632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1635958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64TruncUwD: {
1636958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      FPURegister scratch = kScratchDoubleReg;
1637958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // TODO(plind): Fix wrong param order of Trunc_uw_d() macro-asm function.
1638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Trunc_uw_d(i.InputDoubleRegister(0), i.OutputRegister(), scratch);
1639958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1640958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1641109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kMips64TruncUwS: {
1642109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      FPURegister scratch = kScratchDoubleReg;
1643109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // TODO(plind): Fix wrong param order of Trunc_uw_d() macro-asm function.
1644109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Trunc_uw_s(i.InputDoubleRegister(0), i.OutputRegister(), scratch);
1645f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Avoid UINT32_MAX as an overflow indicator and use 0 instead,
1646f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // because 0 allows easier out-of-bounds detection.
1647f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ addiu(kScratchReg, i.OutputRegister(), 1);
1648f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Movz(i.OutputRegister(), zero_reg, kScratchReg);
1649109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
1650109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
1651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64TruncUlS: {
1652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FPURegister scratch = kScratchDoubleReg;
1653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register result = instr->OutputCount() > 1 ? i.OutputRegister(1) : no_reg;
1654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // TODO(plind): Fix wrong param order of Trunc_ul_s() macro-asm function.
1655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Trunc_ul_s(i.InputDoubleRegister(0), i.OutputRegister(), scratch,
1656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    result);
1657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64TruncUlD: {
1660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      FPURegister scratch = kScratchDoubleReg;
1661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register result = instr->OutputCount() > 1 ? i.OutputRegister(1) : no_reg;
1662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // TODO(plind): Fix wrong param order of Trunc_ul_d() macro-asm function.
1663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Trunc_ul_d(i.InputDoubleRegister(0), i.OutputRegister(0), scratch,
1664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    result);
1665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64BitcastDL:
1668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ dmfc1(i.OutputRegister(), i.InputDoubleRegister(0));
1669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64BitcastLD:
1671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ dmtc1(i.InputRegister(0), i.OutputDoubleRegister());
1672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64Float64ExtractLowWord32:
1674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ FmoveLow(i.OutputRegister(), i.InputDoubleRegister(0));
1675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64Float64ExtractHighWord32:
1677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ FmoveHigh(i.OutputRegister(), i.InputDoubleRegister(0));
1678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64Float64InsertLowWord32:
1680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ FmoveLow(i.OutputDoubleRegister(), i.InputRegister(1));
1681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kMips64Float64InsertHighWord32:
1683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ FmoveHigh(i.OutputDoubleRegister(), i.InputRegister(1));
1684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1685958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // ... more basic instructions ...
1686958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1687f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case kMips64Seb:
1688f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      __ seb(i.OutputRegister(), i.InputRegister(0));
1689f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
1690f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case kMips64Seh:
1691f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      __ seh(i.OutputRegister(), i.InputRegister(0));
1692f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
1693958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Lbu:
1694958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ lbu(i.OutputRegister(), i.MemoryOperand());
1695958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1696958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Lb:
1697958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ lb(i.OutputRegister(), i.MemoryOperand());
1698958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1699958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Sb:
1700c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      __ sb(i.InputOrZeroRegister(2), i.MemoryOperand());
1701958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1702958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Lhu:
1703958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ lhu(i.OutputRegister(), i.MemoryOperand());
1704958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1705f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64Ulhu:
1706f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Ulhu(i.OutputRegister(), i.MemoryOperand());
1707f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1708958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Lh:
1709958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ lh(i.OutputRegister(), i.MemoryOperand());
1710958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1711f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64Ulh:
1712f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Ulh(i.OutputRegister(), i.MemoryOperand());
1713f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1714958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Sh:
1715c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      __ sh(i.InputOrZeroRegister(2), i.MemoryOperand());
1716958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1717f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64Ush:
1718c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      __ Ush(i.InputOrZeroRegister(2), i.MemoryOperand(), kScratchReg);
1719f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1720958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Lw:
1721958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ lw(i.OutputRegister(), i.MemoryOperand());
1722958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1723f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64Ulw:
1724f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Ulw(i.OutputRegister(), i.MemoryOperand());
1725f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1726bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kMips64Lwu:
1727bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ lwu(i.OutputRegister(), i.MemoryOperand());
1728bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
1729f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64Ulwu:
1730f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Ulwu(i.OutputRegister(), i.MemoryOperand());
1731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1732958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Ld:
1733958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ ld(i.OutputRegister(), i.MemoryOperand());
1734958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1735f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64Uld:
1736f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Uld(i.OutputRegister(), i.MemoryOperand());
1737f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1738958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Sw:
1739c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      __ sw(i.InputOrZeroRegister(2), i.MemoryOperand());
1740958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1741f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64Usw:
1742c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      __ Usw(i.InputOrZeroRegister(2), i.MemoryOperand());
1743f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1744958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Sd:
1745c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      __ sd(i.InputOrZeroRegister(2), i.MemoryOperand());
1746958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1747f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64Usd:
1748c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      __ Usd(i.InputOrZeroRegister(2), i.MemoryOperand());
1749f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1750958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Lwc1: {
1751958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ lwc1(i.OutputSingleRegister(), i.MemoryOperand());
1752958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1753958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1754f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64Ulwc1: {
1755f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Ulwc1(i.OutputSingleRegister(), i.MemoryOperand(), kScratchReg);
1756f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1757f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
1758958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Swc1: {
1759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size_t index = 0;
1760958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      MemOperand operand = i.MemoryOperand(&index);
1761c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      FPURegister ft = i.InputOrZeroSingleRegister(index);
1762c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (ft.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) {
1763c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        __ Move(kDoubleRegZero, 0.0);
1764c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
1765c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      __ swc1(ft, operand);
1766958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1767958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1768f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64Uswc1: {
1769f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      size_t index = 0;
1770f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      MemOperand operand = i.MemoryOperand(&index);
1771c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      FPURegister ft = i.InputOrZeroSingleRegister(index);
1772c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (ft.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) {
1773c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        __ Move(kDoubleRegZero, 0.0);
1774c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
1775c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      __ Uswc1(ft, operand, kScratchReg);
1776f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1777f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
1778958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Ldc1:
1779958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ ldc1(i.OutputDoubleRegister(), i.MemoryOperand());
1780958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1781f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64Uldc1:
1782f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Uldc1(i.OutputDoubleRegister(), i.MemoryOperand(), kScratchReg);
1783f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1784c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case kMips64Sdc1: {
1785c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      FPURegister ft = i.InputOrZeroDoubleRegister(2);
1786c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (ft.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) {
1787c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        __ Move(kDoubleRegZero, 0.0);
1788c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
1789c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      __ sdc1(ft, i.MemoryOperand());
1790958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1791c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
1792c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case kMips64Usdc1: {
1793c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      FPURegister ft = i.InputOrZeroDoubleRegister(2);
1794c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (ft.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) {
1795c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        __ Move(kDoubleRegZero, 0.0);
1796c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
1797c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      __ Usdc1(ft, i.MemoryOperand(), kScratchReg);
1798f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1799c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
1800958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64Push:
1801bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPRegister()) {
1802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ sdc1(i.InputDoubleRegister(0), MemOperand(sp, -kDoubleSize));
1803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Subu(sp, sp, Operand(kDoubleSize));
1804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
1805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Push(i.InputRegister(0));
1807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        frame_access_state()->IncreaseSPDelta(1);
1808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1809958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64StackClaim: {
1811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Dsubu(sp, sp, Operand(i.InputInt32(0)));
1812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->IncreaseSPDelta(i.InputInt32(0) / kPointerSize);
1813958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1814958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1815958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kMips64StoreToStackSlot: {
1816bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPRegister()) {
1817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ sdc1(i.InputDoubleRegister(0), MemOperand(sp, i.InputInt32(1)));
1818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ sd(i.InputRegister(0), MemOperand(sp, i.InputInt32(1)));
1820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1821958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1823f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64ByteSwap64: {
1824f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ ByteSwapSigned(i.OutputRegister(0), i.InputRegister(0), 8);
1825f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1826f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
1827f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kMips64ByteSwap32: {
1828f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ ByteSwapUnsigned(i.OutputRegister(0), i.InputRegister(0), 4);
1829f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ dsrl32(i.OutputRegister(0), i.OutputRegister(0), 0);
1830f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1831f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
1832958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedLoadInt8:
1833958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_LOAD_INTEGER(lb);
1834958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1835958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedLoadUint8:
1836958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_LOAD_INTEGER(lbu);
1837958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1838958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedLoadInt16:
1839958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_LOAD_INTEGER(lh);
1840958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1841958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedLoadUint16:
1842958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_LOAD_INTEGER(lhu);
1843958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1844958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedLoadWord32:
1845958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_LOAD_INTEGER(lw);
1846958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCheckedLoadWord64:
1848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_CHECKED_LOAD_INTEGER(ld);
1849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1850958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedLoadFloat32:
1851958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_LOAD_FLOAT(Single, lwc1);
1852958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1853958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedLoadFloat64:
1854958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_LOAD_FLOAT(Double, ldc1);
1855958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1856958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedStoreWord8:
1857958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_STORE_INTEGER(sb);
1858958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1859958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedStoreWord16:
1860958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_STORE_INTEGER(sh);
1861958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1862958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedStoreWord32:
1863958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_STORE_INTEGER(sw);
1864958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCheckedStoreWord64:
1866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_CHECKED_STORE_INTEGER(sd);
1867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1868958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedStoreFloat32:
1869958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_STORE_FLOAT(Single, swc1);
1870958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1871958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedStoreFloat64:
1872958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_STORE_FLOAT(Double, sdc1);
1873958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1874bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicLoadInt8:
1875bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      ASSEMBLE_ATOMIC_LOAD_INTEGER(lb);
1876bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
1877bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicLoadUint8:
1878bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      ASSEMBLE_ATOMIC_LOAD_INTEGER(lbu);
1879bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
1880bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicLoadInt16:
1881bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      ASSEMBLE_ATOMIC_LOAD_INTEGER(lh);
1882bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
1883bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicLoadUint16:
1884bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      ASSEMBLE_ATOMIC_LOAD_INTEGER(lhu);
1885bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
1886bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicLoadWord32:
1887bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      ASSEMBLE_ATOMIC_LOAD_INTEGER(lw);
1888bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
1889bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicStoreWord8:
1890bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      ASSEMBLE_ATOMIC_STORE_INTEGER(sb);
1891bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
1892bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicStoreWord16:
1893bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      ASSEMBLE_ATOMIC_STORE_INTEGER(sh);
1894bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
1895bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicStoreWord32:
1896bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      ASSEMBLE_ATOMIC_STORE_INTEGER(sw);
1897bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
1898c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case kMips64AssertEqual:
1899c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      __ Assert(eq, static_cast<BailoutReason>(i.InputOperand(2).immediate()),
1900c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                i.InputRegister(0), Operand(i.InputRegister(1)));
1901c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      break;
1902958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1903bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return kSuccess;
1904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // NOLINT(readability/fn_size)
1905958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1906958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1907958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define UNSUPPORTED_COND(opcode, condition)                                  \
1908958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  OFStream out(stdout);                                                      \
1909958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  out << "Unsupported " << #opcode << " condition: \"" << condition << "\""; \
1910958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UNIMPLEMENTED();
1911958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic bool convertCondition(FlagsCondition condition, Condition& cc) {
1913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (condition) {
1914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kEqual:
1915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      cc = eq;
1916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
1917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kNotEqual:
1918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      cc = ne;
1919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
1920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedLessThan:
1921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      cc = lt;
1922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
1923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedGreaterThanOrEqual:
1924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      cc = uge;
1925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
1926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedLessThanOrEqual:
1927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      cc = le;
1928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
1929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedGreaterThan:
1930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      cc = ugt;
1931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
1932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
1933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
1936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1939958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Assembles branches after an instruction.
1940958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
1941958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandConverter i(this, instr);
1942958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Label* tlabel = branch->true_label;
1943958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Label* flabel = branch->false_label;
1944958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Condition cc = kNoCondition;
1945958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // MIPS does not have condition code flags, so compare and branch are
1946958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // implemented differently than on the other arch's. The compare operations
1947958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // emit mips psuedo-instructions, which are handled here by branch
1948958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // instructions that do the actual comparison. Essential that the input
1949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // registers to compare pseudo-op are not modified before this branch op, as
1950958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // they are tested here.
1951958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1952958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (instr->arch_opcode() == kMips64Tst) {
1953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cc = FlagsConditionToConditionTst(branch->condition);
1954958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ And(at, i.InputRegister(0), i.InputOperand(1));
1955958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ Branch(tlabel, cc, at, Operand(zero_reg));
1956958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else if (instr->arch_opcode() == kMips64Dadd ||
1957958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier             instr->arch_opcode() == kMips64Dsub) {
1958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cc = FlagsConditionToConditionOvf(branch->condition);
1959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ dsra32(kScratchReg, i.OutputRegister(), 0);
1960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ sra(at, i.OutputRegister(), 31);
1961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ Branch(tlabel, cc, at, Operand(kScratchReg));
1962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (instr->arch_opcode() == kMips64DaddOvf) {
1963958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    switch (branch->condition) {
1964958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kOverflow:
1965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ DaddBranchOvf(i.OutputRegister(), i.InputRegister(0),
1966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         i.InputOperand(1), tlabel, flabel);
1967958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
1968958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kNotOverflow:
1969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ DaddBranchOvf(i.OutputRegister(), i.InputRegister(0),
1970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         i.InputOperand(1), flabel, tlabel);
1971958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
1972958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      default:
1973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UNSUPPORTED_COND(kMips64DaddOvf, branch->condition);
1974958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
1975958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (instr->arch_opcode() == kMips64DsubOvf) {
1977958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    switch (branch->condition) {
1978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kOverflow:
1979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ DsubBranchOvf(i.OutputRegister(), i.InputRegister(0),
1980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         i.InputOperand(1), tlabel, flabel);
1981958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
1982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kNotOverflow:
1983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ DsubBranchOvf(i.OutputRegister(), i.InputRegister(0),
1984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         i.InputOperand(1), flabel, tlabel);
1985958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
1986958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      default:
1987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UNSUPPORTED_COND(kMips64DsubOvf, branch->condition);
1988958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
1989958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1990f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else if (instr->arch_opcode() == kMips64MulOvf) {
1991f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    switch (branch->condition) {
1992f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case kOverflow: {
1993f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ MulBranchOvf(i.OutputRegister(), i.InputRegister(0),
1994f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                        i.InputOperand(1), tlabel, flabel, kScratchReg);
1995f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } break;
1996f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case kNotOverflow: {
1997f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ MulBranchOvf(i.OutputRegister(), i.InputRegister(0),
1998f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                        i.InputOperand(1), flabel, tlabel, kScratchReg);
1999f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } break;
2000f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      default:
2001f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        UNSUPPORTED_COND(kMips64MulOvf, branch->condition);
2002f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        break;
2003f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
2004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (instr->arch_opcode() == kMips64Cmp) {
2005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cc = FlagsConditionToConditionCmp(branch->condition);
2006958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
2007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (instr->arch_opcode() == kMips64CmpS) {
2008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!convertCondition(branch->condition, cc)) {
2009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UNSUPPORTED_COND(kMips64CmpS, branch->condition);
2010958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FPURegister left = i.InputOrZeroSingleRegister(0);
2012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FPURegister right = i.InputOrZeroSingleRegister(1);
2013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) &&
2014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        !__ IsDoubleZeroRegSet()) {
2015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Move(kDoubleRegZero, 0.0);
2016958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ BranchF32(tlabel, nullptr, cc, left, right);
2018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else if (instr->arch_opcode() == kMips64CmpD) {
2019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!convertCondition(branch->condition, cc)) {
2020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UNSUPPORTED_COND(kMips64CmpD, branch->condition);
2021958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FPURegister left = i.InputOrZeroDoubleRegister(0);
2023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FPURegister right = i.InputOrZeroDoubleRegister(1);
2024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) &&
2025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        !__ IsDoubleZeroRegSet()) {
2026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Move(kDoubleRegZero, 0.0);
2027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ BranchF64(tlabel, nullptr, cc, left, right);
2029958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
2030958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PrintF("AssembleArchBranch Unimplemented arch_opcode: %d\n",
2031958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           instr->arch_opcode());
2032958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    UNIMPLEMENTED();
2033958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!branch->fallthru) __ Branch(flabel);  // no fallthru to flabel.
2035958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2036958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2037958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchJump(RpoNumber target) {
2039958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target));
2040958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2041958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2042958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2043958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Assembles boolean materializations after an instruction.
2044958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid CodeGenerator::AssembleArchBoolean(Instruction* instr,
2045958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                        FlagsCondition condition) {
2046958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MipsOperandConverter i(this, instr);
2047958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Label done;
2048958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2049958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Materialize a full 32-bit 1 or 0 value. The result register is always the
2050958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // last output of the instruction.
2051958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Label false_value;
2052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_NE(0u, instr->OutputCount());
2053958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Register result = i.OutputRegister(instr->OutputCount() - 1);
2054958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Condition cc = kNoCondition;
2055958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // MIPS does not have condition code flags, so compare and branch are
2056958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // implemented differently than on the other arch's. The compare operations
2057958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // emit mips pseudo-instructions, which are checked and handled here.
2058958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2059958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (instr->arch_opcode() == kMips64Tst) {
2060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cc = FlagsConditionToConditionTst(condition);
2061c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (instr->InputAt(1)->IsImmediate() &&
2062c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        base::bits::IsPowerOfTwo64(i.InputOperand(1).immediate())) {
2063c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      uint16_t pos =
2064c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          base::bits::CountTrailingZeros64(i.InputOperand(1).immediate());
2065c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      __ ExtractBits(result, i.InputRegister(0), pos, 1);
2066c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    } else {
2067c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      __ And(kScratchReg, i.InputRegister(0), i.InputOperand(1));
2068c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      __ Sltu(result, zero_reg, kScratchReg);
2069c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
2070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (cc == eq) {
2071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Sltu produces 0 for equality, invert the result.
2072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ xori(result, result, 1);
2073958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
2075958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else if (instr->arch_opcode() == kMips64Dadd ||
2076958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier             instr->arch_opcode() == kMips64Dsub) {
2077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cc = FlagsConditionToConditionOvf(condition);
2078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Check for overflow creates 1 or 0 for result.
2079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ dsrl32(kScratchReg, i.OutputRegister(), 31);
2080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ srl(at, i.OutputRegister(), 31);
2081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ xor_(result, kScratchReg, at);
2082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (cc == eq)  // Toggle result for not overflow.
2083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ xori(result, result, 1);
2084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
2085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (instr->arch_opcode() == kMips64DaddOvf ||
2086f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch             instr->arch_opcode() == kMips64DsubOvf ||
2087f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch             instr->arch_opcode() == kMips64MulOvf) {
2088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Label flabel, tlabel;
2089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (instr->arch_opcode()) {
2090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMips64DaddOvf:
2091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ DaddBranchNoOvf(i.OutputRegister(), i.InputRegister(0),
2092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           i.InputOperand(1), &flabel);
2093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
2095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMips64DsubOvf:
2096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ DsubBranchNoOvf(i.OutputRegister(), i.InputRegister(0),
2097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           i.InputOperand(1), &flabel);
2098958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
2099f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case kMips64MulOvf:
2100f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ MulBranchNoOvf(i.OutputRegister(), i.InputRegister(0),
2101f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                          i.InputOperand(1), &flabel, kScratchReg);
2102f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        break;
2103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      default:
2104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UNREACHABLE();
2105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
2106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ li(result, 1);
2108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ Branch(&tlabel);
2109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ bind(&flabel);
2110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ li(result, 0);
2111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ bind(&tlabel);
2112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else if (instr->arch_opcode() == kMips64Cmp) {
2113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cc = FlagsConditionToConditionCmp(condition);
2114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (cc) {
2115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case eq:
2116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case ne: {
2117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register left = i.InputRegister(0);
2118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Operand right = i.InputOperand(1);
2119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register select;
2120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (instr->InputAt(1)->IsImmediate() && right.immediate() == 0) {
2121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // Pass left operand if right is zero.
2122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          select = left;
2123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
2124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ Dsubu(kScratchReg, left, right);
2125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          select = kScratchReg;
2126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
2127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Sltu(result, zero_reg, select);
2128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (cc == eq) {
2129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // Sltu produces 0 for equality, invert the result.
2130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ xori(result, result, 1);
2131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } break;
2133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case lt:
2134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case ge: {
2135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register left = i.InputRegister(0);
2136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Operand right = i.InputOperand(1);
2137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Slt(result, left, right);
2138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (cc == ge) {
2139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ xori(result, result, 1);
2140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } break;
2142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case gt:
2143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case le: {
2144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register left = i.InputRegister(1);
2145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Operand right = i.InputOperand(0);
2146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Slt(result, left, right);
2147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (cc == le) {
2148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ xori(result, result, 1);
2149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } break;
2151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case lo:
2152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case hs: {
2153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register left = i.InputRegister(0);
2154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Operand right = i.InputOperand(1);
2155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Sltu(result, left, right);
2156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (cc == hs) {
2157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ xori(result, result, 1);
2158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } break;
2160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case hi:
2161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case ls: {
2162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register left = i.InputRegister(1);
2163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Operand right = i.InputOperand(0);
2164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Sltu(result, left, right);
2165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (cc == ls) {
2166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ xori(result, result, 1);
2167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } break;
2169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      default:
2170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UNREACHABLE();
2171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
2173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (instr->arch_opcode() == kMips64CmpD ||
2174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             instr->arch_opcode() == kMips64CmpS) {
2175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FPURegister left = i.InputOrZeroDoubleRegister(0);
2176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FPURegister right = i.InputOrZeroDoubleRegister(1);
2177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) &&
2178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        !__ IsDoubleZeroRegSet()) {
2179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Move(kDoubleRegZero, 0.0);
2180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool predicate;
2182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FPUCondition cc = FlagsConditionToConditionCmpFPU(predicate, condition);
2183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (kArchVariant != kMips64r6) {
2184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ li(result, Operand(1));
2185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->arch_opcode() == kMips64CmpD) {
2186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ c(cc, D, left, right);
2187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(instr->arch_opcode() == kMips64CmpS);
2189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ c(cc, S, left, right);
2190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (predicate) {
2192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Movf(result, zero_reg);
2193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Movt(result, zero_reg);
2195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
2197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->arch_opcode() == kMips64CmpD) {
2198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ cmp(cc, L, kDoubleCompareReg, left, right);
2199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(instr->arch_opcode() == kMips64CmpS);
2201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ cmp(cc, W, kDoubleCompareReg, left, right);
2202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ dmfc1(result, kDoubleCompareReg);
2204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ andi(result, result, 1);  // Cmp returns all 1's/0's, use only LSB.
2205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!predicate)  // Toggle result for not equal.
2207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ xori(result, result, 1);
2208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
2210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
2211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PrintF("AssembleArchBranch Unimplemented arch_opcode is : %d\n",
2212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           instr->arch_opcode());
2213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    TRACE_UNIMPL();
2214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    UNIMPLEMENTED();
2215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) {
2220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MipsOperandConverter i(this, instr);
2221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register input = i.InputRegister(0);
2222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t index = 2; index < instr->InputCount(); index += 2) {
2223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ li(at, Operand(i.InputInt32(index + 0)));
2224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ beq(input, at, GetLabel(i.InputRpo(index + 1)));
2225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ nop();  // Branch delay slot of the last beq.
2227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AssembleArchJump(i.InputRpo(1));
2228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
2231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MipsOperandConverter i(this, instr);
2232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register input = i.InputRegister(0);
2233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t const case_count = instr->InputCount() - 2;
2234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ Branch(GetLabel(i.InputRpo(1)), hs, input, Operand(case_count));
2236109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ GenerateSwitchTable(input, case_count, [&i, this](size_t index) {
2237109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return GetLabel(i.InputRpo(index + 2));
2238109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  });
2239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2241bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall(
2242f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    int deoptimization_id, Deoptimizer::BailoutType bailout_type,
2243f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    SourcePosition pos) {
2244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
2245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate(), deoptimization_id, bailout_type);
2246bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (deopt_entry == nullptr) return kTooManyDeoptimizationBailouts;
2247f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeoptimizeReason deoptimization_reason =
2248f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      GetDeoptimizationReason(deoptimization_id);
2249c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  __ RecordDeoptReason(deoptimization_reason, pos, deoptimization_id);
2250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
2251bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return kSuccess;
2252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2254bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeGenerator::FinishFrame(Frame* frame) {
2255bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
2256bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2257bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
2258bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (saves_fpu != 0) {
2259bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    int count = base::bits::CountPopulation32(saves_fpu);
2260bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(kNumCalleeSavedFPU == count);
2261bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    frame->AllocateSavedCalleeRegisterSlots(count *
2262bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                            (kDoubleSize / kPointerSize));
2263bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
2264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2265bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  const RegList saves = descriptor->CalleeSavedRegisters();
2266bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (saves != 0) {
2267bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    int count = base::bits::CountPopulation32(saves);
2268bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(kNumCalleeSaved == count + 1);
2269bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    frame->AllocateSavedCalleeRegisterSlots(count);
2270bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
2271bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
2272bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2273bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeGenerator::AssembleConstructFrame() {
2274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
22753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (frame_access_state()->has_frame()) {
22763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (descriptor->IsCFunctionCall()) {
22773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ Push(ra, fp);
22783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ mov(fp, sp);
22793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    } else if (descriptor->IsJSFunctionCall()) {
22803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ Prologue(this->info()->GeneratePreagedPrologue());
2281c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (descriptor->PushArgumentCount()) {
2282c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        __ Push(kJavaScriptCallArgCountRegister);
2283c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
22843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    } else {
22853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ StubPrologue(info()->GetOutputStackFrameType());
22863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
2287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2289c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int shrink_slots =
2290c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      frame()->GetTotalFrameSlotCount() - descriptor->CalculateFixedFrameSize();
2291bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (info()->is_osr()) {
2293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // TurboFan OSR-compiled functions cannot be entered directly.
2294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ Abort(kShouldNotDirectlyEnterOsrFunction);
2295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Unoptimized code jumps directly to this entrypoint while the unoptimized
2297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // frame is still on the stack. Optimized code uses OSR values directly from
2298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // the unoptimized frame. Thus, all that needs to be done is to allocate the
2299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // remaining stack slots.
2300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
2301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    osr_pc_offset_ = __ pc_offset();
2302bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots();
2303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2305bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (shrink_slots > 0) {
2306bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    __ Dsubu(sp, sp, Operand(shrink_slots * kPointerSize));
2307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
2310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (saves_fpu != 0) {
2311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Save callee-saved FPU registers.
2312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ MultiPushFPU(saves_fpu);
2313bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(kNumCalleeSavedFPU == base::bits::CountPopulation32(saves_fpu));
2314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const RegList saves = descriptor->CalleeSavedRegisters();
2317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (saves != 0) {
2318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Save callee-saved registers.
2319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ MultiPush(saves);
2320bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(kNumCalleeSaved == base::bits::CountPopulation32(saves) + 1);
2321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2324c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid CodeGenerator::AssembleReturn(InstructionOperand* pop) {
2325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
2326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Restore GP registers.
2328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const RegList saves = descriptor->CalleeSavedRegisters();
2329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (saves != 0) {
2330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ MultiPop(saves);
2331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Restore FPU registers.
2334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
2335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (saves_fpu != 0) {
2336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ MultiPopFPU(saves_fpu);
2337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2339c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  MipsOperandConverter g(this, nullptr);
2340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (descriptor->IsCFunctionCall()) {
23413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    AssembleDeconstructFrame();
23423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else if (frame_access_state()->has_frame()) {
2343c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // Canonicalize JSFunction return sites for now unless they have an variable
2344c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // number of stack slot pops.
2345c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (pop->IsImmediate() && g.ToConstant(pop).ToInt32() == 0) {
2346c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (return_label_.is_bound()) {
2347c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        __ Branch(&return_label_);
2348c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        return;
2349c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      } else {
2350c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        __ bind(&return_label_);
2351c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        AssembleDeconstructFrame();
2352c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
2353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
23543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      AssembleDeconstructFrame();
2355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int pop_count = static_cast<int>(descriptor->StackParameterCount());
2358c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (pop->IsImmediate()) {
2359c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    DCHECK_EQ(Constant::kInt32, g.ToConstant(pop).type());
2360c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    pop_count += g.ToConstant(pop).ToInt32();
2361c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else {
2362c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Register pop_reg = g.ToRegister(pop);
2363c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    __ dsll(pop_reg, pop_reg, kPointerSizeLog2);
2364c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    __ Daddu(sp, sp, pop_reg);
2365c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
2366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pop_count != 0) {
2367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ DropAndRet(pop_count);
2368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ Ret();
2370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid CodeGenerator::AssembleMove(InstructionOperand* source,
2375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                 InstructionOperand* destination) {
2376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MipsOperandConverter g(this, nullptr);
2377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Dispatch on the source and destination operand kinds.  Not all
2378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // combinations are possible.
2379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (source->IsRegister()) {
2380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(destination->IsRegister() || destination->IsStackSlot());
2381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Register src = g.ToRegister(source);
2382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (destination->IsRegister()) {
2383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ mov(g.ToRegister(destination), src);
2384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
2385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ sd(src, g.ToMemOperand(destination));
2386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else if (source->IsStackSlot()) {
2388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(destination->IsRegister() || destination->IsStackSlot());
2389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    MemOperand src = g.ToMemOperand(source);
2390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (destination->IsRegister()) {
2391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ ld(g.ToRegister(destination), src);
2392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
2393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Register temp = kScratchReg;
2394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ ld(temp, src);
2395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ sd(temp, g.ToMemOperand(destination));
2396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else if (source->IsConstant()) {
2398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Constant src = g.ToConstant(source);
2399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (destination->IsRegister() || destination->IsStackSlot()) {
2400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Register dst =
2401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          destination->IsRegister() ? g.ToRegister(destination) : kScratchReg;
2402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      switch (src.type()) {
2403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        case Constant::kInt32:
2404bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          if (src.rmode() == RelocInfo::WASM_MEMORY_SIZE_REFERENCE) {
2405bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch            __ li(dst, Operand(src.ToInt32(), src.rmode()));
2406bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          } else {
2407bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch            __ li(dst, Operand(src.ToInt32()));
2408bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          }
2409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          break;
2410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        case Constant::kFloat32:
2411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ li(dst, isolate()->factory()->NewNumber(src.ToFloat32(), TENURED));
2412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          break;
2413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        case Constant::kInt64:
241413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          if (src.rmode() == RelocInfo::WASM_MEMORY_REFERENCE ||
241513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch              src.rmode() == RelocInfo::WASM_GLOBAL_REFERENCE) {
2416bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch            __ li(dst, Operand(src.ToInt64(), src.rmode()));
2417bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          } else {
2418bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch            DCHECK(src.rmode() != RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
2419bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch            __ li(dst, Operand(src.ToInt64()));
2420bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          }
2421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          break;
2422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        case Constant::kFloat64:
2423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ li(dst, isolate()->factory()->NewNumber(src.ToFloat64(), TENURED));
2424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          break;
2425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        case Constant::kExternalReference:
2426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ li(dst, Operand(src.ToExternalReference()));
2427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          break;
2428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case Constant::kHeapObject: {
2429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<HeapObject> src_object = src.ToHeapObject();
2430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Heap::RootListIndex index;
2431f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          if (IsMaterializableFromRoot(src_object, &index)) {
2432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            __ LoadRoot(dst, index);
2433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          } else {
2434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            __ li(dst, src_object);
2435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
2436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          break;
2437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        case Constant::kRpoNumber:
2439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          UNREACHABLE();  // TODO(titzer): loading RPO numbers on mips64.
2440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          break;
2441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
2442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (destination->IsStackSlot()) __ sd(dst, g.ToMemOperand(destination));
2443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else if (src.type() == Constant::kFloat32) {
2444bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (destination->IsFPStackSlot()) {
2445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        MemOperand dst = g.ToMemOperand(destination);
2446f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        if (bit_cast<int32_t>(src.ToFloat32()) == 0) {
2447f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          __ sw(zero_reg, dst);
2448f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        } else {
2449f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          __ li(at, Operand(bit_cast<int32_t>(src.ToFloat32())));
2450f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          __ sw(at, dst);
2451f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        }
2452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
2453f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        DCHECK(destination->IsFPRegister());
2454958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        FloatRegister dst = g.ToSingleRegister(destination);
2455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ Move(dst, src.ToFloat32());
2456958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
2457958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
2458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      DCHECK_EQ(Constant::kFloat64, src.type());
2459bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      DoubleRegister dst = destination->IsFPRegister()
2460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                               ? g.ToDoubleRegister(destination)
2461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                               : kScratchDoubleReg;
2462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Move(dst, src.ToFloat64());
2463bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (destination->IsFPStackSlot()) {
2464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ sdc1(dst, g.ToMemOperand(destination));
2465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
2466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2467bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (source->IsFPRegister()) {
2468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    FPURegister src = g.ToDoubleRegister(source);
2469bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (destination->IsFPRegister()) {
2470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      FPURegister dst = g.ToDoubleRegister(destination);
2471958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Move(dst, src);
2472958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
2473bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      DCHECK(destination->IsFPStackSlot());
2474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ sdc1(src, g.ToMemOperand(destination));
2475958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2476bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (source->IsFPStackSlot()) {
2477bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(destination->IsFPRegister() || destination->IsFPStackSlot());
2478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    MemOperand src = g.ToMemOperand(source);
2479bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (destination->IsFPRegister()) {
2480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ ldc1(g.ToDoubleRegister(destination), src);
2481958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
2482958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      FPURegister temp = kScratchDoubleReg;
2483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ ldc1(temp, src);
2484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ sdc1(temp, g.ToMemOperand(destination));
2485958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2486958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
2487958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    UNREACHABLE();
2488958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2489958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2490958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2491958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid CodeGenerator::AssembleSwap(InstructionOperand* source,
2493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                 InstructionOperand* destination) {
2494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MipsOperandConverter g(this, nullptr);
2495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Dispatch on the source and destination operand kinds.  Not all
2496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // combinations are possible.
2497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (source->IsRegister()) {
2498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Register-register.
2499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Register temp = kScratchReg;
2500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Register src = g.ToRegister(source);
2501958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (destination->IsRegister()) {
2502958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Register dst = g.ToRegister(destination);
2503958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Move(temp, src);
2504958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Move(src, dst);
2505958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Move(dst, temp);
2506958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
2507958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      DCHECK(destination->IsStackSlot());
2508958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      MemOperand dst = g.ToMemOperand(destination);
2509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ mov(temp, src);
2510958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ ld(src, dst);
2511958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ sd(temp, dst);
2512958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2513958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else if (source->IsStackSlot()) {
2514958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(destination->IsStackSlot());
2515958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Register temp_0 = kScratchReg;
2516958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Register temp_1 = kScratchReg2;
2517958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    MemOperand src = g.ToMemOperand(source);
2518958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    MemOperand dst = g.ToMemOperand(destination);
2519958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ ld(temp_0, src);
2520958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ ld(temp_1, dst);
2521958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ sd(temp_0, dst);
2522958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ sd(temp_1, src);
2523bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (source->IsFPRegister()) {
2524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    FPURegister temp = kScratchDoubleReg;
2525958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    FPURegister src = g.ToDoubleRegister(source);
2526bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (destination->IsFPRegister()) {
2527958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      FPURegister dst = g.ToDoubleRegister(destination);
2528958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Move(temp, src);
2529958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Move(src, dst);
2530958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Move(dst, temp);
2531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
2532bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      DCHECK(destination->IsFPStackSlot());
2533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      MemOperand dst = g.ToMemOperand(destination);
2534958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Move(temp, src);
2535958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ ldc1(src, dst);
2536958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ sdc1(temp, dst);
2537958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2538bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (source->IsFPStackSlot()) {
2539bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(destination->IsFPStackSlot());
2540958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Register temp_0 = kScratchReg;
2541958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    FPURegister temp_1 = kScratchDoubleReg;
2542958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    MemOperand src0 = g.ToMemOperand(source);
2543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MemOperand src1(src0.rm(), src0.offset() + kIntSize);
2544958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    MemOperand dst0 = g.ToMemOperand(destination);
2545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MemOperand dst1(dst0.rm(), dst0.offset() + kIntSize);
2546958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ ldc1(temp_1, dst0);  // Save destination in temp_1.
2547958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ lw(temp_0, src0);    // Then use temp_0 to copy source to destination.
2548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ sw(temp_0, dst0);
2549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ lw(temp_0, src1);
2550958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ sw(temp_0, dst1);
2551958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ sdc1(temp_1, src0);
2552958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
2553958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // No other combinations are possible.
2554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    UNREACHABLE();
2555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2556958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2558958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) {
2560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // On 64-bit MIPS we emit the jump tables inline.
2561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
2562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2565958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid CodeGenerator::EnsureSpaceForLazyDeopt() {
2566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!info()->ShouldEnsureSpaceForLazyDeopt()) {
2567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
2568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2570958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int space_needed = Deoptimizer::patch_size();
2571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Ensure that we have enough space after the previous lazy-bailout
2572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // instruction for patching the code here.
2573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int current_pc = masm()->pc_offset();
2574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (current_pc < last_lazy_deopt_pc_ + space_needed) {
2575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Block tramoline pool emission for duration of padding.
2576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
2577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        masm());
2578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
2579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(0, padding_size % v8::internal::Assembler::kInstrSize);
2580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (padding_size > 0) {
2581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ nop();
2582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      padding_size -= v8::internal::Assembler::kInstrSize;
2583958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2584958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2585958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2586958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2587958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#undef __
2588958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2589958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace compiler
2590958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace internal
2591958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace v8
2592