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