1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/base/adapters.h" 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/bits.h" 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/instruction-selector-impl.h" 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/node-matchers.h" 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/node-properties.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler { 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Adds Arm-specific methods for generating InstructionOperands. 16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass ArmOperandGenerator : public OperandGenerator { 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit ArmOperandGenerator(InstructionSelector* selector) 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : OperandGenerator(selector) {} 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 21958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool CanBeImmediate(int32_t value) const { 22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Assembler::ImmediateFitsAddrMode1Instruction(value); 23958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool CanBeImmediate(uint32_t value) const { 26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return CanBeImmediate(bit_cast<int32_t>(value)); 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool CanBeImmediate(Node* node, InstructionCode opcode) { 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Int32Matcher m(node); 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!m.HasValue()) return false; 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t value = m.Value(); 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (ArchOpcodeField::decode(opcode)) { 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmAnd: 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmMov: 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmMvn: 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmBic: 38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return CanBeImmediate(value) || CanBeImmediate(~value); 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmAdd: 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmSub: 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmCmp: 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmCmn: 44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return CanBeImmediate(value) || CanBeImmediate(-value); 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmTst: 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmTeq: 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmOrr: 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmEor: 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmRsb: 51958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return CanBeImmediate(value); 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 53958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kArmVldrF32: 54958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kArmVstrF32: 55958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kArmVldrF64: 56958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kArmVstrF64: 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return value >= -1020 && value <= 1020 && (value % 4) == 0; 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmLdrb: 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmLdrsb: 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmStrb: 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmLdr: 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmStr: 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return value >= -4095 && value <= 4095; 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmLdrh: 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmLdrsh: 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArmStrh: 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return value >= -255 && value <= 255; 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 71958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: 72958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace { 80958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) { 82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ArmOperandGenerator g(selector); 83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier selector->Emit(opcode, g.DefineAsRegister(node), 84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(node->InputAt(0))); 85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 86958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 87958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitRRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) { 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArmOperandGenerator g(selector); 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch selector->Emit(opcode, g.DefineAsRegister(node), 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.UseRegister(node->InputAt(0)), 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.UseRegister(node->InputAt(1))); 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate <IrOpcode::Value kOpcode, int kImmMin, int kImmMax, 97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddressingMode kImmMode, AddressingMode kRegMode> 98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool TryMatchShift(InstructionSelector* selector, 99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionCode* opcode_return, Node* node, 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* value_return, 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* shift_return) { 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArmOperandGenerator g(selector); 103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (node->opcode() == kOpcode) { 104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32BinopMatcher m(node); 105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *value_return = g.UseRegister(m.left().node()); 106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (m.right().IsInRange(kImmMin, kImmMax)) { 107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *opcode_return |= AddressingModeField::encode(kImmMode); 108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *shift_return = g.UseImmediate(m.right().node()); 109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *opcode_return |= AddressingModeField::encode(kRegMode); 111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *shift_return = g.UseRegister(m.right().node()); 112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return true; 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return false; 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochtemplate <IrOpcode::Value kOpcode, int kImmMin, int kImmMax, 11913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch AddressingMode kImmMode> 12013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochbool TryMatchShiftImmediate(InstructionSelector* selector, 12113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InstructionCode* opcode_return, Node* node, 12213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InstructionOperand* value_return, 12313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InstructionOperand* shift_return) { 12413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ArmOperandGenerator g(selector); 12513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (node->opcode() == kOpcode) { 12613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Int32BinopMatcher m(node); 12713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (m.right().IsInRange(kImmMin, kImmMax)) { 12813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch *opcode_return |= AddressingModeField::encode(kImmMode); 12913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch *value_return = g.UseRegister(m.left().node()); 13013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch *shift_return = g.UseImmediate(m.right().node()); 13113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return true; 13213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 13313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 13413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return false; 13513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool TryMatchROR(InstructionSelector* selector, InstructionCode* opcode_return, 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* node, InstructionOperand* value_return, 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* shift_return) { 140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return TryMatchShift<IrOpcode::kWord32Ror, 1, 31, kMode_Operand2_R_ROR_I, 141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier kMode_Operand2_R_ROR_R>(selector, opcode_return, node, 142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier value_return, shift_return); 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool TryMatchASR(InstructionSelector* selector, InstructionCode* opcode_return, 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* node, InstructionOperand* value_return, 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* shift_return) { 149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return TryMatchShift<IrOpcode::kWord32Sar, 1, 32, kMode_Operand2_R_ASR_I, 150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier kMode_Operand2_R_ASR_R>(selector, opcode_return, node, 151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier value_return, shift_return); 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool TryMatchLSL(InstructionSelector* selector, InstructionCode* opcode_return, 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* node, InstructionOperand* value_return, 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* shift_return) { 158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return TryMatchShift<IrOpcode::kWord32Shl, 0, 31, kMode_Operand2_R_LSL_I, 159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier kMode_Operand2_R_LSL_R>(selector, opcode_return, node, 160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier value_return, shift_return); 161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 16313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochbool TryMatchLSLImmediate(InstructionSelector* selector, 16413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InstructionCode* opcode_return, Node* node, 16513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InstructionOperand* value_return, 16613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InstructionOperand* shift_return) { 16713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return TryMatchShiftImmediate<IrOpcode::kWord32Shl, 0, 31, 16813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch kMode_Operand2_R_LSL_I>( 16913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch selector, opcode_return, node, value_return, shift_return); 17013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool TryMatchLSR(InstructionSelector* selector, InstructionCode* opcode_return, 173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* node, InstructionOperand* value_return, 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* shift_return) { 175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return TryMatchShift<IrOpcode::kWord32Shr, 1, 32, kMode_Operand2_R_LSR_I, 176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier kMode_Operand2_R_LSR_R>(selector, opcode_return, node, 177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier value_return, shift_return); 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool TryMatchShift(InstructionSelector* selector, 182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionCode* opcode_return, Node* node, 183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* value_return, 184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* shift_return) { 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ( 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TryMatchASR(selector, opcode_return, node, value_return, shift_return) || 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TryMatchLSL(selector, opcode_return, node, value_return, shift_return) || 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TryMatchLSR(selector, opcode_return, node, value_return, shift_return) || 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TryMatchROR(selector, opcode_return, node, value_return, shift_return)); 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool TryMatchImmediateOrShift(InstructionSelector* selector, 194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionCode* opcode_return, Node* node, 195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size_t* input_count_return, 196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* inputs) { 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArmOperandGenerator g(selector); 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (g.CanBeImmediate(node, *opcode_return)) { 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *opcode_return |= AddressingModeField::encode(kMode_Operand2_I); 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inputs[0] = g.UseImmediate(node); 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *input_count_return = 1; 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryMatchShift(selector, opcode_return, node, &inputs[0], &inputs[1])) { 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *input_count_return = 2; 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitBinop(InstructionSelector* selector, Node* node, 213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionCode opcode, InstructionCode reverse_opcode, 214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FlagsContinuation* cont) { 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArmOperandGenerator g(selector); 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Int32BinopMatcher m(node); 217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand inputs[5]; 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t input_count = 0; 219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand outputs[2]; 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t output_count = 0; 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (m.left().node() == m.right().node()) { 223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If both inputs refer to the same operand, enforce allocating a register 224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // for both of them to ensure that we don't end up generating code like 225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // this: 226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // 227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // mov r0, r1, asr #16 228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // adds r0, r0, r1, asr #16 229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // bvs label 230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand const input = g.UseRegister(m.left().node()); 231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode |= AddressingModeField::encode(kMode_Operand2_R); 232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inputs[input_count++] = input; 233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inputs[input_count++] = input; 234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (TryMatchImmediateOrShift(selector, &opcode, m.right().node(), 235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier &input_count, &inputs[1])) { 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inputs[0] = g.UseRegister(m.left().node()); 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch input_count++; 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (TryMatchImmediateOrShift(selector, &reverse_opcode, 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch m.left().node(), &input_count, 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &inputs[1])) { 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inputs[0] = g.UseRegister(m.right().node()); 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch opcode = reverse_opcode; 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch input_count++; 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch opcode |= AddressingModeField::encode(kMode_Operand2_R); 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inputs[input_count++] = g.UseRegister(m.left().node()); 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inputs[input_count++] = g.UseRegister(m.right().node()); 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cont->IsBranch()) { 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inputs[input_count++] = g.Label(cont->true_block()); 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inputs[input_count++] = g.Label(cont->false_block()); 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 255f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch outputs[output_count++] = g.DefineAsRegister(node); 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cont->IsSet()) { 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outputs[output_count++] = g.DefineAsRegister(cont->result()); 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(0u, input_count); 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(0u, output_count); 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_GE(arraysize(inputs), input_count); 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_GE(arraysize(outputs), output_count); 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NE(kMode_None, AddressingModeField::decode(opcode)); 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch opcode = cont->Encode(opcode); 2673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (cont->IsDeoptimize()) { 2683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, 269f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cont->reason(), cont->frame_state()); 2703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 2713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch selector->Emit(opcode, output_count, outputs, input_count, inputs); 2723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitBinop(InstructionSelector* selector, Node* node, 277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionCode opcode, InstructionCode reverse_opcode) { 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlagsContinuation cont; 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitBinop(selector, node, opcode, reverse_opcode, &cont); 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid EmitDiv(InstructionSelector* selector, ArchOpcode div_opcode, 284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArchOpcode f64i32_opcode, ArchOpcode i32f64_opcode, 285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand result_operand, InstructionOperand left_operand, 286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand right_operand) { 287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArmOperandGenerator g(selector); 288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (selector->IsSupported(SUDIV)) { 289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->Emit(div_opcode, result_operand, left_operand, right_operand); 290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand left_double_operand = g.TempDoubleRegister(); 293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand right_double_operand = g.TempDoubleRegister(); 294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand result_double_operand = g.TempDoubleRegister(); 295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->Emit(f64i32_opcode, left_double_operand, left_operand); 296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->Emit(f64i32_opcode, right_double_operand, right_operand); 297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->Emit(kArmVdivF64, result_double_operand, left_double_operand, 298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch right_double_operand); 299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->Emit(i32f64_opcode, result_operand, result_double_operand); 300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode div_opcode, 304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArchOpcode f64i32_opcode, ArchOpcode i32f64_opcode) { 305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArmOperandGenerator g(selector); 306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Int32BinopMatcher m(node); 307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EmitDiv(selector, div_opcode, f64i32_opcode, i32f64_opcode, 308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.DefineAsRegister(node), g.UseRegister(m.left().node()), 309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseRegister(m.right().node())); 310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitMod(InstructionSelector* selector, Node* node, ArchOpcode div_opcode, 314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArchOpcode f64i32_opcode, ArchOpcode i32f64_opcode) { 315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArmOperandGenerator g(selector); 316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Int32BinopMatcher m(node); 317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand div_operand = g.TempRegister(); 318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand result_operand = g.DefineAsRegister(node); 319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand left_operand = g.UseRegister(m.left().node()); 320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand right_operand = g.UseRegister(m.right().node()); 321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EmitDiv(selector, div_opcode, f64i32_opcode, i32f64_opcode, div_operand, 322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left_operand, right_operand); 32313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (selector->IsSupported(ARMv7)) { 324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->Emit(kArmMls, result_operand, div_operand, right_operand, 325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left_operand); 326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand mul_operand = g.TempRegister(); 328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->Emit(kArmMul, mul_operand, div_operand, right_operand); 32913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch selector->Emit(kArmSub | AddressingModeField::encode(kMode_Operand2_R), 33013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch result_operand, left_operand, mul_operand); 331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 334f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid EmitLoad(InstructionSelector* selector, InstructionCode opcode, 335f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand* output, Node* base, Node* index) { 336f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ArmOperandGenerator g(selector); 337f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand inputs[3]; 338f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch size_t input_count = 2; 339f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 340f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs[0] = g.UseRegister(base); 341f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (g.CanBeImmediate(index, opcode)) { 342f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs[1] = g.UseImmediate(index); 343f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch opcode |= AddressingModeField::encode(kMode_Offset_RI); 344f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if ((opcode == kArmLdr) && 345f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TryMatchLSLImmediate(selector, &opcode, index, &inputs[1], 346f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch &inputs[2])) { 347f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch input_count = 3; 348f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 349f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs[1] = g.UseRegister(index); 350f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch opcode |= AddressingModeField::encode(kMode_Offset_RR); 351f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 352f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch selector->Emit(opcode, 1, output, input_count, inputs); 353f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 354f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 355f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid EmitStore(InstructionSelector* selector, InstructionCode opcode, 356f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch size_t input_count, InstructionOperand* inputs, 357f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* index) { 358f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ArmOperandGenerator g(selector); 359f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 360f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (g.CanBeImmediate(index, opcode)) { 361f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs[input_count++] = g.UseImmediate(index); 362f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch opcode |= AddressingModeField::encode(kMode_Offset_RI); 363f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if ((opcode == kArmStr) && 364f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TryMatchLSLImmediate(selector, &opcode, index, &inputs[2], 365f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch &inputs[3])) { 366f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch input_count = 4; 367f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 368f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs[input_count++] = g.UseRegister(index); 369f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch opcode |= AddressingModeField::encode(kMode_Offset_RR); 370f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 371f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch selector->Emit(opcode, 0, nullptr, input_count, inputs); 372f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 373f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace 375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitLoad(Node* node) { 378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadRepresentation load_rep = LoadRepresentationOf(node->op()); 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArmOperandGenerator g(this); 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* base = node->InputAt(0); 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* index = node->InputAt(1); 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 38313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InstructionCode opcode = kArchNop; 384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (load_rep.representation()) { 385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat32: 386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = kArmVldrF32; 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat64: 389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = kArmVldrF64; 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kBit: // Fall through. 392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord8: 393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode = load_rep.IsUnsigned() ? kArmLdrb : kArmLdrsb; 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord16: 396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode = load_rep.IsUnsigned() ? kArmLdrh : kArmLdrsh; 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 398f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kTaggedSigned: // Fall through. 399f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kTaggedPointer: // Fall through. 400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kTagged: // Fall through. 401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord32: 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch opcode = kArmLdr; 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 404109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kWord64: // Fall through. 405109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kSimd128: // Fall through. 406109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kNone: 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 411f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand output = g.DefineAsRegister(node); 412f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch EmitLoad(this, opcode, &output, base, index); 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 415f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid InstructionSelector::VisitProtectedLoad(Node* node) { 416f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // TODO(eholk) 417f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch UNIMPLEMENTED(); 418f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitStore(Node* node) { 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArmOperandGenerator g(this); 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* base = node->InputAt(0); 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* index = node->InputAt(1); 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = node->InputAt(2); 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StoreRepresentation store_rep = StoreRepresentationOf(node->op()); 427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); 428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineRepresentation rep = store_rep.representation(); 429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (write_barrier_kind != kNoWriteBarrier) { 431f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(CanBeTaggedPointer(rep)); 432109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AddressingMode addressing_mode; 433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand inputs[3]; 434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t input_count = 0; 435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inputs[input_count++] = g.UseUniqueRegister(base); 436109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // OutOfLineRecordWrite uses the index in an 'add' instruction as well as 437109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // for the store itself, so we must check compatibility with both. 438109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (g.CanBeImmediate(index, kArmAdd) && g.CanBeImmediate(index, kArmStr)) { 439109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch inputs[input_count++] = g.UseImmediate(index); 440109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch addressing_mode = kMode_Offset_RI; 441109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 442109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch inputs[input_count++] = g.UseUniqueRegister(index); 443109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch addressing_mode = kMode_Offset_RR; 444109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 4453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inputs[input_count++] = g.UseUniqueRegister(value); 446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; 447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (write_barrier_kind) { 448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kNoWriteBarrier: 449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMapWriteBarrier: 452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch record_write_mode = RecordWriteMode::kValueIsMap; 453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPointerWriteBarrier: 455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch record_write_mode = RecordWriteMode::kValueIsPointer; 456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kFullWriteBarrier: 458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch record_write_mode = RecordWriteMode::kValueIsAny; 459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; 462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t const temp_count = arraysize(temps); 463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionCode code = kArchStoreWithWriteBarrier; 464109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch code |= AddressingModeField::encode(addressing_mode); 465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch code |= MiscField::encode(static_cast<int>(record_write_mode)); 466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 46813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InstructionCode opcode = kArchNop; 469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (rep) { 470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat32: 471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode = kArmVstrF32; 472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat64: 474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode = kArmVstrF64; 475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kBit: // Fall through. 477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord8: 478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode = kArmStrb; 479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord16: 481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode = kArmStrh; 482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 483f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kTaggedSigned: // Fall through. 484f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kTaggedPointer: // Fall through. 485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kTagged: // Fall through. 486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord32: 487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode = kArmStr; 488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 489109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kWord64: // Fall through. 490109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kSimd128: // Fall through. 491109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kNone: 492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 496f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand inputs[4]; 497f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch size_t input_count = 0; 498f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs[input_count++] = g.UseRegister(value); 499f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs[input_count++] = g.UseRegister(base); 500f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch EmitStore(this, opcode, input_count, inputs, index); 501f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 502f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 50313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 504f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitUnalignedLoad(Node* node) { 505f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UnalignedLoadRepresentation load_rep = 506f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UnalignedLoadRepresentationOf(node->op()); 507f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ArmOperandGenerator g(this); 508f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* base = node->InputAt(0); 509f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* index = node->InputAt(1); 510f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 511f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionCode opcode = kArmLdr; 512f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Only floating point loads need to be specially handled; integer loads 513f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // support unaligned access. We support unaligned FP loads by loading to 514f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // integer registers first, then moving to the destination FP register. 515f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (load_rep.representation()) { 516f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kFloat32: { 517f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand temp = g.TempRegister(); 518f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch EmitLoad(this, opcode, &temp, base, index); 519f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Emit(kArmVmovF32U32, g.DefineAsRegister(node), temp); 520f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return; 521f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 522f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kFloat64: { 523f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // TODO(arm): use vld1.8 for this when NEON is available. 524f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Compute the address of the least-significant half of the FP value. 525f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // We assume that the base node is unlikely to be an encodable immediate 526f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // or the result of a shift operation, so only consider the addressing 527f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // mode that should be used for the index node. 528f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionCode add_opcode = kArmAdd; 529f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand inputs[3]; 530f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs[0] = g.UseRegister(base); 531f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 532f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch size_t input_count; 533f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (TryMatchImmediateOrShift(this, &add_opcode, index, &input_count, 534f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch &inputs[1])) { 535f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // input_count has been set by TryMatchImmediateOrShift(), so increment 536f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // it to account for the base register in inputs[0]. 537f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch input_count++; 538f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 539f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch add_opcode |= AddressingModeField::encode(kMode_Operand2_R); 540f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs[1] = g.UseRegister(index); 541f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch input_count = 2; // Base register and index. 542f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 543f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 544f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand addr = g.TempRegister(); 545f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Emit(add_opcode, 1, &addr, input_count, inputs); 546f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 547f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Load both halves and move to an FP register. 548f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand fp_lo = g.TempRegister(); 549f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand fp_hi = g.TempRegister(); 55013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch opcode |= AddressingModeField::encode(kMode_Offset_RI); 551f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Emit(opcode, fp_lo, addr, g.TempImmediate(0)); 552f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Emit(opcode, fp_hi, addr, g.TempImmediate(4)); 553f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Emit(kArmVmovF64U32U32, g.DefineAsRegister(node), fp_lo, fp_hi); 554f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return; 555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 556f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch default: 557f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // All other cases should support unaligned accesses. 558f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 559f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return; 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 563f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitUnalignedStore(Node* node) { 564f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ArmOperandGenerator g(this); 565f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* base = node->InputAt(0); 566f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* index = node->InputAt(1); 567f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* value = node->InputAt(2); 568f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 569f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand inputs[4]; 570f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch size_t input_count = 0; 571f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 572f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UnalignedStoreRepresentation store_rep = 573f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UnalignedStoreRepresentationOf(node->op()); 574f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 575f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Only floating point stores need to be specially handled; integer stores 576f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // support unaligned access. We support unaligned FP stores by moving the 577f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // value to integer registers first, then storing to the destination address. 578f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (store_rep) { 579f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kFloat32: { 580f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs[input_count++] = g.TempRegister(); 581f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Emit(kArmVmovU32F32, inputs[0], g.UseRegister(value)); 582f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs[input_count++] = g.UseRegister(base); 583f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch EmitStore(this, kArmStr, input_count, inputs, index); 584f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return; 585f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 586f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kFloat64: { 587f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // TODO(arm): use vst1.8 for this when NEON is available. 588f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Store a 64-bit floating point value using two 32-bit integer stores. 589f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Computing the store address here would require three live temporary 590f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // registers (fp<63:32>, fp<31:0>, address), so compute base + 4 after 591f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // storing the least-significant half of the value. 592f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 593f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // First, move the 64-bit FP value into two temporary integer registers. 594f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand fp[] = {g.TempRegister(), g.TempRegister()}; 595f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs[input_count++] = g.UseRegister(value); 596f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Emit(kArmVmovU32U32F64, arraysize(fp), fp, input_count, 597f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs); 598f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 599f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Store the least-significant half. 600f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs[0] = fp[0]; // Low 32-bits of FP value. 601f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs[input_count++] = g.UseRegister(base); // First store base address. 602f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch EmitStore(this, kArmStr, input_count, inputs, index); 603f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 604f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Store the most-significant half. 605f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand base4 = g.TempRegister(); 606f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Emit(kArmAdd | AddressingModeField::encode(kMode_Operand2_I), base4, 607f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch g.UseRegister(base), g.TempImmediate(4)); // Compute base + 4. 608f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs[0] = fp[1]; // High 32-bits of FP value. 609f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs[1] = base4; // Second store base + 4 address. 610f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch EmitStore(this, kArmStr, input_count, inputs, index); 611f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return; 612f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 613f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch default: 614f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // All other cases should support unaligned accesses. 615f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 616f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return; 617f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 618f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 620958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitCheckedLoad(Node* node) { 621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); 622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ArmOperandGenerator g(this); 623958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* const buffer = node->InputAt(0); 624958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* const offset = node->InputAt(1); 625958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* const length = node->InputAt(2); 626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArchOpcode opcode = kArchNop; 627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (load_rep.representation()) { 628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord8: 629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; 630958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord16: 632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16; 633958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord32: 635958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = kCheckedLoadWord32; 636958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat32: 638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = kCheckedLoadFloat32; 639958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat64: 641958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = kCheckedLoadFloat64; 642958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 643109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kBit: // Fall through. 644f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kTaggedSigned: // Fall through. 645f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kTaggedPointer: // Fall through. 646109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kTagged: // Fall through. 647109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kWord64: // Fall through. 648109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kSimd128: // Fall through. 649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kNone: 650958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); 651958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 652958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand offset_operand = g.UseRegister(offset); 654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand length_operand = g.CanBeImmediate(length, kArmCmp) 655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? g.UseImmediate(length) 656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : g.UseRegister(length); 657958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), 658958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.DefineAsRegister(node), offset_operand, length_operand, 659958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(buffer), offset_operand); 660958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 661958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 662958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 663958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitCheckedStore(Node* node) { 664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineRepresentation rep = CheckedStoreRepresentationOf(node->op()); 665958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ArmOperandGenerator g(this); 666958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* const buffer = node->InputAt(0); 667958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* const offset = node->InputAt(1); 668958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* const length = node->InputAt(2); 669958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* const value = node->InputAt(3); 670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArchOpcode opcode = kArchNop; 671958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (rep) { 672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord8: 673958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = kCheckedStoreWord8; 674958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord16: 676958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = kCheckedStoreWord16; 677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord32: 679958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = kCheckedStoreWord32; 680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat32: 682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = kCheckedStoreFloat32; 683958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat64: 685958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = kCheckedStoreFloat64; 686958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 687109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kBit: // Fall through. 688f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kTaggedSigned: // Fall through. 689f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kTaggedPointer: // Fall through. 690109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kTagged: // Fall through. 691109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kWord64: // Fall through. 692109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kSimd128: // Fall through. 693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kNone: 694958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); 695958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 696958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand offset_operand = g.UseRegister(offset); 698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand length_operand = g.CanBeImmediate(length, kArmCmp) 699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? g.UseImmediate(length) 700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : g.UseRegister(length); 701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), g.NoOutput(), 702958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier offset_operand, length_operand, g.UseRegister(value), 703958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(buffer), offset_operand); 704958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 705958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 706958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 707958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace { 708958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 709958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid EmitBic(InstructionSelector* selector, Node* node, Node* left, 710958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* right) { 711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArmOperandGenerator g(selector); 712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionCode opcode = kArmBic; 713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand value_operand; 714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand shift_operand; 715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryMatchShift(selector, &opcode, right, &value_operand, &shift_operand)) { 716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch selector->Emit(opcode, g.DefineAsRegister(node), g.UseRegister(left), 717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value_operand, shift_operand); 718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch selector->Emit(opcode | AddressingModeField::encode(kMode_Operand2_R), 721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.DefineAsRegister(node), g.UseRegister(left), 722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.UseRegister(right)); 723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 726958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid EmitUbfx(InstructionSelector* selector, Node* node, Node* left, 727958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t lsb, uint32_t width) { 728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_LE(1u, width); 729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_LE(width, 32u - lsb); 730958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ArmOperandGenerator g(selector); 731958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier selector->Emit(kArmUbfx, g.DefineAsRegister(node), g.UseRegister(left), 732958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.TempImmediate(lsb), g.TempImmediate(width)); 733958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 734958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 735958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace 736958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 737958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord32And(Node* node) { 739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArmOperandGenerator g(this); 740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Int32BinopMatcher m(node); 741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (m.left().IsWord32Xor() && CanCover(node, m.left().node())) { 742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Int32BinopMatcher mleft(m.left().node()); 743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mleft.right().Is(-1)) { 744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitBic(this, node, m.right().node(), mleft.left().node()); 745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (m.right().IsWord32Xor() && CanCover(node, m.right().node())) { 749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Int32BinopMatcher mright(m.right().node()); 750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mright.right().Is(-1)) { 751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmitBic(this, node, m.left().node(), mright.left().node()); 752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 755958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (m.right().HasValue()) { 756958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t const value = m.right().Value(); 757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t width = base::bits::CountPopulation32(value); 758109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch uint32_t leading_zeros = base::bits::CountLeadingZeros32(value); 759109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 760109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Try to merge SHR operations on the left hand input into this AND. 761109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (m.left().IsWord32Shr()) { 762109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Int32BinopMatcher mshr(m.left().node()); 763109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (mshr.right().HasValue()) { 764109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch uint32_t const shift = mshr.right().Value(); 765109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 766109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (((shift == 8) || (shift == 16) || (shift == 24)) && 767109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ((value == 0xff) || (value == 0xffff))) { 768109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Merge SHR into AND by emitting a UXTB or UXTH instruction with a 769109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // bytewise rotation. 770109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Emit((value == 0xff) ? kArmUxtb : kArmUxth, 771109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch g.DefineAsRegister(m.node()), g.UseRegister(mshr.left().node()), 772109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch g.TempImmediate(mshr.right().Value())); 773109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return; 774109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else if (IsSupported(ARMv7) && (width != 0) && 775109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ((leading_zeros + width) == 32)) { 776109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Merge Shr into And by emitting a UBFX instruction. 777109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(0u, base::bits::CountTrailingZeros32(value)); 778109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if ((1 <= shift) && (shift <= 31)) { 779109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // UBFX cannot extract bits past the register size, however since 780109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // shifting the original value would have introduced some zeros we 781109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // can still use UBFX with a smaller mask and the remaining bits 782109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // will be zeros. 783109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch EmitUbfx(this, node, mshr.left().node(), shift, 784109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch std::min(width, 32 - shift)); 785109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return; 786109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 789109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else if (value == 0xffff) { 790109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Emit UXTH for this AND. We don't bother testing for UXTB, as it's no 791109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // better than AND 0xff for this operation. 792109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Emit(kArmUxth, g.DefineAsRegister(m.node()), 793109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch g.UseRegister(m.left().node()), g.TempImmediate(0)); 794109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return; 795958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 796958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (g.CanBeImmediate(~value)) { 797109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Emit BIC for this AND by inverting the immediate value first. 798958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kArmBic | AddressingModeField::encode(kMode_Operand2_I), 799958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.DefineAsRegister(node), g.UseRegister(m.left().node()), 800958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.TempImmediate(~value)); 801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 803109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!g.CanBeImmediate(value) && IsSupported(ARMv7)) { 804109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // If value has 9 to 23 contiguous set bits, and has the lsb set, we can 805109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // replace this AND with UBFX. Other contiguous bit patterns have already 806109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // been handled by BIC or will be handled by AND. 807109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if ((width != 0) && ((leading_zeros + width) == 32) && 808109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch (9 <= leading_zeros) && (leading_zeros <= 23)) { 809109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(0u, base::bits::CountTrailingZeros32(value)); 810109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch EmitUbfx(this, node, m.left().node(), 0, width); 811109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return; 812109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 813109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 814958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier width = 32 - width; 815109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch leading_zeros = base::bits::CountLeadingZeros32(~value); 816958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t lsb = base::bits::CountTrailingZeros32(~value); 817109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if ((leading_zeros + width + lsb) == 32) { 818109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // This AND can be replaced with BFC. 819958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kArmBfc, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()), 820958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.TempImmediate(lsb), g.TempImmediate(width)); 821958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 823958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitBinop(this, node, kArmAnd, kArmAnd); 826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord32Or(Node* node) { 830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitBinop(this, node, kArmOrr, kArmOrr); 831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord32Xor(Node* node) { 835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArmOperandGenerator g(this); 836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Int32BinopMatcher m(node); 837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (m.right().Is(-1)) { 838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionCode opcode = kArmMvn; 839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand value_operand; 840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand shift_operand; 841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryMatchShift(this, &opcode, m.left().node(), &value_operand, 842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &shift_operand)) { 843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(opcode, g.DefineAsRegister(node), value_operand, shift_operand); 844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(opcode | AddressingModeField::encode(kMode_Operand2_R), 847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.DefineAsRegister(node), g.UseRegister(m.left().node())); 848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitBinop(this, node, kArmEor, kArmEor); 851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace { 855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename TryMatchShift> 857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitShift(InstructionSelector* selector, Node* node, 858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TryMatchShift try_match_shift, FlagsContinuation* cont) { 859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArmOperandGenerator g(selector); 860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionCode opcode = kArmMov; 861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand inputs[4]; 862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t input_count = 2; 863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand outputs[2]; 864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t output_count = 0; 865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(try_match_shift(selector, &opcode, node, &inputs[0], &inputs[1])); 867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cont->IsBranch()) { 869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inputs[input_count++] = g.Label(cont->true_block()); 870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inputs[input_count++] = g.Label(cont->false_block()); 871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outputs[output_count++] = g.DefineAsRegister(node); 874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cont->IsSet()) { 875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outputs[output_count++] = g.DefineAsRegister(cont->result()); 876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(0u, input_count); 879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(0u, output_count); 880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_GE(arraysize(inputs), input_count); 881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_GE(arraysize(outputs), output_count); 882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NE(kMode_None, AddressingModeField::decode(opcode)); 883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch opcode = cont->Encode(opcode); 8853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (cont->IsDeoptimize()) { 8863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, 887f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cont->reason(), cont->frame_state()); 8883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 8893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch selector->Emit(opcode, output_count, outputs, input_count, inputs); 8903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <typename TryMatchShift> 895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitShift(InstructionSelector* selector, Node* node, 896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TryMatchShift try_match_shift) { 897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlagsContinuation cont; 898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitShift(selector, node, try_match_shift, &cont); 899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace 902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord32Shl(Node* node) { 905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitShift(this, node, TryMatchLSL); 906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord32Shr(Node* node) { 910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArmOperandGenerator g(this); 911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Int32BinopMatcher m(node); 912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsSupported(ARMv7) && m.left().IsWord32And() && 913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch m.right().IsInRange(0, 31)) { 914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t lsb = m.right().Value(); 915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Int32BinopMatcher mleft(m.left().node()); 916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mleft.right().HasValue()) { 917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t value = (mleft.right().Value() >> lsb) << lsb; 918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t width = base::bits::CountPopulation32(value); 919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t msb = base::bits::CountLeadingZeros32(value); 920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (msb + width + lsb == 32) { 921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(lsb, base::bits::CountTrailingZeros32(value)); 922958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return EmitUbfx(this, node, mleft.left().node(), lsb, width); 923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitShift(this, node, TryMatchLSR); 927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord32Sar(Node* node) { 931958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ArmOperandGenerator g(this); 932958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32BinopMatcher m(node); 933958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (CanCover(m.node(), m.left().node()) && m.left().IsWord32Shl()) { 934958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32BinopMatcher mleft(m.left().node()); 935109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (m.right().HasValue() && mleft.right().HasValue()) { 936109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch uint32_t sar = m.right().Value(); 937109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch uint32_t shl = mleft.right().Value(); 938109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if ((sar == shl) && (sar == 16)) { 939109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Emit(kArmSxth, g.DefineAsRegister(node), 940109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch g.UseRegister(mleft.left().node()), g.TempImmediate(0)); 941109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return; 942109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else if ((sar == shl) && (sar == 24)) { 943109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Emit(kArmSxtb, g.DefineAsRegister(node), 944109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch g.UseRegister(mleft.left().node()), g.TempImmediate(0)); 945109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return; 946109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else if (IsSupported(ARMv7) && (sar >= shl)) { 947109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Emit(kArmSbfx, g.DefineAsRegister(node), 948109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch g.UseRegister(mleft.left().node()), g.TempImmediate(sar - shl), 949109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch g.TempImmediate(32 - sar)); 950109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return; 951109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 952958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 953958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitShift(this, node, TryMatchASR); 955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid InstructionSelector::VisitInt32PairAdd(Node* node) { 9583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ArmOperandGenerator g(this); 9593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 960c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* projection1 = NodeProperties::FindProjection(node, 1); 961c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (projection1) { 962c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // We use UseUniqueRegister here to avoid register sharing with the output 963c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // registers. 964c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InstructionOperand inputs[] = { 965c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), 966c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; 967c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 968c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InstructionOperand outputs[] = { 969c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.DefineAsRegister(node), 970c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; 971c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 972c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Emit(kArmAddPair, 2, outputs, 4, inputs); 973c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 974c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // The high word of the result is not used, so we emit the standard 32 bit 975c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // instruction. 976c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Emit(kArmAdd | AddressingModeField::encode(kMode_Operand2_R), 977c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0)), 978c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.UseRegister(node->InputAt(2))); 979c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 9803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 9813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 9823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid InstructionSelector::VisitInt32PairSub(Node* node) { 9833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ArmOperandGenerator g(this); 9843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 985c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* projection1 = NodeProperties::FindProjection(node, 1); 986c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (projection1) { 987c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // We use UseUniqueRegister here to avoid register sharing with the output 988c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // register. 989c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InstructionOperand inputs[] = { 990c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), 991c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; 9923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 993c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InstructionOperand outputs[] = { 994c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.DefineAsRegister(node), 995c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; 9963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 997c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Emit(kArmSubPair, 2, outputs, 4, inputs); 998c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 999c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // The high word of the result is not used, so we emit the standard 32 bit 1000c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // instruction. 1001c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Emit(kArmSub | AddressingModeField::encode(kMode_Operand2_R), 1002c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0)), 1003c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.UseRegister(node->InputAt(2))); 1004c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 10053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 10063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 10073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid InstructionSelector::VisitInt32PairMul(Node* node) { 10083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ArmOperandGenerator g(this); 1009c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* projection1 = NodeProperties::FindProjection(node, 1); 1010c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (projection1) { 1011c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InstructionOperand inputs[] = {g.UseUniqueRegister(node->InputAt(0)), 1012c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.UseUniqueRegister(node->InputAt(1)), 1013c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.UseUniqueRegister(node->InputAt(2)), 1014c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.UseUniqueRegister(node->InputAt(3))}; 1015c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1016c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InstructionOperand outputs[] = { 1017c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.DefineAsRegister(node), 1018c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; 1019c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1020c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Emit(kArmMulPair, 2, outputs, 4, inputs); 10213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 1022c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // The high word of the result is not used, so we emit the standard 32 bit 1023c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // instruction. 1024c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Emit(kArmMul | AddressingModeField::encode(kMode_Operand2_R), 1025c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0)), 1026c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.UseRegister(node->InputAt(2))); 10273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 10293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1030c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochnamespace { 1031c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// Shared routine for multiple shift operations. 1032c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid VisitWord32PairShift(InstructionSelector* selector, InstructionCode opcode, 1033c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* node) { 1034c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ArmOperandGenerator g(selector); 1035c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // We use g.UseUniqueRegister here to guarantee that there is 1036c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // no register aliasing of input registers with output registers. 10373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Int32Matcher m(node->InputAt(2)); 10383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch InstructionOperand shift_operand; 10393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (m.HasValue()) { 10403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch shift_operand = g.UseImmediate(m.node()); 10413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 10423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch shift_operand = g.UseUniqueRegister(m.node()); 10433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1045c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InstructionOperand inputs[] = {g.UseUniqueRegister(node->InputAt(0)), 10463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch g.UseUniqueRegister(node->InputAt(1)), 10473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch shift_operand}; 10483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1049c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Node* projection1 = NodeProperties::FindProjection(node, 1); 10503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1051c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InstructionOperand outputs[2]; 1052c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InstructionOperand temps[1]; 1053c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t output_count = 0; 1054c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t temp_count = 0; 10553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1056c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch outputs[output_count++] = g.DefineAsRegister(node); 1057c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (projection1) { 1058c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch outputs[output_count++] = g.DefineAsRegister(projection1); 10593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 1060c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch temps[temp_count++] = g.TempRegister(); 10613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1063c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch selector->Emit(opcode, output_count, outputs, 3, inputs, temp_count, temps); 1064c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 1065c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} // namespace 1066c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid InstructionSelector::VisitWord32PairShl(Node* node) { 1067c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch VisitWord32PairShift(this, kArmLslPair, node); 1068c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 10693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1070c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid InstructionSelector::VisitWord32PairShr(Node* node) { 1071c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch VisitWord32PairShift(this, kArmLsrPair, node); 1072c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 10733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1074c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid InstructionSelector::VisitWord32PairSar(Node* node) { 1075c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch VisitWord32PairShift(this, kArmAsrPair, node); 10763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord32Ror(Node* node) { 1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitShift(this, node, TryMatchROR); 1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitWord32Clz(Node* node) { 1084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmClz, node); 1085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitWord32Ctz(Node* node) { UNREACHABLE(); } 1089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1091109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InstructionSelector::VisitWord32ReverseBits(Node* node) { 1092109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(IsSupported(ARMv7)); 1093109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch VisitRR(this, kArmRbit, node); 1094109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1095109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1096f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitWord64ReverseBytes(Node* node) { UNREACHABLE(); } 1097f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1098f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitWord32ReverseBytes(Node* node) { UNREACHABLE(); } 1099109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitWord32Popcnt(Node* node) { UNREACHABLE(); } 1101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt32Add(Node* node) { 1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArmOperandGenerator g(this); 1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Int32BinopMatcher m(node); 1106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (CanCover(node, m.left().node())) { 1107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (m.left().opcode()) { 1108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32Mul: { 1109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32BinopMatcher mleft(m.left().node()); 1110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kArmMla, g.DefineAsRegister(node), 1111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(mleft.left().node()), 1112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(mleft.right().node()), 1113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(m.right().node())); 1114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32MulHigh: { 1117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32BinopMatcher mleft(m.left().node()); 1118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kArmSmmla, g.DefineAsRegister(node), 1119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(mleft.left().node()), 1120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(mleft.right().node()), 1121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(m.right().node())); 1122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32And: { 1125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32BinopMatcher mleft(m.left().node()); 1126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (mleft.right().Is(0xff)) { 1127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kArmUxtab, g.DefineAsRegister(node), 1128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(m.right().node()), 1129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(mleft.left().node()), g.TempImmediate(0)); 1130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (mleft.right().Is(0xffff)) { 1132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kArmUxtah, g.DefineAsRegister(node), 1133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(m.right().node()), 1134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(mleft.left().node()), g.TempImmediate(0)); 1135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32Sar: { 1139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32BinopMatcher mleft(m.left().node()); 1140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (CanCover(mleft.node(), mleft.left().node()) && 1141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mleft.left().IsWord32Shl()) { 1142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32BinopMatcher mleftleft(mleft.left().node()); 1143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (mleft.right().Is(24) && mleftleft.right().Is(24)) { 1144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kArmSxtab, g.DefineAsRegister(node), 1145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(m.right().node()), 1146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(mleftleft.left().node()), g.TempImmediate(0)); 1147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (mleft.right().Is(16) && mleftleft.right().Is(16)) { 1149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kArmSxtah, g.DefineAsRegister(node), 1150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(m.right().node()), 1151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(mleftleft.left().node()), g.TempImmediate(0)); 1152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: 1157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (CanCover(node, m.right().node())) { 1161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (m.right().opcode()) { 1162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32Mul: { 1163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32BinopMatcher mright(m.right().node()); 1164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kArmMla, g.DefineAsRegister(node), 1165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(mright.left().node()), 1166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(mright.right().node()), 1167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(m.left().node())); 1168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32MulHigh: { 1171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32BinopMatcher mright(m.right().node()); 1172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kArmSmmla, g.DefineAsRegister(node), 1173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(mright.left().node()), 1174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(mright.right().node()), 1175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(m.left().node())); 1176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32And: { 1179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32BinopMatcher mright(m.right().node()); 1180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (mright.right().Is(0xff)) { 1181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kArmUxtab, g.DefineAsRegister(node), 1182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(m.left().node()), 1183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(mright.left().node()), g.TempImmediate(0)); 1184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (mright.right().Is(0xffff)) { 1186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kArmUxtah, g.DefineAsRegister(node), 1187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(m.left().node()), 1188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(mright.left().node()), g.TempImmediate(0)); 1189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32Sar: { 1193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32BinopMatcher mright(m.right().node()); 1194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (CanCover(mright.node(), mright.left().node()) && 1195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mright.left().IsWord32Shl()) { 1196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32BinopMatcher mrightleft(mright.left().node()); 1197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (mright.right().Is(24) && mrightleft.right().Is(24)) { 1198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kArmSxtab, g.DefineAsRegister(node), 1199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(m.left().node()), 1200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(mrightleft.left().node()), g.TempImmediate(0)); 1201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (mright.right().Is(16) && mrightleft.right().Is(16)) { 1203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kArmSxtah, g.DefineAsRegister(node), 1204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(m.left().node()), 1205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(mrightleft.left().node()), g.TempImmediate(0)); 1206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: 1211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitBinop(this, node, kArmAdd, kArmAdd); 1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt32Sub(Node* node) { 1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArmOperandGenerator g(this); 1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Int32BinopMatcher m(node); 122113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (IsSupported(ARMv7) && m.right().IsInt32Mul() && 1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CanCover(node, m.right().node())) { 1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Int32BinopMatcher mright(m.right().node()); 1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(kArmMls, g.DefineAsRegister(node), g.UseRegister(mright.left().node()), 1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.UseRegister(mright.right().node()), g.UseRegister(m.left().node())); 1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitBinop(this, node, kArmSub, kArmRsb); 1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace { 1232f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1233f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid EmitInt32MulWithOverflow(InstructionSelector* selector, Node* node, 1234f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FlagsContinuation* cont) { 1235f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ArmOperandGenerator g(selector); 1236f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Int32BinopMatcher m(node); 1237f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand result_operand = g.DefineAsRegister(node); 1238f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand temp_operand = g.TempRegister(); 1239f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand outputs[] = {result_operand, temp_operand}; 1240f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand inputs[] = {g.UseRegister(m.left().node()), 1241f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch g.UseRegister(m.right().node())}; 1242f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch selector->Emit(kArmSmull, 2, outputs, 2, inputs); 1243f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // result operand needs shift operator. 1245f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand shift_31 = g.UseImmediate(31); 1246f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionCode opcode = cont->Encode(kArmCmp) | 1247f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AddressingModeField::encode(kMode_Operand2_R_ASR_I); 1248f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (cont->IsBranch()) { 1249f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch selector->Emit(opcode, g.NoOutput(), temp_operand, result_operand, shift_31, 1250f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch g.Label(cont->true_block()), g.Label(cont->false_block())); 1251f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (cont->IsDeoptimize()) { 1252f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand in[] = {temp_operand, result_operand, shift_31}; 1253f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch selector->EmitDeoptimize(opcode, 0, nullptr, 3, in, cont->reason(), 1254f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cont->frame_state()); 1255f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 1256f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(cont->IsSet()); 1257f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch selector->Emit(opcode, g.DefineAsRegister(cont->result()), temp_operand, 1258f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch result_operand, shift_31); 1259f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1260f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 1261f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1262f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} // namespace 1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt32Mul(Node* node) { 1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArmOperandGenerator g(this); 1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Int32BinopMatcher m(node); 1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (m.right().HasValue() && m.right().Value() > 0) { 1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t value = m.right().Value(); 1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (base::bits::IsPowerOfTwo32(value - 1)) { 1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(kArmAdd | AddressingModeField::encode(kMode_Operand2_R_LSL_I), 1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.DefineAsRegister(node), g.UseRegister(m.left().node()), 1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.UseRegister(m.left().node()), 1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.TempImmediate(WhichPowerOf2(value - 1))); 1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (value < kMaxInt && base::bits::IsPowerOfTwo32(value + 1)) { 1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(kArmRsb | AddressingModeField::encode(kMode_Operand2_R_LSL_I), 1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.DefineAsRegister(node), g.UseRegister(m.left().node()), 1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.UseRegister(m.left().node()), 1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.TempImmediate(WhichPowerOf2(value + 1))); 1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRRR(this, kArmMul, node); 1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32MulHigh(Node* node) { 1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRRR(this, kArmSmmul, node); 1290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32MulHigh(Node* node) { 1294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ArmOperandGenerator g(this); 1295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand outputs[] = {g.TempRegister(), g.DefineAsRegister(node)}; 1296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0)), 1297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseRegister(node->InputAt(1))}; 1298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kArmUmull, arraysize(outputs), outputs, arraysize(inputs), inputs); 1299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt32Div(Node* node) { 1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitDiv(this, node, kArmSdiv, kArmVcvtF64S32, kArmVcvtS32F64); 1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32Div(Node* node) { 1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitDiv(this, node, kArmUdiv, kArmVcvtF64U32, kArmVcvtU32F64); 1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt32Mod(Node* node) { 1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitMod(this, node, kArmSdiv, kArmVcvtF64S32, kArmVcvtS32F64); 1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32Mod(Node* node) { 1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitMod(this, node, kArmUdiv, kArmVcvtF64U32, kArmVcvtU32F64); 1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { 1323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVcvtF64F32, node); 1324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1327109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InstructionSelector::VisitRoundInt32ToFloat32(Node* node) { 1328109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch VisitRR(this, kArmVcvtF32S32, node); 1329109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1330109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1331109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1332109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InstructionSelector::VisitRoundUint32ToFloat32(Node* node) { 1333109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch VisitRR(this, kArmVcvtF32U32, node); 1334109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1335109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1336109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { 1338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVcvtF64S32, node); 1339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitChangeUint32ToFloat64(Node* node) { 1343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVcvtF64U32, node); 1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1347109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InstructionSelector::VisitTruncateFloat32ToInt32(Node* node) { 1348109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch VisitRR(this, kArmVcvtS32F32, node); 1349109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1350109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1351109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1352109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InstructionSelector::VisitTruncateFloat32ToUint32(Node* node) { 1353109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch VisitRR(this, kArmVcvtU32F32, node); 1354109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1355109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1356109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitChangeFloat64ToInt32(Node* node) { 1358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVcvtS32F64, node); 1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { 1363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVcvtU32F64, node); 1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 13663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid InstructionSelector::VisitTruncateFloat64ToUint32(Node* node) { 13673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch VisitRR(this, kArmVcvtU32F64, node); 13683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 1369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) { 1370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVcvtF32F64, node); 1371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1373bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitTruncateFloat64ToWord32(Node* node) { 1374bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch VisitRR(this, kArchTruncateDoubleToI, node); 1375bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 1376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1377bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitRoundFloat64ToInt32(Node* node) { 1378bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch VisitRR(this, kArmVcvtS32F64, node); 1379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitBitcastFloat32ToInt32(Node* node) { 138213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch VisitRR(this, kArmVmovU32F32, node); 1383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitBitcastInt32ToFloat32(Node* node) { 138613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch VisitRR(this, kArmVmovF32U32, node); 1387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Add(Node* node) { 1390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArmOperandGenerator g(this); 1391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Float32BinopMatcher m(node); 1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (m.left().IsFloat32Mul() && CanCover(node, m.left().node())) { 1393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Float32BinopMatcher mleft(m.left().node()); 1394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kArmVmlaF32, g.DefineSameAsFirst(node), 1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()), 1396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseRegister(mleft.right().node())); 1397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (m.right().IsFloat32Mul() && CanCover(node, m.right().node())) { 1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Float32BinopMatcher mright(m.right().node()); 1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kArmVmlaF32, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()), 1402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseRegister(mright.left().node()), 1403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseRegister(mright.right().node())); 1404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 1405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRRR(this, kArmVaddF32, node); 1407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitFloat64Add(Node* node) { 1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArmOperandGenerator g(this); 1412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Float64BinopMatcher m(node); 1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (m.left().IsFloat64Mul() && CanCover(node, m.left().node())) { 1414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Float64BinopMatcher mleft(m.left().node()); 1415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(kArmVmlaF64, g.DefineSameAsFirst(node), 1416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()), 1417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.UseRegister(mleft.right().node())); 1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (m.right().IsFloat64Mul() && CanCover(node, m.right().node())) { 1421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Float64BinopMatcher mright(m.right().node()); 1422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(kArmVmlaF64, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()), 1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.UseRegister(mright.left().node()), 1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.UseRegister(mright.right().node())); 1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRRR(this, kArmVaddF64, node); 1428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Sub(Node* node) { 1431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArmOperandGenerator g(this); 1432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Float32BinopMatcher m(node); 1433f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (m.right().IsFloat32Mul() && CanCover(node, m.right().node())) { 1434f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Float32BinopMatcher mright(m.right().node()); 1435f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Emit(kArmVmlsF32, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()), 1436f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch g.UseRegister(mright.left().node()), 1437f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch g.UseRegister(mright.right().node())); 1438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 1439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1440f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitRRR(this, kArmVsubF32, node); 1441bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitFloat64Sub(Node* node) { 1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArmOperandGenerator g(this); 1445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Float64BinopMatcher m(node); 1446f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (m.right().IsFloat64Mul() && CanCover(node, m.right().node())) { 1447f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Float64BinopMatcher mright(m.right().node()); 1448f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Emit(kArmVmlsF64, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()), 1449f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch g.UseRegister(mright.left().node()), 1450f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch g.UseRegister(mright.right().node())); 1451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1453f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitRRR(this, kArmVsubF64, node); 1454bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 1455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Mul(Node* node) { 1457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRRR(this, kArmVmulF32, node); 1458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitFloat64Mul(Node* node) { 1462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRRR(this, kArmVmulF64, node); 1463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Div(Node* node) { 1467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRRR(this, kArmVdivF32, node); 1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitFloat64Div(Node* node) { 1472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRRR(this, kArmVdivF64, node); 1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitFloat64Mod(Node* node) { 1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArmOperandGenerator g(this); 1478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(kArmVmodF64, g.DefineAsFixed(node, d0), g.UseFixed(node->InputAt(0), d0), 1479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.UseFixed(node->InputAt(1), d1))->MarkAsCall(); 1480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1482bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitFloat32Max(Node* node) { 1483bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch VisitRRR(this, kArmFloat32Max, node); 1484bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1486bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitFloat64Max(Node* node) { 1487bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch VisitRRR(this, kArmFloat64Max, node); 1488bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 1489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 149013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid InstructionSelector::VisitFloat64SilenceNaN(Node* node) { 149113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch VisitRR(this, kArmFloat64SilenceNaN, node); 149213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 149313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 1494bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitFloat32Min(Node* node) { 1495bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch VisitRRR(this, kArmFloat32Min, node); 1496bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 1497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1498bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitFloat64Min(Node* node) { 1499bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch VisitRRR(this, kArmFloat64Min, node); 1500bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 1501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Abs(Node* node) { 1503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVabsF32, node); 1504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64Abs(Node* node) { 1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVabsF64, node); 1509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Sqrt(Node* node) { 1512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVsqrtF32, node); 1513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitFloat64Sqrt(Node* node) { 1517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVsqrtF64, node); 1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32RoundDown(Node* node) { 1522f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(CpuFeatures::IsSupported(ARMv8)); 1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVrintmF32, node); 1524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1525958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1526958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64RoundDown(Node* node) { 1528f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(CpuFeatures::IsSupported(ARMv8)); 1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVrintmF64, node); 1530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32RoundUp(Node* node) { 1534f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(CpuFeatures::IsSupported(ARMv8)); 1535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVrintpF32, node); 1536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64RoundUp(Node* node) { 1540f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(CpuFeatures::IsSupported(ARMv8)); 1541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVrintpF64, node); 1542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32RoundTruncate(Node* node) { 1546f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(CpuFeatures::IsSupported(ARMv8)); 1547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVrintzF32, node); 1548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1550958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1551958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64RoundTruncate(Node* node) { 1552f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(CpuFeatures::IsSupported(ARMv8)); 1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVrintzF64, node); 1554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1556958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { 1558f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(CpuFeatures::IsSupported(ARMv8)); 1559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVrintaF64, node); 1560958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1561958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1562958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32RoundTiesEven(Node* node) { 1564f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(CpuFeatures::IsSupported(ARMv8)); 1565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVrintnF32, node); 1566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64RoundTiesEven(Node* node) { 1570f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(CpuFeatures::IsSupported(ARMv8)); 1571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVrintnF64, node); 1572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 157413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid InstructionSelector::VisitFloat32Neg(Node* node) { 157513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch VisitRR(this, kArmVnegF32, node); 157613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 157713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 157813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid InstructionSelector::VisitFloat64Neg(Node* node) { 157913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch VisitRR(this, kArmVnegF64, node); 158013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 158113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 158213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid InstructionSelector::VisitFloat64Ieee754Binop(Node* node, 158313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InstructionCode opcode) { 158413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ArmOperandGenerator g(this); 158513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Emit(opcode, g.DefineAsFixed(node, d0), g.UseFixed(node->InputAt(0), d0), 158613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch g.UseFixed(node->InputAt(1), d1)) 158713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ->MarkAsCall(); 158813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 158913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 159013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid InstructionSelector::VisitFloat64Ieee754Unop(Node* node, 159113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InstructionCode opcode) { 159213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ArmOperandGenerator g(this); 159313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Emit(opcode, g.DefineAsFixed(node, d0), g.UseFixed(node->InputAt(0), d0)) 159413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ->MarkAsCall(); 159513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::EmitPrepareArguments( 1598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor, 1599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* node) { 1600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArmOperandGenerator g(this); 1601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Prepare for C function call. 1603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (descriptor->IsCFunctionCall()) { 1604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kArchPrepareCallCFunction | 1605f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MiscField::encode(static_cast<int>(descriptor->ParameterCount())), 1606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 0, nullptr, 0, nullptr); 1607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Poke any stack arguments. 1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (size_t n = 0; n < arguments->size(); ++n) { 1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PushParameter input = (*arguments)[n]; 1611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (input.node()) { 1612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int slot = static_cast<int>(n); 1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kArmPoke | MiscField::encode(slot), g.NoOutput(), 1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseRegister(input.node())); 1615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Push any stack arguments. 1619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (PushParameter input : base::Reversed(*arguments)) { 1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Skip any alignment holes in pushed nodes. 1621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (input.node() == nullptr) continue; 1622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kArmPush, g.NoOutput(), g.UseRegister(input.node())); 1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool InstructionSelector::IsTailCallAddressImmediate() { return false; } 1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 16303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochint InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; } 1631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1632958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace { 1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Shared routine for multiple compare operations. 1635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitCompare(InstructionSelector* selector, InstructionCode opcode, 1636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand left, InstructionOperand right, 1637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FlagsContinuation* cont) { 1638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArmOperandGenerator g(selector); 1639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode = cont->Encode(opcode); 1640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (cont->IsBranch()) { 1641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->Emit(opcode, g.NoOutput(), left, right, 1642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.Label(cont->true_block()), g.Label(cont->false_block())); 16433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else if (cont->IsDeoptimize()) { 1644f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->reason(), 16453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->frame_state()); 1646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(cont->IsSet()); 1648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); 1649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Shared routine for multiple float32 compare operations. 1654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitFloat32Compare(InstructionSelector* selector, Node* node, 1655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FlagsContinuation* cont) { 1656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArmOperandGenerator g(selector); 1657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Float32BinopMatcher m(node); 1658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (m.right().Is(0.0f)) { 1659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitCompare(selector, kArmVcmpF32, g.UseRegister(m.left().node()), 1660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseImmediate(m.right().node()), cont); 1661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (m.left().Is(0.0f)) { 1662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cont->Commute(); 1663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitCompare(selector, kArmVcmpF32, g.UseRegister(m.right().node()), 1664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseImmediate(m.left().node()), cont); 1665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitCompare(selector, kArmVcmpF32, g.UseRegister(m.left().node()), 1667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseRegister(m.right().node()), cont); 1668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Shared routine for multiple float64 compare operations. 1673958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitFloat64Compare(InstructionSelector* selector, Node* node, 1674958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FlagsContinuation* cont) { 1675958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ArmOperandGenerator g(selector); 1676958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Float64BinopMatcher m(node); 1677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (m.right().Is(0.0)) { 1678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitCompare(selector, kArmVcmpF64, g.UseRegister(m.left().node()), 1679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseImmediate(m.right().node()), cont); 1680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (m.left().Is(0.0)) { 1681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cont->Commute(); 1682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitCompare(selector, kArmVcmpF64, g.UseRegister(m.right().node()), 1683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseImmediate(m.left().node()), cont); 1684958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitCompare(selector, kArmVcmpF64, g.UseRegister(m.left().node()), 1686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseRegister(m.right().node()), cont); 1687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1690f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Check whether we can convert: 1691f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ((a <op> b) cmp 0), b.<cond> 1692f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// to: 1693f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// (a <ops> b), b.<cond'> 1694f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// where <ops> is the flag setting version of <op>. 1695f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// We only generate conditions <cond'> that are a combination of the N 1696f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// and Z flags. This avoids the need to make this function dependent on 1697f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// the flag-setting operation. 1698f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool CanUseFlagSettingBinop(FlagsCondition cond) { 1699f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (cond) { 1700f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kEqual: 1701f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kNotEqual: 1702f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kSignedLessThan: 1703f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kSignedGreaterThanOrEqual: 1704f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kUnsignedLessThanOrEqual: // x <= 0 -> x == 0 1705f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kUnsignedGreaterThan: // x > 0 -> x != 0 1706f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 1707f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch default: 1708f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 1709f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1710f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 1711f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1712f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Map <cond> to <cond'> so that the following transformation is possible: 1713f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ((a <op> b) cmp 0), b.<cond> 1714f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// to: 1715f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// (a <ops> b), b.<cond'> 1716f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// where <ops> is the flag setting version of <op>. 1717f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochFlagsCondition MapForFlagSettingBinop(FlagsCondition cond) { 1718f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(CanUseFlagSettingBinop(cond)); 1719f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (cond) { 1720f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kEqual: 1721f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kNotEqual: 1722f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return cond; 1723f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kSignedLessThan: 1724f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return kNegative; 1725f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kSignedGreaterThanOrEqual: 1726f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return kPositiveOrZero; 1727f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kUnsignedLessThanOrEqual: // x <= 0 -> x == 0 1728f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return kEqual; 1729f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kUnsignedGreaterThan: // x > 0 -> x != 0 1730f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return kNotEqual; 1731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch default: 1732f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 1733f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return cond; 1734f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1735f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 1736f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1737f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Check if we can perform the transformation: 1738f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ((a <op> b) cmp 0), b.<cond> 1739f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// to: 1740f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// (a <ops> b), b.<cond'> 1741f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// where <ops> is the flag setting version of <op>, and if so, 1742f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// updates {node}, {opcode} and {cont} accordingly. 1743f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MaybeReplaceCmpZeroWithFlagSettingBinop(InstructionSelector* selector, 1744f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node** node, Node* binop, 1745f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionCode* opcode, 1746f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FlagsCondition cond, 1747f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FlagsContinuation* cont) { 1748f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionCode binop_opcode; 1749f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionCode no_output_opcode; 1750f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (binop->opcode()) { 1751f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kInt32Add: 1752f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch binop_opcode = kArmAdd; 1753f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch no_output_opcode = kArmCmn; 1754f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1755f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kWord32And: 1756f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch binop_opcode = kArmAnd; 1757f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch no_output_opcode = kArmTst; 1758f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1759f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kWord32Or: 1760f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch binop_opcode = kArmOrr; 1761f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch no_output_opcode = kArmOrr; 1762f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1763f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kWord32Xor: 1764f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch binop_opcode = kArmEor; 1765f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch no_output_opcode = kArmTeq; 1766f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1767f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch default: 1768f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 1769f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return; 1770f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1771f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (selector->CanCover(*node, binop)) { 1772f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // The comparison is the only user of {node}. 1773f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cont->Overwrite(MapForFlagSettingBinop(cond)); 1774f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch *opcode = no_output_opcode; 1775f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch *node = binop; 1776f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (selector->IsOnlyUserOfNodeInSameBlock(*node, binop)) { 1777f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // We can also handle the case where the {node} and the comparison are in 1778f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // the same basic block, and the comparison is the only user of {node} in 1779f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // this basic block ({node} has users in other basic blocks). 1780f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cont->Overwrite(MapForFlagSettingBinop(cond)); 1781f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch *opcode = binop_opcode; 1782f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch *node = binop; 1783f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1784f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1786958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Shared routine for multiple word compare operations. 1787958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitWordCompare(InstructionSelector* selector, Node* node, 1788958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionCode opcode, FlagsContinuation* cont) { 1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ArmOperandGenerator g(selector); 1790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Int32BinopMatcher m(node); 1791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand inputs[5]; 1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t input_count = 0; 1793f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand outputs[2]; 1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t output_count = 0; 1795f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool has_result = (opcode != kArmCmp) && (opcode != kArmCmn) && 1796f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (opcode != kArmTst) && (opcode != kArmTeq); 1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (TryMatchImmediateOrShift(selector, &opcode, m.right().node(), 1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &input_count, &inputs[1])) { 1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inputs[0] = g.UseRegister(m.left().node()); 1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch input_count++; 1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (TryMatchImmediateOrShift(selector, &opcode, m.left().node(), 1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &input_count, &inputs[1])) { 1804958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); 1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inputs[0] = g.UseRegister(m.right().node()); 1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch input_count++; 1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch opcode |= AddressingModeField::encode(kMode_Operand2_R); 1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inputs[input_count++] = g.UseRegister(m.left().node()); 1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inputs[input_count++] = g.UseRegister(m.right().node()); 1811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1813f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (has_result) { 1814f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (cont->IsDeoptimize()) { 1815f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // If we can deoptimize as a result of the binop, we need to make sure 1816f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // that the deopt inputs are not overwritten by the binop result. One way 1817f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // to achieve that is to declare the output register as same-as-first. 1818f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch outputs[output_count++] = g.DefineSameAsFirst(node); 1819f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 1820f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch outputs[output_count++] = g.DefineAsRegister(node); 1821f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1822f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1823f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cont->IsBranch()) { 1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inputs[input_count++] = g.Label(cont->true_block()); 1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inputs[input_count++] = g.Label(cont->false_block()); 18273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else if (cont->IsSet()) { 1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outputs[output_count++] = g.DefineAsRegister(cont->result()); 1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(0u, input_count); 1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_GE(arraysize(inputs), input_count); 1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_GE(arraysize(outputs), output_count); 1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 18353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch opcode = cont->Encode(opcode); 18363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (cont->IsDeoptimize()) { 18373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, 1838f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cont->reason(), cont->frame_state()); 18393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 18403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch selector->Emit(opcode, output_count, outputs, input_count, inputs); 18413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1845958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitWordCompare(InstructionSelector* selector, Node* node, 1846958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FlagsContinuation* cont) { 1847f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionCode opcode = kArmCmp; 1848f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Int32BinopMatcher m(node); 1849f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1850f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FlagsCondition cond = cont->condition(); 1851f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (m.right().Is(0) && (m.left().IsInt32Add() || m.left().IsWord32Or() || 1852f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch m.left().IsWord32And() || m.left().IsWord32Xor())) { 1853f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Emit flag setting instructions for comparisons against zero. 1854f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CanUseFlagSettingBinop(cond)) { 1855f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* binop = m.left().node(); 1856f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MaybeReplaceCmpZeroWithFlagSettingBinop(selector, &node, binop, &opcode, 1857f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cond, cont); 1858f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1859f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (m.left().Is(0) && 1860f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (m.right().IsInt32Add() || m.right().IsWord32Or() || 1861f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch m.right().IsWord32And() || m.right().IsWord32Xor())) { 1862f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Same as above, but we need to commute the condition before we 1863f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // continue with the rest of the checks. 1864f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cond = CommuteFlagsCondition(cond); 1865f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CanUseFlagSettingBinop(cond)) { 1866f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* binop = m.right().node(); 1867f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MaybeReplaceCmpZeroWithFlagSettingBinop(selector, &node, binop, &opcode, 1868f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cond, cont); 1869f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1870f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1871f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1872f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitWordCompare(selector, node, opcode, cont); 1873958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1874958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1875958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1876958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Shared routine for word comparisons against zero. 1877958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitWordCompareZero(InstructionSelector* selector, Node* user, 1878958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* value, FlagsContinuation* cont) { 1879c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Try to combine with comparisons against 0 by simply inverting the branch. 1880c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch while (value->opcode() == IrOpcode::kWord32Equal && 1881c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch selector->CanCover(user, value)) { 1882c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Int32BinopMatcher m(value); 1883c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!m.right().Is(0)) break; 1884c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1885c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch user = value; 1886c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch value = m.left().node(); 1887c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch cont->Negate(); 1888c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1889c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1890c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (selector->CanCover(user, value)) { 1891958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (value->opcode()) { 1892c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case IrOpcode::kWord32Equal: 1893958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cont->OverwriteAndNegateIfEqual(kEqual); 1894958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitWordCompare(selector, value, cont); 1895958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32LessThan: 1896958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cont->OverwriteAndNegateIfEqual(kSignedLessThan); 1897958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitWordCompare(selector, value, cont); 1898958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32LessThanOrEqual: 1899958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); 1900958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitWordCompare(selector, value, cont); 1901958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kUint32LessThan: 1902958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); 1903958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitWordCompare(selector, value, cont); 1904958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kUint32LessThanOrEqual: 1905958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); 1906958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitWordCompare(selector, value, cont); 1907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kFloat32Equal: 1908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cont->OverwriteAndNegateIfEqual(kEqual); 1909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return VisitFloat32Compare(selector, value, cont); 1910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kFloat32LessThan: 1911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cont->OverwriteAndNegateIfEqual(kFloatLessThan); 1912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return VisitFloat32Compare(selector, value, cont); 1913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kFloat32LessThanOrEqual: 1914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cont->OverwriteAndNegateIfEqual(kFloatLessThanOrEqual); 1915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return VisitFloat32Compare(selector, value, cont); 1916958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kFloat64Equal: 1917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cont->OverwriteAndNegateIfEqual(kEqual); 1918958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitFloat64Compare(selector, value, cont); 1919958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kFloat64LessThan: 1920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cont->OverwriteAndNegateIfEqual(kFloatLessThan); 1921958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitFloat64Compare(selector, value, cont); 1922958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kFloat64LessThanOrEqual: 1923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cont->OverwriteAndNegateIfEqual(kFloatLessThanOrEqual); 1924958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitFloat64Compare(selector, value, cont); 1925958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kProjection: 1926958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check if this is the overflow output projection of an 1927958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // <Operation>WithOverflow node. 1928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (ProjectionIndexOf(value->op()) == 1u) { 1929958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // We cannot combine the <Operation>WithOverflow with this branch 1930958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // unless the 0th projection (the use of the actual value of the 1931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // <Operation> is either nullptr, which means there's no use of the 1932958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // actual value, or was already defined, which means it is scheduled 1933958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // *AFTER* this branch). 1934958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* const node = value->InputAt(0); 1935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* const result = NodeProperties::FindProjection(node, 0); 1936958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!result || selector->IsDefined(result)) { 1937958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (node->opcode()) { 1938958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32AddWithOverflow: 1939958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cont->OverwriteAndNegateIfEqual(kOverflow); 1940958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitBinop(selector, node, kArmAdd, kArmAdd, cont); 1941958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32SubWithOverflow: 1942958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cont->OverwriteAndNegateIfEqual(kOverflow); 1943958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitBinop(selector, node, kArmSub, kArmRsb, cont); 1944f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kInt32MulWithOverflow: 1945f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // ARM doesn't set the overflow flag for multiplication, so we 1946f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // need to test on kNotEqual. Here is the code sequence used: 1947f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // smull resultlow, resulthigh, left, right 1948f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // cmp resulthigh, Operand(resultlow, ASR, 31) 1949f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cont->OverwriteAndNegateIfEqual(kNotEqual); 1950f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return EmitInt32MulWithOverflow(selector, node, cont); 1951958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: 1952958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1953958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1954958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1955958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1956958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1957958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32Add: 1958958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitWordCompare(selector, value, kArmCmn, cont); 1959958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32Sub: 1960958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitWordCompare(selector, value, kArmCmp, cont); 1961958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32And: 1962958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitWordCompare(selector, value, kArmTst, cont); 1963958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32Or: 1964958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitBinop(selector, value, kArmOrr, kArmOrr, cont); 1965958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32Xor: 1966958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitWordCompare(selector, value, kArmTeq, cont); 1967958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32Sar: 1968958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitShift(selector, value, TryMatchASR, cont); 1969958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32Shl: 1970958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitShift(selector, value, TryMatchLSL, cont); 1971958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32Shr: 1972958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitShift(selector, value, TryMatchLSR, cont); 1973958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32Ror: 1974958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitShift(selector, value, TryMatchROR, cont); 1975958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: 1976958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1977958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1980f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (user->opcode() == IrOpcode::kWord32Equal) { 1981f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return VisitWordCompare(selector, user, cont); 1982f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1983f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1984958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Continuation could not be combined with a compare, emit compare against 0. 1985958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ArmOperandGenerator g(selector); 1986958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionCode const opcode = 1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cont->Encode(kArmTst) | AddressingModeField::encode(kMode_Operand2_R); 1988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand const value_operand = g.UseRegister(value); 1989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cont->IsBranch()) { 1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->Emit(opcode, g.NoOutput(), value_operand, value_operand, 1991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.Label(cont->true_block()), g.Label(cont->false_block())); 19923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else if (cont->IsDeoptimize()) { 19933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch selector->EmitDeoptimize(opcode, g.NoOutput(), value_operand, value_operand, 1994f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cont->reason(), cont->frame_state()); 1995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 19963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(cont->IsSet()); 1997958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand, 1998958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier value_operand); 1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2002958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace 2003958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2004958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, 2005958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BasicBlock* fbranch) { 2006958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FlagsContinuation cont(kNotEqual, tbranch, fbranch); 2007958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitWordCompareZero(this, branch, branch->InputAt(0), &cont); 2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 20103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid InstructionSelector::VisitDeoptimizeIf(Node* node) { 2011f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FlagsContinuation cont = FlagsContinuation::ForDeoptimize( 2012f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch kNotEqual, DeoptimizeReasonOf(node->op()), node->InputAt(1)); 20133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch VisitWordCompareZero(this, node, node->InputAt(0), &cont); 20143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 20153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 20163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid InstructionSelector::VisitDeoptimizeUnless(Node* node) { 2017f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FlagsContinuation cont = FlagsContinuation::ForDeoptimize( 2018f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch kEqual, DeoptimizeReasonOf(node->op()), node->InputAt(1)); 20193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch VisitWordCompareZero(this, node, node->InputAt(0), &cont); 20203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 2021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { 2023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArmOperandGenerator g(this); 2024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); 2025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Emit either ArchTableSwitch or ArchLookupSwitch. 2027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t table_space_cost = 4 + sw.value_range; 2028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t table_time_cost = 3; 2029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t lookup_space_cost = 3 + 2 * sw.case_count; 2030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t lookup_time_cost = sw.case_count; 2031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (sw.case_count > 0 && 2032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch table_space_cost + 3 * table_time_cost <= 2033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lookup_space_cost + 3 * lookup_time_cost && 2034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sw.min_value > std::numeric_limits<int32_t>::min()) { 2035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand index_operand = value_operand; 2036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (sw.min_value) { 2037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch index_operand = g.TempRegister(); 2038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kArmSub | AddressingModeField::encode(kMode_Operand2_I), 2039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch index_operand, value_operand, g.TempImmediate(sw.min_value)); 2040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Generate a table lookup. 2042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return EmitTableSwitch(sw, index_operand); 2043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Generate a sequence of conditional jumps. 2046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return EmitLookupSwitch(sw, value_operand); 2047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2050958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitWord32Equal(Node* const node) { 20513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); 2052958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32BinopMatcher m(node); 2053958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (m.right().Is(0)) { 2054958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitWordCompareZero(this, m.node(), m.left().node(), &cont); 2055958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2056958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitWordCompare(this, node, &cont); 2057958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2058958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2059958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2060958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32LessThan(Node* node) { 20613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node); 2062958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitWordCompare(this, node, &cont); 2063958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2064958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2065958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2066958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32LessThanOrEqual(Node* node) { 20673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = 20683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation::ForSet(kSignedLessThanOrEqual, node); 2069958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitWordCompare(this, node, &cont); 2070958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2071958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2072958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2073958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32LessThan(Node* node) { 20743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node); 2075958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitWordCompare(this, node, &cont); 2076958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2077958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2078958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2079958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32LessThanOrEqual(Node* node) { 20803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = 20813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node); 2082958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitWordCompare(this, node, &cont); 2083958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2084958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2085958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2086958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32AddWithOverflow(Node* node) { 2087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (Node* ovf = NodeProperties::FindProjection(node, 1)) { 20883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); 2089958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitBinop(this, node, kArmAdd, kArmAdd, &cont); 2090958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2091958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FlagsContinuation cont; 2092958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitBinop(this, node, kArmAdd, kArmAdd, &cont); 2093958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2094958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2095958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32SubWithOverflow(Node* node) { 2096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (Node* ovf = NodeProperties::FindProjection(node, 1)) { 20973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); 2098958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitBinop(this, node, kArmSub, kArmRsb, &cont); 2099958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FlagsContinuation cont; 2101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitBinop(this, node, kArmSub, kArmRsb, &cont); 2102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2104f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitInt32MulWithOverflow(Node* node) { 2105f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (Node* ovf = NodeProperties::FindProjection(node, 1)) { 2106f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // ARM doesn't set the overflow flag for multiplication, so we need to test 2107f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // on kNotEqual. Here is the code sequence used: 2108f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // smull resultlow, resulthigh, left, right 2109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // cmp resulthigh, Operand(resultlow, ASR, 31) 2110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kNotEqual, ovf); 2111f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return EmitInt32MulWithOverflow(this, node, &cont); 2112f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2113f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FlagsContinuation cont; 2114f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch EmitInt32MulWithOverflow(this, node, &cont); 2115f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 2116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Equal(Node* node) { 21183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); 2119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitFloat32Compare(this, node, &cont); 2120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32LessThan(Node* node) { 21243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kFloatLessThan, node); 2125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitFloat32Compare(this, node, &cont); 2126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) { 21303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = 21313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation::ForSet(kFloatLessThanOrEqual, node); 2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitFloat32Compare(this, node, &cont); 2133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64Equal(Node* node) { 21373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); 2138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitFloat64Compare(this, node, &cont); 2139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64LessThan(Node* node) { 21433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kFloatLessThan, node); 2144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitFloat64Compare(this, node, &cont); 2145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { 21493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = 21503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation::ForSet(kFloatLessThanOrEqual, node); 2151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitFloat64Compare(this, node, &cont); 2152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) { 2156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVmovLowU32F64, node); 2157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) { 2161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitRR(this, kArmVmovHighU32F64, node); 2162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64InsertLowWord32(Node* node) { 2166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArmOperandGenerator g(this); 2167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* left = node->InputAt(0); 2168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* right = node->InputAt(1); 2169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (left->opcode() == IrOpcode::kFloat64InsertHighWord32 && 2170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CanCover(node, left)) { 2171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left = left->InputAt(1); 2172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kArmVmovF64U32U32, g.DefineAsRegister(node), g.UseRegister(right), 2173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseRegister(left)); 2174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 2175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kArmVmovLowF64U32, g.DefineSameAsFirst(node), g.UseRegister(left), 2177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseRegister(right)); 2178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64InsertHighWord32(Node* node) { 2182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArmOperandGenerator g(this); 2183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* left = node->InputAt(0); 2184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* right = node->InputAt(1); 2185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (left->opcode() == IrOpcode::kFloat64InsertLowWord32 && 2186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CanCover(node, left)) { 2187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch left = left->InputAt(1); 2188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kArmVmovF64U32U32, g.DefineAsRegister(node), g.UseRegister(left), 2189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseRegister(right)); 2190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 2191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kArmVmovHighF64U32, g.DefineSameAsFirst(node), g.UseRegister(left), 2193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseRegister(right)); 2194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2196bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitAtomicLoad(Node* node) { 2197bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch LoadRepresentation load_rep = LoadRepresentationOf(node->op()); 2198bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ArmOperandGenerator g(this); 2199bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* base = node->InputAt(0); 2200bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* index = node->InputAt(1); 2201bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ArchOpcode opcode = kArchNop; 2202bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch switch (load_rep.representation()) { 2203bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case MachineRepresentation::kWord8: 2204bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch opcode = load_rep.IsSigned() ? kAtomicLoadInt8 : kAtomicLoadUint8; 2205bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 2206bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case MachineRepresentation::kWord16: 2207bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch opcode = load_rep.IsSigned() ? kAtomicLoadInt16 : kAtomicLoadUint16; 2208bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 2209bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case MachineRepresentation::kWord32: 2210bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch opcode = kAtomicLoadWord32; 2211bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 2212bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch default: 2213bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UNREACHABLE(); 2214bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return; 2215bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2216bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), 2217bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index)); 2218bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 2219bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 2220bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitAtomicStore(Node* node) { 2221bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch MachineRepresentation rep = AtomicStoreRepresentationOf(node->op()); 2222bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ArmOperandGenerator g(this); 2223bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* base = node->InputAt(0); 2224bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* index = node->InputAt(1); 2225bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* value = node->InputAt(2); 2226bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ArchOpcode opcode = kArchNop; 2227bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch switch (rep) { 2228bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case MachineRepresentation::kWord8: 2229bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch opcode = kAtomicStoreWord8; 2230bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 2231bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case MachineRepresentation::kWord16: 2232bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch opcode = kAtomicStoreWord16; 2233bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 2234bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case MachineRepresentation::kWord32: 2235bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch opcode = kAtomicStoreWord32; 2236bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 2237bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch default: 2238bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UNREACHABLE(); 2239bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return; 2240bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2241bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 2242bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch AddressingMode addressing_mode = kMode_Offset_RR; 2243bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch InstructionOperand inputs[4]; 2244bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch size_t input_count = 0; 2245bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch inputs[input_count++] = g.UseUniqueRegister(base); 2246bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch inputs[input_count++] = g.UseUniqueRegister(index); 2247bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch inputs[input_count++] = g.UseUniqueRegister(value); 2248bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch InstructionCode code = opcode | AddressingModeField::encode(addressing_mode); 2249bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Emit(code, 0, nullptr, input_count, inputs); 2250bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 2251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// static 2253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierMachineOperatorBuilder::Flags 2254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierInstructionSelector::SupportedMachineOperatorFlags() { 225513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch MachineOperatorBuilder::Flags flags; 225613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (CpuFeatures::IsSupported(SUDIV)) { 225713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // The sdiv and udiv instructions correctly return 0 if the divisor is 0, 225813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // but the fall-back implementation does not. 225913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch flags |= MachineOperatorBuilder::kInt32DivIsSafe | 226013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch MachineOperatorBuilder::kUint32DivIsSafe; 226113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 2262109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (CpuFeatures::IsSupported(ARMv7)) { 2263109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch flags |= MachineOperatorBuilder::kWord32ReverseBits; 2264109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 2265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (CpuFeatures::IsSupported(ARMv8)) { 2266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch flags |= MachineOperatorBuilder::kFloat32RoundDown | 2267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineOperatorBuilder::kFloat64RoundDown | 2268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineOperatorBuilder::kFloat32RoundUp | 2269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineOperatorBuilder::kFloat64RoundUp | 2270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineOperatorBuilder::kFloat32RoundTruncate | 2271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MachineOperatorBuilder::kFloat64RoundTruncate | 2272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineOperatorBuilder::kFloat64RoundTiesAway | 2273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineOperatorBuilder::kFloat32RoundTiesEven | 2274f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MachineOperatorBuilder::kFloat64RoundTiesEven; 2275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return flags; 2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 227913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// static 228013e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochMachineOperatorBuilder::AlignmentRequirements 228113e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochInstructionSelector::AlignmentRequirements() { 2282f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Vector<MachineType> req_aligned = Vector<MachineType>::New(2); 2283f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch req_aligned[0] = MachineType::Float32(); 2284f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch req_aligned[1] = MachineType::Float64(); 228513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return MachineOperatorBuilder::AlignmentRequirements:: 2286f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch SomeUnalignedAccessUnsupported(req_aligned, req_aligned); 228713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 228813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 2289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace compiler 2290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace internal 2291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace v8 2292