1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2013 the V8 project authors. All rights reserved. 2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file. 4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/code-generator.h" 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 7f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/compilation-info.h" 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/code-generator-impl.h" 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/gap-resolver.h" 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/node-matchers.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/osr.h" 12109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/frames.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/x87/assembler-x87.h" 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/x87/frames-x87.h" 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/x87/macro-assembler-x87.h" 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace v8 { 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace internal { 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace compiler { 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define __ masm()-> 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Adds X87 specific methods for decoding operands. 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass X87OperandConverter : public InstructionOperandConverter { 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X87OperandConverter(CodeGenerator* gen, Instruction* instr) 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : InstructionOperandConverter(gen, instr) {} 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand InputOperand(size_t index, int extra = 0) { 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ToOperand(instr_->InputAt(index), extra); 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Immediate InputImmediate(size_t index) { 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ToImmediate(instr_->InputAt(index)); 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand OutputOperand() { return ToOperand(instr_->Output()); } 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand ToOperand(InstructionOperand* op, int extra = 0) { 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (op->IsRegister()) { 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(extra == 0); 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Operand(ToRegister(op)); 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 45bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(op->IsStackSlot() || op->IsFPStackSlot()); 463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return SlotToOperand(AllocatedOperand::cast(op)->index(), extra); 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Operand SlotToOperand(int slot, int extra = 0) { 503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FrameOffset offset = frame_access_state()->GetFrameOffset(slot); 513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return Operand(offset.from_stack_pointer() ? esp : ebp, 523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch offset.offset() + extra); 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand HighOperand(InstructionOperand* op) { 56bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(op->IsFPStackSlot()); 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ToOperand(op, kPointerSize); 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Immediate ToImmediate(InstructionOperand* operand) { 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Constant constant = ToConstant(operand); 62bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (constant.type() == Constant::kInt32 && 6362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch RelocInfo::IsWasmReference(constant.rmode())) { 64bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Immediate(reinterpret_cast<Address>(constant.ToInt32()), 65bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch constant.rmode()); 66bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (constant.type()) { 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kInt32: 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Immediate(constant.ToInt32()); 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kFloat32: 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Immediate( 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED)); 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kFloat64: 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Immediate( 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED)); 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kExternalReference: 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Immediate(constant.ToExternalReference()); 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kHeapObject: 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Immediate(constant.ToHeapObject()); 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kInt64: 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case Constant::kRpoNumber: 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Immediate::CodeRelativeOffset(ToLabel(operand)); 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Immediate(-1); 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static size_t NextOffset(size_t* offset) { 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t i = *offset; 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (*offset)++; 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return i; 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static ScaleFactor ScaleFor(AddressingMode one, AddressingMode mode) { 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(0 == static_cast<int>(times_1)); 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(1 == static_cast<int>(times_2)); 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(2 == static_cast<int>(times_4)); 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(3 == static_cast<int>(times_8)); 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int scale = static_cast<int>(mode - one); 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(scale >= 0 && scale < 4); 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return static_cast<ScaleFactor>(scale); 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand MemoryOperand(size_t* offset) { 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddressingMode mode = AddressingModeField::decode(instr_->opcode()); 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (mode) { 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_MR: { 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register base = InputRegister(NextOffset(offset)); 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t disp = 0; 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Operand(base, disp); 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_MRI: { 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register base = InputRegister(NextOffset(offset)); 11513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Constant ctant = ToConstant(instr_->InputAt(NextOffset(offset))); 11613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return Operand(base, ctant.ToInt32(), ctant.rmode()); 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_MR1: 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_MR2: 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_MR4: 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_MR8: { 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register base = InputRegister(NextOffset(offset)); 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register index = InputRegister(NextOffset(offset)); 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ScaleFactor scale = ScaleFor(kMode_MR1, mode); 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t disp = 0; 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Operand(base, index, scale, disp); 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_MR1I: 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_MR2I: 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_MR4I: 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_MR8I: { 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register base = InputRegister(NextOffset(offset)); 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register index = InputRegister(NextOffset(offset)); 134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ScaleFactor scale = ScaleFor(kMode_MR1I, mode); 13513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Constant ctant = ToConstant(instr_->InputAt(NextOffset(offset))); 13613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return Operand(base, index, scale, ctant.ToInt32(), ctant.rmode()); 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_M1: 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_M2: 140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_M4: 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_M8: { 142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register index = InputRegister(NextOffset(offset)); 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ScaleFactor scale = ScaleFor(kMode_M1, mode); 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t disp = 0; 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Operand(index, scale, disp); 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_M1I: 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_M2I: 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_M4I: 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_M8I: { 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register index = InputRegister(NextOffset(offset)); 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ScaleFactor scale = ScaleFor(kMode_M1I, mode); 15313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Constant ctant = ToConstant(instr_->InputAt(NextOffset(offset))); 15413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return Operand(index, scale, ctant.ToInt32(), ctant.rmode()); 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_MI: { 15713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Constant ctant = ToConstant(instr_->InputAt(NextOffset(offset))); 15813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return Operand(ctant.ToInt32(), ctant.rmode()); 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kMode_None: 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Operand(no_reg, 0); 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Operand(no_reg, 0); 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand MemoryOperand(size_t first_input = 0) { 169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return MemoryOperand(&first_input); 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace { 175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool HasImmediateInput(Instruction* instr, size_t index) { 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return instr->InputAt(index)->IsImmediate(); 178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineLoadInteger final : public OutOfLineCode { 182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutOfLineLoadInteger(CodeGenerator* gen, Register result) 184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : OutOfLineCode(gen), result_(result) {} 185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Generate() final { __ xor_(result_, result_); } 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register const result_; 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass OutOfLineLoadFloat32NaN final : public OutOfLineCode { 193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public: 194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch OutOfLineLoadFloat32NaN(CodeGenerator* gen, X87Register result) 195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch : OutOfLineCode(gen), result_(result) {} 196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void Generate() final { 198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(result_.code() == 0); 199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch USE(result_); 200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fstp(0); 201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ push(Immediate(0xffc00000)); 202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fld_s(MemOperand(esp, 0)); 203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ lea(esp, Operand(esp, kFloatSize)); 204f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private: 207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch X87Register const result_; 208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}; 209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 210f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass OutOfLineLoadFloat64NaN final : public OutOfLineCode { 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch OutOfLineLoadFloat64NaN(CodeGenerator* gen, X87Register result) 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : OutOfLineCode(gen), result_(result) {} 214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Generate() final { 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(result_.code() == 0); 217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch USE(result_); 218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ push(Immediate(0xfff80000)); 220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ push(Immediate(0x00000000)); 221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(esp, 0)); 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, kDoubleSize)); 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X87Register const result_; 227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineTruncateDoubleToI final : public OutOfLineCode { 230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutOfLineTruncateDoubleToI(CodeGenerator* gen, Register result, 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X87Register input) 233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : OutOfLineCode(gen), result_(result), input_(input) {} 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Generate() final { 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNIMPLEMENTED(); 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch USE(result_); 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch USE(input_); 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register const result_; 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X87Register const input_; 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineRecordWrite final : public OutOfLineCode { 248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutOfLineRecordWrite(CodeGenerator* gen, Register object, Operand operand, 250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register value, Register scratch0, Register scratch1, 251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordWriteMode mode) 252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : OutOfLineCode(gen), 253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object_(object), 254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch operand_(operand), 255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value_(value), 256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch scratch0_(scratch0), 257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch scratch1_(scratch1), 258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch mode_(mode) {} 259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Generate() final { 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mode_ > RecordWriteMode::kValueIsPointer) { 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ JumpIfSmi(value_, exit()); 263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 264109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ CheckPageFlag(value_, scratch0_, 265109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch MemoryChunk::kPointersToHereAreInterestingMask, zero, 266109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch exit()); 267109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch RememberedSetAction const remembered_set_action = 268109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET 269109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch : OMIT_REMEMBERED_SET; 270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SaveFPRegsMode const save_fp_mode = 271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; 272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_, 273109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch remembered_set_action, save_fp_mode); 274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(scratch1_, operand_); 275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ CallStub(&stub); 276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register const object_; 280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand const operand_; 281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register const value_; 282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register const scratch0_; 283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register const scratch1_; 284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordWriteMode const mode_; 285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace 288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 289f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr, OutOfLineLoadNaN) \ 290f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch do { \ 291f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto result = i.OutputDoubleRegister(); \ 292f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto offset = i.InputRegister(0); \ 293f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(result.code() == 0); \ 294f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (instr->InputAt(1)->IsRegister()) { \ 295f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ cmp(offset, i.InputRegister(1)); \ 296f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { \ 297f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ cmp(offset, i.InputImmediate(1)); \ 298f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } \ 299f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch OutOfLineCode* ool = new (zone()) OutOfLineLoadNaN(this, result); \ 300f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(above_equal, ool->entry()); \ 301f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fstp(0); \ 302f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ asm_instr(i.MemoryOperand(2)); \ 303f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(ool->exit()); \ 304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (false) 305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ 307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto result = i.OutputRegister(); \ 309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto offset = i.InputRegister(0); \ 310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(1)->IsRegister()) { \ 311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmp(offset, i.InputRegister(1)); \ 312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmp(offset, i.InputImmediate(1)); \ 314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutOfLineCode* ool = new (zone()) OutOfLineLoadInteger(this, result); \ 316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ j(above_equal, ool->entry()); \ 317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr(result, i.MemoryOperand(2)); \ 318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(ool->exit()); \ 319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (false) 320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr) \ 323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto offset = i.InputRegister(0); \ 325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(1)->IsRegister()) { \ 326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmp(offset, i.InputRegister(1)); \ 327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmp(offset, i.InputImmediate(1)); \ 329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label done; \ 331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(i.InputDoubleRegister(2).code() == 0); \ 332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ j(above_equal, &done, Label::kNear); \ 333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr(i.MemoryOperand(3)); \ 334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(&done); \ 335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (false) 336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ 339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch do { \ 340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto offset = i.InputRegister(0); \ 341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(1)->IsRegister()) { \ 342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmp(offset, i.InputRegister(1)); \ 343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmp(offset, i.InputImmediate(1)); \ 345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label done; \ 347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ j(above_equal, &done, Label::kNear); \ 348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(2)->IsRegister()) { \ 349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr(i.MemoryOperand(3), i.InputRegister(2)); \ 350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { \ 351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ asm_instr(i.MemoryOperand(3), i.InputImmediate(2)); \ 352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } \ 353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(&done); \ 354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } while (false) 355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#define ASSEMBLE_COMPARE(asm_instr) \ 3573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch do { \ 3583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (AddressingModeField::decode(instr->opcode()) != kMode_None) { \ 3593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch size_t index = 0; \ 3603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Operand left = i.MemoryOperand(&index); \ 3613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (HasImmediateInput(instr, index)) { \ 3623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ asm_instr(left, i.InputImmediate(index)); \ 3633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { \ 3643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ asm_instr(left, i.InputRegister(index)); \ 3653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } \ 3663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { \ 3673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (HasImmediateInput(instr, 1)) { \ 3683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (instr->InputAt(0)->IsRegister()) { \ 3693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ asm_instr(i.InputRegister(0), i.InputImmediate(1)); \ 3703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { \ 3713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ asm_instr(i.InputOperand(0), i.InputImmediate(1)); \ 3723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } \ 3733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { \ 3743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (instr->InputAt(1)->IsRegister()) { \ 3753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ asm_instr(i.InputRegister(0), i.InputRegister(1)); \ 3763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { \ 3773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ asm_instr(i.InputRegister(0), i.InputOperand(1)); \ 3783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } \ 3793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } \ 3803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } \ 3813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } while (0) 3823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 38313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#define ASSEMBLE_IEEE754_BINOP(name) \ 38413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch do { \ 38513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* Saves the esp into ebx */ \ 38613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ push(ebx); \ 38713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ mov(ebx, esp); \ 38813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* Pass one double as argument on the stack. */ \ 38913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ PrepareCallCFunction(4, eax); \ 39013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ fstp(0); \ 39113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* Load first operand from original stack */ \ 39213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ fld_d(MemOperand(ebx, 4 + kDoubleSize)); \ 39313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* Put first operand into stack for function call */ \ 39413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ fstp_d(Operand(esp, 0 * kDoubleSize)); \ 39513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* Load second operand from original stack */ \ 39613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ fld_d(MemOperand(ebx, 4)); \ 39713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* Put second operand into stack for function call */ \ 39813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ fstp_d(Operand(esp, 1 * kDoubleSize)); \ 39913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ 40013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 4); \ 40113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* Restore the ebx */ \ 40213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ pop(ebx); \ 40313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* Return value is in st(0) on x87. */ \ 40413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ lea(esp, Operand(esp, 2 * kDoubleSize)); \ 40513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } while (false) 40613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 40713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#define ASSEMBLE_IEEE754_UNOP(name) \ 40813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch do { \ 40913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* Saves the esp into ebx */ \ 41013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ push(ebx); \ 41113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ mov(ebx, esp); \ 41213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* Pass one double as argument on the stack. */ \ 41313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ PrepareCallCFunction(2, eax); \ 41413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ fstp(0); \ 41513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* Load operand from original stack */ \ 41613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ fld_d(MemOperand(ebx, 4)); \ 41713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* Put operand into stack for function call */ \ 41813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ fstp_d(Operand(esp, 0)); \ 41913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ 42013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 2); \ 42113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* Restore the ebx */ \ 42213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ pop(ebx); \ 42313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch /* Return value is in st(0) on x87. */ \ 42413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ lea(esp, Operand(esp, kDoubleSize)); \ 42513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } while (false) 42613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 4273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid CodeGenerator::AssembleDeconstructFrame() { 4283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ mov(esp, ebp); 4293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ pop(ebp); 4303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 4313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 432f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::AssemblePrepareTailCall() { 4333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (frame_access_state()->has_frame()) { 434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(ebp, MemOperand(ebp, 0)); 435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->SetFrameAccessToSP(); 437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg, 4403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register, Register, 4413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register) { 4423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // There are not enough temp registers left on ia32 for a call instruction 4433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // so we pick some scratch registers and save/restore them manually here. 4443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int scratch_count = 3; 4453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register scratch1 = ebx; 4463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register scratch2 = ecx; 4473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register scratch3 = edx; 4483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3)); 4493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label done; 4503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 4513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Check if current frame is an arguments adaptor frame. 4523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ cmp(Operand(ebp, StandardFrameConstants::kContextOffset), 4533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 4543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ j(not_equal, &done, Label::kNear); 4553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 4563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ push(scratch1); 4573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ push(scratch2); 4583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ push(scratch3); 4593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 4603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Load arguments count from current arguments adaptor frame (note, it 4613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // does not include receiver). 4623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register caller_args_count_reg = scratch1; 4633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ mov(caller_args_count_reg, 4643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset)); 4653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ SmiUntag(caller_args_count_reg); 4663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 4673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ParameterCount callee_args_count(args_reg); 4683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2, 4693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch scratch3, ReturnAddressState::kOnStack, scratch_count); 4703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ pop(scratch3); 4713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ pop(scratch2); 4723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ pop(scratch1); 4733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 4743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ bind(&done); 4753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 477f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace { 478f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 479f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid AdjustStackPointerForTailCall(MacroAssembler* masm, 480f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FrameAccessState* state, 481f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int new_slot_above_sp, 482f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool allow_shrinkage = true) { 483f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int current_sp_offset = state->GetSPToFPSlotCount() + 484f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch StandardFrameConstants::kFixedSlotCountAboveFp; 485f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int stack_slot_delta = new_slot_above_sp - current_sp_offset; 486f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (stack_slot_delta > 0) { 487f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch masm->sub(esp, Immediate(stack_slot_delta * kPointerSize)); 488f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch state->IncreaseSPDelta(stack_slot_delta); 489f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (allow_shrinkage && stack_slot_delta < 0) { 490f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch masm->add(esp, Immediate(-stack_slot_delta * kPointerSize)); 491f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch state->IncreaseSPDelta(stack_slot_delta); 492f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 493f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 494f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 495f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} // namespace 496f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 497f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::AssembleTailCallBeforeGap(Instruction* instr, 498f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int first_unused_stack_slot) { 499f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CodeGenerator::PushTypeFlags flags(kImmediatePush | kScalarPush); 500f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ZoneVector<MoveOperands*> pushes(zone()); 501f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch GetPushCompatibleMoves(instr, flags, &pushes); 502f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 503f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!pushes.empty() && 504f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (LocationOperand::cast(pushes.back()->destination()).index() + 1 == 505f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch first_unused_stack_slot)) { 506f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch X87OperandConverter g(this, instr); 507f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (auto move : pushes) { 508f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LocationOperand destination_location( 509f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LocationOperand::cast(move->destination())); 510f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand source(move->source()); 511f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AdjustStackPointerForTailCall(masm(), frame_access_state(), 512f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch destination_location.index()); 513f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (source.IsStackSlot()) { 514f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LocationOperand source_location(LocationOperand::cast(source)); 515f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ push(g.SlotToOperand(source_location.index())); 516f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (source.IsRegister()) { 517f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LocationOperand source_location(LocationOperand::cast(source)); 518f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ push(source_location.GetRegister()); 519f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (source.IsImmediate()) { 520f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ push(Immediate(ImmediateOperand::cast(source).inline_value())); 521f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 522f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Pushes of non-scalar data types is not supported. 523f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNIMPLEMENTED(); 524f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 525f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_access_state()->IncreaseSPDelta(1); 526f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch move->Eliminate(); 527f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 528f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 529f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AdjustStackPointerForTailCall(masm(), frame_access_state(), 530f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch first_unused_stack_slot, false); 531f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 532f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 533f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::AssembleTailCallAfterGap(Instruction* instr, 534f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int first_unused_stack_slot) { 535f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AdjustStackPointerForTailCall(masm(), frame_access_state(), 536f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch first_unused_stack_slot); 537f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 538f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Assembles an instruction after register allocation, producing machine code. 540bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( 541bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Instruction* instr) { 542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X87OperandConverter i(this, instr); 5433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch InstructionCode opcode = instr->opcode(); 5443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode); 5453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 5463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch switch (arch_opcode) { 547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchCallCodeObject: { 548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EnsureSpaceForLazyDeopt(); 553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, 0)) { 554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); 555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ call(code, RelocInfo::CODE_TARGET); 556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register reg = i.InputRegister(0); 558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); 559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ call(reg); 560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordCallPosition(instr); 562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool double_result = 563bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch instr->HasOutput() && instr->Output()->IsFPRegister(); 564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (double_result) { 565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, -kDoubleSize)); 566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_d(Operand(esp, 0)); 567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fninit(); 569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (double_result) { 570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(Operand(esp, 0)); 571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, kDoubleSize)); 572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld1(); 574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->ClearSPDelta(); 576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 5783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kArchTailCallCodeObjectFromJSFunction: 579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchTailCallCodeObject: { 580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 5843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) { 5853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, 5863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch no_reg, no_reg, no_reg); 5873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, 0)) { 589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); 590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ jmp(code, RelocInfo::CODE_TARGET); 591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register reg = i.InputRegister(0); 593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); 594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ jmp(reg); 595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->ClearSPDelta(); 597f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_access_state()->SetFrameAccessToDefault(); 598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 600bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kArchTailCallAddress: { 601bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CHECK(!HasImmediateInput(instr, 0)); 602bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Register reg = i.InputRegister(0); 603bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ jmp(reg); 604bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch frame_access_state()->ClearSPDelta(); 605f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_access_state()->SetFrameAccessToDefault(); 606bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 607bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchCallJSFunction: { 609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch EnsureSpaceForLazyDeopt(); 610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register func = i.InputRegister(0); 611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code) { 612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check the function's context matches the context argument. 613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); 614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Assert(equal, kWrongFunctionContext); 615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ call(FieldOperand(func, JSFunction::kCodeEntryOffset)); 621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordCallPosition(instr); 622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool double_result = 623bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch instr->HasOutput() && instr->Output()->IsFPRegister(); 624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (double_result) { 625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, -kDoubleSize)); 626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_d(Operand(esp, 0)); 627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fninit(); 629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (double_result) { 630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(Operand(esp, 0)); 631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, kDoubleSize)); 632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld1(); 634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->ClearSPDelta(); 636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 638c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch case kArchTailCallJSFunctionFromJSFunction: { 639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register func = i.InputRegister(0); 640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code) { 641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check the function's context matches the context argument. 642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); 643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Assert(equal, kWrongFunctionContext); 644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 649c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister, no_reg, 650c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch no_reg, no_reg); 651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset)); 652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->ClearSPDelta(); 653f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_access_state()->SetFrameAccessToDefault(); 654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchPrepareCallCFunction: { 657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Frame alignment requires using FP-relative frame addressing. 658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->SetFrameAccessToFP(); 659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int const num_parameters = MiscField::decode(instr->opcode()); 660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ PrepareCallCFunction(num_parameters, i.TempRegister(0)); 661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchPrepareTailCall: 664f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AssemblePrepareTailCall(); 665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchCallCFunction: { 667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int const num_parameters = MiscField::decode(instr->opcode()); 672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, 0)) { 673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExternalReference ref = i.InputExternalReference(0); 674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ CallCFunction(ref, num_parameters); 675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register func = i.InputRegister(0); 677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ CallCFunction(func, num_parameters); 678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool double_result = 680bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch instr->HasOutput() && instr->Output()->IsFPRegister(); 681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (double_result) { 682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, -kDoubleSize)); 683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_d(Operand(esp, 0)); 684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fninit(); 686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (double_result) { 687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(Operand(esp, 0)); 688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, kDoubleSize)); 689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld1(); 691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->SetFrameAccessToDefault(); 693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->ClearSPDelta(); 694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchJmp: 697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleArchJump(i.InputRpo(0)); 698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchLookupSwitch: 700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleArchLookupSwitch(instr); 701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchTableSwitch: 703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleArchTableSwitch(instr); 704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 70513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kArchComment: { 70613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Address comment_string = i.InputExternalReference(0).address(); 70713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ RecordComment(reinterpret_cast<const char*>(comment_string)); 70813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 70913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 71013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kArchDebugBreak: 71113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ int3(); 71213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchNop: 714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchThrowTerminator: 715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // don't emit code for nops. 716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchDeoptimize: { 718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int deopt_state_id = 719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore()); 720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int double_register_param_count = 0; 721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int x87_layout = 0; 722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (size_t i = 0; i < instr->InputCount(); i++) { 723bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(i)->IsFPRegister()) { 724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double_register_param_count++; 725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Currently we use only one X87 register. If double_register_param_count 728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // is bigger than 1, it means duplicated double register is added to input 729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // of this instruction. 730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (double_register_param_count > 0) { 731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch x87_layout = (0 << 3) | 1; 732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The layout of x87 register stack is loaded on the top of FPU register 734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // stack for deoptimization. 735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ push(Immediate(x87_layout)); 736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fild_s(MemOperand(esp, 0)); 737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, kPointerSize)); 738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 73962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CodeGenResult result = 74062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AssembleDeoptimizerCall(deopt_state_id, current_source_position_); 741bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (result != kSuccess) return result; 742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchRet: 745c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch AssembleReturn(instr->InputAt(0)); 746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchFramePointer: 748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(i.OutputRegister(), ebp); 749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchStackPointer: 751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(i.OutputRegister(), esp); 752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 753109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case kArchParentFramePointer: 7543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (frame_access_state()->has_frame()) { 755109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ mov(i.OutputRegister(), Operand(ebp, 0)); 756109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 757109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ mov(i.OutputRegister(), ebp); 758109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 759109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchTruncateDoubleToI: { 761bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!instr->InputAt(0)->IsFPRegister()) { 762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(i.InputOperand(0)); 763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ TruncateX87TOSToI(i.OutputRegister()); 765bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!instr->InputAt(0)->IsFPRegister()) { 766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kArchStoreWithWriteBarrier: { 771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RecordWriteMode mode = 772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<RecordWriteMode>(MiscField::decode(instr->opcode())); 773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register object = i.InputRegister(0); 774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; 775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand operand = i.MemoryOperand(&index); 776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register value = i.InputRegister(index); 777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch0 = i.TempRegister(0); 778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch1 = i.TempRegister(1); 779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto ool = new (zone()) OutOfLineRecordWrite(this, object, operand, value, 780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch scratch0, scratch1, mode); 781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(operand, value); 782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ CheckPageFlag(object, scratch0, 783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MemoryChunk::kPointersFromHereAreInterestingMask, 784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch not_zero, ool->entry()); 785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(ool->exit()); 786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 788109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case kArchStackSlot: { 789109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FrameOffset offset = 790109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch frame_access_state()->GetFrameOffset(i.InputInt32(0)); 791109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Register base; 792109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (offset.from_stack_pointer()) { 793109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch base = esp; 794109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 795109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch base = ebp; 796109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 797109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ lea(i.OutputRegister(), Operand(base, offset.offset())); 798109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 799109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 800f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Acos: 801f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(acos); 802f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 803f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Acosh: 804f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(acosh); 805f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 806f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Asin: 807f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(asin); 808f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 809f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Asinh: 810f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(asinh); 811f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 81213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Atan: 81313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(atan); 81413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 815f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Atanh: 816f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(atanh); 817f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 81813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Atan2: 81913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_BINOP(atan2); 82013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 82113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Cbrt: 82213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(cbrt); 82313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 82413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Cos: 82513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ X87SetFPUCW(0x027F); 82613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(cos); 82713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ X87SetFPUCW(0x037F); 82813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 829f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Cosh: 830f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(cosh); 831f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 83213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Expm1: 83313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ X87SetFPUCW(0x027F); 83413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(expm1); 83513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ X87SetFPUCW(0x037F); 83613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 83713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Exp: 83813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(exp); 83913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 84013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Log: 84113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(log); 84213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 84313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Log1p: 84413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(log1p); 84513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 84613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Log2: 84713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(log2); 84813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 84913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Log10: 85013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(log10); 85113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 852f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Pow: { 853f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Keep the x87 FPU stack empty before calling stub code 854f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fstp(0); 855f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Call the MathStub and put return value in stX_0 856f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MathPowStub stub(isolate(), MathPowStub::DOUBLE); 857f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ CallStub(&stub); 858f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch /* Return value is in st(0) on x87. */ 859f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ lea(esp, Operand(esp, 2 * kDoubleSize)); 860f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 861f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 86213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Sin: 86313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ X87SetFPUCW(0x027F); 86413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(sin); 86513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ X87SetFPUCW(0x037F); 86613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 867f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Sinh: 868f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(sinh); 869f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 87013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kIeee754Float64Tan: 87113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ X87SetFPUCW(0x027F); 87213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ASSEMBLE_IEEE754_UNOP(tan); 87313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ X87SetFPUCW(0x037F); 87413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 875f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kIeee754Float64Tanh: 876f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_IEEE754_UNOP(tanh); 877f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Add: 879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, 1)) { 880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ add(i.InputOperand(0), i.InputImmediate(1)); 881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ add(i.InputRegister(0), i.InputOperand(1)); 883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87And: 886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, 1)) { 887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ and_(i.InputOperand(0), i.InputImmediate(1)); 888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ and_(i.InputRegister(0), i.InputOperand(1)); 890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Cmp: 8933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_COMPARE(cmp); 8943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 8953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX87Cmp16: 8963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_COMPARE(cmpw); 8973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 8983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX87Cmp8: 8993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_COMPARE(cmpb); 900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Test: 9023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_COMPARE(test); 9033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 9043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX87Test16: 9053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_COMPARE(test_w); 9063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 9073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX87Test8: 9083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSEMBLE_COMPARE(test_b); 909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Imul: 911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, 1)) { 912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ imul(i.OutputRegister(), i.InputOperand(0), i.InputInt32(1)); 913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ imul(i.OutputRegister(), i.InputOperand(1)); 915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87ImulHigh: 918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ imul(i.InputRegister(1)); 919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87UmulHigh: 921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mul(i.InputRegister(1)); 922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Idiv: 924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cdq(); 925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ idiv(i.InputOperand(1)); 926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Udiv: 928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Move(edx, Immediate(0)); 929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ div(i.InputOperand(1)); 930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Not: 932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ not_(i.OutputOperand()); 933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Neg: 935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ neg(i.OutputOperand()); 936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Or: 938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, 1)) { 939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ or_(i.InputOperand(0), i.InputImmediate(1)); 940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ or_(i.InputRegister(0), i.InputOperand(1)); 942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Xor: 945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, 1)) { 946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ xor_(i.InputOperand(0), i.InputImmediate(1)); 947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ xor_(i.InputRegister(0), i.InputOperand(1)); 949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Sub: 952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, 1)) { 953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sub(i.InputOperand(0), i.InputImmediate(1)); 954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sub(i.InputRegister(0), i.InputOperand(1)); 956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Shl: 959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, 1)) { 960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ shl(i.OutputOperand(), i.InputInt5(1)); 961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ shl_cl(i.OutputOperand()); 963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Shr: 966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, 1)) { 967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ shr(i.OutputOperand(), i.InputInt5(1)); 968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ shr_cl(i.OutputOperand()); 970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Sar: 973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, 1)) { 974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sar(i.OutputOperand(), i.InputInt5(1)); 975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sar_cl(i.OutputOperand()); 977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 9793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX87AddPair: { 9803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.OutputRegister(0) == i.InputRegister(0) ... left low word. 9813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.InputRegister(1) ... left high word. 9823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.InputRegister(2) ... right low word. 9833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.InputRegister(3) ... right high word. 9843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bool use_temp = false; 9853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (i.OutputRegister(0).code() == i.InputRegister(1).code() || 9863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch i.OutputRegister(0).code() == i.InputRegister(3).code()) { 9873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // We cannot write to the output register directly, because it would 9883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // overwrite an input for adc. We have to use the temp register. 9893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch use_temp = true; 9903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Move(i.TempRegister(0), i.InputRegister(0)); 9913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ add(i.TempRegister(0), i.InputRegister(2)); 9923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 9933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ add(i.OutputRegister(0), i.InputRegister(2)); 9943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 9953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (i.OutputRegister(1).code() != i.InputRegister(1).code()) { 9963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Move(i.OutputRegister(1), i.InputRegister(1)); 9973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 99862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ adc(i.OutputRegister(1), Operand(i.InputRegister(3))); 9993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (use_temp) { 10003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Move(i.OutputRegister(0), i.TempRegister(0)); 10013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 10033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX87SubPair: { 10053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.OutputRegister(0) == i.InputRegister(0) ... left low word. 10063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.InputRegister(1) ... left high word. 10073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.InputRegister(2) ... right low word. 10083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // i.InputRegister(3) ... right high word. 10093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bool use_temp = false; 10103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (i.OutputRegister(0).code() == i.InputRegister(1).code() || 10113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch i.OutputRegister(0).code() == i.InputRegister(3).code()) { 10123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // We cannot write to the output register directly, because it would 10133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // overwrite an input for adc. We have to use the temp register. 10143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch use_temp = true; 10153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Move(i.TempRegister(0), i.InputRegister(0)); 10163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ sub(i.TempRegister(0), i.InputRegister(2)); 10173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 10183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ sub(i.OutputRegister(0), i.InputRegister(2)); 10193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (i.OutputRegister(1).code() != i.InputRegister(1).code()) { 10213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Move(i.OutputRegister(1), i.InputRegister(1)); 10223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 102362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ sbb(i.OutputRegister(1), Operand(i.InputRegister(3))); 10243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (use_temp) { 10253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Move(i.OutputRegister(0), i.TempRegister(0)); 10263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 10283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX87MulPair: { 10303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ imul(i.OutputRegister(1), i.InputOperand(0)); 10313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ mov(i.TempRegister(0), i.InputOperand(1)); 10323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ imul(i.TempRegister(0), i.InputOperand(2)); 10333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ add(i.OutputRegister(1), i.TempRegister(0)); 10343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ mov(i.OutputRegister(0), i.InputOperand(0)); 10353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Multiplies the low words and stores them in eax and edx. 10363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ mul(i.InputRegister(2)); 10373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ add(i.OutputRegister(1), i.TempRegister(0)); 10383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 10393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 10403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX87ShlPair: 10423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (HasImmediateInput(instr, 2)) { 10433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ ShlPair(i.InputRegister(1), i.InputRegister(0), i.InputInt6(2)); 10443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 10453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Shift has been loaded into CL by the register allocator. 10463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ ShlPair_cl(i.InputRegister(1), i.InputRegister(0)); 10473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 10493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX87ShrPair: 10503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (HasImmediateInput(instr, 2)) { 10513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ ShrPair(i.InputRegister(1), i.InputRegister(0), i.InputInt6(2)); 10523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 10533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Shift has been loaded into CL by the register allocator. 10543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ ShrPair_cl(i.InputRegister(1), i.InputRegister(0)); 10553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 10573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch case kX87SarPair: 10583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (HasImmediateInput(instr, 2)) { 10593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ SarPair(i.InputRegister(1), i.InputRegister(0), i.InputInt6(2)); 10603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 10613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Shift has been loaded into CL by the register allocator. 10623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ SarPair_cl(i.InputRegister(1), i.InputRegister(0)); 10633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 1065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Ror: 1066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, 1)) { 1067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ror(i.OutputOperand(), i.InputInt5(1)); 1068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ror_cl(i.OutputOperand()); 1070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Lzcnt: 1073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Lzcnt(i.OutputRegister(), i.InputOperand(0)); 1074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Popcnt: 1076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Popcnt(i.OutputRegister(), i.InputOperand(0)); 1077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87LoadFloat64Constant: { 1079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* source = instr->InputAt(0); 1080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* destination = instr->Output(); 1081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(source->IsConstant()); 1082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X87OperandConverter g(this, nullptr); 1083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Constant src_constant = g.ToConstant(source); 1084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(Constant::kFloat64, src_constant.type()); 1086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint64_t src = bit_cast<uint64_t>(src_constant.ToFloat64()); 1087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t lower = static_cast<uint32_t>(src); 1088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t upper = static_cast<uint32_t>(src >> 32); 1089bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (destination->IsFPRegister()) { 1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sub(esp, Immediate(kDoubleSize)); 1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(MemOperand(esp, 0), Immediate(lower)); 1092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(MemOperand(esp, kInt32Size), Immediate(upper)); 1093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(esp, 0)); 1095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ add(esp, Immediate(kDoubleSize)); 1096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 1098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float32Cmp: { 1102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(MemOperand(esp, kFloatSize)); 1103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(MemOperand(esp, 0)); 1104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ FCmp(); 1105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, 2 * kFloatSize)); 1106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float32Add: { 1109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetFPUCW(0x027F); 1113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(MemOperand(esp, 0)); 1115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(MemOperand(esp, kFloatSize)); 1116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ faddp(); 1117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Clear stack. 1118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, 2 * kFloatSize)); 1119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Restore the default value of control word. 1120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetFPUCW(0x037F); 1121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float32Sub: { 1124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetFPUCW(0x027F); 1128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(MemOperand(esp, kFloatSize)); 1130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(MemOperand(esp, 0)); 1131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fsubp(); 1132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Clear stack. 1133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, 2 * kFloatSize)); 1134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Restore the default value of control word. 1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetFPUCW(0x037F); 1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float32Mul: { 1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetFPUCW(0x027F); 1143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(MemOperand(esp, kFloatSize)); 1145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(MemOperand(esp, 0)); 1146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fmulp(); 1147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Clear stack. 1148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, 2 * kFloatSize)); 1149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Restore the default value of control word. 1150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetFPUCW(0x037F); 1151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float32Div: { 1154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetFPUCW(0x027F); 1158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(MemOperand(esp, kFloatSize)); 1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(MemOperand(esp, 0)); 1161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fdivp(); 1162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Clear stack. 1163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, 2 * kFloatSize)); 1164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Restore the default value of control word. 1165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetFPUCW(0x037F); 1166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kX87Float32Sqrt: { 1170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(MemOperand(esp, 0)); 1175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fsqrt(); 1176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ lea(esp, Operand(esp, kFloatSize)); 1177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kX87Float32Abs: { 1180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(MemOperand(esp, 0)); 1185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fabs(); 1186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, kFloatSize)); 1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kX87Float32Neg: { 1190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(MemOperand(esp, 0)); 1195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fchs(); 1196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, kFloatSize)); 1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float32Round: { 1200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RoundingMode mode = 1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<RoundingMode>(MiscField::decode(instr->opcode())); 1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Set the correct round mode in x87 control register 1203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetRC((mode << 10)); 1204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1205bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!instr->InputAt(0)->IsFPRegister()) { 1206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* input = instr->InputAt(0); 1207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch USE(input); 1208bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(input->IsFPStackSlot()); 1209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(i.InputOperand(0)); 1214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ frndint(); 1216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetRC(0x0000); 1217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float64Add: { 1220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetFPUCW(0x027F); 1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(esp, 0)); 1226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(esp, kDoubleSize)); 1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ faddp(); 1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Clear stack. 1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, 2 * kDoubleSize)); 1230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Restore the default value of control word. 1231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetFPUCW(0x037F); 1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float64Sub: { 1235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetFPUCW(0x027F); 1239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(esp, kDoubleSize)); 1241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fsub_d(MemOperand(esp, 0)); 1242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Clear stack. 1243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, 2 * kDoubleSize)); 1244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Restore the default value of control word. 1245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetFPUCW(0x037F); 1246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float64Mul: { 1249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetFPUCW(0x027F); 1253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(esp, kDoubleSize)); 1255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fmul_d(MemOperand(esp, 0)); 1256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Clear stack. 1257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, 2 * kDoubleSize)); 1258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Restore the default value of control word. 1259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetFPUCW(0x037F); 1260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float64Div: { 1263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetFPUCW(0x027F); 1267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(esp, kDoubleSize)); 1269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fdiv_d(MemOperand(esp, 0)); 1270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Clear stack. 1271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, 2 * kDoubleSize)); 1272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Restore the default value of control word. 1273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetFPUCW(0x037F); 1274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float64Mod: { 1277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrameScope frame_scope(&masm_, StackFrame::MANUAL); 1278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(eax, esp); 1282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ PrepareCallCFunction(4, eax); 1283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(eax, 0)); 1285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_d(Operand(esp, 1 * kDoubleSize)); 1286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(eax, kDoubleSize)); 1287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_d(Operand(esp, 0)); 1288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()), 1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4); 1290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, 2 * kDoubleSize)); 1291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1293f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kX87Float32Max: { 1294f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Label compare_swap, done_compare; 1295f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1296f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ VerifyX87StackDepth(1); 1297f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1298f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fstp(0); 1299f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fld_s(MemOperand(esp, kFloatSize)); 1300f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fld_s(MemOperand(esp, 0)); 1301f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fld(1); 1302f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fld(1); 1303f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ FCmp(); 1304f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1305f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto ool = 1306f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch new (zone()) OutOfLineLoadFloat32NaN(this, i.OutputDoubleRegister()); 1307f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(parity_even, ool->entry()); 1308f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(below, &done_compare, Label::kNear); 1309f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(above, &compare_swap, Label::kNear); 1310f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ push(eax); 1311f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ lea(esp, Operand(esp, -kFloatSize)); 1312f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fld(1); 1313f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fstp_s(Operand(esp, 0)); 1314f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ mov(eax, MemOperand(esp, 0)); 1315f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ and_(eax, Immediate(0x80000000)); 1316f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ lea(esp, Operand(esp, kFloatSize)); 1317f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ pop(eax); 1318f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(zero, &done_compare, Label::kNear); 1319f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1320f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&compare_swap); 1321f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(ool->exit()); 1322f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fxch(1); 1323f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1324f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&done_compare); 1325f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fstp(0); 1326f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ lea(esp, Operand(esp, 2 * kFloatSize)); 1327f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1328f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float64Max: { 1330f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Label compare_swap, done_compare; 1331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(esp, kDoubleSize)); 1336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(esp, 0)); 1337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld(1); 1338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld(1); 1339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ FCmp(); 1340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1341f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto ool = 1342f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch new (zone()) OutOfLineLoadFloat64NaN(this, i.OutputDoubleRegister()); 1343f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(parity_even, ool->entry()); 1344f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(below, &done_compare, Label::kNear); 1345f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(above, &compare_swap, Label::kNear); 1346f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ push(eax); 1347f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ lea(esp, Operand(esp, -kDoubleSize)); 1348f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fld(1); 1349f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fstp_d(Operand(esp, 0)); 1350f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ mov(eax, MemOperand(esp, 4)); 1351f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ and_(eax, Immediate(0x80000000)); 1352f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ lea(esp, Operand(esp, kDoubleSize)); 1353f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ pop(eax); 1354f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(zero, &done_compare, Label::kNear); 1355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1356f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&compare_swap); 1357f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(ool->exit()); 1358f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fxch(1); 1359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1360f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&done_compare); 1361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, 2 * kDoubleSize)); 1363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1365f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kX87Float32Min: { 1366f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Label compare_swap, done_compare; 1367f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1368f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ VerifyX87StackDepth(1); 1369f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1370f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fstp(0); 1371f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fld_s(MemOperand(esp, kFloatSize)); 1372f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fld_s(MemOperand(esp, 0)); 1373f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fld(1); 1374f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fld(1); 1375f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ FCmp(); 1376f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1377f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto ool = 1378f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch new (zone()) OutOfLineLoadFloat32NaN(this, i.OutputDoubleRegister()); 1379f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(parity_even, ool->entry()); 1380f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(above, &done_compare, Label::kNear); 1381f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(below, &compare_swap, Label::kNear); 1382f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ push(eax); 1383f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ lea(esp, Operand(esp, -kFloatSize)); 1384f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fld(0); 1385f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fstp_s(Operand(esp, 0)); 1386f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ mov(eax, MemOperand(esp, 0)); 1387f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ and_(eax, Immediate(0x80000000)); 1388f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ lea(esp, Operand(esp, kFloatSize)); 1389f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ pop(eax); 1390f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(zero, &done_compare, Label::kNear); 1391f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1392f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&compare_swap); 1393f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(ool->exit()); 1394f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fxch(1); 1395f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1396f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&done_compare); 1397f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fstp(0); 1398f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ lea(esp, Operand(esp, 2 * kFloatSize)); 1399f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1400f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float64Min: { 1402f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Label compare_swap, done_compare; 1403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(esp, kDoubleSize)); 1408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(esp, 0)); 1409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld(1); 1410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld(1); 1411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ FCmp(); 1412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben 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 __ push(eax); 1419f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ lea(esp, Operand(esp, -kDoubleSize)); 1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld(0); 1421f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fstp_d(Operand(esp, 0)); 1422f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ mov(eax, MemOperand(esp, 4)); 1423f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ and_(eax, Immediate(0x80000000)); 1424f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ lea(esp, Operand(esp, kDoubleSize)); 1425f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ pop(eax); 1426f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ j(zero, &done_compare, Label::kNear); 1427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1428f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&compare_swap); 1429f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(ool->exit()); 1430f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fxch(1); 1431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1432f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ bind(&done_compare); 1433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, 2 * kDoubleSize)); 1435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float64Abs: { 1438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(esp, 0)); 1443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fabs(); 1444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, kDoubleSize)); 1445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1447f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kX87Float64Neg: { 1448f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1449f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ VerifyX87StackDepth(1); 1450f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1451f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fstp(0); 1452f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fld_d(MemOperand(esp, 0)); 1453f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fchs(); 1454f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ lea(esp, Operand(esp, kDoubleSize)); 1455f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1456f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1457109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case kX87Int32ToFloat32: { 1458109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch InstructionOperand* input = instr->InputAt(0); 1459109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(input->IsRegister() || input->IsStackSlot()); 1460109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1461109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ VerifyX87StackDepth(1); 1462109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1463109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ fstp(0); 1464109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (input->IsRegister()) { 1465109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Register input_reg = i.InputRegister(0); 1466109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ push(input_reg); 1467109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ fild_s(Operand(esp, 0)); 1468109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ pop(input_reg); 1469109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 1470109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ fild_s(i.InputOperand(0)); 1471109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1472109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 1473109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1474109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case kX87Uint32ToFloat32: { 1475109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch InstructionOperand* input = instr->InputAt(0); 1476109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(input->IsRegister() || input->IsStackSlot()); 1477109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1478109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ VerifyX87StackDepth(1); 1479109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1480109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ fstp(0); 1481109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Label msb_set_src; 1482109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Label jmp_return; 1483109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Put input integer into eax(tmporarilly) 1484109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ push(eax); 1485109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (input->IsRegister()) 1486109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ mov(eax, i.InputRegister(0)); 1487109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch else 1488109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ mov(eax, i.InputOperand(0)); 1489109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1490109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ test(eax, eax); 1491109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ j(sign, &msb_set_src, Label::kNear); 1492109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ push(eax); 1493109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ fild_s(Operand(esp, 0)); 1494109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ pop(eax); 1495109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1496109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ jmp(&jmp_return, Label::kNear); 1497109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ bind(&msb_set_src); 1498109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Need another temp reg 1499109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ push(ebx); 1500109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ mov(ebx, eax); 1501109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ shr(eax, 1); 1502109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Recover the least significant bit to avoid rounding errors. 1503109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ and_(ebx, Immediate(1)); 1504109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ or_(eax, ebx); 1505109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ push(eax); 1506109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ fild_s(Operand(esp, 0)); 1507109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ pop(eax); 1508109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ fld(0); 1509109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ faddp(); 1510109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Restore the ebx 1511109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ pop(ebx); 1512109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ bind(&jmp_return); 1513109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Restore the eax 1514109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ pop(eax); 1515109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 1516109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Int32ToFloat64: { 1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* input = instr->InputAt(0); 1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(input->IsRegister() || input->IsStackSlot()); 1520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (input->IsRegister()) { 1525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register input_reg = i.InputRegister(0); 1526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ push(input_reg); 1527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fild_s(Operand(esp, 0)); 1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ pop(input_reg); 1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fild_s(i.InputOperand(0)); 1531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float32ToFloat64: { 1535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* input = instr->InputAt(0); 1536bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (input->IsFPRegister()) { 1537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sub(esp, Immediate(kDoubleSize)); 15383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ fstp_s(MemOperand(esp, 0)); 15393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ fld_s(MemOperand(esp, 0)); 1540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ add(esp, Immediate(kDoubleSize)); 1541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1542bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(input->IsFPStackSlot()); 1543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(i.InputOperand(0)); 1548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Uint32ToFloat64: { 1552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadUint32NoSSE2(i.InputRegister(0)); 1557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1559109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case kX87Float32ToInt32: { 1560bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!instr->InputAt(0)->IsFPRegister()) { 1561109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ fld_s(i.InputOperand(0)); 1562109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1563109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ TruncateX87TOSToI(i.OutputRegister(0)); 1564bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!instr->InputAt(0)->IsFPRegister()) { 1565109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ fstp(0); 1566109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1567109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 1568109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1569109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case kX87Float32ToUint32: { 1570bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!instr->InputAt(0)->IsFPRegister()) { 1571109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ fld_s(i.InputOperand(0)); 1572109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1573109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Label success; 1574109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ TruncateX87TOSToI(i.OutputRegister(0)); 1575109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ test(i.OutputRegister(0), i.OutputRegister(0)); 1576109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ j(positive, &success); 1577f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Need to reserve the input float32 data. 1578f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fld(0); 1579109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ push(Immediate(INT32_MIN)); 1580109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ fild_s(Operand(esp, 0)); 1581109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ lea(esp, Operand(esp, kPointerSize)); 1582109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ faddp(); 1583109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ TruncateX87TOSToI(i.OutputRegister(0)); 1584109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ or_(i.OutputRegister(0), Immediate(0x80000000)); 1585f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Only keep input float32 data in x87 stack when return. 1586f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch __ fstp(0); 1587109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ bind(&success); 1588bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!instr->InputAt(0)->IsFPRegister()) { 1589109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ fstp(0); 1590109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1591109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 1592109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float64ToInt32: { 1594bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!instr->InputAt(0)->IsFPRegister()) { 1595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(i.InputOperand(0)); 1596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ TruncateX87TOSToI(i.OutputRegister(0)); 1598bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!instr->InputAt(0)->IsFPRegister()) { 1599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float64ToFloat32: { 1604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* input = instr->InputAt(0); 1605bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (input->IsFPRegister()) { 1606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sub(esp, Immediate(kDoubleSize)); 1607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_s(MemOperand(esp, 0)); 1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(MemOperand(esp, 0)); 1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ add(esp, Immediate(kDoubleSize)); 1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1611bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(input->IsFPStackSlot()); 1612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(i.InputOperand(0)); 1617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sub(esp, Immediate(kDoubleSize)); 1618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_s(MemOperand(esp, 0)); 1619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(MemOperand(esp, 0)); 1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ add(esp, Immediate(kDoubleSize)); 1621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float64ToUint32: { 1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ push_imm32(-2147483648); 1626bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!instr->InputAt(0)->IsFPRegister()) { 1627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(i.InputOperand(0)); 1628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fild_s(Operand(esp, 0)); 16303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ fld(1); 16313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ faddp(); 1632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ TruncateX87TOSToI(i.OutputRegister(0)); 1633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ add(esp, Immediate(kInt32Size)); 1634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ add(i.OutputRegister(), Immediate(0x80000000)); 16353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ fstp(0); 1636bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!instr->InputAt(0)->IsFPRegister()) { 1637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float64ExtractHighWord32: { 1642bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sub(esp, Immediate(kDoubleSize)); 1644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fst_d(MemOperand(esp, 0)); 1645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(i.OutputRegister(), MemOperand(esp, kDoubleSize / 2)); 1646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ add(esp, Immediate(kDoubleSize)); 1647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* input = instr->InputAt(0); 1649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch USE(input); 1650bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(input->IsFPStackSlot()); 1651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(i.OutputRegister(), i.InputOperand(0, kDoubleSize / 2)); 1652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float64ExtractLowWord32: { 1656bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sub(esp, Immediate(kDoubleSize)); 1658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fst_d(MemOperand(esp, 0)); 1659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(i.OutputRegister(), MemOperand(esp, 0)); 1660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ add(esp, Immediate(kDoubleSize)); 1661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* input = instr->InputAt(0); 1663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch USE(input); 1664bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(input->IsFPStackSlot()); 1665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(i.OutputRegister(), i.InputOperand(0)); 1666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float64InsertHighWord32: { 1670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sub(esp, Immediate(kDoubleSize)); 1671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_d(MemOperand(esp, 0)); 1672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(MemOperand(esp, kDoubleSize / 2), i.InputRegister(1)); 1673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(esp, 0)); 1674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ add(esp, Immediate(kDoubleSize)); 1675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float64InsertLowWord32: { 1678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sub(esp, Immediate(kDoubleSize)); 1679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_d(MemOperand(esp, 0)); 1680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(MemOperand(esp, 0), i.InputRegister(1)); 1681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(esp, 0)); 1682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ add(esp, Immediate(kDoubleSize)); 1683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float64Sqrt: { 1686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetFPUCW(0x027F); 1690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(esp, 0)); 1692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fsqrt(); 1693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, kDoubleSize)); 1694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetFPUCW(0x037F); 1695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float64Round: { 1698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RoundingMode mode = 1699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<RoundingMode>(MiscField::decode(instr->opcode())); 1700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Set the correct round mode in x87 control register 1701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetRC((mode << 10)); 1702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1703bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!instr->InputAt(0)->IsFPRegister()) { 1704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* input = instr->InputAt(0); 1705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch USE(input); 1706bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(input->IsFPStackSlot()); 1707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(i.InputOperand(0)); 1712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ frndint(); 1714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ X87SetRC(0x0000); 1715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Float64Cmp: { 1718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(esp, kDoubleSize)); 1719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(esp, 0)); 1720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ FCmp(); 1721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, 2 * kDoubleSize)); 1722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 172413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case kX87Float64SilenceNaN: { 172513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Label end, return_qnan; 172613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ fstp(0); 172713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ push(ebx); 172813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Load Half word of HoleNan(SNaN) into ebx 172913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ mov(ebx, MemOperand(esp, 2 * kInt32Size)); 173013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ cmp(ebx, Immediate(kHoleNanUpper32)); 173113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Check input is HoleNaN(SNaN)? 173213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ j(equal, &return_qnan, Label::kNear); 173313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // If input isn't HoleNaN(SNaN), just load it and return 173413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ fld_d(MemOperand(esp, 1 * kInt32Size)); 173513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ jmp(&end); 173613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ bind(&return_qnan); 173713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // If input is HoleNaN(SNaN), Return QNaN 173813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ push(Immediate(0xffffffff)); 173913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ push(Immediate(0xfff7ffff)); 174013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ fld_d(MemOperand(esp, 0)); 174113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ lea(esp, Operand(esp, kDoubleSize)); 174213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ bind(&end); 174313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ pop(ebx); 174413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Clear stack. 174513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ lea(esp, Operand(esp, 1 * kDoubleSize)); 174613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch break; 174713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 1748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Movsxbl: 1749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movsx_b(i.OutputRegister(), i.MemoryOperand()); 1750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Movzxbl: 1752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movzx_b(i.OutputRegister(), i.MemoryOperand()); 1753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Movb: { 1755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; 1756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand operand = i.MemoryOperand(&index); 1757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, index)) { 1758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov_b(operand, i.InputInt8(index)); 1759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov_b(operand, i.InputRegister(index)); 1761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Movsxwl: 1765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movsx_w(i.OutputRegister(), i.MemoryOperand()); 1766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Movzxwl: 1768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movzx_w(i.OutputRegister(), i.MemoryOperand()); 1769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Movw: { 1771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; 1772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand operand = i.MemoryOperand(&index); 1773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, index)) { 1774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov_w(operand, i.InputInt16(index)); 1775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov_w(operand, i.InputRegister(index)); 1777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Movl: 1781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->HasOutput()) { 1782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(i.OutputRegister(), i.MemoryOperand()); 1783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; 1785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand operand = i.MemoryOperand(&index); 1786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, index)) { 1787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(operand, i.InputImmediate(index)); 1788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(operand, i.InputRegister(index)); 1790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Movsd: { 1794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->HasOutput()) { 1795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X87Register output = i.OutputDoubleRegister(); 1796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch USE(output); 1797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(output.code() == 0); 1798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(i.MemoryOperand()); 1803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; 1805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand operand = i.MemoryOperand(&index); 1806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fst_d(operand); 1807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Movss: { 1811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->HasOutput()) { 1812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X87Register output = i.OutputDoubleRegister(); 1813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch USE(output); 1814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(output.code() == 0); 1815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(i.MemoryOperand()); 1820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t index = 0; 1822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand operand = i.MemoryOperand(&index); 1823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fst_s(operand); 1824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87BitcastFI: { 1828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(i.OutputRegister(), MemOperand(esp, 0)); 1829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, kFloatSize)); 1830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87BitcastIF: { 1833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 1834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 1835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 1837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (instr->InputAt(0)->IsRegister()) { 1838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, -kFloatSize)); 1839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(MemOperand(esp, 0), i.InputRegister(0)); 1840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(MemOperand(esp, 0)); 1841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, kFloatSize)); 1842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(i.InputOperand(0)); 1844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Lea: { 1848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddressingMode mode = AddressingModeField::decode(instr->opcode()); 1849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Shorten "leal" to "addl", "subl" or "shll" if the register allocation 1850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // and addressing mode just happens to work out. The "addl"/"subl" forms 1851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // in these cases are faster based on measurements. 1852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mode == kMode_MI) { 1853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Move(i.OutputRegister(), Immediate(i.InputInt32(0))); 1854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (i.InputRegister(0).is(i.OutputRegister())) { 1855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (mode == kMode_MRI) { 1856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t constant_summand = i.InputInt32(1); 1857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (constant_summand > 0) { 1858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ add(i.OutputRegister(), Immediate(constant_summand)); 1859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (constant_summand < 0) { 1860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sub(i.OutputRegister(), Immediate(-constant_summand)); 1861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (mode == kMode_MR1) { 1863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (i.InputRegister(1).is(i.OutputRegister())) { 1864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ shl(i.OutputRegister(), 1); 1865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1866c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ add(i.OutputRegister(), i.InputRegister(1)); 1867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (mode == kMode_M2) { 1869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ shl(i.OutputRegister(), 1); 1870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (mode == kMode_M4) { 1871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ shl(i.OutputRegister(), 2); 1872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (mode == kMode_M8) { 1873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ shl(i.OutputRegister(), 3); 1874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(i.OutputRegister(), i.MemoryOperand()); 1876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1877c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else if (mode == kMode_MR1 && 1878c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch i.InputRegister(1).is(i.OutputRegister())) { 1879c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ add(i.OutputRegister(), i.InputRegister(0)); 1880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(i.OutputRegister(), i.MemoryOperand()); 1882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Push: 1886bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPRegister()) { 1887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto allocated = AllocatedOperand::cast(*instr->InputAt(0)); 1888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (allocated.representation() == MachineRepresentation::kFloat32) { 188913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ sub(esp, Immediate(kFloatSize)); 1890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fst_s(Operand(esp, 0)); 189113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch frame_access_state()->IncreaseSPDelta(kFloatSize / kPointerSize); 1892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(allocated.representation() == MachineRepresentation::kFloat64); 1894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sub(esp, Immediate(kDoubleSize)); 1895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fst_d(Operand(esp, 0)); 1896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); 189713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 1898bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (instr->InputAt(0)->IsFPStackSlot()) { 1899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto allocated = AllocatedOperand::cast(*instr->InputAt(0)); 1900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (allocated.representation() == MachineRepresentation::kFloat32) { 190113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ sub(esp, Immediate(kFloatSize)); 1902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(i.InputOperand(0)); 1903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_s(MemOperand(esp, 0)); 190413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch frame_access_state()->IncreaseSPDelta(kFloatSize / kPointerSize); 1905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(allocated.representation() == MachineRepresentation::kFloat64); 1907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sub(esp, Immediate(kDoubleSize)); 1908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(i.InputOperand(0)); 1909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_d(MemOperand(esp, 0)); 1910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize); 191113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 1912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (HasImmediateInput(instr, 0)) { 1913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ push(i.InputImmediate(0)); 1914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->IncreaseSPDelta(1); 1915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ push(i.InputOperand(0)); 1917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->IncreaseSPDelta(1); 1918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87Poke: { 1921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int const slot = MiscField::decode(instr->opcode()); 1922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (HasImmediateInput(instr, 0)) { 1923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(Operand(esp, slot * kPointerSize), i.InputImmediate(0)); 1924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(Operand(esp, slot * kPointerSize), i.InputRegister(0)); 1926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1929bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kX87Xchgb: { 1930bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch size_t index = 0; 1931bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Operand operand = i.MemoryOperand(&index); 1932bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ xchg_b(i.InputRegister(index), operand); 1933bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 1934bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 1935bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kX87Xchgw: { 1936bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch size_t index = 0; 1937bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Operand operand = i.MemoryOperand(&index); 1938bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ xchg_w(i.InputRegister(index), operand); 1939bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 1940bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 1941bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kX87Xchgl: { 1942bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch size_t index = 0; 1943bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Operand operand = i.MemoryOperand(&index); 1944bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ xchg(i.InputRegister(index), operand); 1945bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 1946bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 1947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87PushFloat32: 1948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, -kFloatSize)); 1949bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPStackSlot()) { 1950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(i.InputOperand(0)); 1951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_s(MemOperand(esp, 0)); 1952bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (instr->InputAt(0)->IsFPRegister()) { 1953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fst_s(MemOperand(esp, 0)); 1954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 1956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87PushFloat64: 1959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lea(esp, Operand(esp, -kDoubleSize)); 1960bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(0)->IsFPStackSlot()) { 1961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(i.InputOperand(0)); 1962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_d(MemOperand(esp, 0)); 1963bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (instr->InputAt(0)->IsFPRegister()) { 1964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fst_d(MemOperand(esp, 0)); 1965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 1967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedLoadInt8: 1970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_LOAD_INTEGER(movsx_b); 1971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedLoadUint8: 1973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_LOAD_INTEGER(movzx_b); 1974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedLoadInt16: 1976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_LOAD_INTEGER(movsx_w); 1977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedLoadUint16: 1979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_LOAD_INTEGER(movzx_w); 1980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedLoadWord32: 1982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_LOAD_INTEGER(mov); 1983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedLoadFloat32: 1985f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_CHECKED_LOAD_FLOAT(fld_s, OutOfLineLoadFloat32NaN); 1986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedLoadFloat64: 1988f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSEMBLE_CHECKED_LOAD_FLOAT(fld_d, OutOfLineLoadFloat64NaN); 1989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedStoreWord8: 1991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_STORE_INTEGER(mov_b); 1992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedStoreWord16: 1994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_STORE_INTEGER(mov_w); 1995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedStoreWord32: 1997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_STORE_INTEGER(mov); 1998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 1999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedStoreFloat32: 2000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_STORE_FLOAT(fst_s); 2001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedStoreFloat64: 2003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ASSEMBLE_CHECKED_STORE_FLOAT(fst_d); 2004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kX87StackCheck: { 2006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExternalReference const stack_limit = 2007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExternalReference::address_of_stack_limit(isolate()); 2008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmp(esp, Operand::StaticVariable(stack_limit)); 2009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedLoadWord64: 2012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kCheckedStoreWord64: 2013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); // currently unsupported checked int64 load/store. 2014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2015bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicLoadInt8: 2016bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicLoadUint8: 2017bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicLoadInt16: 2018bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicLoadUint16: 2019bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicLoadWord32: 2020bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicStoreWord8: 2021bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicStoreWord16: 2022bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case kAtomicStoreWord32: 2023bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UNREACHABLE(); // Won't be generated by instruction selector. 2024bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch break; 2025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2026bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return kSuccess; 2027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // NOLINT(readability/fn_size) 2028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 202962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochstatic Condition FlagsConditionToCondition(FlagsCondition condition) { 203062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch switch (condition) { 2031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kUnorderedEqual: 2032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kEqual: 203362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return equal; 2034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kUnorderedNotEqual: 2036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kNotEqual: 203762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return not_equal; 2038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSignedLessThan: 204062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return less; 2041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSignedGreaterThanOrEqual: 204362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return greater_equal; 2044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSignedLessThanOrEqual: 204662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return less_equal; 2047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kSignedGreaterThan: 204962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return greater; 2050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kUnsignedLessThan: 205262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return below; 2053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kUnsignedGreaterThanOrEqual: 205562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return above_equal; 2056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kUnsignedLessThanOrEqual: 205862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return below_equal; 2059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kUnsignedGreaterThan: 206162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return above; 2062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kOverflow: 206462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return overflow; 2065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case kNotOverflow: 206762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return no_overflow; 2068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 2070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 207162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return no_condition; 2072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 207462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 207562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 207662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Assembles a branch after an instruction. 207762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { 207862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label::Distance flabel_distance = 207962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch branch->fallthru ? Label::kNear : Label::kFar; 208062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 208162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label done; 208262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label tlabel_tmp; 208362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label flabel_tmp; 208462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label* tlabel = &tlabel_tmp; 208562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label* flabel = &flabel_tmp; 208662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 208762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label* tlabel_dst = branch->true_label; 208862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label* flabel_dst = branch->false_label; 208962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 209062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (branch->condition == kUnorderedEqual) { 209162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ j(parity_even, flabel, flabel_distance); 209262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (branch->condition == kUnorderedNotEqual) { 209362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ j(parity_even, tlabel); 209462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 209562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ j(FlagsConditionToCondition(branch->condition), tlabel); 209662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 2097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Add a jump if not falling through to the next block. 2098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!branch->fallthru) __ jmp(flabel); 20993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 21003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ jmp(&done); 21013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ bind(&tlabel_tmp); 21023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsMode mode = FlagsModeField::decode(instr->opcode()); 21033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (mode == kFlags_deoptimize) { 21043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int double_register_param_count = 0; 21053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int x87_layout = 0; 21063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (size_t i = 0; i < instr->InputCount(); i++) { 2107bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (instr->InputAt(i)->IsFPRegister()) { 21083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch double_register_param_count++; 21093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 21103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 21113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Currently we use only one X87 register. If double_register_param_count 21123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // is bigger than 1, it means duplicated double register is added to input 21133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // of this instruction. 21143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (double_register_param_count > 0) { 21153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch x87_layout = (0 << 3) | 1; 21163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 21173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // The layout of x87 register stack is loaded on the top of FPU register 21183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // stack for deoptimization. 21193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ push(Immediate(x87_layout)); 21203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ fild_s(MemOperand(esp, 0)); 21213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ lea(esp, Operand(esp, kPointerSize)); 21223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 21233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ jmp(tlabel_dst); 21243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ bind(&flabel_tmp); 21253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ jmp(flabel_dst); 21263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ bind(&done); 2127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchJump(RpoNumber target) { 2131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target)); 2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 213462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid CodeGenerator::AssembleArchTrap(Instruction* instr, 213562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FlagsCondition condition) { 213662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch class OutOfLineTrap final : public OutOfLineCode { 213762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch public: 213862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch OutOfLineTrap(CodeGenerator* gen, bool frame_elided, Instruction* instr) 213962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : OutOfLineCode(gen), 214062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch frame_elided_(frame_elided), 214162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch instr_(instr), 214262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch gen_(gen) {} 214362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 214462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void Generate() final { 214562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch X87OperandConverter i(gen_, instr_); 214662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 214762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Runtime::FunctionId trap_id = static_cast<Runtime::FunctionId>( 214862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch i.InputInt32(instr_->InputCount() - 1)); 214962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool old_has_frame = __ has_frame(); 215062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (frame_elided_) { 215162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ set_has_frame(true); 215262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ EnterFrame(StackFrame::WASM_COMPILED); 215362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 215462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GenerateCallToTrap(trap_id); 215562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (frame_elided_) { 215662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ReferenceMap* reference_map = 215762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch new (gen_->zone()) ReferenceMap(gen_->zone()); 215862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch gen_->RecordSafepoint(reference_map, Safepoint::kSimple, 0, 215962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Safepoint::kNoLazyDeopt); 216062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ set_has_frame(old_has_frame); 216162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 216262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (FLAG_debug_code) { 216362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ ud2(); 216462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 216562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 216662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 216762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch private: 216862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void GenerateCallToTrap(Runtime::FunctionId trap_id) { 216962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (trap_id == Runtime::kNumFunctions) { 217062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // We cannot test calls to the runtime in cctest/test-run-wasm. 217162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Therefore we emit a call to C here instead of a call to the runtime. 217262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ PrepareCallCFunction(0, esi); 217362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ CallCFunction( 217462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ExternalReference::wasm_call_trap_callback_for_testing(isolate()), 217562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 0); 217662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 217762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ Move(esi, isolate()->native_context()); 217862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch gen_->AssembleSourcePosition(instr_); 217962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ CallRuntime(trap_id); 218062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 218162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 218262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 218362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool frame_elided_; 218462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Instruction* instr_; 218562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CodeGenerator* gen_; 218662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch }; 218762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool frame_elided = !frame_access_state()->has_frame(); 218862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto ool = new (zone()) OutOfLineTrap(this, frame_elided, instr); 218962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label* tlabel = ool->entry(); 219062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label end; 219162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (condition == kUnorderedEqual) { 219262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ j(parity_even, &end); 219362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (condition == kUnorderedNotEqual) { 219462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ j(parity_even, tlabel); 219562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 219662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ j(FlagsConditionToCondition(condition), tlabel); 219762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ bind(&end); 219862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 2199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Assembles boolean materializations after an instruction. 2201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchBoolean(Instruction* instr, 2202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FlagsCondition condition) { 2203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X87OperandConverter i(this, instr); 2204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label done; 2205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Materialize a full 32-bit 1 or 0 value. The result register is always the 2207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // last output of the instruction. 2208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label check; 2209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(0u, instr->OutputCount()); 2210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register reg = i.OutputRegister(instr->OutputCount() - 1); 221162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (condition == kUnorderedEqual) { 221262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ j(parity_odd, &check, Label::kNear); 221362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ Move(reg, Immediate(0)); 221462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ jmp(&done, Label::kNear); 221562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (condition == kUnorderedNotEqual) { 221662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ j(parity_odd, &check, Label::kNear); 221762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ mov(reg, Immediate(1)); 221862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ jmp(&done, Label::kNear); 2219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 222062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Condition cc = FlagsConditionToCondition(condition); 222162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 2222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(&check); 2223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (reg.is_byte_register()) { 2224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // setcc for byte registers (al, bl, cl, dl). 2225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ setcc(cc, reg); 2226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ movzx_b(reg, reg); 2227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Emit a branch to set a register to either 1 or 0. 2229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label set; 2230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ j(cc, &set, Label::kNear); 2231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Move(reg, Immediate(0)); 2232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ jmp(&done, Label::kNear); 2233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(&set); 2234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(reg, Immediate(1)); 2235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ bind(&done); 2237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) { 2241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X87OperandConverter i(this, instr); 2242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register input = i.InputRegister(0); 2243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (size_t index = 2; index < instr->InputCount(); index += 2) { 2244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmp(input, Immediate(i.InputInt32(index + 0))); 2245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ j(equal, GetLabel(i.InputRpo(index + 1))); 2246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssembleArchJump(i.InputRpo(1)); 2248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchTableSwitch(Instruction* instr) { 2252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X87OperandConverter i(this, instr); 2253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register input = i.InputRegister(0); 2254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t const case_count = instr->InputCount() - 2; 2255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label** cases = zone()->NewArray<Label*>(case_count); 2256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (size_t index = 0; index < case_count; ++index) { 2257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cases[index] = GetLabel(i.InputRpo(index + 2)); 2258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* const table = AddJumpTable(cases, case_count); 2260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmp(input, Immediate(case_count)); 2261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ j(above_equal, GetLabel(i.InputRpo(1))); 2262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ jmp(Operand::JumpTable(input, times_4, table)); 2263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2265bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall( 226662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int deoptimization_id, SourcePosition pos) { 226762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DeoptimizeKind deoptimization_kind = GetDeoptimizationKind(deoptimization_id); 226862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DeoptimizeReason deoptimization_reason = 226962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GetDeoptimizationReason(deoptimization_id); 227062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Deoptimizer::BailoutType bailout_type = 227162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch deoptimization_kind == DeoptimizeKind::kSoft ? Deoptimizer::SOFT 227262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : Deoptimizer::EAGER; 2273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( 2274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate(), deoptimization_id, bailout_type); 2275bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (deopt_entry == nullptr) return kTooManyDeoptimizationBailouts; 2276c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ RecordDeoptReason(deoptimization_reason, pos, deoptimization_id); 2277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ call(deopt_entry, RelocInfo::RUNTIME_ENTRY); 2278bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return kSuccess; 2279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// The calling convention for JSFunctions on X87 passes arguments on the 2283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// stack and the JSFunction and context in EDI and ESI, respectively, thus 2284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// the steps of the call look as follows: 2285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ before the call instruction }-------------------------------------------- 2287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | caller frame | 2288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ esp ^ ebp 2289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ push arguments and setup ESI, EDI }-------------------------------------- 2291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | args + receiver | caller frame | 2292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ esp ^ ebp 2293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// [edi = JSFunction, esi = context] 2294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ call [edi + kCodeEntryOffset] }------------------------------------------ 2296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | RET | args + receiver | caller frame | 2297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ esp ^ ebp 2298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// =={ prologue of called function }============================================ 2300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ push ebp }--------------------------------------------------------------- 2301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | FP | RET | args + receiver | caller frame | 2302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ esp ^ ebp 2303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ mov ebp, esp }----------------------------------------------------------- 2305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | FP | RET | args + receiver | caller frame | 2306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ ebp,esp 2307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ push esi }--------------------------------------------------------------- 2309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | CTX | FP | RET | args + receiver | caller frame | 2310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^esp ^ ebp 2311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ push edi }--------------------------------------------------------------- 2313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | FNC | CTX | FP | RET | args + receiver | caller frame | 2314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^esp ^ ebp 2315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ subi esp, #N }----------------------------------------------------------- 2317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | callee frame | FNC | CTX | FP | RET | args + receiver | caller frame | 2318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^esp ^ ebp 2319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// =={ body of called function }================================================ 2321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// =={ epilogue of called function }============================================ 2323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ mov esp, ebp }----------------------------------------------------------- 2324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | FP | RET | args + receiver | caller frame | 2325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ esp,ebp 2326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ pop ebp }----------------------------------------------------------- 2328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | | RET | args + receiver | caller frame | 2329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ esp ^ ebp 2330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ ret #A+1 }----------------------------------------------------------- 2332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | | caller frame | 2333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ esp ^ ebp 2334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Runtime function calls are accomplished by doing a stub call to the 2337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// CEntryStub (a real code object). On X87 passes arguments on the 2338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// stack, the number of arguments in EAX, the address of the runtime function 2339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// in EBX, and the context in ESI. 2340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ before the call instruction }-------------------------------------------- 2342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | caller frame | 2343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ esp ^ ebp 2344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ push arguments and setup EAX, EBX, and ESI }----------------------------- 2346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | args + receiver | caller frame | 2347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ esp ^ ebp 2348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// [eax = #args, ebx = runtime function, esi = context] 2349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ call #CEntryStub }------------------------------------------------------- 2351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | RET | args + receiver | caller frame | 2352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ esp ^ ebp 2353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// =={ body of runtime function }=============================================== 2355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ runtime returns }-------------------------------------------------------- 2357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | caller frame | 2358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ esp ^ ebp 2359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Other custom linkages (e.g. for calling directly into and out of C++) may 2361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// need to save callee-saved registers on the stack, which is done in the 2362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// function prologue of generated code. 2363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ before the call instruction }-------------------------------------------- 2365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | caller frame | 2366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ esp ^ ebp 2367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ set up arguments in registers on stack }--------------------------------- 2369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | args | caller frame | 2370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ esp ^ ebp 2371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// [r0 = arg0, r1 = arg1, ...] 2372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ call code }-------------------------------------------------------------- 2374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | RET | args | caller frame | 2375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ esp ^ ebp 2376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// =={ prologue of called function }============================================ 2378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ push ebp }--------------------------------------------------------------- 2379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | FP | RET | args | caller frame | 2380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ esp ^ ebp 2381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ mov ebp, esp }----------------------------------------------------------- 2383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | FP | RET | args | caller frame | 2384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ ebp,esp 2385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ save registers }--------------------------------------------------------- 2387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | regs | FP | RET | args | caller frame | 2388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ esp ^ ebp 2389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ subi esp, #N }----------------------------------------------------------- 2391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | callee frame | regs | FP | RET | args | caller frame | 2392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^esp ^ ebp 2393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// =={ body of called function }================================================ 2395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// =={ epilogue of called function }============================================ 2397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ restore registers }------------------------------------------------------ 2398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | regs | FP | RET | args | caller frame | 2399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ esp ^ ebp 2400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ mov esp, ebp }----------------------------------------------------------- 2402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | FP | RET | args | caller frame | 2403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ esp,ebp 2404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// --{ pop ebp }---------------------------------------------------------------- 2406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// | RET | args | caller frame | 2407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// ^ esp ^ ebp 2408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2409bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeGenerator::FinishFrame(Frame* frame) { 2410bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 2411bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch const RegList saves = descriptor->CalleeSavedRegisters(); 2412bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (saves != 0) { // Save callee-saved registers. 2413bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(!info()->is_osr()); 2414bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch int pushed = 0; 2415bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch for (int i = Register::kNumRegisters - 1; i >= 0; i--) { 2416bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!((1 << i) & saves)) continue; 2417bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ++pushed; 2418bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2419bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch frame->AllocateSavedCalleeRegisterSlots(pushed); 2420bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 2421bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 2422bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Initailize FPU state. 2423bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ fninit(); 2424bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ fld1(); 2425bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 2426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2427bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeGenerator::AssembleConstructFrame() { 2428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 24293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (frame_access_state()->has_frame()) { 24303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (descriptor->IsCFunctionCall()) { 24313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ push(ebp); 24323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ mov(ebp, esp); 24333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else if (descriptor->IsJSFunctionCall()) { 24343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Prologue(this->info()->GeneratePreagedPrologue()); 2435c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (descriptor->PushArgumentCount()) { 2436c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ push(kJavaScriptCallArgCountRegister); 2437c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 24383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 24393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ StubPrologue(info()->GetOutputStackFrameType()); 24403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 2441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2442bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 2443c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int shrink_slots = 2444c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch frame()->GetTotalFrameSlotCount() - descriptor->CalculateFixedFrameSize(); 2445bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 2446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (info()->is_osr()) { 2447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TurboFan OSR-compiled functions cannot be entered directly. 2448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Abort(kShouldNotDirectlyEnterOsrFunction); 2449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Unoptimized code jumps directly to this entrypoint while the unoptimized 2451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // frame is still on the stack. Optimized code uses OSR values directly from 2452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the unoptimized frame. Thus, all that needs to be done is to allocate the 2453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // remaining stack slots. 2454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --"); 2455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch osr_pc_offset_ = __ pc_offset(); 2456bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots(); 24573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 24583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Initailize FPU state. 24593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ fninit(); 24603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ fld1(); 2461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const RegList saves = descriptor->CalleeSavedRegisters(); 2464bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (shrink_slots > 0) { 2465bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ sub(esp, Immediate(shrink_slots * kPointerSize)); 2466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (saves != 0) { // Save callee-saved registers. 2469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!info()->is_osr()); 2470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int pushed = 0; 2471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = Register::kNumRegisters - 1; i >= 0; i--) { 2472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!((1 << i) & saves)) continue; 2473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ push(Register::from_code(i)); 2474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ++pushed; 2475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2479c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid CodeGenerator::AssembleReturn(InstructionOperand* pop) { 2480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 2481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Clear the FPU stack only if there is no return value in the stack. 2483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_debug_code && FLAG_enable_slow_asserts) { 2484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ VerifyX87StackDepth(1); 2485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool clear_stack = true; 2487c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch for (size_t i = 0; i < descriptor->ReturnCount(); i++) { 2488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineRepresentation rep = descriptor->GetReturnType(i).representation(); 2489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LinkageLocation loc = descriptor->GetReturnLocation(i); 2490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsFloatingPoint(rep) && loc == LinkageLocation::ForRegister(0)) { 2491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch clear_stack = false; 2492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (clear_stack) __ fstp(0); 2496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const RegList saves = descriptor->CalleeSavedRegisters(); 2498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Restore registers. 2499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (saves != 0) { 2500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < Register::kNumRegisters; i++) { 2501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!((1 << i) & saves)) continue; 2502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ pop(Register::from_code(i)); 2503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2506c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Might need ecx for scratch if pop_size is too big or if there is a variable 2507c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // pop count. 2508c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & ecx.bit()); 2509c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch size_t pop_size = descriptor->StackParameterCount() * kPointerSize; 2510c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch X87OperandConverter g(this, nullptr); 2511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (descriptor->IsCFunctionCall()) { 25123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AssembleDeconstructFrame(); 25133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else if (frame_access_state()->has_frame()) { 2514c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Canonicalize JSFunction return sites for now if they always have the same 2515c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // number of return args. 2516c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (pop->IsImmediate() && g.ToConstant(pop).ToInt32() == 0) { 2517c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (return_label_.is_bound()) { 2518c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ jmp(&return_label_); 2519c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return; 2520c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 2521c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ bind(&return_label_); 2522c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch AssembleDeconstructFrame(); 2523c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 2524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 25253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AssembleDeconstructFrame(); 2526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2528c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & edx.bit()); 2529c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & ecx.bit()); 2530c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (pop->IsImmediate()) { 2531c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(Constant::kInt32, g.ToConstant(pop).type()); 2532c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch pop_size += g.ToConstant(pop).ToInt32() * kPointerSize; 2533c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ Ret(static_cast<int>(pop_size), ecx); 2534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2535c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Register pop_reg = g.ToRegister(pop); 2536c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Register scratch_reg = pop_reg.is(ecx) ? edx : ecx; 2537c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ pop(scratch_reg); 2538c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ lea(esp, Operand(esp, pop_reg, times_4, static_cast<int>(pop_size))); 2539c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ jmp(scratch_reg); 2540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleMove(InstructionOperand* source, 2545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* destination) { 2546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X87OperandConverter g(this, nullptr); 2547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Dispatch on the source and destination operand kinds. Not all 2548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // combinations are possible. 2549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (source->IsRegister()) { 2550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(destination->IsRegister() || destination->IsStackSlot()); 2551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register src = g.ToRegister(source); 2552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand dst = g.ToOperand(destination); 2553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(dst, src); 2554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (source->IsStackSlot()) { 2555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(destination->IsRegister() || destination->IsStackSlot()); 2556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand src = g.ToOperand(source); 2557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (destination->IsRegister()) { 2558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register dst = g.ToRegister(destination); 2559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(dst, src); 2560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand dst = g.ToOperand(destination); 2562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ push(src); 2563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ pop(dst); 2564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (source->IsConstant()) { 2566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Constant src_constant = g.ToConstant(source); 2567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (src_constant.type() == Constant::kHeapObject) { 2568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<HeapObject> src = src_constant.ToHeapObject(); 2569f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (destination->IsRegister()) { 2570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register dst = g.ToRegister(destination); 2571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadHeapObject(dst, src); 2572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(destination->IsStackSlot()); 2574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand dst = g.ToOperand(destination); 2575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference embedding_raw_address; 2576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (isolate()->heap()->InNewSpace(*src)) { 2577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ PushHeapObject(src); 2578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ pop(dst); 2579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(dst, src); 2581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (destination->IsRegister()) { 2584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register dst = g.ToRegister(destination); 2585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Move(dst, g.ToImmediate(source)); 2586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (destination->IsStackSlot()) { 2587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand dst = g.ToOperand(destination); 2588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Move(dst, g.ToImmediate(source)); 2589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (src_constant.type() == Constant::kFloat32) { 2590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(turbofan): Can we do better here? 259162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch uint32_t src = src_constant.ToFloat32AsInt(); 2592bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (destination->IsFPRegister()) { 2593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sub(esp, Immediate(kInt32Size)); 2594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(MemOperand(esp, 0), Immediate(src)); 2595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // always only push one value into the x87 stack. 2596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 2597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(MemOperand(esp, 0)); 2598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ add(esp, Immediate(kInt32Size)); 2599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2600bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(destination->IsFPStackSlot()); 2601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand dst = g.ToOperand(destination); 2602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Move(dst, Immediate(src)); 2603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(Constant::kFloat64, src_constant.type()); 260662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch uint64_t src = src_constant.ToFloat64AsInt(); 2607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t lower = static_cast<uint32_t>(src); 2608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t upper = static_cast<uint32_t>(src >> 32); 2609bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (destination->IsFPRegister()) { 2610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ sub(esp, Immediate(kDoubleSize)); 2611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(MemOperand(esp, 0), Immediate(lower)); 2612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(MemOperand(esp, kInt32Size), Immediate(upper)); 2613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // always only push one value into the x87 stack. 2614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 2615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(MemOperand(esp, 0)); 2616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ add(esp, Immediate(kDoubleSize)); 2617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2618bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(destination->IsFPStackSlot()); 2619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand dst0 = g.ToOperand(destination); 2620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand dst1 = g.HighOperand(destination); 2621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Move(dst0, Immediate(lower)); 2622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Move(dst1, Immediate(upper)); 2623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2625bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (source->IsFPRegister()) { 2626bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(destination->IsFPStackSlot()); 2627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand dst = g.ToOperand(destination); 2628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto allocated = AllocatedOperand::cast(*source); 2629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (allocated.representation()) { 2630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat32: 2631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fst_s(dst); 2632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat64: 2634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fst_d(dst); 2635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 2637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 2638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2639bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (source->IsFPStackSlot()) { 2640bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(destination->IsFPRegister() || destination->IsFPStackSlot()); 2641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand src = g.ToOperand(source); 2642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto allocated = AllocatedOperand::cast(*source); 2643bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (destination->IsFPRegister()) { 2644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // always only push one value into the x87 stack. 2645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp(0); 2646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (allocated.representation()) { 2647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat32: 2648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(src); 2649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat64: 2651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(src); 2652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 2654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 2655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand dst = g.ToOperand(destination); 2658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (allocated.representation()) { 2659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat32: 2660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(src); 2661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_s(dst); 2662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat64: 2664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(src); 2665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_d(dst); 2666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 2668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 2669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 2673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleSwap(InstructionOperand* source, 2678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand* destination) { 2679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch X87OperandConverter g(this, nullptr); 2680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Dispatch on the source and destination operand kinds. Not all 2681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // combinations are possible. 2682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (source->IsRegister() && destination->IsRegister()) { 2683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Register-register. 2684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register src = g.ToRegister(source); 2685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register dst = g.ToRegister(destination); 2686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ xchg(dst, src); 2687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (source->IsRegister() && destination->IsStackSlot()) { 2688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Register-memory. 2689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ xchg(g.ToRegister(source), g.ToOperand(destination)); 2690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (source->IsStackSlot() && destination->IsStackSlot()) { 2691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Memory-memory. 2692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand dst1 = g.ToOperand(destination); 2693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ push(dst1); 2694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->IncreaseSPDelta(1); 2695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand src1 = g.ToOperand(source); 2696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ push(src1); 2697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand dst2 = g.ToOperand(destination); 2698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ pop(dst2); 2699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_access_state()->IncreaseSPDelta(-1); 2700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand src2 = g.ToOperand(source); 2701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ pop(src2); 2702bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (source->IsFPRegister() && destination->IsFPRegister()) { 2703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 2704bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (source->IsFPRegister() && destination->IsFPStackSlot()) { 2705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto allocated = AllocatedOperand::cast(*source); 2706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (allocated.representation()) { 2707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat32: 2708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(g.ToOperand(destination)); 2709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fxch(); 2710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_s(g.ToOperand(destination)); 2711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat64: 2713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(g.ToOperand(destination)); 2714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fxch(); 2715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_d(g.ToOperand(destination)); 2716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 2718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 2719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2720bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (source->IsFPStackSlot() && destination->IsFPStackSlot()) { 2721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto allocated = AllocatedOperand::cast(*source); 2722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch switch (allocated.representation()) { 2723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat32: 2724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(g.ToOperand(source)); 2725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_s(g.ToOperand(destination)); 2726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_s(g.ToOperand(source)); 2727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_s(g.ToOperand(destination)); 2728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case MachineRepresentation::kFloat64: 2730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(g.ToOperand(source)); 2731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fld_d(g.ToOperand(destination)); 2732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_d(g.ToOperand(source)); 2733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ fstp_d(g.ToOperand(destination)); 2734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 2735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch default: 2736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 2737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // No other combinations are possible. 2740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 2741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) { 2746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (size_t index = 0; index < target_count; ++index) { 2747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ dd(targets[index]); 2748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::EnsureSpaceForLazyDeopt() { 2753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!info()->ShouldEnsureSpaceForLazyDeopt()) { 2754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 2755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int space_needed = Deoptimizer::patch_size(); 2758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Ensure that we have enough space after the previous lazy-bailout 2759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // instruction for patching the code here. 2760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int current_pc = masm()->pc_offset(); 2761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (current_pc < last_lazy_deopt_pc_ + space_needed) { 2762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; 2763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Nop(padding_size); 2764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef __ 2768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace compiler 2770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 2771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 2772