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 <algorithm> 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/base/adapters.h" 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/instruction-selector-impl.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/node-matchers.h" 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/node-properties.h" 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler { 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Adds X64-specific methods for generating operands. 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass X64OperandGenerator final : public OperandGenerator { 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit X64OperandGenerator(InstructionSelector* selector) 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : OperandGenerator(selector) {} 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool CanBeImmediate(Node* node) { 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (node->opcode()) { 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kInt32Constant: 25bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case IrOpcode::kRelocatableInt32Constant: 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt64Constant: { 28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const int64_t value = OpParameter<int64_t>(node); 29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return value == static_cast<int64_t>(static_cast<int32_t>(value)); 30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kNumberConstant: { 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const double value = OpParameter<double>(node); 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return bit_cast<int64_t>(value) == 0; 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 40f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int32_t GetImmediateIntegerValue(Node* node) { 41f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(CanBeImmediate(node)); 42f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (node->opcode() == IrOpcode::kInt32Constant) { 43f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return OpParameter<int32_t>(node); 44f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_EQ(IrOpcode::kInt64Constant, node->opcode()); 46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return static_cast<int32_t>(OpParameter<int64_t>(node)); 47f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 48f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 49bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch bool CanBeMemoryOperand(InstructionCode opcode, Node* node, Node* input, 50bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch int effect_level) { 513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (input->opcode() != IrOpcode::kLoad || 523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch !selector()->CanCover(node, input)) { 533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return false; 543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 55bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (effect_level != selector()->GetEffectLevel(input)) { 56bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return false; 57bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch MachineRepresentation rep = 593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch LoadRepresentationOf(input->op()).representation(); 603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch switch (opcode) { 6162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case kX64Push: 623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX64Cmp: 633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX64Test: 64f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return rep == MachineRepresentation::kWord64 || IsAnyTagged(rep); 653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX64Cmp32: 663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX64Test32: 673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return rep == MachineRepresentation::kWord32; 683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX64Cmp16: 693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX64Test16: 703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return rep == MachineRepresentation::kWord16; 713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX64Cmp8: 723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX64Test8: 733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return rep == MachineRepresentation::kWord8; 743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch default: 753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return false; 783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 80958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddressingMode GenerateMemoryOperandInputs(Node* index, int scale_exponent, 81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* base, Node* displacement, 82f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DisplacementMode displacement_mode, 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand inputs[], 84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size_t* input_count) { 85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddressingMode mode = kMode_MRI; 8662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (base != nullptr && (index != nullptr || displacement != nullptr)) { 8762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (base->opcode() == IrOpcode::kInt32Constant && 8862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch OpParameter<int32_t>(base) == 0) { 8962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch base = nullptr; 9062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (base->opcode() == IrOpcode::kInt64Constant && 9162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch OpParameter<int64_t>(base) == 0) { 9262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch base = nullptr; 9362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 9462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (base != nullptr) { 96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inputs[(*input_count)++] = UseRegister(base); 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (index != nullptr) { 98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(scale_exponent >= 0 && scale_exponent <= 3); 99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inputs[(*input_count)++] = UseRegister(index); 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (displacement != nullptr) { 101f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs[(*input_count)++] = displacement_mode 102f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ? UseNegatedImmediate(displacement) 103f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch : UseImmediate(displacement); 104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const AddressingMode kMRnI_modes[] = {kMode_MR1I, kMode_MR2I, 105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier kMode_MR4I, kMode_MR8I}; 106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mode = kMRnI_modes[scale_exponent]; 107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const AddressingMode kMRn_modes[] = {kMode_MR1, kMode_MR2, 109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier kMode_MR4, kMode_MR8}; 110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mode = kMRn_modes[scale_exponent]; 111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (displacement == nullptr) { 114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mode = kMode_MR; 115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 116f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs[(*input_count)++] = displacement_mode == kNegativeDisplacement 117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ? UseNegatedImmediate(displacement) 118f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch : UseImmediate(displacement); 119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mode = kMode_MRI; 120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(scale_exponent >= 0 && scale_exponent <= 3); 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (displacement != nullptr) { 12562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (index == nullptr) { 12662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch inputs[(*input_count)++] = UseRegister(displacement); 12762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch mode = kMode_MR; 12862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 12962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch inputs[(*input_count)++] = UseRegister(index); 13062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch inputs[(*input_count)++] = displacement_mode == kNegativeDisplacement 13162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ? UseNegatedImmediate(displacement) 13262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : UseImmediate(displacement); 13362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static const AddressingMode kMnI_modes[] = {kMode_MRI, kMode_M2I, 13462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch kMode_M4I, kMode_M8I}; 13562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch mode = kMnI_modes[scale_exponent]; 13662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 13862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch inputs[(*input_count)++] = UseRegister(index); 139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static const AddressingMode kMn_modes[] = {kMode_MR, kMode_MR1, 140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier kMode_M4, kMode_M8}; 141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mode = kMn_modes[scale_exponent]; 142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (mode == kMode_MR1) { 143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // [%r1 + %r1*1] has a smaller encoding than [%r1*2+0] 144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inputs[(*input_count)++] = UseRegister(index); 145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return mode; 149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddressingMode GetEffectiveAddressMemoryOperand(Node* operand, 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand inputs[], 153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size_t* input_count) { 154f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (selector()->CanAddressRelativeToRootsRegister()) { 155f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch LoadMatcher<ExternalReferenceMatcher> m(operand); 156f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (m.index().HasValue() && m.object().HasValue()) { 157f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Address const kRootsRegisterValue = 158f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch kRootRegisterBias + 159f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch reinterpret_cast<Address>( 160f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch selector()->isolate()->heap()->roots_array_start()); 161f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ptrdiff_t const delta = 162f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m.index().Value() + 163f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch (m.object().Value().address() - kRootsRegisterValue); 164f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (is_int32(delta)) { 165f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch inputs[(*input_count)++] = TempImmediate(static_cast<int32_t>(delta)); 166f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return kMode_Root; 167f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 168f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 169f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BaseWithIndexAndDisplacement64Matcher m(operand, AddressOption::kAllowAll); 171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(m.matches()); 17262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (m.displacement() == nullptr || CanBeImmediate(m.displacement())) { 173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return GenerateMemoryOperandInputs( 174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch m.index(), m.scale(), m.base(), m.displacement(), 175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch m.displacement_mode(), inputs, input_count); 17662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (m.base() == nullptr && 17762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m.displacement_mode() == kPositiveDisplacement) { 17862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // The displacement cannot be an immediate, but we can use the 17962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // displacement as base instead and still benefit from addressing 18062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // modes for the scale. 18162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return GenerateMemoryOperandInputs(m.index(), m.scale(), m.displacement(), 18262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch nullptr, m.displacement_mode(), inputs, 18362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch input_count); 184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inputs[(*input_count)++] = UseRegister(operand->InputAt(0)); 186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inputs[(*input_count)++] = UseRegister(operand->InputAt(1)); 187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return kMode_MR1; 188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool CanBeBetterLeftOperand(Node* node) const { 192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return !selector()->IsLive(node); 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 196f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochnamespace { 197f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochArchOpcode GetLoadOpcode(LoadRepresentation load_rep) { 198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArchOpcode opcode = kArchNop; 199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (load_rep.representation()) { 200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat32: 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch opcode = kX64Movss; 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat64: 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch opcode = kX64Movsd; 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kBit: // Fall through. 207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord8: 208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode = load_rep.IsSigned() ? kX64Movsxbl : kX64Movzxbl; 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord16: 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode = load_rep.IsSigned() ? kX64Movsxwl : kX64Movzxwl; 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord32: 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch opcode = kX64Movl; 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 216f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kTaggedSigned: // Fall through. 217f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kTaggedPointer: // Fall through. 218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kTagged: // Fall through. 219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord64: 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch opcode = kX64Movq; 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 222109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kSimd128: // Fall through. 22362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kSimd1x4: // Fall through. 22462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kSimd1x8: // Fall through. 22562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kSimd1x16: // Fall through. 226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kNone: 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 228f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch break; 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 230f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return opcode; 231f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 232f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 23362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochArchOpcode GetStoreOpcode(StoreRepresentation store_rep) { 23462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch switch (store_rep.representation()) { 23562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kFloat32: 23662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return kX64Movss; 23762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch break; 23862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kFloat64: 23962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return kX64Movsd; 24062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch break; 24162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kBit: // Fall through. 24262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kWord8: 24362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return kX64Movb; 24462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch break; 24562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kWord16: 24662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return kX64Movw; 24762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch break; 24862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kWord32: 24962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return kX64Movl; 25062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch break; 25162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kTaggedSigned: // Fall through. 25262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kTaggedPointer: // Fall through. 25362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kTagged: // Fall through. 25462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kWord64: 25562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return kX64Movq; 25662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch break; 25762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kSimd128: // Fall through. 25862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kSimd1x4: // Fall through. 25962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kSimd1x8: // Fall through. 26062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kSimd1x16: // Fall through. 26162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kNone: 26262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 26362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return kArchNop; 26462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 26562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 26662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return kArchNop; 26762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 26862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 269f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} // namespace 270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 271f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid InstructionSelector::VisitLoad(Node* node) { 272f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch LoadRepresentation load_rep = LoadRepresentationOf(node->op()); 273f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch X64OperandGenerator g(this); 274f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 275f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ArchOpcode opcode = GetLoadOpcode(load_rep); 276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand outputs[1]; 277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier outputs[0] = g.DefineAsRegister(node); 278f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch InstructionOperand inputs[4]; 279f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch size_t input_count = 0; 280f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch AddressingMode mode = 281f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); 282f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch InstructionCode code = opcode | AddressingModeField::encode(mode); 28362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (node->opcode() == IrOpcode::kProtectedLoad) { 28462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch code |= MiscField::encode(X64MemoryProtection::kProtected); 28562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Add the source position as an input 28662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch inputs[input_count++] = g.UseImmediate(node->InputAt(2)); 28762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 288f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Emit(code, 1, outputs, input_count, inputs); 289f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 29162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InstructionSelector::VisitProtectedLoad(Node* node) { VisitLoad(node); } 29262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitStore(Node* node) { 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X64OperandGenerator g(this); 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* base = node->InputAt(0); 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* index = node->InputAt(1); 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* value = node->InputAt(2); 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StoreRepresentation store_rep = StoreRepresentationOf(node->op()); 300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); 301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (write_barrier_kind != kNoWriteBarrier) { 30362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(CanBeTaggedPointer(store_rep.representation())); 304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddressingMode addressing_mode; 305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand inputs[3]; 306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t input_count = 0; 307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inputs[input_count++] = g.UseUniqueRegister(base); 308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (g.CanBeImmediate(index)) { 309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inputs[input_count++] = g.UseImmediate(index); 310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addressing_mode = kMode_MRI; 311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inputs[input_count++] = g.UseUniqueRegister(index); 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addressing_mode = kMode_MR1; 314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inputs[input_count++] = g.UseUniqueRegister(value); 316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; 317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (write_barrier_kind) { 318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kNoWriteBarrier: 319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMapWriteBarrier: 322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch record_write_mode = RecordWriteMode::kValueIsMap; 323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kPointerWriteBarrier: 325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch record_write_mode = RecordWriteMode::kValueIsPointer; 326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kFullWriteBarrier: 328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch record_write_mode = RecordWriteMode::kValueIsAny; 329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; 332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t const temp_count = arraysize(temps); 333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionCode code = kArchStoreWithWriteBarrier; 334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch code |= AddressingModeField::encode(addressing_mode); 335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch code |= MiscField::encode(static_cast<int>(record_write_mode)); 336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); 337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 33862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ArchOpcode opcode = GetStoreOpcode(store_rep); 339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand inputs[4]; 340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t input_count = 0; 341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddressingMode addressing_mode = 342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); 343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionCode code = 344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode | AddressingModeField::encode(addressing_mode); 34562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if ((ElementSizeLog2Of(store_rep.representation()) < kPointerSizeLog2) && 34662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch (value->opcode() == IrOpcode::kTruncateInt64ToInt32) && 34762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CanCover(node, value)) { 34862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value = value->InputAt(0); 34962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand value_operand = 351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); 352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inputs[input_count++] = value_operand; 353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(code, 0, static_cast<InstructionOperand*>(nullptr), input_count, 354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inputs); 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 35862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InstructionSelector::VisitProtectedStore(Node* node) { 35962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch X64OperandGenerator g(this); 36062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* value = node->InputAt(2); 36162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* position = node->InputAt(3); 36262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 36362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch StoreRepresentation store_rep = StoreRepresentationOf(node->op()); 36462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 36562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ArchOpcode opcode = GetStoreOpcode(store_rep); 36662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstructionOperand inputs[5]; 36762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t input_count = 0; 36862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AddressingMode addressing_mode = 36962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); 37062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstructionCode code = opcode | AddressingModeField::encode(addressing_mode) | 37162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MiscField::encode(X64MemoryProtection::kProtected); 37262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstructionOperand value_operand = 37362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); 37462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch inputs[input_count++] = value_operand; 37562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch inputs[input_count++] = g.UseImmediate(position); 37662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Emit(code, 0, static_cast<InstructionOperand*>(nullptr), input_count, inputs); 37762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 37862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 379f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Architecture supports unaligned access, therefore VisitLoad is used instead 380f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitUnalignedLoad(Node* node) { UNREACHABLE(); } 381f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 382f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Architecture supports unaligned access, therefore VisitStore is used instead 383f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitUnalignedStore(Node* node) { UNREACHABLE(); } 384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitCheckedLoad(Node* node) { 386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); 387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier X64OperandGenerator g(this); 388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* const buffer = node->InputAt(0); 389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* const offset = node->InputAt(1); 390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* const length = node->InputAt(2); 391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArchOpcode opcode = kArchNop; 392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (load_rep.representation()) { 393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord8: 394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; 395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord16: 397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16; 398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord32: 400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = kCheckedLoadWord32; 401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord64: 403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode = kCheckedLoadWord64; 404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat32: 406958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = kCheckedLoadFloat32; 407958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat64: 409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = kCheckedLoadFloat64; 410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 411109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kBit: // Fall through. 412109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kSimd128: // Fall through. 41362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kSimd1x4: // Fall through. 41462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kSimd1x8: // Fall through. 41562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kSimd1x16: // Fall through. 416f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kTaggedSigned: // Fall through. 417f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kTaggedPointer: // Fall through. 418109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kTagged: // Fall through. 419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kNone: 420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); 421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) { 424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32Matcher mlength(length); 425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32BinopMatcher moffset(offset); 426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (mlength.HasValue() && moffset.right().HasValue() && 427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier moffset.right().Value() >= 0 && 428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mlength.Value() >= moffset.right().Value()) { 429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer), 430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(moffset.left().node()), 431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseImmediate(moffset.right().node()), g.UseImmediate(length)); 432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand length_operand = 436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); 437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer), 438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(offset), g.TempImmediate(0), length_operand); 439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitCheckedStore(Node* node) { 443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineRepresentation rep = CheckedStoreRepresentationOf(node->op()); 444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier X64OperandGenerator g(this); 445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* const buffer = node->InputAt(0); 446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* const offset = node->InputAt(1); 447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* const length = node->InputAt(2); 448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* const value = node->InputAt(3); 449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArchOpcode opcode = kArchNop; 450958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (rep) { 451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord8: 452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = kCheckedStoreWord8; 453958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord16: 455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = kCheckedStoreWord16; 456958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord32: 458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = kCheckedStoreWord32; 459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kWord64: 461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch opcode = kCheckedStoreWord64; 462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat32: 464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = kCheckedStoreFloat32; 465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat64: 467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = kCheckedStoreFloat64; 468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 469109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kBit: // Fall through. 470109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kSimd128: // Fall through. 47162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kSimd1x4: // Fall through. 47262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kSimd1x8: // Fall through. 47362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case MachineRepresentation::kSimd1x16: // Fall through. 474f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kTaggedSigned: // Fall through. 475f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kTaggedPointer: // Fall through. 476109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case MachineRepresentation::kTagged: // Fall through. 477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kNone: 478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); 479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand value_operand = 482958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); 483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) { 484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32Matcher mlength(length); 485958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32BinopMatcher moffset(offset); 486958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (mlength.HasValue() && moffset.right().HasValue() && 487958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier moffset.right().Value() >= 0 && 488958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier mlength.Value() >= moffset.right().Value()) { 489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(opcode, g.NoOutput(), g.UseRegister(buffer), 490958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(moffset.left().node()), 491958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseImmediate(moffset.right().node()), g.UseImmediate(length), 492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier value_operand); 493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand length_operand = 497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); 498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(opcode, g.NoOutput(), g.UseRegister(buffer), g.UseRegister(offset), 499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.TempImmediate(0), length_operand, value_operand); 500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shared routine for multiple binary operations. 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void VisitBinop(InstructionSelector* selector, Node* node, 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionCode opcode, FlagsContinuation* cont) { 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X64OperandGenerator g(selector); 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Int32BinopMatcher m(node); 508958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* left = m.left().node(); 509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* right = m.right().node(); 510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand inputs[4]; 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t input_count = 0; 512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand outputs[2]; 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t output_count = 0; 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(turbofan): match complex addressing modes. 516958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (left == right) { 517958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If both inputs refer to the same operand, enforce allocating a register 518958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // for both of them to ensure that we don't end up generating code like 519958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // this: 520958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // 521958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // mov rax, [rbp-0x10] 522958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // add rax, [rbp-0x10] 523958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // jo label 524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand const input = g.UseRegister(left); 525958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inputs[input_count++] = input; 526958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inputs[input_count++] = input; 527958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (g.CanBeImmediate(right)) { 528958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inputs[input_count++] = g.UseRegister(left); 529958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inputs[input_count++] = g.UseImmediate(right); 530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (node->op()->HasProperty(Operator::kCommutative) && 532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.CanBeBetterLeftOperand(right)) { 533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier std::swap(left, right); 534958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 535958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inputs[input_count++] = g.UseRegister(left); 536958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inputs[input_count++] = g.Use(right); 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cont->IsBranch()) { 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inputs[input_count++] = g.Label(cont->true_block()); 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inputs[input_count++] = g.Label(cont->false_block()); 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outputs[output_count++] = g.DefineSameAsFirst(node); 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cont->IsSet()) { 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch outputs[output_count++] = g.DefineAsRegister(cont->result()); 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(0u, input_count); 550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(0u, output_count); 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_GE(arraysize(inputs), input_count); 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_GE(arraysize(outputs), output_count); 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch opcode = cont->Encode(opcode); 5553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (cont->IsDeoptimize()) { 5563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, 55762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch cont->kind(), cont->reason(), cont->frame_state()); 5583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 5593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch selector->Emit(opcode, output_count, outputs, input_count, inputs); 5603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shared routine for multiple binary operations. 565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void VisitBinop(InstructionSelector* selector, Node* node, 566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionCode opcode) { 567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlagsContinuation cont; 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitBinop(selector, node, opcode, &cont); 569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord32And(Node* node) { 573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandGenerator g(this); 574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Uint32BinopMatcher m(node); 575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (m.right().Is(0xff)) { 576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kX64Movzxbl, g.DefineAsRegister(node), g.Use(m.left().node())); 577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (m.right().Is(0xffff)) { 578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kX64Movzxwl, g.DefineAsRegister(node), g.Use(m.left().node())); 579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitBinop(this, node, kX64And32); 581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord64And(Node* node) { 586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitBinop(this, node, kX64And); 587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord32Or(Node* node) { 591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitBinop(this, node, kX64Or32); 592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord64Or(Node* node) { 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitBinop(this, node, kX64Or); 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord32Xor(Node* node) { 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X64OperandGenerator g(this); 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Uint32BinopMatcher m(node); 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (m.right().Is(-1)) { 604958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kX64Not32, g.DefineSameAsFirst(node), g.UseRegister(m.left().node())); 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitBinop(this, node, kX64Xor32); 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord64Xor(Node* node) { 612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X64OperandGenerator g(this); 613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Uint64BinopMatcher m(node); 614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (m.right().Is(-1)) { 615958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kX64Not, g.DefineSameAsFirst(node), g.UseRegister(m.left().node())); 616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitBinop(this, node, kX64Xor); 618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace { 623958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shared routine for multiple 32-bit shift operations. 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(bmeurer): Merge this with VisitWord64Shift using template magic? 626958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitWord32Shift(InstructionSelector* selector, Node* node, 627958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ArchOpcode opcode) { 628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X64OperandGenerator g(selector); 629958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32BinopMatcher m(node); 630958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* left = m.left().node(); 631958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* right = m.right().node(); 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (g.CanBeImmediate(right)) { 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), 635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.UseImmediate(right)); 636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), 638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.UseFixed(right, rcx)); 639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shared routine for multiple 64-bit shift operations. 644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(bmeurer): Merge this with VisitWord32Shift using template magic? 645958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitWord64Shift(InstructionSelector* selector, Node* node, 646958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ArchOpcode opcode) { 647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X64OperandGenerator g(selector); 648958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int64BinopMatcher m(node); 649958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* left = m.left().node(); 650958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* right = m.right().node(); 651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (g.CanBeImmediate(right)) { 653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), 654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.UseImmediate(right)); 655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (m.right().IsWord64And()) { 657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Int64BinopMatcher mright(right); 658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mright.right().Is(0x3F)) { 659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch right = mright.left().node(); 660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), 663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.UseFixed(right, rcx)); 664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 667958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid EmitLea(InstructionSelector* selector, InstructionCode opcode, 668958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* result, Node* index, int scale, Node* base, 669f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* displacement, DisplacementMode displacement_mode) { 670958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier X64OperandGenerator g(selector); 671958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand inputs[4]; 673958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size_t input_count = 0; 674f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AddressingMode mode = 675f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch g.GenerateMemoryOperandInputs(index, scale, base, displacement, 676f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch displacement_mode, inputs, &input_count); 677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(0u, input_count); 679958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_GE(arraysize(inputs), input_count); 680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand outputs[1]; 682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier outputs[0] = g.DefineAsRegister(result); 683958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 684958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode = AddressingModeField::encode(mode) | opcode; 685958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 686958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier selector->Emit(opcode, 1, outputs, input_count, inputs); 687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 688958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 689958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace 690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord32Shl(Node* node) { 693958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32ScaleMatcher m(node, true); 694958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (m.matches()) { 695958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* index = node->InputAt(0); 696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* base = m.power_of_two_plus_one() ? index : nullptr; 697f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch EmitLea(this, kX64Lea32, node, index, m.scale(), base, nullptr, 698f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch kPositiveDisplacement); 699958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 700958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitWord32Shift(this, node, kX64Shl32); 702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord64Shl(Node* node) { 706958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier X64OperandGenerator g(this); 707f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Int64ScaleMatcher m(node, true); 708f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (m.matches()) { 709f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* index = node->InputAt(0); 710f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* base = m.power_of_two_plus_one() ? index : nullptr; 711f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch EmitLea(this, kX64Lea, node, index, m.scale(), base, nullptr, 712f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch kPositiveDisplacement); 713958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 714f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 715f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Int64BinopMatcher m(node); 716f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if ((m.left().IsChangeInt32ToInt64() || 717f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch m.left().IsChangeUint32ToUint64()) && 718f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch m.right().IsInRange(32, 63)) { 719f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // There's no need to sign/zero-extend to 64-bit if we shift out the upper 720f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // 32 bits anyway. 721f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Emit(kX64Shl, g.DefineSameAsFirst(node), 722f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch g.UseRegister(m.left().node()->InputAt(0)), 723f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch g.UseImmediate(m.right().node())); 724f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return; 725f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 726958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitWord64Shift(this, node, kX64Shl); 728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord32Shr(Node* node) { 732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitWord32Shift(this, node, kX64Shr32); 733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 735f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace { 736f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool TryMatchLoadWord64AndShiftRight(InstructionSelector* selector, Node* node, 737f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionCode opcode) { 738f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(IrOpcode::kWord64Sar == node->opcode() || 739f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch IrOpcode::kWord64Shr == node->opcode()); 740f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch X64OperandGenerator g(selector); 7413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Int64BinopMatcher m(node); 742f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (selector->CanCover(m.node(), m.left().node()) && m.left().IsLoad() && 7433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch m.right().Is(32)) { 7443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Just load and sign-extend the interesting 4 bytes instead. This happens, 7453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // for example, when we're loading and untagging SMIs. 746f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BaseWithIndexAndDisplacement64Matcher mleft(m.left().node(), 747f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AddressOption::kAllowAll); 7483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (mleft.matches() && (mleft.displacement() == nullptr || 7493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch g.CanBeImmediate(mleft.displacement()))) { 7503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch size_t input_count = 0; 7513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch InstructionOperand inputs[3]; 7523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AddressingMode mode = g.GetEffectiveAddressMemoryOperand( 7533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch m.left().node(), inputs, &input_count); 7543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (mleft.displacement() == nullptr) { 7553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Make sure that the addressing mode indicates the presence of an 7563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // immediate displacement. It seems that we never use M1 and M2, but we 7573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // handle them here anyways. 7583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch switch (mode) { 7593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kMode_MR: 7603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch mode = kMode_MRI; 7613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 7623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kMode_MR1: 7633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch mode = kMode_MR1I; 7643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 7653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kMode_MR2: 7663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch mode = kMode_MR2I; 7673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 7683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kMode_MR4: 7693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch mode = kMode_MR4I; 7703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 7713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kMode_MR8: 7723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch mode = kMode_MR8I; 7733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 7743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kMode_M1: 7753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch mode = kMode_M1I; 7763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 7773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kMode_M2: 7783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch mode = kMode_M2I; 7793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 7803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kMode_M4: 7813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch mode = kMode_M4I; 7823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 7833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kMode_M8: 7843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch mode = kMode_M8I; 7853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 7863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kMode_None: 7873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kMode_MRI: 7883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kMode_MR1I: 7893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kMode_MR2I: 7903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kMode_MR4I: 7913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kMode_MR8I: 7923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kMode_M1I: 7933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kMode_M2I: 7943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kMode_M4I: 7953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kMode_M8I: 796f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch case kMode_Root: 7973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch UNREACHABLE(); 7983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 7993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch inputs[input_count++] = ImmediateOperand(ImmediateOperand::INLINE, 4); 8003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 801f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int32_t displacement = g.GetImmediateIntegerValue(mleft.displacement()); 802f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch inputs[input_count - 1] = 803f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ImmediateOperand(ImmediateOperand::INLINE, displacement + 4); 8043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 8053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch InstructionOperand outputs[] = {g.DefineAsRegister(node)}; 806f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionCode code = opcode | AddressingModeField::encode(mode); 807f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch selector->Emit(code, 1, outputs, input_count, inputs); 808f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 809f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 810f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 811f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 812f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 813f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} // namespace 814f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 815f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitWord64Shr(Node* node) { 816f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (TryMatchLoadWord64AndShiftRight(this, node, kX64Movl)) return; 817f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitWord64Shift(this, node, kX64Shr); 818f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 819f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 820f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitWord32Sar(Node* node) { 821f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch X64OperandGenerator g(this); 822f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Int32BinopMatcher m(node); 823f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CanCover(m.node(), m.left().node()) && m.left().IsWord32Shl()) { 824f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Int32BinopMatcher mleft(m.left().node()); 825f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (mleft.right().Is(16) && m.right().Is(16)) { 826f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Emit(kX64Movsxwl, g.DefineAsRegister(node), g.Use(mleft.left().node())); 827f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return; 828f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (mleft.right().Is(24) && m.right().Is(24)) { 829f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Emit(kX64Movsxbl, g.DefineAsRegister(node), g.Use(mleft.left().node())); 8303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return; 8313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 8323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 833f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitWord32Shift(this, node, kX64Sar32); 834f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 835f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 836f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitWord64Sar(Node* node) { 837f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (TryMatchLoadWord64AndShiftRight(this, node, kX64Movsxlq)) return; 838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitWord64Shift(this, node, kX64Sar); 839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord32Ror(Node* node) { 843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitWord32Shift(this, node, kX64Ror32); 844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord64Ror(Node* node) { 848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitWord64Shift(this, node, kX64Ror); 849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 851109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InstructionSelector::VisitWord32ReverseBits(Node* node) { UNREACHABLE(); } 852109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 853109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 854109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InstructionSelector::VisitWord64ReverseBits(Node* node) { UNREACHABLE(); } 855109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 856f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitWord64ReverseBytes(Node* node) { UNREACHABLE(); } 857f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 858f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitWord32ReverseBytes(Node* node) { UNREACHABLE(); } 859109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt32Add(Node* node) { 861958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier X64OperandGenerator g(this); 862958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 863958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Try to match the Add to a leal pattern 864958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BaseWithIndexAndDisplacement32Matcher m(node); 865958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (m.matches() && 866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (m.displacement() == nullptr || g.CanBeImmediate(m.displacement()))) { 867958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier EmitLea(this, kX64Lea32, node, m.index(), m.scale(), m.base(), 868f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch m.displacement(), m.displacement_mode()); 869958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 870958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 871958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 872958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // No leal pattern match, use addl 873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitBinop(this, node, kX64Add32); 874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt64Add(Node* node) { 878f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch X64OperandGenerator g(this); 879f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 880f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Try to match the Add to a leaq pattern 881f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BaseWithIndexAndDisplacement64Matcher m(node); 882f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (m.matches() && 883f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (m.displacement() == nullptr || g.CanBeImmediate(m.displacement()))) { 884f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch EmitLea(this, kX64Lea, node, m.index(), m.scale(), m.base(), 885f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch m.displacement(), m.displacement_mode()); 886f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return; 887f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 888f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 889f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // No leal pattern match, use addq 890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitBinop(this, node, kX64Add); 891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitInt64AddWithOverflow(Node* node) { 895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (Node* ovf = NodeProperties::FindProjection(node, 1)) { 8963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); 8973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitBinop(this, node, kX64Add, &cont); 898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FlagsContinuation cont; 900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitBinop(this, node, kX64Add, &cont); 901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt32Sub(Node* node) { 905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X64OperandGenerator g(this); 906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Int32BinopMatcher m(node); 907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (m.left().Is(0)) { 908958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kX64Neg32, g.DefineSameAsFirst(node), g.UseRegister(m.right().node())); 909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 910958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (m.right().HasValue() && g.CanBeImmediate(m.right().node())) { 911958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Turn subtractions of constant values into immediate "leal" instructions 912958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // by negating the value. 913958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kX64Lea32 | AddressingModeField::encode(kMode_MRI), 914958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.DefineAsRegister(node), g.UseRegister(m.left().node()), 915958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.TempImmediate(-m.right().Value())); 916958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 917958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitBinop(this, node, kX64Sub32); 919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt64Sub(Node* node) { 924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X64OperandGenerator g(this); 925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Int64BinopMatcher m(node); 926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (m.left().Is(0)) { 927958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kX64Neg, g.DefineSameAsFirst(node), g.UseRegister(m.right().node())); 928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 929f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (m.right().HasValue() && g.CanBeImmediate(m.right().node())) { 930f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Turn subtractions of constant values into immediate "leaq" instructions 931f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // by negating the value. 932f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Emit(kX64Lea | AddressingModeField::encode(kMode_MRI), 933f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch g.DefineAsRegister(node), g.UseRegister(m.left().node()), 934f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch g.TempImmediate(-static_cast<int32_t>(m.right().Value()))); 935f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return; 936f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitBinop(this, node, kX64Sub); 938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitInt64SubWithOverflow(Node* node) { 943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (Node* ovf = NodeProperties::FindProjection(node, 1)) { 9443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); 945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return VisitBinop(this, node, kX64Sub, &cont); 946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FlagsContinuation cont; 948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitBinop(this, node, kX64Sub, &cont); 949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 952958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace { 953958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 954958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitMul(InstructionSelector* selector, Node* node, ArchOpcode opcode) { 955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X64OperandGenerator g(selector); 956958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32BinopMatcher m(node); 957958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* left = m.left().node(); 958958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* right = m.right().node(); 959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (g.CanBeImmediate(right)) { 960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch selector->Emit(opcode, g.DefineAsRegister(node), g.Use(left), 961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.UseImmediate(right)); 962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 963958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (g.CanBeBetterLeftOperand(right)) { 964958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier std::swap(left, right); 965958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), 967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.Use(right)); 968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 971958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitMulHigh(InstructionSelector* selector, Node* node, 972958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ArchOpcode opcode) { 973958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier X64OperandGenerator g(selector); 974958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* left = node->InputAt(0); 975958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* right = node->InputAt(1); 976958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (selector->IsLive(left) && !selector->IsLive(right)) { 977958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier std::swap(left, right); 978958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 979109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch InstructionOperand temps[] = {g.TempRegister(rax)}; 980958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(turbofan): We use UseUniqueRegister here to improve register 981958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // allocation. 982958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier selector->Emit(opcode, g.DefineAsFixed(node, rdx), g.UseFixed(left, rax), 983109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch g.UseUniqueRegister(right), arraysize(temps), temps); 984958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 985958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 986958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 987958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) { 988958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier X64OperandGenerator g(selector); 989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand temps[] = {g.TempRegister(rdx)}; 990958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier selector->Emit( 991958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier opcode, g.DefineAsFixed(node, rax), g.UseFixed(node->InputAt(0), rax), 992958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps); 993958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 994958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 995958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 996958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) { 997958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier X64OperandGenerator g(selector); 998109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch InstructionOperand temps[] = {g.TempRegister(rax)}; 999109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch selector->Emit( 1000109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch opcode, g.DefineAsFixed(node, rdx), g.UseFixed(node->InputAt(0), rax), 1001109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps); 1002958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1003958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1004958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace 1005958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1006958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt32Mul(Node* node) { 1008958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32ScaleMatcher m(node, true); 1009958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (m.matches()) { 1010958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* index = node->InputAt(0); 1011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* base = m.power_of_two_plus_one() ? index : nullptr; 1012f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch EmitLea(this, kX64Lea32, node, index, m.scale(), base, nullptr, 1013f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch kPositiveDisplacement); 1014958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1015958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitMul(this, node, kX64Imul32); 1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1019f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitInt32MulWithOverflow(Node* node) { 1020f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // TODO(mvstanton): Use Int32ScaleMatcher somehow. 1021f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (Node* ovf = NodeProperties::FindProjection(node, 1)) { 1022f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); 1023f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return VisitBinop(this, node, kX64Imul32, &cont); 1024f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1025f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FlagsContinuation cont; 1026f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitBinop(this, node, kX64Imul32, &cont); 1027f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt64Mul(Node* node) { 1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitMul(this, node, kX64Imul); 1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1033958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32MulHigh(Node* node) { 1034958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitMulHigh(this, node, kX64ImulHigh32); 1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt32Div(Node* node) { 1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitDiv(this, node, kX64Idiv32); 1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt64Div(Node* node) { 1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitDiv(this, node, kX64Idiv); 1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1048958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32Div(Node* node) { 1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitDiv(this, node, kX64Udiv32); 1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1053958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint64Div(Node* node) { 1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitDiv(this, node, kX64Udiv); 1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt32Mod(Node* node) { 1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitMod(this, node, kX64Idiv32); 1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt64Mod(Node* node) { 1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitMod(this, node, kX64Idiv); 1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1068958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32Mod(Node* node) { 1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitMod(this, node, kX64Udiv32); 1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1073958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint64Mod(Node* node) { 1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch VisitMod(this, node, kX64Udiv); 1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1078958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32MulHigh(Node* node) { 1079958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitMulHigh(this, node, kX64UmulHigh32); 1080958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1081958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) { 1083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandGenerator g(this); 1084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))}; 1085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand outputs[2]; 1086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t output_count = 0; 1087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch outputs[output_count++] = g.DefineAsRegister(node); 1088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* success_output = NodeProperties::FindProjection(node, 1); 1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (success_output) { 1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch outputs[output_count++] = g.DefineAsRegister(success_output); 1092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kSSEFloat32ToInt64, output_count, outputs, 1, inputs); 1095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) { 1099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandGenerator g(this); 1100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))}; 1101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand outputs[2]; 1102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t output_count = 0; 1103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch outputs[output_count++] = g.DefineAsRegister(node); 1104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* success_output = NodeProperties::FindProjection(node, 1); 1106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (success_output) { 1107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch outputs[output_count++] = g.DefineAsRegister(success_output); 1108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kSSEFloat64ToInt64, output_count, outputs, 1, inputs); 1111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitTryTruncateFloat32ToUint64(Node* node) { 1115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandGenerator g(this); 1116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))}; 1117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand outputs[2]; 1118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t output_count = 0; 1119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch outputs[output_count++] = g.DefineAsRegister(node); 1120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* success_output = NodeProperties::FindProjection(node, 1); 1122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (success_output) { 1123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch outputs[output_count++] = g.DefineAsRegister(success_output); 1124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kSSEFloat32ToUint64, output_count, outputs, 1, inputs); 1127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitTryTruncateFloat64ToUint64(Node* node) { 1131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandGenerator g(this); 1132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))}; 1133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand outputs[2]; 1134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t output_count = 0; 1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch outputs[output_count++] = g.DefineAsRegister(node); 1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* success_output = NodeProperties::FindProjection(node, 1); 1138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (success_output) { 1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch outputs[output_count++] = g.DefineAsRegister(success_output); 1140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kSSEFloat64ToUint64, output_count, outputs, 1, inputs); 1143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitChangeInt32ToInt64(Node* node) { 1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X64OperandGenerator g(this); 1148f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* const value = node->InputAt(0); 1149f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (value->opcode() == IrOpcode::kLoad && CanCover(node, value)) { 1150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LoadRepresentation load_rep = LoadRepresentationOf(value->op()); 1151f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MachineRepresentation rep = load_rep.representation(); 1152f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionCode opcode = kArchNop; 1153f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (rep) { 1154f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kBit: // Fall through. 1155f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kWord8: 1156f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch opcode = load_rep.IsSigned() ? kX64Movsxbq : kX64Movzxbq; 1157f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1158f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kWord16: 1159f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch opcode = load_rep.IsSigned() ? kX64Movsxwq : kX64Movzxwq; 1160f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1161f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kWord32: 1162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch opcode = load_rep.IsSigned() ? kX64Movsxlq : kX64Movl; 1163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch default: 1165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 1166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return; 1167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand outputs[] = {g.DefineAsRegister(node)}; 1169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch size_t input_count = 0; 1170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand inputs[3]; 1171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AddressingMode mode = g.GetEffectiveAddressMemoryOperand( 1172f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch node->InputAt(0), inputs, &input_count); 1173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch opcode |= AddressingModeField::encode(mode); 1174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Emit(opcode, 1, outputs, input_count, inputs); 1175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 1176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Emit(kX64Movsxlq, g.DefineAsRegister(node), g.Use(node->InputAt(0))); 1177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1180f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochnamespace { 1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1182f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool ZeroExtendsWord32ToWord64(Node* node) { 1183f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch switch (node->opcode()) { 1184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32And: 1185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32Or: 1186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32Xor: 1187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32Shl: 1188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32Shr: 1189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32Sar: 1190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32Ror: 1191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32Equal: 1192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32Add: 1193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32Sub: 1194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32Mul: 1195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32MulHigh: 1196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32Div: 1197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32LessThan: 1198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32LessThanOrEqual: 1199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32Mod: 1200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kUint32Div: 1201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kUint32LessThan: 1202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kUint32LessThanOrEqual: 1203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kUint32Mod: 1204f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch case IrOpcode::kUint32MulHigh: 1205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // These 32-bit operations implicitly zero-extend to 64-bit on x64, so the 1206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // zero-extension is a no-op. 1207f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return true; 1208f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch case IrOpcode::kProjection: { 1209f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* const value = node->InputAt(0); 1210f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch switch (value->opcode()) { 1211f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch case IrOpcode::kInt32AddWithOverflow: 1212f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch case IrOpcode::kInt32SubWithOverflow: 1213f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch case IrOpcode::kInt32MulWithOverflow: 1214f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return true; 1215f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch default: 1216f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return false; 1217f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1219c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case IrOpcode::kLoad: { 1220c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // The movzxbl/movsxbl/movzxwl/movsxwl operations implicitly zero-extend 1221c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // to 64-bit on x64, 1222c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // so the zero-extension is a no-op. 1223c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch LoadRepresentation load_rep = LoadRepresentationOf(node->op()); 1224c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch switch (load_rep.representation()) { 1225c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case MachineRepresentation::kWord8: 1226c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case MachineRepresentation::kWord16: 1227c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return true; 1228c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch default: 1229c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return false; 1230c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1231c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: 1233f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return false; 1234f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1235f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 1236f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1237f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} // namespace 1238f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1239f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid InstructionSelector::VisitChangeUint32ToUint64(Node* node) { 1240f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch X64OperandGenerator g(this); 1241f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Node* value = node->InputAt(0); 1242f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (ZeroExtendsWord32ToWord64(value)) { 1243f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // These 32-bit operations implicitly zero-extend to 64-bit on x64, so the 1244f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // zero-extension is a no-op. 1245f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return EmitIdentity(node); 1246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kX64Movl, g.DefineAsRegister(node), g.Use(value)); 1248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace { 1252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitRO(InstructionSelector* selector, Node* node, 1254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionCode opcode) { 1255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandGenerator g(selector); 1256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->Emit(opcode, g.DefineAsRegister(node), g.Use(node->InputAt(0))); 1257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitRR(InstructionSelector* selector, Node* node, 1261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionCode opcode) { 1262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandGenerator g(selector); 1263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->Emit(opcode, g.DefineAsRegister(node), 1264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseRegister(node->InputAt(0))); 1265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1267f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid VisitRRO(InstructionSelector* selector, Node* node, 1268f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionCode opcode) { 1269f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch X64OperandGenerator g(selector); 1270f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch selector->Emit(opcode, g.DefineSameAsFirst(node), 1271f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1))); 1272f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 1273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitFloatBinop(InstructionSelector* selector, Node* node, 1275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArchOpcode avx_opcode, ArchOpcode sse_opcode) { 1276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandGenerator g(selector); 1277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand operand0 = g.UseRegister(node->InputAt(0)); 1278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand operand1 = g.Use(node->InputAt(1)); 1279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (selector->IsSupported(AVX)) { 1280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->Emit(avx_opcode, g.DefineAsRegister(node), operand0, operand1); 1281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->Emit(sse_opcode, g.DefineSameAsFirst(node), operand0, operand1); 1283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitFloatUnop(InstructionSelector* selector, Node* node, Node* input, 1288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArchOpcode avx_opcode, ArchOpcode sse_opcode) { 1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandGenerator g(selector); 1290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (selector->IsSupported(AVX)) { 1291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->Emit(avx_opcode, g.DefineAsRegister(node), g.Use(input)); 1292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->Emit(sse_opcode, g.DefineSameAsFirst(node), g.UseRegister(input)); 1294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace 1298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 129962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define RO_OP_LIST(V) \ 130062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Word64Clz, kX64Lzcnt) \ 130162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Word32Clz, kX64Lzcnt32) \ 130262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Word64Ctz, kX64Tzcnt) \ 130362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Word32Ctz, kX64Tzcnt32) \ 130462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Word64Popcnt, kX64Popcnt) \ 130562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Word32Popcnt, kX64Popcnt32) \ 130662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float64Sqrt, kSSEFloat64Sqrt) \ 130762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float32Sqrt, kSSEFloat32Sqrt) \ 130862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(ChangeFloat64ToInt32, kSSEFloat64ToInt32) \ 130962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(ChangeFloat64ToUint32, kSSEFloat64ToUint32 | MiscField::encode(1)) \ 131062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(TruncateFloat64ToUint32, kSSEFloat64ToUint32 | MiscField::encode(0)) \ 131162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(TruncateFloat64ToFloat32, kSSEFloat64ToFloat32) \ 131262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(ChangeFloat32ToFloat64, kSSEFloat32ToFloat64) \ 131362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(TruncateFloat32ToInt32, kSSEFloat32ToInt32) \ 131462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(TruncateFloat32ToUint32, kSSEFloat32ToUint32) \ 131562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(ChangeInt32ToFloat64, kSSEInt32ToFloat64) \ 131662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(ChangeUint32ToFloat64, kSSEUint32ToFloat64) \ 131762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(RoundFloat64ToInt32, kSSEFloat64ToInt32) \ 131862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(RoundInt32ToFloat32, kSSEInt32ToFloat32) \ 131962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(RoundInt64ToFloat32, kSSEInt64ToFloat32) \ 132062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(RoundInt64ToFloat64, kSSEInt64ToFloat64) \ 132162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(RoundUint32ToFloat32, kSSEUint32ToFloat32) \ 132262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(BitcastFloat32ToInt32, kX64BitcastFI) \ 132362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(BitcastFloat64ToInt64, kX64BitcastDL) \ 132462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(BitcastInt32ToFloat32, kX64BitcastIF) \ 132562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(BitcastInt64ToFloat64, kX64BitcastLD) \ 132662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float64ExtractLowWord32, kSSEFloat64ExtractLowWord32) \ 132762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float64ExtractHighWord32, kSSEFloat64ExtractHighWord32) 132862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 132962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define RR_OP_LIST(V) \ 133062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float32RoundDown, kSSEFloat32Round | MiscField::encode(kRoundDown)) \ 133162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float64RoundDown, kSSEFloat64Round | MiscField::encode(kRoundDown)) \ 133262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float32RoundUp, kSSEFloat32Round | MiscField::encode(kRoundUp)) \ 133362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float64RoundUp, kSSEFloat64Round | MiscField::encode(kRoundUp)) \ 133462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float32RoundTruncate, kSSEFloat32Round | MiscField::encode(kRoundToZero)) \ 133562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float64RoundTruncate, kSSEFloat64Round | MiscField::encode(kRoundToZero)) \ 133662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float32RoundTiesEven, \ 133762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch kSSEFloat32Round | MiscField::encode(kRoundToNearest)) \ 133862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float64RoundTiesEven, kSSEFloat64Round | MiscField::encode(kRoundToNearest)) 133962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 134062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define RO_VISITOR(Name, opcode) \ 134162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void InstructionSelector::Visit##Name(Node* node) { \ 134262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch VisitRO(this, node, opcode); \ 134362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 134462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochRO_OP_LIST(RO_VISITOR) 134562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#undef RO_VISITOR 134662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 134762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define RR_VISITOR(Name, opcode) \ 134862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void InstructionSelector::Visit##Name(Node* node) { \ 134962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch VisitRR(this, node, opcode); \ 135062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 135162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochRR_OP_LIST(RR_VISITOR) 135262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#undef RR_VISITOR 1353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1354bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitTruncateFloat64ToWord32(Node* node) { 1355bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch VisitRR(this, node, kArchTruncateDoubleToI); 1356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { 1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X64OperandGenerator g(this); 1360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* value = node->InputAt(0); 1361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (CanCover(node, value)) { 1362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (value->opcode()) { 1363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord64Sar: 1364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord64Shr: { 1365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int64BinopMatcher m(value); 1366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (m.right().Is(32)) { 1367f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (TryMatchLoadWord64AndShiftRight(this, value, kX64Movl)) { 1368f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return EmitIdentity(node); 1369f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kX64Shr, g.DefineSameAsFirst(node), 1371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier g.UseRegister(m.left().node()), g.TempImmediate(32)); 1372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: 1377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Emit(kX64Movl, g.DefineAsRegister(node), g.Use(value)); 1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitRoundUint64ToFloat32(Node* node) { 1384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandGenerator g(this); 1385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand temps[] = {g.TempRegister()}; 1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kSSEUint64ToFloat32, g.DefineAsRegister(node), g.Use(node->InputAt(0)), 1387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch arraysize(temps), temps); 1388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitRoundUint64ToFloat64(Node* node) { 1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandGenerator g(this); 1393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand temps[] = {g.TempRegister()}; 1394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kSSEUint64ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)), 1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch arraysize(temps), temps); 1396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Add(Node* node) { 1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitFloatBinop(this, node, kAVXFloat32Add, kSSEFloat32Add); 1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Sub(Node* node) { 1404bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch VisitFloatBinop(this, node, kAVXFloat32Sub, kSSEFloat32Sub); 1405bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 1406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Mul(Node* node) { 1408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitFloatBinop(this, node, kAVXFloat32Mul, kSSEFloat32Mul); 1409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Div(Node* node) { 1413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitFloatBinop(this, node, kAVXFloat32Div, kSSEFloat32Div); 1414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Abs(Node* node) { 1418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat32Abs, kSSEFloat32Abs); 1419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1422f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitFloat32Max(Node* node) { 1423f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitRRO(this, node, kSSEFloat32Max); 1424f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 1425f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1426f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitFloat32Min(Node* node) { 1427f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitRRO(this, node, kSSEFloat32Min); 1428f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 1429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64Add(Node* node) { 1431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitFloatBinop(this, node, kAVXFloat64Add, kSSEFloat64Add); 1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitFloat64Sub(Node* node) { 1436bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch VisitFloatBinop(this, node, kAVXFloat64Sub, kSSEFloat64Sub); 1437bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitFloat64Mul(Node* node) { 1440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitFloatBinop(this, node, kAVXFloat64Mul, kSSEFloat64Mul); 1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitFloat64Div(Node* node) { 1445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitFloatBinop(this, node, kAVXFloat64Div, kSSEFloat64Div); 1446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitFloat64Mod(Node* node) { 1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X64OperandGenerator g(this); 1451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand temps[] = {g.TempRegister(rax)}; 1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Emit(kSSEFloat64Mod, g.DefineSameAsFirst(node), 1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), 1, 1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch temps); 1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64Max(Node* node) { 1459f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitRRO(this, node, kSSEFloat64Max); 1460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64Min(Node* node) { 1464f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitRRO(this, node, kSSEFloat64Min); 1465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64Abs(Node* node) { 1469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat64Abs, kSSEFloat64Abs); 1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1473958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { 1474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); 1475958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1478f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitFloat32Neg(Node* node) { 1479f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat32Neg, kSSEFloat32Neg); 1480f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 148113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 1482f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitFloat64Neg(Node* node) { 1483f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat64Neg, kSSEFloat64Neg); 1484f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 148513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 148613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid InstructionSelector::VisitFloat64Ieee754Binop(Node* node, 148713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InstructionCode opcode) { 148813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch X64OperandGenerator g(this); 148913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Emit(opcode, g.DefineAsFixed(node, xmm0), g.UseFixed(node->InputAt(0), xmm0), 149013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch g.UseFixed(node->InputAt(1), xmm1)) 149113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ->MarkAsCall(); 149213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 149313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 149413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid InstructionSelector::VisitFloat64Ieee754Unop(Node* node, 149513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InstructionCode opcode) { 149613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch X64OperandGenerator g(this); 149713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Emit(opcode, g.DefineAsFixed(node, xmm0), g.UseFixed(node->InputAt(0), xmm0)) 149813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ->MarkAsCall(); 149913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 1500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::EmitPrepareArguments( 1502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor, 1503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* node) { 1504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandGenerator g(this); 1505958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Prepare for C function call. 1507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (descriptor->IsCFunctionCall()) { 1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kArchPrepareCallCFunction | 1509f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MiscField::encode(static_cast<int>(descriptor->ParameterCount())), 1510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 0, nullptr, 0, nullptr); 1511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Poke any stack arguments. 1513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (size_t n = 0; n < arguments->size(); ++n) { 1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PushParameter input = (*arguments)[n]; 1515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (input.node()) { 1516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int slot = static_cast<int>(n); 1517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand value = g.CanBeImmediate(input.node()) 1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? g.UseImmediate(input.node()) 1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : g.UseRegister(input.node()); 1520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kX64Poke | MiscField::encode(slot), g.NoOutput(), value); 1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Push any stack arguments. 152562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int effect_level = GetEffectLevel(node); 1526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (PushParameter input : base::Reversed(*arguments)) { 152762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* input_node = input.node(); 152862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (g.CanBeImmediate(input_node)) { 152962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Emit(kX64Push, g.NoOutput(), g.UseImmediate(input_node)); 153062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (IsSupported(ATOM) || 153162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch sequence()->IsFP(GetVirtualRegister(input_node))) { 153262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // TODO(titzer): X64Push cannot handle stack->stack double moves 153362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // because there is no way to encode fixed double slots. 153462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Emit(kX64Push, g.NoOutput(), g.UseRegister(input_node)); 153562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (g.CanBeMemoryOperand(kX64Push, node, input_node, 153662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch effect_level)) { 153762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstructionOperand outputs[1]; 153862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstructionOperand inputs[4]; 153962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t input_count = 0; 154062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstructionCode opcode = kX64Push; 154162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AddressingMode mode = g.GetEffectiveAddressMemoryOperand( 154262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch input_node, inputs, &input_count); 154362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch opcode |= AddressingModeField::encode(mode); 154462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Emit(opcode, 0, outputs, input_count, inputs); 154562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 154662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Emit(kX64Push, g.NoOutput(), g.Use(input_node)); 154762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 1548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool InstructionSelector::IsTailCallAddressImmediate() { return true; } 1554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 15553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochint InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; } 1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace { 1558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1559109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid VisitCompareWithMemoryOperand(InstructionSelector* selector, 1560109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch InstructionCode opcode, Node* left, 1561109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch InstructionOperand right, 1562109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FlagsContinuation* cont) { 1563109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(left->opcode() == IrOpcode::kLoad); 1564109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch X64OperandGenerator g(selector); 1565109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch size_t input_count = 0; 1566109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch InstructionOperand inputs[6]; 1567109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AddressingMode addressing_mode = 1568109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch g.GetEffectiveAddressMemoryOperand(left, inputs, &input_count); 1569109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch opcode |= AddressingModeField::encode(addressing_mode); 1570109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch opcode = cont->Encode(opcode); 1571109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch inputs[input_count++] = right; 1572109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1573109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (cont->IsBranch()) { 1574109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch inputs[input_count++] = g.Label(cont->true_block()); 1575109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch inputs[input_count++] = g.Label(cont->false_block()); 1576109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch selector->Emit(opcode, 0, nullptr, input_count, inputs); 15773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else if (cont->IsDeoptimize()) { 15783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch selector->EmitDeoptimize(opcode, 0, nullptr, input_count, inputs, 157962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch cont->kind(), cont->reason(), cont->frame_state()); 158062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (cont->IsSet()) { 1581109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch InstructionOperand output = g.DefineAsRegister(cont->result()); 1582109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch selector->Emit(opcode, 1, &output, input_count, inputs); 158362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 158462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(cont->IsTrap()); 158562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch inputs[input_count++] = g.UseImmediate(cont->trap_id()); 158662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch selector->Emit(opcode, 0, nullptr, input_count, inputs); 1587109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1588109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1589109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shared routine for multiple compare operations. 1591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitCompare(InstructionSelector* selector, InstructionCode opcode, 1592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand left, InstructionOperand right, 1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FlagsContinuation* cont) { 1594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X64OperandGenerator g(selector); 1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch opcode = cont->Encode(opcode); 1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cont->IsBranch()) { 1597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->Emit(opcode, g.NoOutput(), left, right, 1598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.Label(cont->true_block()), g.Label(cont->false_block())); 15993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else if (cont->IsDeoptimize()) { 160062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(), 160162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch cont->reason(), cont->frame_state()); 160262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (cont->IsSet()) { 1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); 160462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 160562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(cont->IsTrap()); 160662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch selector->Emit(opcode, g.NoOutput(), left, right, 160762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch g.UseImmediate(cont->trap_id())); 1608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1612958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Shared routine for multiple compare operations. 1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitCompare(InstructionSelector* selector, InstructionCode opcode, 1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* left, Node* right, FlagsContinuation* cont, 1615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool commutative) { 1616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier X64OperandGenerator g(selector); 1617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (commutative && g.CanBeBetterLeftOperand(right)) { 1618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier std::swap(left, right); 1619958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1620958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont); 1621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 162362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochMachineType MachineTypeForNarrow(Node* node, Node* hint_node) { 162462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (hint_node->opcode() == IrOpcode::kLoad) { 162562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MachineType hint = LoadRepresentationOf(hint_node->op()); 162662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (node->opcode() == IrOpcode::kInt32Constant || 162762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch node->opcode() == IrOpcode::kInt64Constant) { 162862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int64_t constant = node->opcode() == IrOpcode::kInt32Constant 162962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ? OpParameter<int32_t>(node) 163062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : OpParameter<int64_t>(node); 163162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (hint == MachineType::Int8()) { 163262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (constant >= std::numeric_limits<int8_t>::min() && 163362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch constant <= std::numeric_limits<int8_t>::max()) { 163462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return hint; 163562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 163662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (hint == MachineType::Uint8()) { 163762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (constant >= std::numeric_limits<uint8_t>::min() && 163862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch constant <= std::numeric_limits<uint8_t>::max()) { 163962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return hint; 164062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 164162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (hint == MachineType::Int16()) { 164262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (constant >= std::numeric_limits<int16_t>::min() && 164362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch constant <= std::numeric_limits<int16_t>::max()) { 164462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return hint; 164562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 164662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (hint == MachineType::Uint16()) { 164762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (constant >= std::numeric_limits<uint16_t>::min() && 164862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch constant <= std::numeric_limits<uint16_t>::max()) { 164962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return hint; 165062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 165162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (hint == MachineType::Int32()) { 165262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return hint; 165362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (hint == MachineType::Uint32()) { 165462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (constant >= 0) return hint; 165562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 165662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 165762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 165862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return node->opcode() == IrOpcode::kLoad ? LoadRepresentationOf(node->op()) 165962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : MachineType::None(); 166062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 166162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 16623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// Tries to match the size of the given opcode to that of the operands, if 16633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// possible. 16643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochInstructionCode TryNarrowOpcodeSize(InstructionCode opcode, Node* left, 1665f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* right, FlagsContinuation* cont) { 166662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // TODO(epertoso): we can probably get some size information out phi nodes. 16673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // If the load representations don't match, both operands will be 16683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // zero/sign-extended to 32bit. 166962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MachineType left_type = MachineTypeForNarrow(left, right); 167062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MachineType right_type = MachineTypeForNarrow(right, left); 1671f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (left_type == right_type) { 1672f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (left_type.representation()) { 1673f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kBit: 1674f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kWord8: { 1675f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (opcode == kX64Test32) return kX64Test8; 1676f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (opcode == kX64Cmp32) { 1677f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (left_type.semantic() == MachineSemantic::kUint32) { 1678f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cont->OverwriteUnsignedIfSigned(); 1679f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 1680f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CHECK_EQ(MachineSemantic::kInt32, left_type.semantic()); 1681f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1682f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return kX64Cmp8; 1683f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1684f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1685f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1686f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case MachineRepresentation::kWord16: 1687f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (opcode == kX64Test32) return kX64Test16; 1688f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (opcode == kX64Cmp32) { 1689f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (left_type.semantic() == MachineSemantic::kUint32) { 1690f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cont->OverwriteUnsignedIfSigned(); 1691f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 1692f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CHECK_EQ(MachineSemantic::kInt32, left_type.semantic()); 1693f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1694f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return kX64Cmp16; 1695f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1696f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1697f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch default: 1698f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1699f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 17003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 1701f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return opcode; 17023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 17033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shared routine for multiple word compare operations. 1705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitWordCompare(InstructionSelector* selector, Node* node, 1706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionCode opcode, FlagsContinuation* cont) { 1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X64OperandGenerator g(selector); 1708109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* left = node->InputAt(0); 1709109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Node* right = node->InputAt(1); 1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1711f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch opcode = TryNarrowOpcodeSize(opcode, left, right, cont); 17123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 17133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // If one of the two inputs is an immediate, make sure it's on the right, or 17143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // if one of the two inputs is a memory operand, make sure it's on the left. 1715bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch int effect_level = selector->GetEffectLevel(node); 1716bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (cont->IsBranch()) { 1717bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch effect_level = selector->GetEffectLevel( 1718bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch cont->true_block()->PredecessorAt(0)->control_input()); 1719bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 1720bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 17213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if ((!g.CanBeImmediate(right) && g.CanBeImmediate(left)) || 1722bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch (g.CanBeMemoryOperand(opcode, node, right, effect_level) && 1723bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch !g.CanBeMemoryOperand(opcode, node, left, effect_level))) { 1724109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); 1725109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch std::swap(left, right); 1726109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1727109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1728109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Match immediates on right side of comparison. 1729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (g.CanBeImmediate(right)) { 1730bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (g.CanBeMemoryOperand(opcode, node, left, effect_level)) { 1731109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return VisitCompareWithMemoryOperand(selector, opcode, left, 1732109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch g.UseImmediate(right), cont); 1733109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1734109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), 1735109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch cont); 1736109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1737109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 17383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Match memory operands on left side of comparison. 1739bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (g.CanBeMemoryOperand(opcode, node, left, effect_level)) { 17403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitCompareWithMemoryOperand(selector, opcode, left, 17413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch g.UseRegister(right), cont); 17423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 17433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1744109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return VisitCompare(selector, opcode, left, right, cont, 1745109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch node->op()->HasProperty(Operator::kCommutative)); 1746109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1747f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch 1748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Shared routine for 64-bit word comparison operations. 1749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitWord64Compare(InstructionSelector* selector, Node* node, 1750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FlagsContinuation* cont) { 1751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandGenerator g(selector); 1752c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (selector->CanUseRootsRegister()) { 1753c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Heap* const heap = selector->isolate()->heap(); 1754c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Heap::RootListIndex root_index; 1755c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HeapObjectBinopMatcher m(node); 1756c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (m.right().HasValue() && 1757c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch heap->IsRootHandle(m.right().Value(), &root_index)) { 1758c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); 1759c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InstructionCode opcode = 1760c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch kX64Cmp | AddressingModeField::encode(kMode_Root); 1761c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return VisitCompare( 1762c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch selector, opcode, 1763c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.TempImmediate((root_index * kPointerSize) - kRootRegisterBias), 1764c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.UseRegister(m.left().node()), cont); 1765c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else if (m.left().HasValue() && 1766c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch heap->IsRootHandle(m.left().Value(), &root_index)) { 1767c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InstructionCode opcode = 1768c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch kX64Cmp | AddressingModeField::encode(kMode_Root); 1769c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return VisitCompare( 1770c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch selector, opcode, 1771c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.TempImmediate((root_index * kPointerSize) - kRootRegisterBias), 1772c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch g.UseRegister(m.right().node()), cont); 1773c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1774c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Int64BinopMatcher m(node); 1776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (m.left().IsLoad() && m.right().IsLoadStackPointer()) { 1777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadMatcher<ExternalReferenceMatcher> mleft(m.left().node()); 1778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExternalReference js_stack_limit = 1779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExternalReference::address_of_stack_limit(selector->isolate()); 1780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mleft.object().Is(js_stack_limit) && mleft.index().Is(0)) { 1781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Compare(Load(js_stack_limit), LoadStackPointer) 1782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); 1783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionCode opcode = cont->Encode(kX64StackCheck); 1784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (cont->IsBranch()) { 1785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->Emit(opcode, g.NoOutput(), g.Label(cont->true_block()), 1786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.Label(cont->false_block())); 17873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else if (cont->IsDeoptimize()) { 178862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch selector->EmitDeoptimize(opcode, 0, nullptr, 0, nullptr, cont->kind(), 178962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch cont->reason(), cont->frame_state()); 179062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (cont->IsSet()) { 1791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->Emit(opcode, g.DefineAsRegister(cont->result())); 179262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 179362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(cont->IsTrap()); 179462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch selector->Emit(opcode, g.NoOutput(), g.UseImmediate(cont->trap_id())); 1795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 1797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitWordCompare(selector, node, kX64Cmp, cont); 1800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1803958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Shared routine for comparison with zero. 1804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitCompareZero(InstructionSelector* selector, Node* node, 1805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionCode opcode, FlagsContinuation* cont) { 1806958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier X64OperandGenerator g(selector); 1807958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitCompare(selector, opcode, g.Use(node), g.TempImmediate(0), cont); 1808958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1809958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Shared routine for multiple float32 compare operations (inputs commuted). 1812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitFloat32Compare(InstructionSelector* selector, Node* node, 1813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FlagsContinuation* cont) { 1814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* const left = node->InputAt(0); 1815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* const right = node->InputAt(1); 1816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionCode const opcode = 1817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->IsSupported(AVX) ? kAVXFloat32Cmp : kSSEFloat32Cmp; 1818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitCompare(selector, opcode, right, left, cont, false); 1819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Shared routine for multiple float64 compare operations (inputs commuted). 1823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitFloat64Compare(InstructionSelector* selector, Node* node, 1824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FlagsContinuation* cont) { 1825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* const left = node->InputAt(0); 1826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* const right = node->InputAt(1); 1827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionCode const opcode = 1828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector->IsSupported(AVX) ? kAVXFloat64Cmp : kSSEFloat64Cmp; 1829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitCompare(selector, opcode, right, left, cont, false); 1830958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1831958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 18323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// Shared routine for word comparison against zero. 18333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid VisitWordCompareZero(InstructionSelector* selector, Node* user, 18343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* value, FlagsContinuation* cont) { 1835c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Try to combine with comparisons against 0 by simply inverting the branch. 1836c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch while (value->opcode() == IrOpcode::kWord32Equal && 1837c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch selector->CanCover(user, value)) { 1838c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Int32BinopMatcher m(value); 1839c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!m.right().Is(0)) break; 1840c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1841c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch user = value; 1842c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch value = m.left().node(); 1843c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch cont->Negate(); 1844c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1845c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1846c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (selector->CanCover(user, value)) { 1847958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (value->opcode()) { 1848c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case IrOpcode::kWord32Equal: 18493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kEqual); 18503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitWordCompare(selector, value, kX64Cmp32, cont); 1851958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32LessThan: 18523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kSignedLessThan); 18533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitWordCompare(selector, value, kX64Cmp32, cont); 1854958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32LessThanOrEqual: 18553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); 18563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitWordCompare(selector, value, kX64Cmp32, cont); 1857958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kUint32LessThan: 18583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); 18593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitWordCompare(selector, value, kX64Cmp32, cont); 1860958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kUint32LessThanOrEqual: 18613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); 18623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitWordCompare(selector, value, kX64Cmp32, cont); 1863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kWord64Equal: { 18643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kEqual); 1865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Int64BinopMatcher m(value); 1866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (m.right().Is(0)) { 1867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Try to combine the branch with a comparison. 1868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* const user = m.node(); 1869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* const value = m.left().node(); 18703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (selector->CanCover(user, value)) { 1871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (value->opcode()) { 1872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kInt64Sub: 18733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitWord64Compare(selector, value, cont); 1874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kWord64And: 18753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitWordCompare(selector, value, kX64Test, cont); 1876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 1877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 18803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitCompareZero(selector, value, kX64Cmp, cont); 1881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 18823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitWord64Compare(selector, value, cont); 1883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1884958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt64LessThan: 18853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kSignedLessThan); 18863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitWord64Compare(selector, value, cont); 1887958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt64LessThanOrEqual: 18883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); 18893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitWord64Compare(selector, value, cont); 1890958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kUint64LessThan: 18913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); 18923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitWord64Compare(selector, value, cont); 1893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kUint64LessThanOrEqual: 18943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); 18953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitWord64Compare(selector, value, cont); 1896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kFloat32Equal: 18973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kUnorderedEqual); 18983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitFloat32Compare(selector, value, cont); 1899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kFloat32LessThan: 19003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThan); 19013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitFloat32Compare(selector, value, cont); 1902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kFloat32LessThanOrEqual: 19033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual); 19043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitFloat32Compare(selector, value, cont); 1905958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kFloat64Equal: 19063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kUnorderedEqual); 19073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitFloat64Compare(selector, value, cont); 1908c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case IrOpcode::kFloat64LessThan: { 1909c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Float64BinopMatcher m(value); 1910c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (m.left().Is(0.0) && m.right().IsFloat64Abs()) { 1911c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // This matches the pattern 1912c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // 1913c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Float64LessThan(#0.0, Float64Abs(x)) 1914c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // 1915c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // which TurboFan generates for NumberToBoolean in the general case, 1916c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // and which evaluates to false if x is 0, -0 or NaN. We can compile 1917c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // this to a simple (v)ucomisd using not_equal flags condition, which 1918c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // avoids the costly Float64Abs. 1919c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch cont->OverwriteAndNegateIfEqual(kNotEqual); 1920c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InstructionCode const opcode = 1921c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch selector->IsSupported(AVX) ? kAVXFloat64Cmp : kSSEFloat64Cmp; 1922c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return VisitCompare(selector, opcode, m.left().node(), 1923c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch m.right().InputAt(0), cont, false); 1924c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 19253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThan); 19263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitFloat64Compare(selector, value, cont); 1927c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1928958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kFloat64LessThanOrEqual: 19293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual); 19303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitFloat64Compare(selector, value, cont); 1931958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kProjection: 1932958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check if this is the overflow output projection of an 1933958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // <Operation>WithOverflow node. 1934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (ProjectionIndexOf(value->op()) == 1u) { 1935958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // We cannot combine the <Operation>WithOverflow with this branch 1936958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // unless the 0th projection (the use of the actual value of the 1937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // <Operation> is either nullptr, which means there's no use of the 1938958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // actual value, or was already defined, which means it is scheduled 1939958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // *AFTER* this branch). 1940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* const node = value->InputAt(0); 1941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* const result = NodeProperties::FindProjection(node, 0); 19423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (result == nullptr || selector->IsDefined(result)) { 1943958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (node->opcode()) { 1944958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32AddWithOverflow: 19453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kOverflow); 19463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitBinop(selector, node, kX64Add32, cont); 1947958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32SubWithOverflow: 19483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kOverflow); 19493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitBinop(selector, node, kX64Sub32, cont); 1950f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kInt32MulWithOverflow: 1951f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch cont->OverwriteAndNegateIfEqual(kOverflow); 1952f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return VisitBinop(selector, node, kX64Imul32, cont); 1953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kInt64AddWithOverflow: 19543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kOverflow); 19553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitBinop(selector, node, kX64Add, cont); 1956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case IrOpcode::kInt64SubWithOverflow: 19573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cont->OverwriteAndNegateIfEqual(kOverflow); 19583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitBinop(selector, node, kX64Sub, cont); 1959958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: 1960958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1961958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1962958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1963958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1964958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1965958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt32Sub: 19663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitWordCompare(selector, value, kX64Cmp32, cont); 1967958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord32And: 19683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitWordCompare(selector, value, kX64Test32, cont); 1969958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: 1970958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1971958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1972958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1973958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1974958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Branch could not be combined with a compare, emit compare against 0. 19753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch VisitCompareZero(selector, value, kX64Cmp32, cont); 1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 19783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} // namespace 19793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 19803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, 19813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch BasicBlock* fbranch) { 19823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont(kNotEqual, tbranch, fbranch); 19833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch VisitWordCompareZero(this, branch, branch->InputAt(0), &cont); 19843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 19853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 19863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid InstructionSelector::VisitDeoptimizeIf(Node* node) { 198762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); 1988f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FlagsContinuation cont = FlagsContinuation::ForDeoptimize( 198962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch kNotEqual, p.kind(), p.reason(), node->InputAt(1)); 19903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch VisitWordCompareZero(this, node, node->InputAt(0), &cont); 19913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 19923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 19933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid InstructionSelector::VisitDeoptimizeUnless(Node* node) { 199462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); 1995f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FlagsContinuation cont = FlagsContinuation::ForDeoptimize( 199662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch kEqual, p.kind(), p.reason(), node->InputAt(1)); 199762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch VisitWordCompareZero(this, node, node->InputAt(0), &cont); 199862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 199962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 200062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InstructionSelector::VisitTrapIf(Node* node, Runtime::FunctionId func_id) { 200162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FlagsContinuation cont = 200262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FlagsContinuation::ForTrap(kNotEqual, func_id, node->InputAt(1)); 200362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch VisitWordCompareZero(this, node, node->InputAt(0), &cont); 200462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 200562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 200662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InstructionSelector::VisitTrapUnless(Node* node, 200762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Runtime::FunctionId func_id) { 200862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FlagsContinuation cont = 200962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FlagsContinuation::ForTrap(kEqual, func_id, node->InputAt(1)); 20103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch VisitWordCompareZero(this, node, node->InputAt(0), &cont); 20113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 2012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { 2014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandGenerator g(this); 2015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); 2016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Emit either ArchTableSwitch or ArchLookupSwitch. 2018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t table_space_cost = 4 + sw.value_range; 2019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t table_time_cost = 3; 2020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t lookup_space_cost = 3 + 2 * sw.case_count; 2021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t lookup_time_cost = sw.case_count; 2022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (sw.case_count > 4 && 2023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch table_space_cost + 3 * table_time_cost <= 2024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lookup_space_cost + 3 * lookup_time_cost && 2025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sw.min_value > std::numeric_limits<int32_t>::min()) { 2026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand index_operand = g.TempRegister(); 2027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (sw.min_value) { 2028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The leal automatically zero extends, so result is a valid 64-bit index. 2029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kX64Lea32 | AddressingModeField::encode(kMode_MRI), index_operand, 2030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value_operand, g.TempImmediate(-sw.min_value)); 2031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Zero extend, because we use it as 64-bit index into the jump table. 2033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kX64Movl, index_operand, value_operand); 2034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Generate a table lookup. 2036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return EmitTableSwitch(sw, index_operand); 2037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Generate a sequence of conditional jumps. 2040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return EmitLookupSwitch(sw, value_operand); 2041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2044958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitWord32Equal(Node* const node) { 2045958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* user = node; 20463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); 2047958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Int32BinopMatcher m(user); 2048958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (m.right().Is(0)) { 204962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return VisitWordCompareZero(this, m.node(), m.left().node(), &cont); 2050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2051958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitWordCompare(this, node, kX64Cmp32, &cont); 2052958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2054958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2055958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32LessThan(Node* node) { 20563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node); 2057958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitWordCompare(this, node, kX64Cmp32, &cont); 2058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2061958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32LessThanOrEqual(Node* node) { 20623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = 20633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation::ForSet(kSignedLessThanOrEqual, node); 2064958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitWordCompare(this, node, kX64Cmp32, &cont); 2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2068958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32LessThan(Node* node) { 20693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node); 2070958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitWordCompare(this, node, kX64Cmp32, &cont); 2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2074958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32LessThanOrEqual(Node* node) { 20753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = 20763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node); 2077958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitWordCompare(this, node, kX64Cmp32, &cont); 2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2081958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitWord64Equal(Node* const node) { 20823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); 2083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Int64BinopMatcher m(node); 2084958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (m.right().Is(0)) { 2085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Try to combine the equality check with a comparison. 2086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* const user = m.node(); 2087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* const value = m.left().node(); 2088958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (CanCover(user, value)) { 2089958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (value->opcode()) { 2090958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kInt64Sub: 2091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return VisitWord64Compare(this, value, &cont); 2092958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kWord64And: 2093958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitWordCompare(this, value, kX64Test, &cont); 2094958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier default: 2095958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2096958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2097958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitWord64Compare(this, node, &cont); 2100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32AddWithOverflow(Node* node) { 2104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (Node* ovf = NodeProperties::FindProjection(node, 1)) { 21053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); 21063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return VisitBinop(this, node, kX64Add32, &cont); 2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FlagsContinuation cont; 2109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitBinop(this, node, kX64Add32, &cont); 2110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32SubWithOverflow(Node* node) { 2114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (Node* ovf = NodeProperties::FindProjection(node, 1)) { 21153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); 2116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return VisitBinop(this, node, kX64Sub32, &cont); 2117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FlagsContinuation cont; 2119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitBinop(this, node, kX64Sub32, &cont); 2120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt64LessThan(Node* node) { 21243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node); 2125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitWord64Compare(this, node, &cont); 2126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt64LessThanOrEqual(Node* node) { 21303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = 21313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation::ForSet(kSignedLessThanOrEqual, node); 2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitWord64Compare(this, node, &cont); 2133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint64LessThan(Node* node) { 21373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node); 2138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitWord64Compare(this, node, &cont); 2139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitUint64LessThanOrEqual(Node* node) { 21433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = 21443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node); 2145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitWord64Compare(this, node, &cont); 2146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Equal(Node* node) { 21503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kUnorderedEqual, node); 2151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitFloat32Compare(this, node, &cont); 2152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32LessThan(Node* node) { 21563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = 21573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation::ForSet(kUnsignedGreaterThan, node); 2158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitFloat32Compare(this, node, &cont); 2159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) { 21633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = 21643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation::ForSet(kUnsignedGreaterThanOrEqual, node); 2165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VisitFloat32Compare(this, node, &cont); 2166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64Equal(Node* node) { 21703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kUnorderedEqual, node); 2171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitFloat64Compare(this, node, &cont); 2172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64LessThan(Node* node) { 2175c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Float64BinopMatcher m(node); 2176c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (m.left().Is(0.0) && m.right().IsFloat64Abs()) { 2177c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // This matches the pattern 2178c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // 2179c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Float64LessThan(#0.0, Float64Abs(x)) 2180c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // 2181c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // which TurboFan generates for NumberToBoolean in the general case, 2182c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // and which evaluates to false if x is 0, -0 or NaN. We can compile 2183c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // this to a simple (v)ucomisd using not_equal flags condition, which 2184c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // avoids the costly Float64Abs. 2185c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch FlagsContinuation cont = FlagsContinuation::ForSet(kNotEqual, node); 2186c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InstructionCode const opcode = 2187c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch IsSupported(AVX) ? kAVXFloat64Cmp : kSSEFloat64Cmp; 2188c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return VisitCompare(this, opcode, m.left().node(), m.right().InputAt(0), 2189c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch &cont, false); 2190c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 21913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = 21923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation::ForSet(kUnsignedGreaterThan, node); 2193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitFloat64Compare(this, node, &cont); 2194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { 21973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation cont = 21983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsContinuation::ForSet(kUnsignedGreaterThanOrEqual, node); 2199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VisitFloat64Compare(this, node, &cont); 2200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64InsertLowWord32(Node* node) { 2203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandGenerator g(this); 2204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* left = node->InputAt(0); 2205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* right = node->InputAt(1); 2206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Float64Matcher mleft(left); 2207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mleft.HasValue() && (bit_cast<uint64_t>(mleft.Value()) >> 32) == 0u) { 2208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kSSEFloat64LoadLowWord32, g.DefineAsRegister(node), g.Use(right)); 2209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 2210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kSSEFloat64InsertLowWord32, g.DefineSameAsFirst(node), 2212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseRegister(left), g.Use(right)); 2213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64InsertHighWord32(Node* node) { 2217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandGenerator g(this); 2218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* left = node->InputAt(0); 2219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* right = node->InputAt(1); 2220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Emit(kSSEFloat64InsertHighWord32, g.DefineSameAsFirst(node), 2221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch g.UseRegister(left), g.Use(right)); 2222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 222413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid InstructionSelector::VisitFloat64SilenceNaN(Node* node) { 222513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch X64OperandGenerator g(this); 222613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Emit(kSSEFloat64SilenceNaN, g.DefineSameAsFirst(node), 222713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch g.UseRegister(node->InputAt(0))); 222813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 222913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 2230bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitAtomicLoad(Node* node) { 2231bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch LoadRepresentation load_rep = LoadRepresentationOf(node->op()); 2232bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(load_rep.representation() == MachineRepresentation::kWord8 || 2233bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch load_rep.representation() == MachineRepresentation::kWord16 || 2234bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch load_rep.representation() == MachineRepresentation::kWord32); 2235bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch USE(load_rep); 2236bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch VisitLoad(node); 2237bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 2238bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 2239bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitAtomicStore(Node* node) { 2240bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch X64OperandGenerator g(this); 2241bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* base = node->InputAt(0); 2242bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* index = node->InputAt(1); 2243bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Node* value = node->InputAt(2); 2244bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 2245bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch MachineRepresentation rep = AtomicStoreRepresentationOf(node->op()); 2246bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ArchOpcode opcode = kArchNop; 2247bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch switch (rep) { 2248bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case MachineRepresentation::kWord8: 2249bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch opcode = kX64Xchgb; 2250bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 2251bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case MachineRepresentation::kWord16: 2252bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch opcode = kX64Xchgw; 2253bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 2254bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case MachineRepresentation::kWord32: 2255bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch opcode = kX64Xchgl; 2256bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 2257bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch default: 2258bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UNREACHABLE(); 2259bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return; 2260bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2261bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch AddressingMode addressing_mode; 2262bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch InstructionOperand inputs[4]; 2263bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch size_t input_count = 0; 2264bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch inputs[input_count++] = g.UseUniqueRegister(base); 2265bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (g.CanBeImmediate(index)) { 2266bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch inputs[input_count++] = g.UseImmediate(index); 2267bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch addressing_mode = kMode_MRI; 2268bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else { 2269bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch inputs[input_count++] = g.UseUniqueRegister(index); 2270bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch addressing_mode = kMode_MR1; 2271bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2272bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch inputs[input_count++] = g.UseUniqueRegister(value); 2273bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch InstructionCode code = opcode | AddressingModeField::encode(addressing_mode); 2274bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Emit(code, 0, static_cast<InstructionOperand*>(nullptr), input_count, inputs); 2275bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 2276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2277f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid InstructionSelector::VisitCreateInt32x4(Node* node) { 2278f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch X64OperandGenerator g(this); 2279f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Emit(kX64Int32x4Create, g.DefineAsRegister(node), g.Use(node->InputAt(0))); 2280f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 2281f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 2282f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid InstructionSelector::VisitInt32x4ExtractLane(Node* node) { 2283f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch X64OperandGenerator g(this); 228462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int32_t lane = OpParameter<int32_t>(node); 2285f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Emit(kX64Int32x4ExtractLane, g.DefineAsRegister(node), 228662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch g.UseRegister(node->InputAt(0)), g.UseImmediate(lane)); 228762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 228862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 228962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InstructionSelector::VisitInt32x4ReplaceLane(Node* node) { 229062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch X64OperandGenerator g(this); 229162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int32_t lane = OpParameter<int32_t>(node); 229262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Emit(kX64Int32x4ReplaceLane, g.DefineSameAsFirst(node), 229362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch g.UseRegister(node->InputAt(0)), g.UseImmediate(lane), 229462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch g.Use(node->InputAt(1))); 229562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 229662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 229762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InstructionSelector::VisitInt32x4Add(Node* node) { 229862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch X64OperandGenerator g(this); 229962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Emit(kX64Int32x4Add, g.DefineSameAsFirst(node), 230062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1))); 230162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 230262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 230362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InstructionSelector::VisitInt32x4Sub(Node* node) { 230462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch X64OperandGenerator g(this); 230562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Emit(kX64Int32x4Sub, g.DefineSameAsFirst(node), 230662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1))); 2307f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 2308f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 2309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// static 2310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierMachineOperatorBuilder::Flags 2311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierInstructionSelector::SupportedMachineOperatorFlags() { 2312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineOperatorBuilder::Flags flags = 2313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineOperatorBuilder::kWord32ShiftIsSafe | 2314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineOperatorBuilder::kWord32Ctz | MachineOperatorBuilder::kWord64Ctz; 2315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(POPCNT)) { 2316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch flags |= MachineOperatorBuilder::kWord32Popcnt | 2317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineOperatorBuilder::kWord64Popcnt; 2318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (CpuFeatures::IsSupported(SSE4_1)) { 2320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch flags |= MachineOperatorBuilder::kFloat32RoundDown | 2321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineOperatorBuilder::kFloat64RoundDown | 2322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineOperatorBuilder::kFloat32RoundUp | 2323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineOperatorBuilder::kFloat64RoundUp | 2324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineOperatorBuilder::kFloat32RoundTruncate | 2325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineOperatorBuilder::kFloat64RoundTruncate | 2326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineOperatorBuilder::kFloat32RoundTiesEven | 2327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineOperatorBuilder::kFloat64RoundTiesEven; 2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return flags; 2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 233213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// static 233313e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochMachineOperatorBuilder::AlignmentRequirements 233413e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochInstructionSelector::AlignmentRequirements() { 233513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return MachineOperatorBuilder::AlignmentRequirements:: 233613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FullUnalignedAccessSupport(); 233713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 233813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 2339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace compiler 2340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace internal 2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace v8 2342