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