1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 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 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/code-generator.h" 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include <limits> 8c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 9f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/compilation-info.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/code-generator-impl.h" 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/gap-resolver.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/node-matchers.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/osr.h" 1462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/heap/heap-inl.h" 15f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/wasm/wasm-module.h" 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/x64/assembler-x64.h" 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/x64/macro-assembler-x64.h" 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler { 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define __ masm()-> 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Adds X64 specific methods for decoding operands. 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass X64OperandConverter : public InstructionOperandConverter { 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X64OperandConverter(CodeGenerator* gen, Instruction* instr) 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : InstructionOperandConverter(gen, instr) {} 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Immediate InputImmediate(size_t index) { 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ToImmediate(instr_->InputAt(index)); 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand InputOperand(size_t index, int extra = 0) { 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ToOperand(instr_->InputAt(index), extra); 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Operand OutputOperand() { return ToOperand(instr_->Output()); } 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate ToImmediate(InstructionOperand* operand) { 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Constant constant = ToConstant(operand); 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (constant.type() == Constant::kFloat64) { 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(0, bit_cast<int64_t>(constant.ToFloat64())); 45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Immediate(0); 46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (RelocInfo::IsWasmReference(constant.rmode())) { 48bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Immediate(constant.ToInt32(), constant.rmode()); 49bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Immediate(constant.ToInt32()); 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand ToOperand(InstructionOperand* op, int extra = 0) { 54bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(op->IsStackSlot() || op->IsFPStackSlot()); 553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return SlotToOperand(AllocatedOperand::cast(op)->index(), extra); 563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Operand SlotToOperand(int slot_index, int extra = 0) { 593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FrameOffset offset = frame_access_state()->GetFrameOffset(slot_index); 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Operand(offset.from_stack_pointer() ? rsp : rbp, 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch offset.offset() + extra); 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static size_t NextOffset(size_t* offset) { 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t i = *offset; 66958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (*offset)++; 67958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return i; 68958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 69958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 70958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static ScaleFactor ScaleFor(AddressingMode one, AddressingMode mode) { 71958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier STATIC_ASSERT(0 == static_cast<int>(times_1)); 72958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier STATIC_ASSERT(1 == static_cast<int>(times_2)); 73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier STATIC_ASSERT(2 == static_cast<int>(times_4)); 74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier STATIC_ASSERT(3 == static_cast<int>(times_8)); 75958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int scale = static_cast<int>(mode - one); 76958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(scale >= 0 && scale < 4); 77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return static_cast<ScaleFactor>(scale); 78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand MemoryOperand(size_t* offset) { 81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddressingMode mode = AddressingModeField::decode(instr_->opcode()); 82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (mode) { 83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kMode_MR: { 84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register base = InputRegister(NextOffset(offset)); 85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t disp = 0; 86958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Operand(base, disp); 87958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 88958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kMode_MRI: { 89958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register base = InputRegister(NextOffset(offset)); 90958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t disp = InputInt32(NextOffset(offset)); 91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Operand(base, disp); 92958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kMode_MR1: 94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kMode_MR2: 95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kMode_MR4: 96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kMode_MR8: { 97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register base = InputRegister(NextOffset(offset)); 98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register index = InputRegister(NextOffset(offset)); 99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ScaleFactor scale = ScaleFor(kMode_MR1, mode); 100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t disp = 0; 101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Operand(base, index, scale, disp); 102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kMode_MR1I: 104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kMode_MR2I: 105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kMode_MR4I: 106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kMode_MR8I: { 107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register base = InputRegister(NextOffset(offset)); 108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register index = InputRegister(NextOffset(offset)); 109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ScaleFactor scale = ScaleFor(kMode_MR1I, mode); 110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t disp = InputInt32(NextOffset(offset)); 111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Operand(base, index, scale, disp); 112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kMode_M1: { 114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register base = InputRegister(NextOffset(offset)); 115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t disp = 0; 116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Operand(base, disp); 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kMode_M2: 119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); // Should use kModeMR with more compact encoding instead 120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Operand(no_reg, 0); 121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kMode_M4: 122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kMode_M8: { 123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register index = InputRegister(NextOffset(offset)); 124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ScaleFactor scale = ScaleFor(kMode_M1, mode); 125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t disp = 0; 126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Operand(index, scale, disp); 127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kMode_M1I: 129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kMode_M2I: 130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kMode_M4I: 131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kMode_M8I: { 132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register index = InputRegister(NextOffset(offset)); 133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ScaleFactor scale = ScaleFor(kMode_M1I, mode); 134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t disp = InputInt32(NextOffset(offset)); 135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Operand(index, scale, disp); 136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 137f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch case kMode_Root: { 138f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Register base = kRootRegister; 139f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int32_t disp = InputInt32(NextOffset(offset)); 140f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return Operand(base, disp); 141f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kMode_None: 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Operand(no_reg, 0); 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); 147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Operand(no_reg, 0); 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand MemoryOperand(size_t first_input = 0) { 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return MemoryOperand(&first_input); 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace { 157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool HasImmediateInput(Instruction* instr, size_t index) { 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return instr->InputAt(index)->IsImmediate(); 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineLoadZero final : public OutOfLineCode { 164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OutOfLineLoadZero(CodeGenerator* gen, Register result) 166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : OutOfLineCode(gen), result_(result) {} 167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Generate() final { __ xorl(result_, result_); } 169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register const result_; 172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass OutOfLineLoadFloat32NaN final : public OutOfLineCode { 175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch OutOfLineLoadFloat32NaN(CodeGenerator* gen, XMMRegister result) 177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : OutOfLineCode(gen), result_(result) {} 178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void Generate() final { 180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Xorps(result_, result_); 181f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Divss(result_, result_); 182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier XMMRegister const result_; 186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass OutOfLineLoadFloat64NaN final : public OutOfLineCode { 189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public: 190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch OutOfLineLoadFloat64NaN(CodeGenerator* gen, XMMRegister result) 191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch : OutOfLineCode(gen), result_(result) {} 192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void Generate() final { 194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Xorpd(result_, result_); 195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Divsd(result_, result_); 196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private: 199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch XMMRegister const result_; 200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}; 201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineTruncateDoubleToI final : public OutOfLineCode { 203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OutOfLineTruncateDoubleToI(CodeGenerator* gen, Register result, 205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch XMMRegister input, 206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UnwindingInfoWriter* unwinding_info_writer) 207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch : OutOfLineCode(gen), 208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch result_(result), 209f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch input_(input), 210f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_(unwinding_info_writer) {} 211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Generate() final { 213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ subp(rsp, Immediate(kDoubleSize)); 214f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_->MaybeIncreaseBaseOffsetAt(__ pc_offset(), 215f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch kDoubleSize); 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Movsd(MemOperand(rsp, 0), input_); 217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ SlowTruncateToI(result_, rsp, 0); 218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ addp(rsp, Immediate(kDoubleSize)); 219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_->MaybeIncreaseBaseOffsetAt(__ pc_offset(), 220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch -kDoubleSize); 221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register const result_; 225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier XMMRegister const input_; 226f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UnwindingInfoWriter* const unwinding_info_writer_; 227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineRecordWrite final : public OutOfLineCode { 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutOfLineRecordWrite(CodeGenerator* gen, Register object, Operand operand, 233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register value, Register scratch0, Register scratch1, 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordWriteMode mode) 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : OutOfLineCode(gen), 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object_(object), 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch operand_(operand), 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value_(value), 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch scratch0_(scratch0), 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch scratch1_(scratch1), 241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch mode_(mode) {} 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Generate() final { 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mode_ > RecordWriteMode::kValueIsPointer) { 245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ JumpIfSmi(value_, exit()); 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 247109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ CheckPageFlag(value_, scratch0_, 248109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch MemoryChunk::kPointersToHereAreInterestingMask, zero, 249109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch exit()); 250109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch RememberedSetAction const remembered_set_action = 251109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET 252109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch : OMIT_REMEMBERED_SET; 253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SaveFPRegsMode const save_fp_mode = 254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; 255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_, 256109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch remembered_set_action, save_fp_mode); 257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ leap(scratch1_, operand_); 258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ CallStub(&stub); 259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register const object_; 263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand const operand_; 264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register const value_; 265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register const scratch0_; 266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register const scratch1_; 267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordWriteMode const mode_; 268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 270f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochclass WasmOutOfLineTrap final : public OutOfLineCode { 271f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch public: 27262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch WasmOutOfLineTrap(CodeGenerator* gen, int pc, bool frame_elided, 27362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int32_t position, Instruction* instr) 274f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch : OutOfLineCode(gen), 27562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch gen_(gen), 276f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch pc_(pc), 277f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch frame_elided_(frame_elided), 27862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch position_(position), 27962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch instr_(instr) {} 280f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 28162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // TODO(eholk): Refactor this method to take the code generator as a 28262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // parameter. 283f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void Generate() final { 28462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ RecordProtectedInstructionLanding(pc_); 285f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 286f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (frame_elided_) { 28762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ EnterFrame(StackFrame::WASM_COMPILED); 288f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 289f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 290f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch wasm::TrapReason trap_id = wasm::kTrapMemOutOfBounds; 291f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int trap_reason = wasm::WasmOpcodes::TrapReasonToMessageId(trap_id); 292f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch __ Push(Smi::FromInt(trap_reason)); 293f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch __ Push(Smi::FromInt(position_)); 29462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ Move(rsi, gen_->isolate()->native_context()); 295f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch __ CallRuntime(Runtime::kThrowWasmError); 29662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 29762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (instr_->reference_map() != nullptr) { 29862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch gen_->RecordSafepoint(instr_->reference_map(), Safepoint::kSimple, 0, 29962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Safepoint::kNoLazyDeopt); 30062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 301f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 302f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 303f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch private: 30462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CodeGenerator* gen_; 30562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int pc_; 306f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch bool frame_elided_; 307f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int32_t position_; 30862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Instruction* instr_; 309f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}; 310f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 31162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid EmitOOLTrapIfNeeded(Zone* zone, CodeGenerator* codegen, 31262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstructionCode opcode, size_t input_count, 31362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch X64OperandConverter& i, int pc, Instruction* instr) { 31462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const X64MemoryProtection protection = 31562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static_cast<X64MemoryProtection>(MiscField::decode(opcode)); 31662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (protection == X64MemoryProtection::kProtected) { 31762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const bool frame_elided = !codegen->frame_access_state()->has_frame(); 31862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const int32_t position = i.InputInt32(input_count - 1); 31962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch new (zone) WasmOutOfLineTrap(codegen, pc, frame_elided, position, instr); 32062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 32162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace 323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_UNOP(asm_instr) \ 326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier do { \ 327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Output()->IsRegister()) { \ 328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(i.OutputRegister()); \ 329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { \ 330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(i.OutputOperand()); \ 331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } while (0) 333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_BINOP(asm_instr) \ 336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier do { \ 337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (HasImmediateInput(instr, 1)) { \ 338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->InputAt(0)->IsRegister()) { \ 339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(i.InputRegister(0), i.InputImmediate(1)); \ 340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { \ 341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(i.InputOperand(0), i.InputImmediate(1)); \ 342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { \ 344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->InputAt(1)->IsRegister()) { \ 345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(i.InputRegister(0), i.InputRegister(1)); \ 346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { \ 347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(i.InputRegister(0), i.InputOperand(1)); \ 348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } while (0) 351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 352109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#define ASSEMBLE_COMPARE(asm_instr) \ 353109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch do { \ 354109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (AddressingModeField::decode(instr->opcode()) != kMode_None) { \ 355109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch size_t index = 0; \ 356109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Operand left = i.MemoryOperand(&index); \ 357109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (HasImmediateInput(instr, index)) { \ 358109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ asm_instr(left, i.InputImmediate(index)); \ 359109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { \ 360109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ asm_instr(left, i.InputRegister(index)); \ 361109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } \ 362109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { \ 363109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (HasImmediateInput(instr, 1)) { \ 364109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (instr->InputAt(0)->IsRegister()) { \ 365109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ asm_instr(i.InputRegister(0), i.InputImmediate(1)); \ 366109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { \ 367109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ asm_instr(i.InputOperand(0), i.InputImmediate(1)); \ 368109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } \ 369109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { \ 370109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (instr->InputAt(1)->IsRegister()) { \ 371109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ asm_instr(i.InputRegister(0), i.InputRegister(1)); \ 372109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { \ 373109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ asm_instr(i.InputRegister(0), i.InputOperand(1)); \ 374109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } \ 375109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } \ 376109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } \ 377109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } while (0) 378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_MULT(asm_instr) \ 380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier do { \ 381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (HasImmediateInput(instr, 1)) { \ 382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->InputAt(0)->IsRegister()) { \ 383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(i.OutputRegister(), i.InputRegister(0), \ 384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier i.InputImmediate(1)); \ 385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { \ 386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(i.OutputRegister(), i.InputOperand(0), \ 387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier i.InputImmediate(1)); \ 388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { \ 390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->InputAt(1)->IsRegister()) { \ 391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(i.OutputRegister(), i.InputRegister(1)); \ 392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { \ 393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(i.OutputRegister(), i.InputOperand(1)); \ 394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } while (0) 397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_SHIFT(asm_instr, width) \ 400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier do { \ 401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (HasImmediateInput(instr, 1)) { \ 402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Output()->IsRegister()) { \ 403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(i.OutputRegister(), Immediate(i.InputInt##width(1))); \ 404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { \ 405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(i.OutputOperand(), Immediate(i.InputInt##width(1))); \ 406958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 407958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { \ 408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->Output()->IsRegister()) { \ 409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr##_cl(i.OutputRegister()); \ 410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { \ 411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr##_cl(i.OutputOperand()); \ 412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } while (0) 415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_MOVX(asm_instr) \ 418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->addressing_mode() != kMode_None) { \ 420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr(i.OutputRegister(), i.MemoryOperand()); \ 421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (instr->InputAt(0)->IsRegister()) { \ 422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr(i.OutputRegister(), i.InputRegister(0)); \ 423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr(i.OutputRegister(), i.InputOperand(0)); \ 425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_SSE_BINOP(asm_instr) \ 429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier do { \ 430bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(1)->IsFPRegister()) { \ 431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); \ 432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { \ 433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(i.InputDoubleRegister(0), i.InputOperand(1)); \ 434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } while (0) 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_SSE_UNOP(asm_instr) \ 438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 439bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { \ 440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \ 441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr(i.OutputDoubleRegister(), i.InputOperand(0)); \ 443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (0) 445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_AVX_BINOP(asm_instr) \ 447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier do { \ 448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CpuFeatureScope avx_scope(masm(), AVX); \ 449bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(1)->IsFPRegister()) { \ 450958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ 451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier i.InputDoubleRegister(1)); \ 452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { \ 453958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ 454958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier i.InputOperand(1)); \ 455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } while (0) 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 458f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr, OutOfLineLoadNaN) \ 459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier do { \ 460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto result = i.OutputDoubleRegister(); \ 461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto buffer = i.InputRegister(0); \ 462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto index1 = i.InputRegister(1); \ 463bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch auto index2 = i.InputUint32(2); \ 464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OutOfLineCode* ool; \ 465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->InputAt(3)->IsRegister()) { \ 466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto length = i.InputRegister(3); \ 467c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(0u, index2); \ 468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ cmpl(index1, length); \ 469958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ool = new (zone()) OutOfLineLoadNaN(this, result); \ 470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { \ 471bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch auto length = i.InputUint32(3); \ 47213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RelocInfo::Mode rmode = i.ToConstant(instr->InputAt(3)).rmode(); \ 473958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_LE(index2, length); \ 47413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ cmpl(index1, Immediate(length - index2, rmode)); \ 475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class OutOfLineLoadFloat final : public OutOfLineCode { \ 476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: \ 477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result, \ 478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register buffer, Register index1, int32_t index2, \ 47913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch int32_t length, RelocInfo::Mode rmode) \ 480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : OutOfLineCode(gen), \ 481958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result_(result), \ 482958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier buffer_(buffer), \ 483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier index1_(index1), \ 484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier index2_(index2), \ 48513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch length_(length), \ 48613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch rmode_(rmode) {} \ 487958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Generate() final { \ 489958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ leal(kScratchRegister, Operand(index1_, index2_)); \ 490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Pcmpeqd(result_, result_); \ 49113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ cmpl(kScratchRegister, Immediate(length_, rmode_)); \ 492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ j(above_equal, exit()); \ 493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(result_, \ 494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Operand(buffer_, kScratchRegister, times_1, 0)); \ 495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: \ 498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier XMMRegister const result_; \ 499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register const buffer_; \ 500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register const index1_; \ 501958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t const index2_; \ 502958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t const length_; \ 50313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RelocInfo::Mode rmode_; \ 504958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier }; \ 50513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ool = new (zone()) OutOfLineLoadFloat(this, result, buffer, index1, \ 50613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch index2, length, rmode); \ 507958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 508958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ j(above_equal, ool->entry()); \ 509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(result, Operand(buffer, index1, times_1, index2)); \ 510958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ bind(ool->exit()); \ 511958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } while (false) 512958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 513958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ 514958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier do { \ 515958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto result = i.OutputRegister(); \ 516958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto buffer = i.InputRegister(0); \ 517958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto index1 = i.InputRegister(1); \ 518bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch auto index2 = i.InputUint32(2); \ 519958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OutOfLineCode* ool; \ 520958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->InputAt(3)->IsRegister()) { \ 521958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto length = i.InputRegister(3); \ 522c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(0u, index2); \ 523958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ cmpl(index1, length); \ 524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ool = new (zone()) OutOfLineLoadZero(this, result); \ 525958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { \ 526bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch auto length = i.InputUint32(3); \ 52713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RelocInfo::Mode rmode = i.ToConstant(instr->InputAt(3)).rmode(); \ 528958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_LE(index2, length); \ 52913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ cmpl(index1, Immediate(length - index2, rmode)); \ 530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class OutOfLineLoadInteger final : public OutOfLineCode { \ 531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: \ 532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OutOfLineLoadInteger(CodeGenerator* gen, Register result, \ 533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register buffer, Register index1, int32_t index2, \ 53413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch int32_t length, RelocInfo::Mode rmode) \ 535958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : OutOfLineCode(gen), \ 536958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result_(result), \ 537958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier buffer_(buffer), \ 538958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier index1_(index1), \ 539958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier index2_(index2), \ 54013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch length_(length), \ 54113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch rmode_(rmode) {} \ 542958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Generate() final { \ 544958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label oob; \ 545958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ leal(kScratchRegister, Operand(index1_, index2_)); \ 54613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ cmpl(kScratchRegister, Immediate(length_, rmode_)); \ 547958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ j(above_equal, &oob, Label::kNear); \ 548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(result_, \ 549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Operand(buffer_, kScratchRegister, times_1, 0)); \ 550958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ jmp(exit()); \ 551958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ bind(&oob); \ 552958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ xorl(result_, result_); \ 553958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: \ 556958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register const result_; \ 557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register const buffer_; \ 558958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register const index1_; \ 559958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t const index2_; \ 560958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t const length_; \ 56113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RelocInfo::Mode const rmode_; \ 562958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier }; \ 56313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ool = new (zone()) OutOfLineLoadInteger(this, result, buffer, index1, \ 56413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch index2, length, rmode); \ 565958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 566958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ j(above_equal, ool->entry()); \ 567958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(result, Operand(buffer, index1, times_1, index2)); \ 568958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ bind(ool->exit()); \ 569958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } while (false) 570958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 571958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr) \ 572958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier do { \ 573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto buffer = i.InputRegister(0); \ 574958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto index1 = i.InputRegister(1); \ 575bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch auto index2 = i.InputUint32(2); \ 576958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto value = i.InputDoubleRegister(4); \ 577958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->InputAt(3)->IsRegister()) { \ 578958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto length = i.InputRegister(3); \ 579c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(0u, index2); \ 580958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label done; \ 581958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ cmpl(index1, length); \ 582958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ j(above_equal, &done, Label::kNear); \ 583958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ 584958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ bind(&done); \ 585958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { \ 586bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch auto length = i.InputUint32(3); \ 58713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RelocInfo::Mode rmode = i.ToConstant(instr->InputAt(3)).rmode(); \ 588958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_LE(index2, length); \ 58913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ cmpl(index1, Immediate(length - index2, rmode)); \ 590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class OutOfLineStoreFloat final : public OutOfLineCode { \ 591958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: \ 592958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OutOfLineStoreFloat(CodeGenerator* gen, Register buffer, \ 593958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register index1, int32_t index2, int32_t length, \ 59413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch XMMRegister value, RelocInfo::Mode rmode) \ 595958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : OutOfLineCode(gen), \ 596958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier buffer_(buffer), \ 597958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier index1_(index1), \ 598958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier index2_(index2), \ 599958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier length_(length), \ 60013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch value_(value), \ 60113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch rmode_(rmode) {} \ 602958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Generate() final { \ 604958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ leal(kScratchRegister, Operand(index1_, index2_)); \ 60513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ cmpl(kScratchRegister, Immediate(length_, rmode_)); \ 606958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ j(above_equal, exit()); \ 607958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(Operand(buffer_, kScratchRegister, times_1, 0), \ 608958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier value_); \ 609958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 610958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 611958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: \ 612958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register const buffer_; \ 613958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register const index1_; \ 614958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t const index2_; \ 615958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t const length_; \ 616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier XMMRegister const value_; \ 61713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RelocInfo::Mode rmode_; \ 618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier }; \ 61913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch auto ool = new (zone()) OutOfLineStoreFloat( \ 62013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch this, buffer, index1, index2, length, value, rmode); \ 621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ j(above_equal, ool->entry()); \ 622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ 623958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ bind(ool->exit()); \ 624958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 625958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } while (false) 626958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 627958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Value) \ 628958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier do { \ 629958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto buffer = i.InputRegister(0); \ 630958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto index1 = i.InputRegister(1); \ 631bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch auto index2 = i.InputUint32(2); \ 632958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->InputAt(3)->IsRegister()) { \ 633958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto length = i.InputRegister(3); \ 634c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(0u, index2); \ 635958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label done; \ 636958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ cmpl(index1, length); \ 637958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ j(above_equal, &done, Label::kNear); \ 638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ 639958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ bind(&done); \ 640958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { \ 641bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch auto length = i.InputUint32(3); \ 64213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RelocInfo::Mode rmode = i.ToConstant(instr->InputAt(3)).rmode(); \ 643958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_LE(index2, length); \ 64413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ cmpl(index1, Immediate(length - index2, rmode)); \ 645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class OutOfLineStoreInteger final : public OutOfLineCode { \ 646958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: \ 647958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OutOfLineStoreInteger(CodeGenerator* gen, Register buffer, \ 648958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register index1, int32_t index2, int32_t length, \ 64913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Value value, RelocInfo::Mode rmode) \ 650958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : OutOfLineCode(gen), \ 651958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier buffer_(buffer), \ 652958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier index1_(index1), \ 653958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier index2_(index2), \ 654958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier length_(length), \ 65513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch value_(value), \ 65613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch rmode_(rmode) {} \ 657958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Generate() final { \ 659958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ leal(kScratchRegister, Operand(index1_, index2_)); \ 66013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ cmpl(kScratchRegister, Immediate(length_, rmode_)); \ 661958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ j(above_equal, exit()); \ 662958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(Operand(buffer_, kScratchRegister, times_1, 0), \ 663958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier value_); \ 664958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 665958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier \ 666958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: \ 667958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register const buffer_; \ 668958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register const index1_; \ 669958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t const index2_; \ 670958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t const length_; \ 671958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Value const value_; \ 67213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RelocInfo::Mode rmode_; \ 673958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier }; \ 67413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch auto ool = new (zone()) OutOfLineStoreInteger( \ 67513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch this, buffer, index1, index2, length, value, rmode); \ 676958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ j(above_equal, ool->entry()); \ 677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ 678958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ bind(ool->exit()); \ 679958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } while (false) 681958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ 683958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier do { \ 684958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->InputAt(4)->IsRegister()) { \ 685958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register value = i.InputRegister(4); \ 686958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Register); \ 687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { \ 688958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Immediate value = i.InputImmediate(4); \ 689958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Immediate); \ 690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } \ 691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } while (false) 692958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 69313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#define ASSEMBLE_IEEE754_BINOP(name) \ 69413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch do { \ 69513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ PrepareCallCFunction(2); \ 69613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ 69713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 2); \ 69813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } while (false) 69913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 70013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#define ASSEMBLE_IEEE754_UNOP(name) \ 70113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch do { \ 70213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ PrepareCallCFunction(1); \ 70313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ 70413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 1); \ 70513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } while (false) 70613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 7073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid CodeGenerator::AssembleDeconstructFrame() { 708f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_.MarkFrameDeconstructed(__ pc_offset()); 7093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ movq(rsp, rbp); 7103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ popq(rbp); 7113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 7123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 713f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::AssemblePrepareTailCall() { 7143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (frame_access_state()->has_frame()) { 715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movq(rbp, MemOperand(rbp, 0)); 716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->SetFrameAccessToSP(); 718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 7203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, 7213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register scratch1, 7223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register scratch2, 7233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register scratch3) { 7243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3)); 7253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label done; 7263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 7273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Check if current frame is an arguments adaptor frame. 72862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ cmpp(Operand(rbp, CommonFrameConstants::kContextOrFrameTypeOffset), 72962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Immediate(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR))); 7303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ j(not_equal, &done, Label::kNear); 7313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 7323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Load arguments count from current arguments adaptor frame (note, it 7333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // does not include receiver). 7343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register caller_args_count_reg = scratch1; 7353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ SmiToInteger32( 7363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch caller_args_count_reg, 7373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Operand(rbp, ArgumentsAdaptorFrameConstants::kLengthOffset)); 7383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 7393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ParameterCount callee_args_count(args_reg); 7403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2, 7413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch scratch3, ReturnAddressState::kOnStack); 7423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ bind(&done); 7433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 745f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace { 746f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 747f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid AdjustStackPointerForTailCall(MacroAssembler* masm, 748f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FrameAccessState* state, 749f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int new_slot_above_sp, 750f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool allow_shrinkage = true) { 751f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int current_sp_offset = state->GetSPToFPSlotCount() + 752f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch StandardFrameConstants::kFixedSlotCountAboveFp; 753f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int stack_slot_delta = new_slot_above_sp - current_sp_offset; 754f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (stack_slot_delta > 0) { 755f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch masm->subq(rsp, Immediate(stack_slot_delta * kPointerSize)); 756f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch state->IncreaseSPDelta(stack_slot_delta); 757f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (allow_shrinkage && stack_slot_delta < 0) { 758f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch masm->addq(rsp, Immediate(-stack_slot_delta * kPointerSize)); 759f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch state->IncreaseSPDelta(stack_slot_delta); 760f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 761f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 762f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 763f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} // namespace 764f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 765f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::AssembleTailCallBeforeGap(Instruction* instr, 766f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int first_unused_stack_slot) { 767f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CodeGenerator::PushTypeFlags flags(kImmediatePush | kScalarPush); 768f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ZoneVector<MoveOperands*> pushes(zone()); 769f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch GetPushCompatibleMoves(instr, flags, &pushes); 770f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 771f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!pushes.empty() && 772f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (LocationOperand::cast(pushes.back()->destination()).index() + 1 == 773f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch first_unused_stack_slot)) { 774f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch X64OperandConverter g(this, instr); 775f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (auto move : pushes) { 776f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LocationOperand destination_location( 777f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LocationOperand::cast(move->destination())); 778f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand source(move->source()); 779f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AdjustStackPointerForTailCall(masm(), frame_access_state(), 780f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch destination_location.index()); 781f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (source.IsStackSlot()) { 782f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LocationOperand source_location(LocationOperand::cast(source)); 783f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Push(g.SlotToOperand(source_location.index())); 784f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (source.IsRegister()) { 785f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LocationOperand source_location(LocationOperand::cast(source)); 786f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Push(source_location.GetRegister()); 787f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (source.IsImmediate()) { 788f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Push(Immediate(ImmediateOperand::cast(source).inline_value())); 789f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 790f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Pushes of non-scalar data types is not supported. 791f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNIMPLEMENTED(); 792f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 793f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_access_state()->IncreaseSPDelta(1); 794f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch move->Eliminate(); 795f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 796f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 797f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AdjustStackPointerForTailCall(masm(), frame_access_state(), 798f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch first_unused_stack_slot, false); 799f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 800f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 801f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::AssembleTailCallAfterGap(Instruction* instr, 802f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int first_unused_stack_slot) { 803f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AdjustStackPointerForTailCall(masm(), frame_access_state(), 804f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch first_unused_stack_slot); 805f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 806f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Assembles an instruction after register allocation, producing machine code. 808bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( 809bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Instruction* instr) { 810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X64OperandConverter i(this, instr); 8113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch InstructionCode opcode = instr->opcode(); 8123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode); 8133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch switch (arch_opcode) { 814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArchCallCodeObject: { 815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EnsureSpaceForLazyDeopt(); 816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasImmediateInput(instr, 0)) { 817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); 818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Call(code, RelocInfo::CODE_TARGET); 819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg = i.InputRegister(0); 821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ addp(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); 822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ call(reg); 823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordCallPosition(instr); 825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->ClearSPDelta(); 826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 8283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kArchTailCallCodeObjectFromJSFunction: 829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchTailCallCodeObject: { 8303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) { 8313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, 8323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch i.TempRegister(0), i.TempRegister(1), 8333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch i.TempRegister(2)); 8343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, 0)) { 836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); 837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ jmp(code, RelocInfo::CODE_TARGET); 838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register reg = i.InputRegister(0); 840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ addp(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); 841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ jmp(reg); 842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 843f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_.MarkBlockWillExit(); 844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->ClearSPDelta(); 845f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_access_state()->SetFrameAccessToDefault(); 846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 848bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kArchTailCallAddress: { 849bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CHECK(!HasImmediateInput(instr, 0)); 850bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Register reg = i.InputRegister(0); 851bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ jmp(reg); 852f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_.MarkBlockWillExit(); 853bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch frame_access_state()->ClearSPDelta(); 854f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_access_state()->SetFrameAccessToDefault(); 855bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 856bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArchCallJSFunction: { 858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EnsureSpaceForLazyDeopt(); 859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register func = i.InputRegister(0); 860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_debug_code) { 861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check the function's context matches the context argument. 862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset)); 863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Assert(equal, kWrongFunctionContext); 864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Call(FieldOperand(func, JSFunction::kCodeEntryOffset)); 866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->ClearSPDelta(); 867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordCallPosition(instr); 868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 870c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case kArchTailCallJSFunctionFromJSFunction: { 871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register func = i.InputRegister(0); 872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code) { 873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check the function's context matches the context argument. 874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset)); 875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Assert(equal, kWrongFunctionContext); 876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 877c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, 878c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i.TempRegister(0), i.TempRegister(1), 879c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i.TempRegister(2)); 880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset)); 881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->ClearSPDelta(); 882f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_access_state()->SetFrameAccessToDefault(); 883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchPrepareCallCFunction: { 886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Frame alignment requires using FP-relative frame addressing. 887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->SetFrameAccessToFP(); 888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int const num_parameters = MiscField::decode(instr->opcode()); 889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ PrepareCallCFunction(num_parameters); 890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchPrepareTailCall: 893f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AssemblePrepareTailCall(); 894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchCallCFunction: { 896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int const num_parameters = MiscField::decode(instr->opcode()); 897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, 0)) { 898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExternalReference ref = i.InputExternalReference(0); 899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ CallCFunction(ref, num_parameters); 900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register func = i.InputRegister(0); 902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ CallCFunction(func, num_parameters); 903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->SetFrameAccessToDefault(); 905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->ClearSPDelta(); 906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArchJmp: 909958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AssembleArchJump(i.InputRpo(0)); 910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchLookupSwitch: 912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleArchLookupSwitch(instr); 913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchTableSwitch: 915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleArchTableSwitch(instr); 916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 91713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kArchComment: { 91813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Address comment_string = i.InputExternalReference(0).address(); 91913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ RecordComment(reinterpret_cast<const char*>(comment_string)); 92013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 92113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 92213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kArchDebugBreak: 92313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ int3(); 92413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArchNop: 926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchThrowTerminator: 927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // don't emit code for nops. 928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchDeoptimize: { 930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int deopt_state_id = 931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore()); 93262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CodeGenResult result = 93362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AssembleDeoptimizerCall(deopt_state_id, current_source_position_); 934bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (result != kSuccess) return result; 935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kArchRet: 938c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch AssembleReturn(instr->InputAt(0)); 939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 940958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kArchStackPointer: 941958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ movq(i.OutputRegister(), rsp); 942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchFramePointer: 944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movq(i.OutputRegister(), rbp); 945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 946109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case kArchParentFramePointer: 9473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (frame_access_state()->has_frame()) { 948109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ movq(i.OutputRegister(), Operand(rbp, 0)); 949109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 950109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ movq(i.OutputRegister(), rbp); 951109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 952109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 953958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kArchTruncateDoubleToI: { 954958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto result = i.OutputRegister(); 955958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto input = i.InputDoubleRegister(0); 956f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto ool = new (zone()) OutOfLineTruncateDoubleToI( 957f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch this, result, input, &unwinding_info_writer_); 958bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // We use Cvttsd2siq instead of Cvttsd2si due to performance reasons. The 959bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // use of Cvttsd2siq requires the movl below to avoid sign extension. 960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvttsd2siq(result, input); 961958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ cmpq(result, Immediate(1)); 962958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ j(overflow, ool->entry()); 963958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ bind(ool->exit()); 964bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ movl(result, result); 965958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 966958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchStoreWithWriteBarrier: { 968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordWriteMode mode = 969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<RecordWriteMode>(MiscField::decode(instr->opcode())); 970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register object = i.InputRegister(0); 971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; 972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand operand = i.MemoryOperand(&index); 973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register value = i.InputRegister(index); 974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch0 = i.TempRegister(0); 975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch1 = i.TempRegister(1); 976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto ool = new (zone()) OutOfLineRecordWrite(this, object, operand, value, 977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch scratch0, scratch1, mode); 978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movp(operand, value); 979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ CheckPageFlag(object, scratch0, 980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemoryChunk::kPointersFromHereAreInterestingMask, 981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch not_zero, ool->entry()); 982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(ool->exit()); 983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 985109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case kArchStackSlot: { 986109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FrameOffset offset = 987109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch frame_access_state()->GetFrameOffset(i.InputInt32(0)); 988109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Register base; 989109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (offset.from_stack_pointer()) { 990109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch base = rsp; 991109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 992109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch base = rbp; 993109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 994109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ leaq(i.OutputRegister(), Operand(base, offset.offset())); 995109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 996109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 997f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Acos: 998f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(acos); 999f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1000f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Acosh: 1001f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(acosh); 1002f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1003f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Asin: 1004f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(asin); 1005f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1006f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Asinh: 1007f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(asinh); 1008f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 100913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Atan: 101013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(atan); 101113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 101213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Atanh: 101313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(atanh); 101413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 1015f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Atan2: 1016f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_BINOP(atan2); 1017f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 101813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Cbrt: 101913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(cbrt); 102013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 102113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Cos: 102213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(cos); 102313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 1024f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Cosh: 1025f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(cosh); 1026f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 102713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Exp: 102813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(exp); 102913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 103013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Expm1: 103113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(expm1); 103213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 103313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Log: 103413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(log); 103513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 103613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Log1p: 103713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(log1p); 103813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 103913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Log2: 104013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(log2); 104113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 104213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Log10: 104313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(log10); 104413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 1045f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Pow: { 1046f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // TODO(bmeurer): Improve integration of the stub. 1047f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movsd(xmm2, xmm0); 1048f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MathPowStub stub(isolate(), MathPowStub::DOUBLE); 1049f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ CallStub(&stub); 1050f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movsd(xmm0, xmm3); 1051f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1052f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 105313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Sin: 105413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(sin); 105513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 1056f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Sinh: 1057f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(sinh); 1058f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 105913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Tan: 106013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(tan); 106113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 1062f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Tanh: 1063f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(tanh); 1064f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Add32: 1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLE_BINOP(addl); 1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Add: 1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLE_BINOP(addq); 1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Sub32: 1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLE_BINOP(subl); 1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Sub: 1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLE_BINOP(subq); 1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64And32: 1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLE_BINOP(andl); 1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64And: 1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLE_BINOP(andq); 1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX64Cmp8: 10843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_COMPARE(cmpb); 10853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 10863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX64Cmp16: 10873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_COMPARE(cmpw); 10883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Cmp32: 1090109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ASSEMBLE_COMPARE(cmpl); 1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Cmp: 1093109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ASSEMBLE_COMPARE(cmpq); 1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 10953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX64Test8: 10963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_COMPARE(testb); 10973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 10983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX64Test16: 10993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_COMPARE(testw); 11003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Test32: 1102109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ASSEMBLE_COMPARE(testl); 1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Test: 1105109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ASSEMBLE_COMPARE(testq); 1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Imul32: 1108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSEMBLE_MULT(imull); 1109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kX64Imul: 1111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSEMBLE_MULT(imulq); 1112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kX64ImulHigh32: 1114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->InputAt(1)->IsRegister()) { 1115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ imull(i.InputRegister(1)); 1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ imull(i.InputOperand(1)); 1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kX64UmulHigh32: 1121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->InputAt(1)->IsRegister()) { 1122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ mull(i.InputRegister(1)); 1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ mull(i.InputOperand(1)); 1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Idiv32: 1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ cdq(); 1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ idivl(i.InputRegister(1)); 1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Idiv: 1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ cqo(); 1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ idivq(i.InputRegister(1)); 1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Udiv32: 1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ xorl(rdx, rdx); 1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ divl(i.InputRegister(1)); 1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Udiv: 1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ xorq(rdx, rdx); 1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ divq(i.InputRegister(1)); 1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kX64Not: 1144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSEMBLE_UNOP(notq); 1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kX64Not32: 1147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSEMBLE_UNOP(notl); 1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kX64Neg: 1150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSEMBLE_UNOP(negq); 1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kX64Neg32: 1153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSEMBLE_UNOP(negl); 1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Or32: 1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLE_BINOP(orl); 1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Or: 1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLE_BINOP(orq); 1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Xor32: 1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLE_BINOP(xorl); 1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Xor: 1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLE_BINOP(xorq); 1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Shl32: 1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLE_SHIFT(shll, 5); 1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Shl: 1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLE_SHIFT(shlq, 6); 1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Shr32: 1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLE_SHIFT(shrl, 5); 1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Shr: 1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLE_SHIFT(shrq, 6); 1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Sar32: 1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLE_SHIFT(sarl, 5); 1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Sar: 1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLE_SHIFT(sarq, 6); 1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Ror32: 1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLE_SHIFT(rorl, 5); 1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Ror: 1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASSEMBLE_SHIFT(rorq, 6); 1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX64Lzcnt: 1192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(0)->IsRegister()) { 1193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Lzcntq(i.OutputRegister(), i.InputRegister(0)); 1194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Lzcntq(i.OutputRegister(), i.InputOperand(0)); 1196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX64Lzcnt32: 1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(0)->IsRegister()) { 1200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Lzcntl(i.OutputRegister(), i.InputRegister(0)); 1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Lzcntl(i.OutputRegister(), i.InputOperand(0)); 1203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX64Tzcnt: 1206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(0)->IsRegister()) { 1207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Tzcntq(i.OutputRegister(), i.InputRegister(0)); 1208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Tzcntq(i.OutputRegister(), i.InputOperand(0)); 1210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX64Tzcnt32: 1213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(0)->IsRegister()) { 1214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Tzcntl(i.OutputRegister(), i.InputRegister(0)); 1215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Tzcntl(i.OutputRegister(), i.InputOperand(0)); 1217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX64Popcnt: 1220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(0)->IsRegister()) { 1221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Popcntq(i.OutputRegister(), i.InputRegister(0)); 1222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Popcntq(i.OutputRegister(), i.InputOperand(0)); 1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX64Popcnt32: 1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(0)->IsRegister()) { 1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Popcntl(i.OutputRegister(), i.InputRegister(0)); 1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Popcntl(i.OutputRegister(), i.InputOperand(0)); 1231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat32Cmp: 1234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_SSE_BINOP(Ucomiss); 1235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat32Add: 1237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_SSE_BINOP(addss); 1238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat32Sub: 1240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_SSE_BINOP(subss); 1241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat32Mul: 1243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_SSE_BINOP(mulss); 1244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat32Div: 1246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_SSE_BINOP(divss); 1247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Don't delete this mov. It may improve performance on some CPUs, 1248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // when there is a (v)mulss depending on the result. 1249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movaps(i.OutputDoubleRegister(), i.OutputDoubleRegister()); 1250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat32Abs: { 1252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(bmeurer): Use RIP relative 128-bit constants. 1253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); 1254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ psrlq(kScratchDoubleReg, 33); 1255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ andps(i.OutputDoubleRegister(), kScratchDoubleReg); 1256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat32Neg: { 1259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(bmeurer): Use RIP relative 128-bit constants. 1260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); 1261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ psllq(kScratchDoubleReg, 31); 1262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ xorps(i.OutputDoubleRegister(), kScratchDoubleReg); 1263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat32Sqrt: 1266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_SSE_UNOP(sqrtss); 1267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat32ToFloat64: 1269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_SSE_UNOP(Cvtss2sd); 1270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat32Round: { 1272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope sse_scope(masm(), SSE4_1); 1273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RoundingMode const mode = 1274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<RoundingMode>(MiscField::decode(instr->opcode())); 1275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Roundss(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode); 1276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1278109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case kSSEFloat32ToInt32: 1279bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1280109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ Cvttss2si(i.OutputRegister(), i.InputDoubleRegister(0)); 1281109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 1282109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ Cvttss2si(i.OutputRegister(), i.InputOperand(0)); 1283109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1284109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 1285109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case kSSEFloat32ToUint32: { 1286bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1287109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ Cvttss2siq(i.OutputRegister(), i.InputDoubleRegister(0)); 1288109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 1289109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ Cvttss2siq(i.OutputRegister(), i.InputOperand(0)); 1290109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1291109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 1292109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kSSEFloat64Cmp: 1294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_SSE_BINOP(Ucomisd); 1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kSSEFloat64Add: 1297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_SSE_BINOP(addsd); 1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kSSEFloat64Sub: 1300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_SSE_BINOP(subsd); 1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kSSEFloat64Mul: 1303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_SSE_BINOP(mulsd); 1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kSSEFloat64Div: 1306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_SSE_BINOP(divsd); 1307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Don't delete this mov. It may improve performance on some CPUs, 1308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // when there is a (v)mulsd depending on the result. 1309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Movapd(i.OutputDoubleRegister(), i.OutputDoubleRegister()); 1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kSSEFloat64Mod: { 1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ subq(rsp, Immediate(kDoubleSize)); 1313f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), 1314f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch kDoubleSize); 1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Move values to st(0) and st(1). 1316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(1)); 1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ fld_d(Operand(rsp, 0)); 1318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0)); 1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ fld_d(Operand(rsp, 0)); 1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Loop while fprem isn't done. 1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label mod_loop; 1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&mod_loop); 1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This instructions traps on all kinds inputs, but we are assuming the 1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // floating point control word is set to ignore them all. 1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ fprem(); 1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The following 2 instruction implicitly use rax. 1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ fnstsw_ax(); 1328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (CpuFeatures::IsSupported(SAHF)) { 1329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CpuFeatureScope sahf_scope(masm(), SAHF); 1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ sahf(); 1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ shrl(rax, Immediate(8)); 1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ andl(rax, Immediate(0xFF)); 1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ pushq(rax); 1335f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), 1336f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch kPointerSize); 1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ popfq(); 1338f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), 1339f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch -kPointerSize); 1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ j(parity_even, &mod_loop); 1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Move output to stack and clean up. 1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ fstp(1); 1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ fstp_d(Operand(rsp, 0)); 1345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Movsd(i.OutputDoubleRegister(), Operand(rsp, 0)); 1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ addq(rsp, Immediate(kDoubleSize)); 1347f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), 1348f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch -kDoubleSize); 1349f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1350f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1351f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kSSEFloat32Max: { 1352f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Label compare_nan, compare_swap, done_compare; 1353f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (instr->InputAt(1)->IsFPRegister()) { 1354f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Ucomiss(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); 1355f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 1356f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Ucomiss(i.InputDoubleRegister(0), i.InputOperand(1)); 1357f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1358f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto ool = 1359f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch new (zone()) OutOfLineLoadFloat32NaN(this, i.OutputDoubleRegister()); 1360f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(parity_even, ool->entry()); 1361f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(above, &done_compare, Label::kNear); 1362f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(below, &compare_swap, Label::kNear); 1363f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movmskps(kScratchRegister, i.InputDoubleRegister(0)); 1364f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ testl(kScratchRegister, Immediate(1)); 1365f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(zero, &done_compare, Label::kNear); 1366f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&compare_swap); 1367f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (instr->InputAt(1)->IsFPRegister()) { 1368f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movss(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); 1369f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 1370f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movss(i.InputDoubleRegister(0), i.InputOperand(1)); 1371f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1372f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&done_compare); 1373f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(ool->exit()); 1374f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1375f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1376f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kSSEFloat32Min: { 1377f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Label compare_swap, done_compare; 1378f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (instr->InputAt(1)->IsFPRegister()) { 1379f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Ucomiss(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); 1380f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 1381f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Ucomiss(i.InputDoubleRegister(0), i.InputOperand(1)); 1382f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1383f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto ool = 1384f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch new (zone()) OutOfLineLoadFloat32NaN(this, i.OutputDoubleRegister()); 1385f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(parity_even, ool->entry()); 1386f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(below, &done_compare, Label::kNear); 1387f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(above, &compare_swap, Label::kNear); 1388f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (instr->InputAt(1)->IsFPRegister()) { 1389f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movmskps(kScratchRegister, i.InputDoubleRegister(1)); 1390f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 1391f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movss(kScratchDoubleReg, i.InputOperand(1)); 1392f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movmskps(kScratchRegister, kScratchDoubleReg); 1393f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1394f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ testl(kScratchRegister, Immediate(1)); 1395f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(zero, &done_compare, Label::kNear); 1396f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&compare_swap); 1397f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (instr->InputAt(1)->IsFPRegister()) { 1398f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movss(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); 1399f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 1400f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movss(i.InputDoubleRegister(0), i.InputOperand(1)); 1401f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1402f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&done_compare); 1403f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(ool->exit()); 1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1406f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kSSEFloat64Max: { 1407f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Label compare_nan, compare_swap, done_compare; 1408f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (instr->InputAt(1)->IsFPRegister()) { 1409f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Ucomisd(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); 1410f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 1411f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Ucomisd(i.InputDoubleRegister(0), i.InputOperand(1)); 1412f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1413f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto ool = 1414f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch new (zone()) OutOfLineLoadFloat64NaN(this, i.OutputDoubleRegister()); 1415f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(parity_even, ool->entry()); 1416f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(above, &done_compare, Label::kNear); 1417f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(below, &compare_swap, Label::kNear); 1418f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movmskpd(kScratchRegister, i.InputDoubleRegister(0)); 1419f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ testl(kScratchRegister, Immediate(1)); 1420f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(zero, &done_compare, Label::kNear); 1421f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&compare_swap); 1422f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (instr->InputAt(1)->IsFPRegister()) { 1423f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); 1424f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 1425f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movsd(i.InputDoubleRegister(0), i.InputOperand(1)); 1426f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1427f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&done_compare); 1428f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(ool->exit()); 1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1430f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1431f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kSSEFloat64Min: { 1432f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Label compare_swap, done_compare; 1433f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (instr->InputAt(1)->IsFPRegister()) { 1434f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Ucomisd(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); 1435f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 1436f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Ucomisd(i.InputDoubleRegister(0), i.InputOperand(1)); 1437f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1438f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto ool = 1439f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch new (zone()) OutOfLineLoadFloat64NaN(this, i.OutputDoubleRegister()); 1440f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(parity_even, ool->entry()); 1441f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(below, &done_compare, Label::kNear); 1442f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(above, &compare_swap, Label::kNear); 1443f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (instr->InputAt(1)->IsFPRegister()) { 1444f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movmskpd(kScratchRegister, i.InputDoubleRegister(1)); 1445f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 1446f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movsd(kScratchDoubleReg, i.InputOperand(1)); 1447f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movmskpd(kScratchRegister, kScratchDoubleReg); 1448f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1449f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ testl(kScratchRegister, Immediate(1)); 1450f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(zero, &done_compare, Label::kNear); 1451f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&compare_swap); 1452f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (instr->InputAt(1)->IsFPRegister()) { 1453f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); 1454f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 1455f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movsd(i.InputDoubleRegister(0), i.InputOperand(1)); 1456f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1457f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&done_compare); 1458f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(ool->exit()); 1459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1460f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat64Abs: { 1462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(bmeurer): Use RIP relative 128-bit constants. 1463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); 1464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ psrlq(kScratchDoubleReg, 1); 1465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ andpd(i.OutputDoubleRegister(), kScratchDoubleReg); 1466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat64Neg: { 1469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(bmeurer): Use RIP relative 128-bit constants. 1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); 1471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ psllq(kScratchDoubleReg, 63); 1472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ xorpd(i.OutputDoubleRegister(), kScratchDoubleReg); 1473958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat64Sqrt: 1476f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ASSEMBLE_SSE_UNOP(Sqrtsd); 1477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat64Round: { 1479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CpuFeatureScope sse_scope(masm(), SSE4_1); 1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RoundingMode const mode = 1481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<RoundingMode>(MiscField::decode(instr->opcode())); 1482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode); 1483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat64ToFloat32: 1486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_SSE_UNOP(Cvtsd2ss); 1487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat64ToInt32: 1489bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvttsd2si(i.OutputRegister(), i.InputDoubleRegister(0)); 1491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvttsd2si(i.OutputRegister(), i.InputOperand(0)); 1493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat64ToUint32: { 1496bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0)); 1498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvttsd2siq(i.OutputRegister(), i.InputOperand(0)); 1500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 15013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (MiscField::decode(instr->opcode())) { 15023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ AssertZeroExtended(i.OutputRegister()); 15033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 1504958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat32ToInt64: 1507bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvttss2siq(i.OutputRegister(), i.InputDoubleRegister(0)); 1509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvttss2siq(i.OutputRegister(), i.InputOperand(0)); 1511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->OutputCount() > 1) { 1513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Set(i.OutputRegister(1), 1); 1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label done; 1515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label fail; 1516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Move(kScratchDoubleReg, static_cast<float>(INT64_MIN)); 1517bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Ucomiss(kScratchDoubleReg, i.InputDoubleRegister(0)); 1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Ucomiss(kScratchDoubleReg, i.InputOperand(0)); 1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the input is NaN, then the conversion fails. 1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ j(parity_even, &fail); 1524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the input is INT64_MIN, then the conversion succeeds. 1525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ j(equal, &done); 1526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmpq(i.OutputRegister(0), Immediate(1)); 1527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the conversion results in INT64_MIN, but the input was not 1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // INT64_MIN, then the conversion fails. 1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ j(no_overflow, &done); 1530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(&fail); 1531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Set(i.OutputRegister(1), 0); 1532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(&done); 1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat64ToInt64: 1536bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvttsd2siq(i.OutputRegister(0), i.InputDoubleRegister(0)); 1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvttsd2siq(i.OutputRegister(0), i.InputOperand(0)); 1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->OutputCount() > 1) { 1542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Set(i.OutputRegister(1), 1); 1543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label done; 1544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label fail; 1545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Move(kScratchDoubleReg, static_cast<double>(INT64_MIN)); 1546bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Ucomisd(kScratchDoubleReg, i.InputDoubleRegister(0)); 1548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Ucomisd(kScratchDoubleReg, i.InputOperand(0)); 1550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the input is NaN, then the conversion fails. 1552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ j(parity_even, &fail); 1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the input is INT64_MIN, then the conversion succeeds. 1554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ j(equal, &done); 1555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmpq(i.OutputRegister(0), Immediate(1)); 1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the conversion results in INT64_MIN, but the input was not 1557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // INT64_MIN, then the conversion fails. 1558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ j(no_overflow, &done); 1559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(&fail); 1560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Set(i.OutputRegister(1), 0); 1561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(&done); 1562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat32ToUint64: { 1565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label done; 1566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label success; 1567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->OutputCount() > 1) { 1568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Set(i.OutputRegister(1), 0); 1569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // There does not exist a Float32ToUint64 instruction, so we have to use 1571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the Float32ToInt64 instruction. 1572bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvttss2siq(i.OutputRegister(), i.InputDoubleRegister(0)); 1574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvttss2siq(i.OutputRegister(), i.InputOperand(0)); 1576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if the result of the Float32ToInt64 conversion is positive, we 1578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // are already done. 1579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ testq(i.OutputRegister(), i.OutputRegister()); 1580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ j(positive, &success); 1581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The result of the first conversion was negative, which means that the 1582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // input value was not within the positive int64 range. We subtract 2^64 1583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // and convert it again to see if it is within the uint64 range. 1584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Move(kScratchDoubleReg, -9223372036854775808.0f); 1585bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ addss(kScratchDoubleReg, i.InputDoubleRegister(0)); 1587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ addss(kScratchDoubleReg, i.InputOperand(0)); 1589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvttss2siq(i.OutputRegister(), kScratchDoubleReg); 1591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ testq(i.OutputRegister(), i.OutputRegister()); 1592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The only possible negative value here is 0x80000000000000000, which is 1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // used on x64 to indicate an integer overflow. 1594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ j(negative, &done); 1595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The input value is within uint64 range and the second conversion worked 1596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // successfully, but we still have to undo the subtraction we did 1597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // earlier. 1598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Set(kScratchRegister, 0x8000000000000000); 1599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ orq(i.OutputRegister(), kScratchRegister); 1600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(&success); 1601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->OutputCount() > 1) { 1602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Set(i.OutputRegister(1), 1); 1603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(&done); 1605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat64ToUint64: { 1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label done; 1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label success; 1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->OutputCount() > 1) { 1611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Set(i.OutputRegister(1), 0); 1612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // There does not exist a Float64ToUint64 instruction, so we have to use 1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the Float64ToInt64 instruction. 1615bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0)); 1617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvttsd2siq(i.OutputRegister(), i.InputOperand(0)); 1619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if the result of the Float64ToInt64 conversion is positive, we 1621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // are already done. 1622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ testq(i.OutputRegister(), i.OutputRegister()); 1623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ j(positive, &success); 1624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The result of the first conversion was negative, which means that the 1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // input value was not within the positive int64 range. We subtract 2^64 1626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // and convert it again to see if it is within the uint64 range. 1627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Move(kScratchDoubleReg, -9223372036854775808.0); 1628bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ addsd(kScratchDoubleReg, i.InputDoubleRegister(0)); 1630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ addsd(kScratchDoubleReg, i.InputOperand(0)); 1632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvttsd2siq(i.OutputRegister(), kScratchDoubleReg); 1634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ testq(i.OutputRegister(), i.OutputRegister()); 1635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The only possible negative value here is 0x80000000000000000, which is 1636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // used on x64 to indicate an integer overflow. 1637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ j(negative, &done); 1638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The input value is within uint64 range and the second conversion worked 1639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // successfully, but we still have to undo the subtraction we did 1640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // earlier. 1641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Set(kScratchRegister, 0x8000000000000000); 1642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ orq(i.OutputRegister(), kScratchRegister); 1643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(&success); 1644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->OutputCount() > 1) { 1645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Set(i.OutputRegister(1), 1); 1646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(&done); 1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1650958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kSSEInt32ToFloat64: 1651958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->InputAt(0)->IsRegister()) { 1652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvtlsi2sd(i.OutputDoubleRegister(), i.InputRegister(0)); 1653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvtlsi2sd(i.OutputDoubleRegister(), i.InputOperand(0)); 1655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1657109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case kSSEInt32ToFloat32: 1658109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (instr->InputAt(0)->IsRegister()) { 1659109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ Cvtlsi2ss(i.OutputDoubleRegister(), i.InputRegister(0)); 1660109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 1661109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ Cvtlsi2ss(i.OutputDoubleRegister(), i.InputOperand(0)); 1662109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1663109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 1664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEInt64ToFloat32: 1665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(0)->IsRegister()) { 1666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvtqsi2ss(i.OutputDoubleRegister(), i.InputRegister(0)); 1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvtqsi2ss(i.OutputDoubleRegister(), i.InputOperand(0)); 1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEInt64ToFloat64: 1672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(0)->IsRegister()) { 1673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvtqsi2sd(i.OutputDoubleRegister(), i.InputRegister(0)); 1674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvtqsi2sd(i.OutputDoubleRegister(), i.InputOperand(0)); 1676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEUint64ToFloat32: 1679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(0)->IsRegister()) { 1680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movq(kScratchRegister, i.InputRegister(0)); 1681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movq(kScratchRegister, i.InputOperand(0)); 1683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvtqui2ss(i.OutputDoubleRegister(), kScratchRegister, 1685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.TempRegister(0)); 1686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEUint64ToFloat64: 1688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(0)->IsRegister()) { 1689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movq(kScratchRegister, i.InputRegister(0)); 1690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movq(kScratchRegister, i.InputOperand(0)); 1692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvtqui2sd(i.OutputDoubleRegister(), kScratchRegister, 1694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.TempRegister(0)); 1695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1696958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kSSEUint32ToFloat64: 1697958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->InputAt(0)->IsRegister()) { 1698958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ movl(kScratchRegister, i.InputRegister(0)); 1699958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1700958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ movl(kScratchRegister, i.InputOperand(0)); 1701958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cvtqsi2sd(i.OutputDoubleRegister(), kScratchRegister); 1703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1704109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case kSSEUint32ToFloat32: 1705109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (instr->InputAt(0)->IsRegister()) { 1706109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ movl(kScratchRegister, i.InputRegister(0)); 1707109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 1708109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ movl(kScratchRegister, i.InputOperand(0)); 1709109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1710109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ Cvtqsi2ss(i.OutputDoubleRegister(), kScratchRegister); 1711109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 1712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat64ExtractLowWord32: 1713bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPStackSlot()) { 1714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movl(i.OutputRegister(), i.InputOperand(0)); 1715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Movd(i.OutputRegister(), i.InputDoubleRegister(0)); 1717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1718958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat64ExtractHighWord32: 1720bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPStackSlot()) { 1721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movl(i.OutputRegister(), i.InputOperand(0, kDoubleSize / 2)); 1722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Pextrd(i.OutputRegister(), i.InputDoubleRegister(0), 1); 1724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat64InsertLowWord32: 1727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(1)->IsRegister()) { 1728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Pinsrd(i.OutputDoubleRegister(), i.InputRegister(1), 0); 1729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 0); 1731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat64InsertHighWord32: 1734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(1)->IsRegister()) { 1735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Pinsrd(i.OutputDoubleRegister(), i.InputRegister(1), 1); 1736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 1); 1738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSSEFloat64LoadLowWord32: 1741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(0)->IsRegister()) { 1742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Movd(i.OutputDoubleRegister(), i.InputRegister(0)); 1743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Movd(i.OutputDoubleRegister(), i.InputOperand(0)); 1745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kAVXFloat32Cmp: { 1748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope avx_scope(masm(), AVX); 1749bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(1)->IsFPRegister()) { 1750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vucomiss(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); 1751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vucomiss(i.InputDoubleRegister(0), i.InputOperand(1)); 1753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kAVXFloat32Add: 1757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_AVX_BINOP(vaddss); 1758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kAVXFloat32Sub: 1760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_AVX_BINOP(vsubss); 1761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kAVXFloat32Mul: 1763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_AVX_BINOP(vmulss); 1764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kAVXFloat32Div: 1766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_AVX_BINOP(vdivss); 1767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Don't delete this mov. It may improve performance on some CPUs, 1768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // when there is a (v)mulss depending on the result. 1769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Movaps(i.OutputDoubleRegister(), i.OutputDoubleRegister()); 1770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kAVXFloat64Cmp: { 1772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope avx_scope(masm(), AVX); 1773bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(1)->IsFPRegister()) { 1774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vucomisd(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); 1775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vucomisd(i.InputDoubleRegister(0), i.InputOperand(1)); 1777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1780958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kAVXFloat64Add: 1781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_AVX_BINOP(vaddsd); 1782958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1783958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kAVXFloat64Sub: 1784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_AVX_BINOP(vsubsd); 1785958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1786958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kAVXFloat64Mul: 1787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_AVX_BINOP(vmulsd); 1788958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1789958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kAVXFloat64Div: 1790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_AVX_BINOP(vdivsd); 1791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Don't delete this mov. It may improve performance on some CPUs, 1792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // when there is a (v)mulsd depending on the result. 1793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Movapd(i.OutputDoubleRegister(), i.OutputDoubleRegister()); 1794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kAVXFloat32Abs: { 1796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(bmeurer): Use RIP relative 128-bit constants. 1797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope avx_scope(masm(), AVX); 1798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg); 1799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vpsrlq(kScratchDoubleReg, kScratchDoubleReg, 33); 1800bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vandps(i.OutputDoubleRegister(), kScratchDoubleReg, 1802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputDoubleRegister(0)); 1803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vandps(i.OutputDoubleRegister(), kScratchDoubleReg, 1805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputOperand(0)); 1806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kAVXFloat32Neg: { 1810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(bmeurer): Use RIP relative 128-bit constants. 1811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope avx_scope(masm(), AVX); 1812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg); 1813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vpsllq(kScratchDoubleReg, kScratchDoubleReg, 31); 1814bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vxorps(i.OutputDoubleRegister(), kScratchDoubleReg, 1816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputDoubleRegister(0)); 1817958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vxorps(i.OutputDoubleRegister(), kScratchDoubleReg, 1819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputOperand(0)); 1820958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kAVXFloat64Abs: { 1824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(bmeurer): Use RIP relative 128-bit constants. 1825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope avx_scope(masm(), AVX); 1826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg); 1827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vpsrlq(kScratchDoubleReg, kScratchDoubleReg, 1); 1828bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vandpd(i.OutputDoubleRegister(), kScratchDoubleReg, 1830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputDoubleRegister(0)); 1831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vandpd(i.OutputDoubleRegister(), kScratchDoubleReg, 1833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputOperand(0)); 1834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kAVXFloat64Neg: { 1838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(bmeurer): Use RIP relative 128-bit constants. 1839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope avx_scope(masm(), AVX); 1840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg); 1841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vpsllq(kScratchDoubleReg, kScratchDoubleReg, 63); 1842bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vxorpd(i.OutputDoubleRegister(), kScratchDoubleReg, 1844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputDoubleRegister(0)); 1845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ vxorpd(i.OutputDoubleRegister(), kScratchDoubleReg, 1847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch i.InputOperand(0)); 1848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 185113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kSSEFloat64SilenceNaN: 185213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Xorpd(kScratchDoubleReg, kScratchDoubleReg); 185313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Subsd(i.InputDoubleRegister(0), kScratchDoubleReg); 185413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 1855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX64Movsxbl: 185662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, 185762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ pc_offset(), instr); 1858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_MOVX(movsxbl); 1859958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ AssertZeroExtended(i.OutputRegister()); 1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Movzxbl: 186262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, 186362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ pc_offset(), instr); 1864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_MOVX(movzxbl); 1865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ AssertZeroExtended(i.OutputRegister()); 1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1867f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kX64Movsxbq: 186862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, 186962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ pc_offset(), instr); 1870f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_MOVX(movsxbq); 1871f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1872f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kX64Movzxbq: 187362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, 187462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ pc_offset(), instr); 1875f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_MOVX(movzxbq); 1876f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ AssertZeroExtended(i.OutputRegister()); 1877f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Movb: { 187962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, 188062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ pc_offset(), instr); 1881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; 1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand operand = i.MemoryOperand(&index); 1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasImmediateInput(instr, index)) { 1884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movb(operand, Immediate(i.InputInt8(index))); 1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movb(operand, i.InputRegister(index)); 1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Movsxwl: 189162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, 189262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ pc_offset(), instr); 1893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_MOVX(movsxwl); 1894958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ AssertZeroExtended(i.OutputRegister()); 1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Movzxwl: 189762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, 189862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ pc_offset(), instr); 1899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_MOVX(movzxwl); 1900958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ AssertZeroExtended(i.OutputRegister()); 1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1902f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kX64Movsxwq: 190362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, 190462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ pc_offset(), instr); 1905f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_MOVX(movsxwq); 1906f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1907f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kX64Movzxwq: 190862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, 190962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ pc_offset(), instr); 1910f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_MOVX(movzxwq); 1911f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ AssertZeroExtended(i.OutputRegister()); 1912f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Movw: { 191462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, 191562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ pc_offset(), instr); 1916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; 1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand operand = i.MemoryOperand(&index); 1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasImmediateInput(instr, index)) { 1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movw(operand, Immediate(i.InputInt16(index))); 1920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movw(operand, i.InputRegister(index)); 1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Movl: 192662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, 192762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ pc_offset(), instr); 1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasOutput()) { 1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->addressing_mode() == kMode_None) { 1930958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (instr->InputAt(0)->IsRegister()) { 1931958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ movl(i.OutputRegister(), i.InputRegister(0)); 1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1933958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ movl(i.OutputRegister(), i.InputOperand(0)); 1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movl(i.OutputRegister(), i.MemoryOperand()); 1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1938958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ AssertZeroExtended(i.OutputRegister()); 1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; 1941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand operand = i.MemoryOperand(&index); 1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasImmediateInput(instr, index)) { 1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movl(operand, i.InputImmediate(index)); 1944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movl(operand, i.InputRegister(index)); 1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX64Movsxlq: 195062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, 195162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ pc_offset(), instr); 1952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_MOVX(movsxlq); 1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Movq: 195562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, 195662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ pc_offset(), instr); 1957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasOutput()) { 1958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movq(i.OutputRegister(), i.MemoryOperand()); 1959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; 1961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand operand = i.MemoryOperand(&index); 1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasImmediateInput(instr, index)) { 1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movq(operand, i.InputImmediate(index)); 1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movq(operand, i.InputRegister(index)); 1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Movss: 197062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, 197162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ pc_offset(), instr); 1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasOutput()) { 1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movss(i.OutputDoubleRegister(), i.MemoryOperand()); 1974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; 1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand operand = i.MemoryOperand(&index); 1977958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ movss(operand, i.InputDoubleRegister(index)); 1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 1980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Movsd: 198162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, 198262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ pc_offset(), instr); 1983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasOutput()) { 1984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Movsd(i.OutputDoubleRegister(), i.MemoryOperand()); 1985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; 1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand operand = i.MemoryOperand(&index); 1988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Movsd(operand, i.InputDoubleRegister(index)); 1989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX64BitcastFI: 1992bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPStackSlot()) { 1993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movl(i.OutputRegister(), i.InputOperand(0)); 1994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Movd(i.OutputRegister(), i.InputDoubleRegister(0)); 1996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX64BitcastDL: 1999bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPStackSlot()) { 2000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movq(i.OutputRegister(), i.InputOperand(0)); 2001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Movq(i.OutputRegister(), i.InputDoubleRegister(0)); 2003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX64BitcastIF: 2006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(0)->IsRegister()) { 2007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Movd(i.OutputDoubleRegister(), i.InputRegister(0)); 2008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movss(i.OutputDoubleRegister(), i.InputOperand(0)); 2010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX64BitcastLD: 2013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(0)->IsRegister()) { 2014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Movq(i.OutputDoubleRegister(), i.InputRegister(0)); 2015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Movsd(i.OutputDoubleRegister(), i.InputOperand(0)); 2017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2019958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kX64Lea32: { 2020958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddressingMode mode = AddressingModeField::decode(instr->opcode()); 2021958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Shorten "leal" to "addl", "subl" or "shll" if the register allocation 2022958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // and addressing mode just happens to work out. The "addl"/"subl" forms 2023958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // in these cases are faster based on measurements. 2024958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (i.InputRegister(0).is(i.OutputRegister())) { 2025958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (mode == kMode_MRI) { 2026958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int32_t constant_summand = i.InputInt32(1); 2027958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (constant_summand > 0) { 2028958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ addl(i.OutputRegister(), Immediate(constant_summand)); 2029958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (constant_summand < 0) { 2030958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ subl(i.OutputRegister(), Immediate(-constant_summand)); 2031958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2032958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (mode == kMode_MR1) { 2033958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (i.InputRegister(1).is(i.OutputRegister())) { 2034958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ shll(i.OutputRegister(), Immediate(1)); 2035958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2036c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ addl(i.OutputRegister(), i.InputRegister(1)); 2037958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2038958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (mode == kMode_M2) { 2039958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ shll(i.OutputRegister(), Immediate(1)); 2040958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (mode == kMode_M4) { 2041958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ shll(i.OutputRegister(), Immediate(2)); 2042958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (mode == kMode_M8) { 2043958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ shll(i.OutputRegister(), Immediate(3)); 2044958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2045958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ leal(i.OutputRegister(), i.MemoryOperand()); 2046958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2047c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else if (mode == kMode_MR1 && 2048c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i.InputRegister(1).is(i.OutputRegister())) { 2049c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ addl(i.OutputRegister(), i.InputRegister(0)); 2050958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2051958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ leal(i.OutputRegister(), i.MemoryOperand()); 2052958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2053958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ AssertZeroExtended(i.OutputRegister()); 2054958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2055958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2056c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case kX64Lea: { 2057c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch AddressingMode mode = AddressingModeField::decode(instr->opcode()); 2058c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Shorten "leaq" to "addq", "subq" or "shlq" if the register allocation 2059c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // and addressing mode just happens to work out. The "addq"/"subq" forms 2060c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // in these cases are faster based on measurements. 2061c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (i.InputRegister(0).is(i.OutputRegister())) { 2062c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (mode == kMode_MRI) { 2063c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int32_t constant_summand = i.InputInt32(1); 2064c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (constant_summand > 0) { 2065c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ addq(i.OutputRegister(), Immediate(constant_summand)); 2066c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else if (constant_summand < 0) { 2067c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ subq(i.OutputRegister(), Immediate(-constant_summand)); 2068c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 2069c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else if (mode == kMode_MR1) { 2070c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (i.InputRegister(1).is(i.OutputRegister())) { 2071c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ shlq(i.OutputRegister(), Immediate(1)); 2072c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 2073c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ addq(i.OutputRegister(), i.InputRegister(1)); 2074c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 2075c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else if (mode == kMode_M2) { 2076c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ shlq(i.OutputRegister(), Immediate(1)); 2077c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else if (mode == kMode_M4) { 2078c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ shlq(i.OutputRegister(), Immediate(2)); 2079c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else if (mode == kMode_M8) { 2080c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ shlq(i.OutputRegister(), Immediate(3)); 2081c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 2082c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ leaq(i.OutputRegister(), i.MemoryOperand()); 2083c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 2084c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else if (mode == kMode_MR1 && 2085c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i.InputRegister(1).is(i.OutputRegister())) { 2086c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ addq(i.OutputRegister(), i.InputRegister(0)); 2087c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 2088c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ leaq(i.OutputRegister(), i.MemoryOperand()); 2089c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 2090958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2091c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 2092958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kX64Dec32: 2093958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ decl(i.OutputRegister()); 2094958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2095958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kX64Inc32: 2096958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ incl(i.OutputRegister()); 2097958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kX64Push: 209962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (AddressingModeField::decode(instr->opcode()) != kMode_None) { 210062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t index = 0; 210162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Operand operand = i.MemoryOperand(&index); 210262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ pushq(operand); 210362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch frame_access_state()->IncreaseSPDelta(1); 210462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), 210562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch kPointerSize); 210662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (HasImmediateInput(instr, 0)) { 2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ pushq(i.InputImmediate(0)); 2108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->IncreaseSPDelta(1); 2109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), 2110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch kPointerSize); 211162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (instr->InputAt(0)->IsRegister()) { 211262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ pushq(i.InputRegister(0)); 211362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch frame_access_state()->IncreaseSPDelta(1); 211462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), 211562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch kPointerSize); 211662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (instr->InputAt(0)->IsFPRegister()) { 211762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // TODO(titzer): use another machine instruction? 211862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ subq(rsp, Immediate(kDoubleSize)); 211962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); 212062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), 212162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch kDoubleSize); 212262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0)); 2123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 212462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ pushq(i.InputOperand(0)); 212562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch frame_access_state()->IncreaseSPDelta(1); 212662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), 212762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch kPointerSize); 2128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX64Poke: { 2131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int const slot = MiscField::decode(instr->opcode()); 2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, 0)) { 2133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movq(Operand(rsp, slot * kPointerSize), i.InputImmediate(0)); 2134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movq(Operand(rsp, slot * kPointerSize), i.InputRegister(0)); 2136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2139bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kX64Xchgb: { 2140bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch size_t index = 0; 2141bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Operand operand = i.MemoryOperand(&index); 2142bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ xchgb(i.InputRegister(index), operand); 2143bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 2144bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2145bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kX64Xchgw: { 2146bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch size_t index = 0; 2147bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Operand operand = i.MemoryOperand(&index); 2148bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ xchgw(i.InputRegister(index), operand); 2149bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 2150bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2151bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kX64Xchgl: { 2152bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch size_t index = 0; 2153bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Operand operand = i.MemoryOperand(&index); 2154bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ xchgl(i.InputRegister(index), operand); 2155bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 2156bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2157f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch case kX64Int32x4Create: { 2158f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch CpuFeatureScope sse_scope(masm(), SSE4_1); 2159f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch XMMRegister dst = i.OutputSimd128Register(); 2160f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch __ Movd(dst, i.InputRegister(0)); 2161f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch __ shufps(dst, dst, 0x0); 2162f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch break; 2163f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 2164f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch case kX64Int32x4ExtractLane: { 2165f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch CpuFeatureScope sse_scope(masm(), SSE4_1); 2166f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch __ Pextrd(i.OutputRegister(), i.InputSimd128Register(0), i.InputInt8(1)); 2167f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch break; 2168f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 216962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case kX64Int32x4ReplaceLane: { 217062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CpuFeatureScope sse_scope(masm(), SSE4_1); 217162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (instr->InputAt(2)->IsRegister()) { 217262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ Pinsrd(i.OutputSimd128Register(), i.InputRegister(2), 217362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i.InputInt8(1)); 217462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 217562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ Pinsrd(i.OutputSimd128Register(), i.InputOperand(2), i.InputInt8(1)); 217662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 217762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch break; 217862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 217962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case kX64Int32x4Add: { 218062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CpuFeatureScope sse_scope(masm(), SSE4_1); 218162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ paddd(i.OutputSimd128Register(), i.InputSimd128Register(1)); 218262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch break; 218362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 218462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case kX64Int32x4Sub: { 218562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CpuFeatureScope sse_scope(masm(), SSE4_1); 218662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ psubd(i.OutputSimd128Register(), i.InputSimd128Register(1)); 218762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch break; 218862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 2189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kCheckedLoadInt8: 2190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSEMBLE_CHECKED_LOAD_INTEGER(movsxbl); 2191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kCheckedLoadUint8: 2193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSEMBLE_CHECKED_LOAD_INTEGER(movzxbl); 2194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kCheckedLoadInt16: 2196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSEMBLE_CHECKED_LOAD_INTEGER(movsxwl); 2197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kCheckedLoadUint16: 2199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSEMBLE_CHECKED_LOAD_INTEGER(movzxwl); 2200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kCheckedLoadWord32: 2202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSEMBLE_CHECKED_LOAD_INTEGER(movl); 2203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedLoadWord64: 2205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_LOAD_INTEGER(movq); 2206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kCheckedLoadFloat32: 2208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_CHECKED_LOAD_FLOAT(Movss, OutOfLineLoadFloat32NaN); 2209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kCheckedLoadFloat64: 2211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_CHECKED_LOAD_FLOAT(Movsd, OutOfLineLoadFloat64NaN); 2212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kCheckedStoreWord8: 2214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSEMBLE_CHECKED_STORE_INTEGER(movb); 2215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kCheckedStoreWord16: 2217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSEMBLE_CHECKED_STORE_INTEGER(movw); 2218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kCheckedStoreWord32: 2220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ASSEMBLE_CHECKED_STORE_INTEGER(movl); 2221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedStoreWord64: 2223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_STORE_INTEGER(movq); 2224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kCheckedStoreFloat32: 2226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_STORE_FLOAT(Movss); 2227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case kCheckedStoreFloat64: 2229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_STORE_FLOAT(Movsd); 2230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX64StackCheck: 2232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ CompareRoot(rsp, Heap::kStackLimitRootIndex); 2233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2234bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicLoadInt8: 2235bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicLoadUint8: 2236bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicLoadInt16: 2237bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicLoadUint16: 2238bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicLoadWord32: 2239bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicStoreWord8: 2240bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicStoreWord16: 2241bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicStoreWord32: 2242bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UNREACHABLE(); // Won't be generated by instruction selector. 2243bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 2244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2245bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return kSuccess; 2246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // NOLINT(readability/fn_size) 2247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 224862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochnamespace { 2249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 225062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochCondition FlagsConditionToCondition(FlagsCondition condition) { 225162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch switch (condition) { 2252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kUnorderedEqual: 2253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kEqual: 225462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return equal; 2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kUnorderedNotEqual: 2256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kNotEqual: 225762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return not_equal; 2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kSignedLessThan: 225962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return less; 2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kSignedGreaterThanOrEqual: 226162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return greater_equal; 2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kSignedLessThanOrEqual: 226362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return less_equal; 2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kSignedGreaterThan: 226562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return greater; 2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kUnsignedLessThan: 226762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return below; 2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kUnsignedGreaterThanOrEqual: 226962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return above_equal; 2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kUnsignedLessThanOrEqual: 227162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return below_equal; 2272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kUnsignedGreaterThan: 227362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return above; 2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kOverflow: 227562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return overflow; 2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kNotOverflow: 227762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return no_overflow; 2278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 2279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 228162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 228262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return no_condition; 228362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 228462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 228562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} // namespace 228662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 228762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Assembles branches after this instruction. 228862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { 228962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label::Distance flabel_distance = 229062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch branch->fallthru ? Label::kNear : Label::kFar; 229162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label* tlabel = branch->true_label; 229262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label* flabel = branch->false_label; 229362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (branch->condition == kUnorderedEqual) { 229462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ j(parity_even, flabel, flabel_distance); 229562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (branch->condition == kUnorderedNotEqual) { 229662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ j(parity_even, tlabel); 229762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 229862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ j(FlagsConditionToCondition(branch->condition), tlabel); 229962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 2300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!branch->fallthru) __ jmp(flabel, flabel_distance); 2301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchJump(RpoNumber target) { 2305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target)); 2306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 230862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid CodeGenerator::AssembleArchTrap(Instruction* instr, 230962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FlagsCondition condition) { 231062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch class OutOfLineTrap final : public OutOfLineCode { 231162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch public: 231262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch OutOfLineTrap(CodeGenerator* gen, bool frame_elided, Instruction* instr) 231362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : OutOfLineCode(gen), 231462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch frame_elided_(frame_elided), 231562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch instr_(instr), 231662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch gen_(gen) {} 231762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 231862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void Generate() final { 231962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch X64OperandConverter i(gen_, instr_); 232062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 232162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Builtins::Name trap_id = 232262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static_cast<Builtins::Name>(i.InputInt32(instr_->InputCount() - 1)); 232362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool old_has_frame = __ has_frame(); 232462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (frame_elided_) { 232562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ set_has_frame(true); 232662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ EnterFrame(StackFrame::WASM_COMPILED); 232762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 232862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GenerateCallToTrap(trap_id); 232962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (frame_elided_) { 233062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ set_has_frame(old_has_frame); 233162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 233262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 233362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 233462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch private: 233562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void GenerateCallToTrap(Builtins::Name trap_id) { 233662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (trap_id == Builtins::builtin_count) { 233762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // We cannot test calls to the runtime in cctest/test-run-wasm. 233862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Therefore we emit a call to C here instead of a call to the runtime. 233962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ PrepareCallCFunction(0); 234062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ CallCFunction( 234162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ExternalReference::wasm_call_trap_callback_for_testing(isolate()), 234262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 0); 234362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ LeaveFrame(StackFrame::WASM_COMPILED); 234462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ Ret(); 234562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 234662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch gen_->AssembleSourcePosition(instr_); 234762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ Call(handle(isolate()->builtins()->builtin(trap_id), isolate()), 234862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch RelocInfo::CODE_TARGET); 234962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ReferenceMap* reference_map = 235062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch new (gen_->zone()) ReferenceMap(gen_->zone()); 235162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch gen_->RecordSafepoint(reference_map, Safepoint::kSimple, 0, 235262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Safepoint::kNoLazyDeopt); 235362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (FLAG_debug_code) { 235462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ ud2(); 235562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 235662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 235762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 235862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 235962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool frame_elided_; 236062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Instruction* instr_; 236162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CodeGenerator* gen_; 236262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch }; 236362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool frame_elided = !frame_access_state()->has_frame(); 236462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto ool = new (zone()) OutOfLineTrap(this, frame_elided, instr); 236562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label* tlabel = ool->entry(); 236662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label end; 236762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (condition == kUnorderedEqual) { 236862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ j(parity_even, &end); 236962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (condition == kUnorderedNotEqual) { 237062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ j(parity_even, tlabel); 237162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 237262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ j(FlagsConditionToCondition(condition), tlabel); 237362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ bind(&end); 237462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Assembles boolean materializations after this instruction. 2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::AssembleArchBoolean(Instruction* instr, 2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlagsCondition condition) { 2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X64OperandConverter i(this, instr); 2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Materialize a full 64-bit 1 or 0 value. The result register is always the 2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // last output of the instruction. 2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label check; 2385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(0u, instr->OutputCount()); 2386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register reg = i.OutputRegister(instr->OutputCount() - 1); 238762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (condition == kUnorderedEqual) { 238862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ j(parity_odd, &check, Label::kNear); 238962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ movl(reg, Immediate(0)); 239062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ jmp(&done, Label::kNear); 239162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (condition == kUnorderedNotEqual) { 239262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ j(parity_odd, &check, Label::kNear); 239362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ movl(reg, Immediate(1)); 239462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ jmp(&done, Label::kNear); 2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&check); 239762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ setcc(FlagsConditionToCondition(condition), reg); 2398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movzxbl(reg, reg); 2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&done); 2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) { 2404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandConverter i(this, instr); 2405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register input = i.InputRegister(0); 2406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (size_t index = 2; index < instr->InputCount(); index += 2) { 2407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmpl(input, Immediate(i.InputInt32(index + 0))); 2408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ j(equal, GetLabel(i.InputRpo(index + 1))); 2409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleArchJump(i.InputRpo(1)); 2411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchTableSwitch(Instruction* instr) { 2415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandConverter i(this, instr); 2416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register input = i.InputRegister(0); 2417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t const case_count = static_cast<int32_t>(instr->InputCount() - 2); 2418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label** cases = zone()->NewArray<Label*>(case_count); 2419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int32_t index = 0; index < case_count; ++index) { 2420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cases[index] = GetLabel(i.InputRpo(index + 2)); 2421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* const table = AddJumpTable(cases, case_count); 2423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmpl(input, Immediate(case_count)); 2424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ j(above_equal, GetLabel(i.InputRpo(1))); 2425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ leaq(kScratchRegister, Operand(table)); 2426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ jmp(Operand(kScratchRegister, input, times_8, 0)); 2427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2429bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall( 243062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int deoptimization_id, SourcePosition pos) { 243162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DeoptimizeKind deoptimization_kind = GetDeoptimizationKind(deoptimization_id); 243262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DeoptimizeReason deoptimization_reason = 243362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GetDeoptimizationReason(deoptimization_id); 243462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Deoptimizer::BailoutType bailout_type = 243562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch deoptimization_kind == DeoptimizeKind::kSoft ? Deoptimizer::SOFT 243662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : Deoptimizer::EAGER; 2437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( 2438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate(), deoptimization_id, bailout_type); 2439bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (deopt_entry == nullptr) return kTooManyDeoptimizationBailouts; 2440c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ RecordDeoptReason(deoptimization_reason, pos, deoptimization_id); 2441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ call(deopt_entry, RelocInfo::RUNTIME_ENTRY); 2442bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return kSuccess; 2443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace { 2447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic const int kQuadWordSize = 16; 2449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace 2451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2452bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeGenerator::FinishFrame(Frame* frame) { 2453bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 2454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2455bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch const RegList saves_fp = descriptor->CalleeSavedFPRegisters(); 2456bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (saves_fp != 0) { 2457bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch frame->AlignSavedCalleeRegisterSlots(); 2458bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (saves_fp != 0) { // Save callee-saved XMM registers. 2459bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch const uint32_t saves_fp_count = base::bits::CountPopulation32(saves_fp); 2460bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch frame->AllocateSavedCalleeRegisterSlots(saves_fp_count * 2461bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch (kQuadWordSize / kPointerSize)); 2462bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2463bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2464bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch const RegList saves = descriptor->CalleeSavedRegisters(); 2465bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (saves != 0) { // Save callee-saved registers. 2466bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch int count = 0; 2467bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch for (int i = Register::kNumRegisters - 1; i >= 0; i--) { 2468bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (((1 << i) & saves)) { 2469bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ++count; 2470bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2471bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2472bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch frame->AllocateSavedCalleeRegisterSlots(count); 2473bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2474bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 2475bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 2476bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeGenerator::AssembleConstructFrame() { 2477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 24783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (frame_access_state()->has_frame()) { 2479f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int pc_base = __ pc_offset(); 2480f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 24813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (descriptor->IsCFunctionCall()) { 24823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ pushq(rbp); 24833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ movq(rbp, rsp); 24843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else if (descriptor->IsJSFunctionCall()) { 24853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Prologue(this->info()->GeneratePreagedPrologue()); 2486c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (descriptor->PushArgumentCount()) { 2487c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ pushq(kJavaScriptCallArgCountRegister); 2488c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 24893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 24903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ StubPrologue(info()->GetOutputStackFrameType()); 24913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 2492f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2493f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!descriptor->IsJSFunctionCall() || !info()->GeneratePreagedPrologue()) { 2494f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_.MarkFrameConstructed(pc_base); 2495f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2497c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int shrink_slots = 2498c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch frame()->GetTotalFrameSlotCount() - descriptor->CalculateFixedFrameSize(); 2499bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 2500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info()->is_osr()) { 2501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TurboFan OSR-compiled functions cannot be entered directly. 2502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Abort(kShouldNotDirectlyEnterOsrFunction); 2503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Unoptimized code jumps directly to this entrypoint while the unoptimized 2505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // frame is still on the stack. Optimized code uses OSR values directly from 2506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the unoptimized frame. Thus, all that needs to be done is to allocate the 2507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // remaining stack slots. 2508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); 2509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch osr_pc_offset_ = __ pc_offset(); 2510bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch shrink_slots -= static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots()); 2511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const RegList saves_fp = descriptor->CalleeSavedFPRegisters(); 2514bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (shrink_slots > 0) { 2515bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ subq(rsp, Immediate(shrink_slots * kPointerSize)); 2516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (saves_fp != 0) { // Save callee-saved XMM registers. 2519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const uint32_t saves_fp_count = base::bits::CountPopulation32(saves_fp); 2520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int stack_size = saves_fp_count * kQuadWordSize; 2521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Adjust the stack pointer. 2522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ subp(rsp, Immediate(stack_size)); 2523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Store the registers on the stack. 2524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int slot_idx = 0; 2525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { 2526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!((1 << i) & saves_fp)) continue; 2527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movdqu(Operand(rsp, kQuadWordSize * slot_idx), 2528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch XMMRegister::from_code(i)); 2529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch slot_idx++; 2530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const RegList saves = descriptor->CalleeSavedRegisters(); 2534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (saves != 0) { // Save callee-saved registers. 2535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = Register::kNumRegisters - 1; i >= 0; i--) { 2536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!((1 << i) & saves)) continue; 2537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ pushq(Register::from_code(i)); 2538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2542c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid CodeGenerator::AssembleReturn(InstructionOperand* pop) { 2543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 2544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Restore registers. 2546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const RegList saves = descriptor->CalleeSavedRegisters(); 2547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (saves != 0) { 2548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < Register::kNumRegisters; i++) { 2549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!((1 << i) & saves)) continue; 2550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ popq(Register::from_code(i)); 2551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const RegList saves_fp = descriptor->CalleeSavedFPRegisters(); 2554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (saves_fp != 0) { 2555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const uint32_t saves_fp_count = base::bits::CountPopulation32(saves_fp); 2556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int stack_size = saves_fp_count * kQuadWordSize; 2557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Load the registers from the stack. 2558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int slot_idx = 0; 2559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { 2560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!((1 << i) & saves_fp)) continue; 2561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movdqu(XMMRegister::from_code(i), 2562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand(rsp, kQuadWordSize * slot_idx)); 2563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch slot_idx++; 2564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Adjust the stack pointer. 2566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ addp(rsp, Immediate(stack_size)); 2567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2569f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_.MarkBlockWillExit(); 2570f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2571c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Might need rcx for scratch if pop_size is too big or if there is a variable 2572c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // pop count. 2573c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & rcx.bit()); 2574c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & rdx.bit()); 2575c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch size_t pop_size = descriptor->StackParameterCount() * kPointerSize; 2576c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch X64OperandConverter g(this, nullptr); 2577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (descriptor->IsCFunctionCall()) { 25783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AssembleDeconstructFrame(); 25793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else if (frame_access_state()->has_frame()) { 2580c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (pop->IsImmediate() && g.ToConstant(pop).ToInt32() == 0) { 2581c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Canonicalize JSFunction return sites for now. 2582c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (return_label_.is_bound()) { 2583c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ jmp(&return_label_); 2584c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return; 2585c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 2586c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ bind(&return_label_); 2587c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch AssembleDeconstructFrame(); 2588c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 2589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 25903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AssembleDeconstructFrame(); 2591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2593c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 2594c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (pop->IsImmediate()) { 2595c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(Constant::kInt32, g.ToConstant(pop).type()); 2596c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch pop_size += g.ToConstant(pop).ToInt32() * kPointerSize; 2597c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch CHECK_LT(pop_size, static_cast<size_t>(std::numeric_limits<int>::max())); 2598c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ Ret(static_cast<int>(pop_size), rcx); 2599c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 2600c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Register pop_reg = g.ToRegister(pop); 2601c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Register scratch_reg = pop_reg.is(rcx) ? rdx : rcx; 2602c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ popq(scratch_reg); 2603c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ leaq(rsp, Operand(rsp, pop_reg, times_8, static_cast<int>(pop_size))); 2604c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ jmp(scratch_reg); 2605c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 2606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::AssembleMove(InstructionOperand* source, 2610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* destination) { 2611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandConverter g(this, nullptr); 2612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Dispatch on the source and destination operand kinds. Not all 2613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // combinations are possible. 2614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (source->IsRegister()) { 2615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(destination->IsRegister() || destination->IsStackSlot()); 2616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src = g.ToRegister(source); 2617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (destination->IsRegister()) { 2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movq(g.ToRegister(destination), src); 2619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movq(g.ToOperand(destination), src); 2621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (source->IsStackSlot()) { 2623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(destination->IsRegister() || destination->IsStackSlot()); 2624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand src = g.ToOperand(source); 2625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (destination->IsRegister()) { 2626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst = g.ToRegister(destination); 2627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movq(dst, src); 2628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Spill on demand to use a temporary register for memory-to-memory 2630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // moves. 2631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register tmp = kScratchRegister; 2632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand dst = g.ToOperand(destination); 2633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movq(tmp, src); 2634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movq(dst, tmp); 2635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (source->IsConstant()) { 2637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ConstantOperand* constant_source = ConstantOperand::cast(source); 2638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Constant src = g.ToConstant(constant_source); 2639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (destination->IsRegister() || destination->IsStackSlot()) { 2640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst = destination->IsRegister() ? g.ToRegister(destination) 2641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : kScratchRegister; 2642958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (src.type()) { 2643bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case Constant::kInt32: { 264462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (RelocInfo::IsWasmPtrReference(src.rmode())) { 2645bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ movq(dst, src.ToInt64(), src.rmode()); 2646bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else { 2647bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // TODO(dcarney): don't need scratch in this case. 2648bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch int32_t value = src.ToInt32(); 2649bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (value == 0) { 2650bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ xorl(dst, dst); 2651bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else { 265262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (RelocInfo::IsWasmSizeReference(src.rmode())) { 2653f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch __ movl(dst, Immediate(value, src.rmode())); 2654f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } else { 2655f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch __ movl(dst, Immediate(value)); 2656f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 2657bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2658bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2659958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2660bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2661958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case Constant::kInt64: 266262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (RelocInfo::IsWasmPtrReference(src.rmode())) { 2663bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ movq(dst, src.ToInt64(), src.rmode()); 2664bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else { 266562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(!RelocInfo::IsWasmSizeReference(src.rmode())); 2666bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ Set(dst, src.ToInt64()); 2667bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2668958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2669958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case Constant::kFloat32: 2670958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Move(dst, 2671958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate()->factory()->NewNumber(src.ToFloat32(), TENURED)); 2672958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2673958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case Constant::kFloat64: 2674958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Move(dst, 2675958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate()->factory()->NewNumber(src.ToFloat64(), TENURED)); 2676958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 2677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case Constant::kExternalReference: 2678958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Move(dst, src.ToExternalReference()); 2679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kHeapObject: { 2681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<HeapObject> src_object = src.ToHeapObject(); 2682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Heap::RootListIndex index; 2683f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsMaterializableFromRoot(src_object, &index)) { 2684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadRoot(dst, index); 2685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Move(dst, src_object); 2687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case Constant::kRpoNumber: 2691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); // TODO(dcarney): load of labels on x64. 2692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (destination->IsStackSlot()) { 2695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movq(g.ToOperand(destination), kScratchRegister); 2696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2697958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (src.type() == Constant::kFloat32) { 2698958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(turbofan): Can we do better here? 2699958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t src_const = bit_cast<uint32_t>(src.ToFloat32()); 2700bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (destination->IsFPRegister()) { 2701958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Move(g.ToDoubleRegister(destination), src_const); 2702958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2703bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(destination->IsFPStackSlot()); 2704958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Operand dst = g.ToOperand(destination); 2705958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ movl(dst, Immediate(src_const)); 2706958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2708958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_EQ(Constant::kFloat64, src.type()); 2709958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint64_t src_const = bit_cast<uint64_t>(src.ToFloat64()); 2710bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (destination->IsFPRegister()) { 2711958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Move(g.ToDoubleRegister(destination), src_const); 2712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2713bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(destination->IsFPStackSlot()); 2714958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ movq(kScratchRegister, src_const); 2715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ movq(g.ToOperand(destination), kScratchRegister); 2716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2718bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (source->IsFPRegister()) { 2719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch XMMRegister src = g.ToDoubleRegister(source); 2720bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (destination->IsFPRegister()) { 2721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch XMMRegister dst = g.ToDoubleRegister(destination); 2722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Movapd(dst, src); 2723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2724bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(destination->IsFPStackSlot()); 2725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand dst = g.ToOperand(destination); 2726f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MachineRepresentation rep = 2727f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LocationOperand::cast(source)->representation(); 2728f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (rep != MachineRepresentation::kSimd128) { 2729f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movsd(dst, src); 2730f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movups(dst, src); 2732f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2734bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (source->IsFPStackSlot()) { 2735bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(destination->IsFPRegister() || destination->IsFPStackSlot()); 2736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand src = g.ToOperand(source); 2737f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MachineRepresentation rep = LocationOperand::cast(source)->representation(); 2738bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (destination->IsFPRegister()) { 2739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch XMMRegister dst = g.ToDoubleRegister(destination); 2740f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (rep != MachineRepresentation::kSimd128) { 2741f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movsd(dst, src); 2742f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2743f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movups(dst, src); 2744f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand dst = g.ToOperand(destination); 2747f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (rep != MachineRepresentation::kSimd128) { 2748f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movsd(kScratchDoubleReg, src); 2749f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movsd(dst, kScratchDoubleReg); 2750f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2751f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movups(kScratchDoubleReg, src); 2752f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movups(dst, kScratchDoubleReg); 2753f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 2757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::AssembleSwap(InstructionOperand* source, 2762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* destination) { 2763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X64OperandConverter g(this, nullptr); 2764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Dispatch on the source and destination operand kinds. Not all 2765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // combinations are possible. 2766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (source->IsRegister() && destination->IsRegister()) { 2767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Register-register. 2768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register src = g.ToRegister(source); 2769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register dst = g.ToRegister(destination); 2770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movq(kScratchRegister, src); 2771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movq(src, dst); 2772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movq(dst, kScratchRegister); 2773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (source->IsRegister() && destination->IsStackSlot()) { 2774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src = g.ToRegister(source); 2775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ pushq(src); 2776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->IncreaseSPDelta(1); 2777f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), 2778f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch kPointerSize); 2779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand dst = g.ToOperand(destination); 2780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movq(src, dst); 2781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->IncreaseSPDelta(-1); 2782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch dst = g.ToOperand(destination); 2783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ popq(dst); 2784f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), 2785f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch -kPointerSize); 2786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if ((source->IsStackSlot() && destination->IsStackSlot()) || 2787bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch (source->IsFPStackSlot() && destination->IsFPStackSlot())) { 2788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Memory-memory. 2789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand src = g.ToOperand(source); 2790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand dst = g.ToOperand(destination); 2791f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MachineRepresentation rep = LocationOperand::cast(source)->representation(); 2792f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (rep != MachineRepresentation::kSimd128) { 2793f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Register tmp = kScratchRegister; 2794f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ movq(tmp, dst); 2795f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ pushq(src); 2796f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), 2797f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch kPointerSize); 2798f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_access_state()->IncreaseSPDelta(1); 2799f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch src = g.ToOperand(source); 2800f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ movq(src, tmp); 2801f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_access_state()->IncreaseSPDelta(-1); 2802f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch dst = g.ToOperand(destination); 2803f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ popq(dst); 2804f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(), 2805f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch -kPointerSize); 2806f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2807f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Use the XOR trick to swap without a temporary. 2808f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movups(kScratchDoubleReg, src); 2809f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Xorps(kScratchDoubleReg, dst); // scratch contains src ^ dst. 2810f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movups(src, kScratchDoubleReg); 2811f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Xorps(kScratchDoubleReg, dst); // scratch contains src. 2812f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movups(dst, kScratchDoubleReg); 2813f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Xorps(kScratchDoubleReg, src); // scratch contains dst. 2814f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movups(src, kScratchDoubleReg); 2815f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2816bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (source->IsFPRegister() && destination->IsFPRegister()) { 281713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // XMM register-register swap. 2818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch XMMRegister src = g.ToDoubleRegister(source); 2819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch XMMRegister dst = g.ToDoubleRegister(destination); 282013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Movapd(kScratchDoubleReg, src); 2821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Movapd(src, dst); 282213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Movapd(dst, kScratchDoubleReg); 2823bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (source->IsFPRegister() && destination->IsFPStackSlot()) { 282413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // XMM register-memory swap. 2825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch XMMRegister src = g.ToDoubleRegister(source); 2826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand dst = g.ToOperand(destination); 2827f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MachineRepresentation rep = LocationOperand::cast(source)->representation(); 2828f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (rep != MachineRepresentation::kSimd128) { 2829f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movsd(kScratchDoubleReg, src); 2830f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movsd(src, dst); 2831f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movsd(dst, kScratchDoubleReg); 2832f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2833f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movups(kScratchDoubleReg, src); 2834f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movups(src, dst); 2835f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ Movups(dst, kScratchDoubleReg); 2836f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // No other combinations are possible. 2839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 2840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) { 2845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (size_t index = 0; index < target_count; ++index) { 2846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ dq(targets[index]); 2847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::EnsureSpaceForLazyDeopt() { 2852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!info()->ShouldEnsureSpaceForLazyDeopt()) { 2853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 2854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int space_needed = Deoptimizer::patch_size(); 2857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Ensure that we have enough space after the previous lazy-bailout 2858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // instruction for patching the code here. 2859f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int current_pc = __ pc_offset(); 2860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (current_pc < last_lazy_deopt_pc_ + space_needed) { 2861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; 2862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Nop(padding_size); 2863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef __ 2867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace compiler 2869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 2870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace v8 2871