1864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 2864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 3864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// found in the LICENSE file. 4864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 6864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#if V8_TARGET_ARCH_X87 8864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 99aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org#include "src/base/bits.h" 10b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org#include "src/code-factory.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/code-stubs.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h" 134b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/deoptimizer.h" 14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-osr.h" 15a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org#include "src/ic/ic.h" 16b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org#include "src/ic/stub-cache.h" 174b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/x87/lithium-codegen-x87.h" 18864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 19864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace v8 { 20864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace internal { 21864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 22864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 23864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// When invoking builtins, we need to record the safepoint in the middle of 24864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// the invoke instruction sequence generated by the macro assembler. 25ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass SafepointGenerator FINAL : public CallWrapper { 26864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 27864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SafepointGenerator(LCodeGen* codegen, 28864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LPointerMap* pointers, 29864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Safepoint::DeoptMode mode) 30864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : codegen_(codegen), 31864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org pointers_(pointers), 32864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org deopt_mode_(mode) {} 33864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org virtual ~SafepointGenerator() {} 34864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 35ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void BeforeCall(int call_size) const OVERRIDE {} 36864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 37ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void AfterCall() const OVERRIDE { 38864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen_->RecordSafepoint(pointers_, deopt_mode_); 39864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 40864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 41864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 42864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LCodeGen* codegen_; 43864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LPointerMap* pointers_; 44864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Safepoint::DeoptMode deopt_mode_; 45864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 46864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 47864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 48864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define __ masm()-> 49864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 50864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgbool LCodeGen::GenerateCode() { 51864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LPhase phase("Z_Code generation", chunk()); 52e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_unused()); 53864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org status_ = GENERATING; 54864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 55864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Open a frame scope to indicate that there is a frame on the stack. The 56864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // MANUAL indicates that the scope shouldn't actually generate code to set up 57864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the frame (that is done in GeneratePrologue). 58864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FrameScope frame_scope(masm_, StackFrame::MANUAL); 59864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 60864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org support_aligned_spilled_doubles_ = info()->IsOptimizing(); 61864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 62864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org dynamic_frame_alignment_ = info()->IsOptimizing() && 63864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ((chunk()->num_double_slots() > 2 && 64864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org !chunk()->graph()->is_recursive()) || 65864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org !info()->osr_ast_id().IsNone()); 66864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 67864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return GeneratePrologue() && 68864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org GenerateBody() && 69864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org GenerateDeferredCode() && 70864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org GenerateJumpTable() && 71864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org GenerateSafepointTable(); 72864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 73864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 74864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 75864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::FinishCode(Handle<Code> code) { 76e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_done()); 77864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org code->set_stack_slots(GetStackSlotCount()); 78864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); 79864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code); 80864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PopulateDeoptimizationData(code); 81864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!info()->IsStub()) { 82864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code); 83864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 84864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 85864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 86864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 87864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef _MSC_VER 88864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::MakeSureStackPagesMapped(int offset) { 89864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const int kPageSize = 4 * KB; 90864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (offset -= kPageSize; offset > 0; offset -= kPageSize) { 91864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esp, offset), eax); 92864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 93864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 94864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif 95864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 96864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 97864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgbool LCodeGen::GeneratePrologue() { 98e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_generating()); 99864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (info()->IsOptimizing()) { 101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ProfileEntryHookStub::MaybeCallEntryHook(masm_); 102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef DEBUG 104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (strlen(FLAG_stop_at) > 0 && 105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ int3(); 107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif 109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Sloppy mode functions and builtins need to replace the receiver with the 111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // global proxy when called as functions (without an explicit receiver 112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // object). 113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (info_->this_has_uses() && 114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org info_->strict_mode() == SLOPPY && 115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org !info_->is_native()) { 116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label ok; 117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // +1 for return address. 118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int receiver_offset = (scope()->num_parameters() + 1) * kPointerSize; 119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, Operand(esp, receiver_offset)); 120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ecx, isolate()->factory()->undefined_value()); 122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &ok, Label::kNear); 123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, GlobalObjectOperand()); 125d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalProxyOffset)); 126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esp, receiver_offset), ecx); 128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&ok); 130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (support_aligned_spilled_doubles_ && dynamic_frame_alignment_) { 133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Move state of dynamic frame alignment into edx. 134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(edx, Immediate(kNoAlignmentPadding)); 135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label do_not_pad, align_loop; 137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(kDoubleSize == 2 * kPointerSize); 138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Align esp + 4 to a multiple of 2 * kPointerSize. 139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(esp, Immediate(kPointerSize)); 140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, &do_not_pad, Label::kNear); 141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(0)); 142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, esp); 143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, Immediate(kAlignmentPaddingPushed)); 144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Copy arguments, receiver, and return address. 145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, Immediate(scope()->num_parameters() + 2)); 146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&align_loop); 148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, Operand(ebx, 1 * kPointerSize)); 149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(ebx, 0), eax); 150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(Operand(ebx), Immediate(kPointerSize)); 151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ dec(ecx); 152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, &align_loop, Label::kNear); 153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(ebx, 0), Immediate(kAlignmentZapValue)); 154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&do_not_pad); 155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org info()->set_prologue_offset(masm_->pc_offset()); 159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (NeedsEagerFrame()) { 160e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!frame_is_built_); 161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org frame_is_built_ = true; 162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (info()->IsStub()) { 163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ StubPrologue(); 164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Prologue(info()->IsCodePreAgingActive()); 166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org info()->AddNoFrameRange(0, masm_->pc_offset()); 168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (info()->IsOptimizing() && 171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org dynamic_frame_alignment_ && 172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FLAG_debug_code) { 173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(esp, Immediate(kPointerSize)); 174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Assert(zero, kFrameIsExpectedToBeAligned); 175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Reserve space for the stack slots needed by the code. 178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int slots = GetStackSlotCount(); 179e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(slots != 0 || !info()->IsOptimizing()); 180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (slots > 0) { 181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (slots == 1) { 182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (dynamic_frame_alignment_) { 183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(edx); 184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(kNoAlignmentPadding)); 186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_debug_code) { 189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(Operand(esp), Immediate(slots * kPointerSize)); 190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef _MSC_VER 191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org MakeSureStackPagesMapped(slots * kPointerSize); 192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif 193864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); 194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(eax), Immediate(slots)); 195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label loop; 196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&loop); 197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(MemOperand(esp, eax, times_4, 0), 198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(kSlotsZapValue)); 199864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ dec(eax); 200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, &loop); 201864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(eax); 202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(Operand(esp), Immediate(slots * kPointerSize)); 204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef _MSC_VER 205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org MakeSureStackPagesMapped(slots * kPointerSize); 206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif 207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (support_aligned_spilled_doubles_) { 210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment(";;; Store dynamic frame alignment tag for spilled doubles"); 211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Store dynamic frame alignment state in the first local. 212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int offset = JavaScriptFrameConstants::kDynamicAlignmentStateOffset; 213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (dynamic_frame_alignment_) { 214864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(ebp, offset), edx); 215864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(ebp, offset), Immediate(kNoAlignmentPadding)); 217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Possibly allocate a local context. 223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 224864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (heap_slots > 0) { 225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment(";;; Allocate local context"); 226d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org bool need_write_barrier = true; 227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Argument to NewContext is the function, which is still in edi. 228864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (heap_slots <= FastNewContextStub::kMaximumSlots) { 229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FastNewContextStub stub(isolate(), heap_slots); 230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&stub); 231d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org // Result of FastNewContextStub is always in new space. 232d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org need_write_barrier = false; 233864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(edi); 23547390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kNewFunctionContext, 1); 236864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordSafepoint(Safepoint::kNoLazyDeopt); 238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Context is returned in eax. It replaces the context passed to us. 239864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // It's saved in the stack and kept live in esi. 240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esi, eax); 241864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), eax); 242864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 243864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Copy parameters into context if necessary. 244864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int num_parameters = scope()->num_parameters(); 245864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < num_parameters; i++) { 246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Variable* var = scope()->parameter(i); 247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (var->IsContextSlot()) { 248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int parameter_offset = StandardFrameConstants::kCallerSPOffset + 249864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (num_parameters - 1 - i) * kPointerSize; 250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load parameter from stack. 251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, Operand(ebp, parameter_offset)); 252864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Store it in the context. 253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int context_offset = Context::SlotOffset(var->index()); 254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esi, context_offset), eax); 255864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Update the write barrier. This clobbers eax and ebx. 256d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org if (need_write_barrier) { 25706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ RecordWriteContextSlot(esi, context_offset, eax, ebx, 25806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org kDontSaveFPRegs); 259d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org } else if (FLAG_debug_code) { 260d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org Label done; 261d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org __ JumpIfInNewSpace(esi, eax, &done, Label::kNear); 262d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org __ Abort(kExpectedNewSpaceObject); 263d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org __ bind(&done); 264d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org } 265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment(";;; End allocate local context"); 268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 27006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Initailize FPU state. 27106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fninit(); 272864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Trace the call. 273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_trace && info()->IsOptimizing()) { 274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We have not executed any compiled code yet, so esi still holds the 275864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // incoming context. 276864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallRuntime(Runtime::kTraceEnter, 0); 277864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 278864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return !is_aborted(); 279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::GenerateOsrPrologue() { 283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Generate the OSR entry prologue at the first unknown OSR value, or if there 284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // are none, at the OSR entrypoint instruction. 285864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (osr_pc_offset_ >= 0) return; 286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 287864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org osr_pc_offset_ = masm()->pc_offset(); 288864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Move state of dynamic frame alignment into edx. 290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(edx, Immediate(kNoAlignmentPadding)); 291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (support_aligned_spilled_doubles_ && dynamic_frame_alignment_) { 293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label do_not_pad, align_loop; 294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Align ebp + 4 to a multiple of 2 * kPointerSize. 295864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(ebp, Immediate(kPointerSize)); 296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(zero, &do_not_pad, Label::kNear); 297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(0)); 298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, esp); 299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, Immediate(kAlignmentPaddingPushed)); 300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Move all parts of the frame over one word. The frame consists of: 302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // unoptimized frame slots, alignment state, context, frame pointer, return 303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // address, receiver, and the arguments. 304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, Immediate(scope()->num_parameters() + 305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5 + graph()->osr()->UnoptimizedFrameSlots())); 306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&align_loop); 308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, Operand(ebx, 1 * kPointerSize)); 309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(ebx, 0), eax); 310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(Operand(ebx), Immediate(kPointerSize)); 311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ dec(ecx); 312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, &align_loop, Label::kNear); 313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(ebx, 0), Immediate(kAlignmentZapValue)); 314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(Operand(ebp), Immediate(kPointerSize)); 315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&do_not_pad); 316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Save the first local, which is overwritten by the alignment state. 319864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand alignment_loc = MemOperand(ebp, -3 * kPointerSize); 320864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(alignment_loc); 321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Set the dynamic frame alignment state. 323864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(alignment_loc, edx); 324864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 325864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Adjust the frame size, subsuming the unoptimized frame into the 326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // optimized frame. 327864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots(); 328e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(slots >= 1); 329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(esp, Immediate((slots - 1) * kPointerSize)); 33006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 33106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Initailize FPU state. 33206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fninit(); 333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) { 337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->IsCall()) { 338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); 339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!instr->IsLazyBailout() && !instr->IsGap()) { 341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org safepoints_.BumpLastLazySafepointIndex(); 342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 343864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FlushX87StackIfNecessary(instr); 344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 345864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) { 34806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // When return from function call, FPU should be initialized again. 34906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (instr->IsCall() && instr->ClobbersDoubleRegisters(isolate())) { 35006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org bool double_result = instr->HasDoubleRegisterResult(); 35106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (double_result) { 35206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ lea(esp, Operand(esp, -kDoubleSize)); 35306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fstp_d(Operand(esp, 0)); 35406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 35506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fninit(); 35606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (double_result) { 35706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld_d(Operand(esp, 0)); 35806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ lea(esp, Operand(esp, kDoubleSize)); 35906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 36006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->IsGoto()) { 36206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org x87_stack_.LeavingBlock(current_block_, LGoto::cast(instr), this); 363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (FLAG_debug_code && FLAG_enable_slow_asserts && 364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org !instr->IsGap() && !instr->IsReturn()) { 365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->ClobbersDoubleRegisters(isolate())) { 366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->HasDoubleRegisterResult()) { 367e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(1, x87_stack_.depth()); 368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 369e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0, x87_stack_.depth()); 370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ VerifyX87StackDepth(x87_stack_.depth()); 373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgbool LCodeGen::GenerateJumpTable() { 378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label needs_frame; 379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (jump_table_.length() > 0) { 380864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment(";;; -------------------- Jump table --------------------"); 381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < jump_table_.length(); i++) { 383a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Deoptimizer::JumpTableEntry* table_entry = &jump_table_[i]; 384a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ bind(&table_entry->label); 385a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Address entry = table_entry->address; 38606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptComment(table_entry->reason); 387a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org if (table_entry->needs_frame) { 388e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!info()->saves_caller_doubles()); 389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(ExternalReference::ForDeoptEntry(entry))); 390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (needs_frame.is_bound()) { 391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&needs_frame); 392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&needs_frame); 394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(MemOperand(ebp, StandardFrameConstants::kContextOffset)); 395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // This variant of deopt can only be used with stubs. Since we don't 396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // have a function pointer to install in the stack frame that we're 397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // building, install a special marker there instead. 398e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(info()->IsStub()); 399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(StackFrame::STUB))); 400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push a PC inside the function so that the deopt code can find where 401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the deopt comes from. It doesn't have to be the precise return 402864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // address of a "calling" LAZY deopt, it only has to be somewhere 403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // inside the code body. 404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label push_approx_pc; 405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ call(&push_approx_pc); 406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&push_approx_pc); 407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push the continuation which was stashed were the ebp should 408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // be. Replace it with the saved ebp. 409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(MemOperand(esp, 3 * kPointerSize)); 410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(MemOperand(esp, 4 * kPointerSize), ebp); 411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(ebp, MemOperand(esp, 4 * kPointerSize)); 412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ret(0); // Call the continuation without clobbering registers. 413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 415864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ call(entry, RelocInfo::RUNTIME_ENTRY); 416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return !is_aborted(); 419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgbool LCodeGen::GenerateDeferredCode() { 423e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_generating()); 424864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (deferred_.length() > 0) { 425864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { 426864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LDeferredCode* code = deferred_[i]; 427864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Stack copy(code->x87_stack()); 428864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org x87_stack_ = copy; 429864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 430864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HValue* value = 431864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instructions_->at(code->instruction_index())->hydrogen_value(); 432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordAndWritePosition( 433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org chunk()->graph()->SourcePositionToScriptPosition(value->position())); 434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment(";;; <@%d,#%d> " 436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org "-------------------- Deferred %s --------------------", 437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org code->instruction_index(), 438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org code->instr()->hydrogen_value()->id(), 439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org code->instr()->Mnemonic()); 440864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(code->entry()); 441864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (NeedsDeferredFrame()) { 442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment(";;; Build frame"); 443e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!frame_is_built_); 444e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(info()->IsStub()); 445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org frame_is_built_ = true; 446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Build the frame in such a way that esi isn't trashed. 447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(ebp); // Caller's frame pointer. 448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Operand(ebp, StandardFrameConstants::kContextOffset)); 449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(StackFrame::STUB))); 450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(ebp, Operand(esp, 2 * kPointerSize)); 451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment(";;; Deferred code"); 452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org code->Generate(); 454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (NeedsDeferredFrame()) { 455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(code->done()); 456864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment(";;; Destroy frame"); 457e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(frame_is_built_); 458864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org frame_is_built_ = false; 459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esp, ebp); 460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(ebp); 461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(code->exit()); 463864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Deferred code is the last part of the instruction sequence. Mark 467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the generated code as done unless we bailed out. 468864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!is_aborted()) status_ = DONE; 469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return !is_aborted(); 470864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 472864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgbool LCodeGen::GenerateSafepointTable() { 474e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_done()); 475864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!info()->IsStub()) { 476864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // For lazy deoptimization we need space to patch a call after every call. 477864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Ensure there is always space for such patching, even if the code ends 478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // in a call. 479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int target_offset = masm()->pc_offset() + Deoptimizer::patch_size(); 480864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org while (masm()->pc_offset() < target_offset) { 481864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org masm()->nop(); 482864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 483864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org safepoints_.Emit(masm(), GetStackSlotCount()); 485864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return !is_aborted(); 486864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 487864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 488864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 489864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgRegister LCodeGen::ToRegister(int index) const { 490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return Register::FromAllocationIndex(index); 491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 493864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 494864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgX87Register LCodeGen::ToX87Register(int index) const { 495864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return X87Register::FromAllocationIndex(index); 496864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 497864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 498864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 499864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::X87LoadForUsage(X87Register reg) { 500e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(x87_stack_.Contains(reg)); 501864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org x87_stack_.Fxch(reg); 502864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org x87_stack_.pop(); 503864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 504864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 505864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 506864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::X87LoadForUsage(X87Register reg1, X87Register reg2) { 507e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(x87_stack_.Contains(reg1)); 508e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(x87_stack_.Contains(reg2)); 50906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (reg1.is(reg2) && x87_stack_.depth() == 1) { 51006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld(x87_stack_.st(reg1)); 51106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org x87_stack_.push(reg1); 51206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org x87_stack_.pop(); 51306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org x87_stack_.pop(); 51406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } else { 51506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org x87_stack_.Fxch(reg1, 1); 51606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org x87_stack_.Fxch(reg2); 51706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org x87_stack_.pop(); 51806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org x87_stack_.pop(); 51906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 52006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org} 52106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 52206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 52306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.orgint LCodeGen::X87Stack::GetLayout() { 52406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org int layout = stack_depth_; 52506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org for (int i = 0; i < stack_depth_; i++) { 52606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org layout |= (stack_[stack_depth_ - 1 - i].code() << ((i + 1) * 3)); 52706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 52806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 52906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org return layout; 530864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 531864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 532864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 533864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::X87Stack::Fxch(X87Register reg, int other_slot) { 534e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_mutable_); 535e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(Contains(reg) && stack_depth_ > other_slot); 536864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int i = ArrayIndex(reg); 537864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int st = st2idx(i); 538864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (st != other_slot) { 539864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int other_i = st2idx(other_slot); 540864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register other = stack_[other_i]; 541864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org stack_[other_i] = reg; 542864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org stack_[i] = other; 543864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (st == 0) { 544864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fxch(other_slot); 545864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (other_slot == 0) { 546864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fxch(st); 547864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 548864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fxch(st); 549864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fxch(other_slot); 550864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fxch(st); 551864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 552864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 553864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 554864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 555864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 556864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint LCodeGen::X87Stack::st2idx(int pos) { 557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return stack_depth_ - pos - 1; 558864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 559864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 560864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 561864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint LCodeGen::X87Stack::ArrayIndex(X87Register reg) { 562864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < stack_depth_; i++) { 563864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (stack_[i].is(reg)) return i; 564864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 565864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return -1; 567864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 569864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 570864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgbool LCodeGen::X87Stack::Contains(X87Register reg) { 571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < stack_depth_; i++) { 572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (stack_[i].is(reg)) return true; 573864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 574864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return false; 575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 578864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::X87Stack::Free(X87Register reg) { 579e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_mutable_); 580e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(Contains(reg)); 581864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int i = ArrayIndex(reg); 582864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int st = st2idx(i); 583864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (st > 0) { 584864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // keep track of how fstp(i) changes the order of elements 585864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int tos_i = st2idx(0); 586864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org stack_[i] = stack_[tos_i]; 587864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 588864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org pop(); 589864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fstp(st); 590864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 591864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 592864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 593864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::X87Mov(X87Register dst, Operand src, X87OperandType opts) { 594864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (x87_stack_.Contains(dst)) { 595864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org x87_stack_.Fxch(dst); 596864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fstp(0); 597864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 598864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org x87_stack_.push(dst); 599864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 600864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Fld(src, opts); 601864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 602864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 603864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 60406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.orgvoid LCodeGen::X87Mov(X87Register dst, X87Register src, X87OperandType opts) { 60506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (x87_stack_.Contains(dst)) { 60606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org x87_stack_.Fxch(dst); 60706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fstp(0); 60806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org x87_stack_.pop(); 60906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Push ST(i) onto the FPU register stack 61006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld(x87_stack_.st(src)); 61106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org x87_stack_.push(dst); 61206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } else { 61306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Push ST(i) onto the FPU register stack 61406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld(x87_stack_.st(src)); 61506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org x87_stack_.push(dst); 61606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 61706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org} 61806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 61906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 620864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::X87Fld(Operand src, X87OperandType opts) { 621e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!src.is_reg_only()); 622864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (opts) { 623864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case kX87DoubleOperand: 624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fld_d(src); 625864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 626864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case kX87FloatOperand: 627864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fld_s(src); 628864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 629864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case kX87IntOperand: 630864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fild_s(src); 631864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 632864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 633864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 634864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 635864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 636864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 637864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 638864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::X87Mov(Operand dst, X87Register src, X87OperandType opts) { 639e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!dst.is_reg_only()); 640864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org x87_stack_.Fxch(src); 641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (opts) { 642864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case kX87DoubleOperand: 643864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fst_d(dst); 644864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 64506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org case kX87FloatOperand: 64606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fst_s(dst); 64706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org break; 648864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case kX87IntOperand: 649864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fist_s(dst); 650864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 651864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 652864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 654864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 655864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 656864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 657864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::X87Stack::PrepareToWrite(X87Register reg) { 658e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_mutable_); 659864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (Contains(reg)) { 660864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Free(reg); 661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Mark this register as the next register to write to 663864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org stack_[stack_depth_] = reg; 664864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::X87Stack::CommitWrite(X87Register reg) { 668e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_mutable_); 669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Assert the reg is prepared to write, but not on the virtual stack yet 670e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!Contains(reg) && stack_[stack_depth_].is(reg) && 671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org stack_depth_ < X87Register::kMaxNumAllocatableRegisters); 672864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org stack_depth_++; 673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 674864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 676864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::X87PrepareBinaryOp( 677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register left, X87Register right, X87Register result) { 678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // You need to use DefineSameAsFirst for x87 instructions 679e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result.is(left)); 680864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org x87_stack_.Fxch(right, 1); 681864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org x87_stack_.Fxch(left); 682864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 684864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 685864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::X87Stack::FlushIfNecessary(LInstruction* instr, LCodeGen* cgen) { 686864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (stack_depth_ > 0 && instr->ClobbersDoubleRegisters(isolate())) { 687864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool double_inputs = instr->HasDoubleRegisterInput(); 688864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 689864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Flush stack from tos down, since FreeX87() will mess with tos 690864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = stack_depth_-1; i >= 0; i--) { 691864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register reg = stack_[i]; 692864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Skip registers which contain the inputs for the next instruction 693864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // when flushing the stack 694864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (double_inputs && instr->IsDoubleInput(reg, cgen)) { 695864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org continue; 696864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 697864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Free(reg); 698864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (i < stack_depth_-1) i++; 699864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 700864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 701864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->IsReturn()) { 702864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org while (stack_depth_ > 0) { 703864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fstp(0); 704864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org stack_depth_--; 705864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 706864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_debug_code && FLAG_enable_slow_asserts) __ VerifyX87StackDepth(0); 707864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 708864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 709864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 710864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 71106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.orgvoid LCodeGen::X87Stack::LeavingBlock(int current_block_id, LGoto* goto_instr, 71206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org LCodeGen* cgen) { 71306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // For going to a joined block, an explicit LClobberDoubles is inserted before 71406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // LGoto. Because all used x87 registers are spilled to stack slots. The 71506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // ResolvePhis phase of register allocator could guarantee the two input's x87 71606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // stacks have the same layout. So don't check stack_depth_ <= 1 here. 71706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org int goto_block_id = goto_instr->block_id(); 71806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (current_block_id + 1 != goto_block_id) { 719864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If we have a value on the x87 stack on leaving a block, it must be a 720864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // phi input. If the next block we compile is not the join block, we have 721864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // to discard the stack state. 72206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Before discarding the stack state, we need to save it if the "goto block" 72306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // has unreachable last predecessor when FLAG_unreachable_code_elimination. 72406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (FLAG_unreachable_code_elimination) { 72506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org int length = goto_instr->block()->predecessors()->length(); 72606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org bool has_unreachable_last_predecessor = false; 72706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org for (int i = 0; i < length; i++) { 72806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org HBasicBlock* block = goto_instr->block()->predecessors()->at(i); 72906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (block->IsUnreachable() && 73006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org (block->block_id() + 1) == goto_block_id) { 73106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org has_unreachable_last_predecessor = true; 73206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 73306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 73406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (has_unreachable_last_predecessor) { 73506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (cgen->x87_stack_map_.find(goto_block_id) == 73606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org cgen->x87_stack_map_.end()) { 73706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Stack* stack = new (cgen->zone()) X87Stack(*this); 73806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org cgen->x87_stack_map_.insert(std::make_pair(goto_block_id, stack)); 73906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 74006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 74106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 74206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 74306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Discard the stack state. 744864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org stack_depth_ = 0; 745864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 746864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 747864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 748864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 749864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::EmitFlushX87ForDeopt() { 750864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The deoptimizer does not support X87 Registers. But as long as we 751864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // deopt from a stub its not a problem, since we will re-materialize the 752864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // original stub inputs, which can't be double registers. 75306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // DCHECK(info()->IsStub()); 754864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_debug_code && FLAG_enable_slow_asserts) { 755864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pushfd(); 756864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ VerifyX87StackDepth(x87_stack_.depth()); 757864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ popfd(); 758864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 75906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 76006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Flush X87 stack in the deoptimizer entry. 761864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 762864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 763864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 764864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgRegister LCodeGen::ToRegister(LOperand* op) const { 765e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(op->IsRegister()); 766864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return ToRegister(op->index()); 767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 768864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 769864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgX87Register LCodeGen::ToX87Register(LOperand* op) const { 771e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(op->IsDoubleRegister()); 772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return ToX87Register(op->index()); 773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 774864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint32_t LCodeGen::ToInteger32(LConstantOperand* op) const { 777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return ToRepresentation(op, Representation::Integer32()); 778864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 779864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 780864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 781864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint32_t LCodeGen::ToRepresentation(LConstantOperand* op, 782864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const Representation& r) const { 783864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HConstant* constant = chunk_->LookupConstant(op); 784864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t value = constant->Integer32Value(); 785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (r.IsInteger32()) return value; 786e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(r.IsSmiOrTagged()); 787864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return reinterpret_cast<int32_t>(Smi::FromInt(value)); 788864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 790864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 791864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgHandle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { 792864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HConstant* constant = chunk_->LookupConstant(op); 793e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); 794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return constant->handle(isolate()); 795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 796864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 797864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 798864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgdouble LCodeGen::ToDouble(LConstantOperand* op) const { 799864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HConstant* constant = chunk_->LookupConstant(op); 800e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(constant->HasDoubleValue()); 801864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return constant->DoubleValue(); 802864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 803864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 804864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 805864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgExternalReference LCodeGen::ToExternalReference(LConstantOperand* op) const { 806864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HConstant* constant = chunk_->LookupConstant(op); 807e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(constant->HasExternalReferenceValue()); 808864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return constant->ExternalReferenceValue(); 809864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 810864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 811864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 812864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgbool LCodeGen::IsInteger32(LConstantOperand* op) const { 813864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); 814864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 815864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 816864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 817864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgbool LCodeGen::IsSmi(LConstantOperand* op) const { 818864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return chunk_->LookupLiteralRepresentation(op).IsSmi(); 819864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 820864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 821864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 822864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic int ArgumentsOffsetWithoutFrame(int index) { 823e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(index < 0); 824864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return -(index + 1) * kPointerSize + kPCOnStackSize; 825864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 826864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 827864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 828864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgOperand LCodeGen::ToOperand(LOperand* op) const { 829864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (op->IsRegister()) return Operand(ToRegister(op)); 830e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!op->IsDoubleRegister()); 831e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); 832864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (NeedsEagerFrame()) { 833864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return Operand(ebp, StackSlotOffset(op->index())); 834864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 835864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Retrieve parameter without eager stack-frame relative to the 836864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // stack-pointer. 837864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return Operand(esp, ArgumentsOffsetWithoutFrame(op->index())); 838864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 839864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 840864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 841864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 842864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgOperand LCodeGen::HighOperand(LOperand* op) { 843e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(op->IsDoubleStackSlot()); 844864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (NeedsEagerFrame()) { 845864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return Operand(ebp, StackSlotOffset(op->index()) + kPointerSize); 846864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 847864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Retrieve parameter without eager stack-frame relative to the 848864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // stack-pointer. 849864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return Operand( 850864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org esp, ArgumentsOffsetWithoutFrame(op->index()) + kPointerSize); 851864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 852864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 853864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 854864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 855864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::WriteTranslation(LEnvironment* environment, 856864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Translation* translation) { 857864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (environment == NULL) return; 858864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 859864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The translation includes one command per value in the environment. 860864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int translation_size = environment->translation_size(); 861864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The output frame height does not include the parameters. 862864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int height = translation_size - environment->parameter_count(); 863864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 864864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org WriteTranslation(environment->outer(), translation); 865864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool has_closure_id = !info()->closure().is_null() && 866864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org !info()->closure().is_identical_to(environment->closure()); 867864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int closure_id = has_closure_id 868864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? DefineDeoptimizationLiteral(environment->closure()) 869864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : Translation::kSelfLiteralId; 870864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (environment->frame_type()) { 871864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case JS_FUNCTION: 872864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation->BeginJSFrame(environment->ast_id(), closure_id, height); 873864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 874864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case JS_CONSTRUCT: 875864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation->BeginConstructStubFrame(closure_id, translation_size); 876864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 877864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case JS_GETTER: 878e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(translation_size == 1); 879e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(height == 0); 880864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation->BeginGetterStubFrame(closure_id); 881864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 882864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case JS_SETTER: 883e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(translation_size == 2); 884e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(height == 0); 885864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation->BeginSetterStubFrame(closure_id); 886864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 887864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case ARGUMENTS_ADAPTOR: 888864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation->BeginArgumentsAdaptorFrame(closure_id, translation_size); 889864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 890864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case STUB: 891864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation->BeginCompiledStubFrame(); 892864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 893864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 894864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 895864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 896864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 897864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int object_index = 0; 898864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int dematerialized_index = 0; 899864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < translation_size; ++i) { 900864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* value = environment->values()->at(i); 901864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AddToTranslation(environment, 902864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation, 903864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org value, 904864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org environment->HasTaggedValueAt(i), 905864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org environment->HasUint32ValueAt(i), 906864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &object_index, 907864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &dematerialized_index); 908864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 909864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 910864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 911864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 912864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::AddToTranslation(LEnvironment* environment, 913864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Translation* translation, 914864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* op, 915864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool is_tagged, 916864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool is_uint32, 917864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int* object_index_pointer, 918864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int* dematerialized_index_pointer) { 919864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (op == LEnvironment::materialization_marker()) { 920864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int object_index = (*object_index_pointer)++; 921864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (environment->ObjectIsDuplicateAt(object_index)) { 922864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int dupe_of = environment->ObjectDuplicateOfAt(object_index); 923864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation->DuplicateObject(dupe_of); 924864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 925864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 926864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int object_length = environment->ObjectLengthAt(object_index); 927864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (environment->ObjectIsArgumentsAt(object_index)) { 928864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation->BeginArgumentsObject(object_length); 929864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 930864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation->BeginCapturedObject(object_length); 931864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 932864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int dematerialized_index = *dematerialized_index_pointer; 933864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int env_offset = environment->translation_size() + dematerialized_index; 934864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org *dematerialized_index_pointer += object_length; 935864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < object_length; ++i) { 936864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* value = environment->values()->at(env_offset + i); 937864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AddToTranslation(environment, 938864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation, 939864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org value, 940864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org environment->HasTaggedValueAt(env_offset + i), 941864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org environment->HasUint32ValueAt(env_offset + i), 942864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org object_index_pointer, 943864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org dematerialized_index_pointer); 944864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 945864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 946864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 947864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 948864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (op->IsStackSlot()) { 949864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (is_tagged) { 950864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation->StoreStackSlot(op->index()); 951864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (is_uint32) { 952864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation->StoreUint32StackSlot(op->index()); 953864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 954864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation->StoreInt32StackSlot(op->index()); 955864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 956864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (op->IsDoubleStackSlot()) { 957864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation->StoreDoubleStackSlot(op->index()); 958864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (op->IsRegister()) { 959864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = ToRegister(op); 960864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (is_tagged) { 961864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation->StoreRegister(reg); 962864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (is_uint32) { 963864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation->StoreUint32Register(reg); 964864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 965864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation->StoreInt32Register(reg); 966864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 96706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } else if (op->IsDoubleRegister()) { 96806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register reg = ToX87Register(op); 96906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org translation->StoreDoubleRegister(reg); 970864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (op->IsConstantOperand()) { 971864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op)); 972864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int src_index = DefineDeoptimizationLiteral(constant->handle(isolate())); 973864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation->StoreLiteral(src_index); 974864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 975864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 976864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 977864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 978864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 979864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 980864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::CallCodeGeneric(Handle<Code> code, 981864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RelocInfo::Mode mode, 982864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LInstruction* instr, 983864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SafepointMode safepoint_mode) { 984e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr != NULL); 985864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ call(code, mode); 986864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordSafepointWithLazyDeopt(instr, safepoint_mode); 987864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 988864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Signal that we don't inline smi code before these stubs in the 989864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // optimizing code generator. 990864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (code->kind() == Code::BINARY_OP_IC || 991864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org code->kind() == Code::COMPARE_IC) { 992864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ nop(); 993864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 994864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 995864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 996864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 997864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::CallCode(Handle<Code> code, 998864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RelocInfo::Mode mode, 999864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LInstruction* instr) { 1000864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT); 1001864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1002864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1003864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 100406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.orgvoid LCodeGen::CallRuntime(const Runtime::Function* fun, int argc, 100506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org LInstruction* instr, SaveFPRegsMode save_doubles) { 1006e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr != NULL); 1007e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->HasPointerMap()); 1008864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 100906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ CallRuntime(fun, argc, save_doubles); 1010864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1011864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 1012864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1013e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(info()->is_calling()); 1014864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1015864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1016864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1017864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::LoadContextFromDeferred(LOperand* context) { 1018864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (context->IsRegister()) { 1019864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!ToRegister(context).is(esi)) { 1020864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esi, ToRegister(context)); 1021864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1022864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (context->IsStackSlot()) { 1023864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esi, ToOperand(context)); 1024864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (context->IsConstantOperand()) { 1025864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HConstant* constant = 1026864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org chunk_->LookupConstant(LConstantOperand::cast(context)); 1027864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadObject(esi, Handle<Object>::cast(constant->handle(isolate()))); 1028864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1029864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 1030864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1031864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1032864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1033864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, 1034864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int argc, 1035864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LInstruction* instr, 1036864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* context) { 1037864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LoadContextFromDeferred(context); 1038864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 103906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ CallRuntimeSaveDoubles(id); 1040864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordSafepointWithRegisters( 1041864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->pointer_map(), argc, Safepoint::kNoLazyDeopt); 1042864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1043e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(info()->is_calling()); 1044864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1045864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1046864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1047864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::RegisterEnvironmentForDeoptimization( 1048864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LEnvironment* environment, Safepoint::DeoptMode mode) { 1049864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org environment->set_has_been_used(); 1050864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!environment->HasBeenRegistered()) { 1051864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Physical stack frame layout: 1052864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // -x ............. -4 0 ..................................... y 1053864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // [incoming arguments] [spill slots] [pushed outgoing arguments] 1054864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1055864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Layout of the environment: 1056864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 0 ..................................................... size-1 1057864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // [parameters] [locals] [expression stack including arguments] 1058864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1059864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Layout of the translation: 1060864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 0 ........................................................ size - 1 + 4 1061864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // [expression stack including arguments] [locals] [4 words] [parameters] 1062864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // |>------------ translation_size ------------<| 1063864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1064864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int frame_count = 0; 1065864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int jsframe_count = 0; 1066864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (LEnvironment* e = environment; e != NULL; e = e->outer()) { 1067864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ++frame_count; 1068864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (e->frame_type() == JS_FUNCTION) { 1069864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ++jsframe_count; 1070864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1071864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1072864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Translation translation(&translations_, frame_count, jsframe_count, zone()); 1073864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org WriteTranslation(environment, &translation); 1074864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int deoptimization_index = deoptimizations_.length(); 1075864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int pc_offset = masm()->pc_offset(); 1076864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org environment->Register(deoptimization_index, 1077864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translation.index(), 1078864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); 1079864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org deoptimizations_.Add(environment, zone()); 1080864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1081864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1082864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1083864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1084a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgvoid LCodeGen::DeoptimizeIf(Condition cc, LInstruction* instr, 108506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org const char* detail, 1086864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Deoptimizer::BailoutType bailout_type) { 1087a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org LEnvironment* environment = instr->environment(); 1088864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 1089e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(environment->HasBeenRegistered()); 1090864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int id = environment->deoptimization_index(); 1091e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(info()->IsOptimizing() || info()->IsStub()); 1092864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Address entry = 1093864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); 1094864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (entry == NULL) { 1095864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Abort(kBailoutWasNotPrepared); 1096864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 1097864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1098864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1099864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (DeoptEveryNTimes()) { 1100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference count = ExternalReference::stress_deopt_count(isolate()); 1101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label no_deopt; 1102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pushfd(); 1103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); 1104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, Operand::StaticVariable(count)); 1105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(eax, Immediate(1)); 1106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, &no_deopt, Label::kNear); 1107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_trap_on_deopt) __ int3(); 1108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, Immediate(FLAG_deopt_every_n_times)); 1109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand::StaticVariable(count), eax); 1110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(eax); 1111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ popfd(); 1112e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(frame_is_built_); 111306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Put the x87 stack layout in TOS. 111406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (x87_stack_.depth() > 0) EmitFlushX87ForDeopt(); 111506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ push(Immediate(x87_stack_.GetLayout())); 111606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fild_s(MemOperand(esp, 0)); 111706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Don't touch eflags. 111806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ lea(esp, Operand(esp, kPointerSize)); 1119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ call(entry, RelocInfo::RUNTIME_ENTRY); 1120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&no_deopt); 1121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand::StaticVariable(count), eax); 1122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(eax); 1123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ popfd(); 1124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1125864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 112606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Put the x87 stack layout in TOS, so that we can save x87 fp registers in 112706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // the correct location. 112806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org { 1129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 1130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (cc != no_condition) __ j(NegateCondition(cc), &done, Label::kNear); 113106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (x87_stack_.depth() > 0) EmitFlushX87ForDeopt(); 113206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 113306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org int x87_stack_layout = x87_stack_.GetLayout(); 113406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ push(Immediate(x87_stack_layout)); 113506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fild_s(MemOperand(esp, 0)); 113606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Don't touch eflags. 113706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ lea(esp, Operand(esp, kPointerSize)); 1138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 1139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (info()->ShouldTrapOnDeopt()) { 1142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 1143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (cc != no_condition) __ j(NegateCondition(cc), &done, Label::kNear); 1144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ int3(); 1145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 1146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 114806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Deoptimizer::Reason reason(instr->hydrogen_value()->position().raw(), 114906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org instr->Mnemonic(), detail); 1150e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(info()->IsStub() || frame_is_built_); 1151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (cc == no_condition && frame_is_built_) { 115206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptComment(reason); 1153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ call(entry, RelocInfo::RUNTIME_ENTRY); 1154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 115506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Deoptimizer::JumpTableEntry table_entry(entry, reason, bailout_type, 115606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org !frame_is_built_); 1157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We often have several deopts to the same entry, reuse the last 1158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // jump entry if this is the case. 1159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (jump_table_.is_empty() || 116006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org !table_entry.IsEquivalentTo(jump_table_.last())) { 1161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org jump_table_.Add(table_entry, zone()); 1162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (cc == no_condition) { 1164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&jump_table_.last().label); 1165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(cc, &jump_table_.last().label); 1167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1172a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgvoid LCodeGen::DeoptimizeIf(Condition cc, LInstruction* instr, 117306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org const char* detail) { 1174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Deoptimizer::BailoutType bailout_type = info()->IsStub() 1175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? Deoptimizer::LAZY 1176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : Deoptimizer::EAGER; 117706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(cc, instr, detail, bailout_type); 1178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { 1182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int length = deoptimizations_.length(); 1183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (length == 0) return; 1184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<DeoptimizationInputData> data = 11856474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org DeoptimizationInputData::New(isolate(), length, TENURED); 1186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<ByteArray> translations = 1188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org translations_.CreateByteArray(isolate()->factory()); 1189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data->SetTranslationByteArray(*translations); 1190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); 1191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data->SetOptimizationId(Smi::FromInt(info_->optimization_id())); 1192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (info_->IsOptimizing()) { 1193864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Reference to shared function info does not change between phases. 1194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AllowDeferredHandleDereference allow_handle_dereference; 1195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data->SetSharedFunctionInfo(*info_->shared_info()); 1196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data->SetSharedFunctionInfo(Smi::FromInt(0)); 1198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1199864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<FixedArray> literals = 1201864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); 1202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { AllowDeferredHandleDereference copy_handles; 1203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < deoptimization_literals_.length(); i++) { 1204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org literals->set(i, *deoptimization_literals_[i]); 1205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data->SetLiteralArray(*literals); 1207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); 1210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); 1211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Populate the deoptimization entries. 1213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < length; i++) { 1214864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LEnvironment* env = deoptimizations_[i]; 1215864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data->SetAstId(i, env->ast_id()); 1216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); 1217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data->SetArgumentsStackHeight(i, 1218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Smi::FromInt(env->arguments_stack_height())); 1219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org data->SetPc(i, Smi::FromInt(env->pc_offset())); 1220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org code->set_deoptimization_data(*data); 1222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1224864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgint LCodeGen::DefineDeoptimizationLiteral(Handle<Object> literal) { 1226864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int result = deoptimization_literals_.length(); 1227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < deoptimization_literals_.length(); ++i) { 1228864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (deoptimization_literals_[i].is_identical_to(literal)) return i; 1229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org deoptimization_literals_.Add(literal, zone()); 1231864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return result; 1232864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1233864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::PopulateDeoptimizationLiteralsWithInlinedFunctions() { 1236e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(deoptimization_literals_.length() == 0); 1237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const ZoneList<Handle<JSFunction> >* inlined_closures = 1239864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org chunk()->inlined_closures(); 1240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1241864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0, length = inlined_closures->length(); 1242864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org i < length; 1243864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org i++) { 1244864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DefineDeoptimizationLiteral(inlined_closures->at(i)); 1245864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org inlined_function_count_ = deoptimization_literals_.length(); 1248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1249864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::RecordSafepointWithLazyDeopt( 1252864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LInstruction* instr, SafepointMode safepoint_mode) { 1253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) { 1254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt); 1255864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1256e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 1257864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordSafepointWithRegisters( 1258864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->pointer_map(), 0, Safepoint::kLazyDeopt); 1259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1260864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1261864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1262864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1263864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::RecordSafepoint( 1264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LPointerMap* pointers, 1265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Safepoint::Kind kind, 1266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int arguments, 1267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Safepoint::DeoptMode deopt_mode) { 1268e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kind == expected_safepoint_kind_); 1269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const ZoneList<LOperand*>* operands = pointers->GetNormalizedOperands(); 1270864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Safepoint safepoint = 1271864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org safepoints_.DefineSafepoint(masm(), kind, arguments, deopt_mode); 1272864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < operands->length(); i++) { 1273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* pointer = operands->at(i); 1274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (pointer->IsStackSlot()) { 1275864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org safepoint.DefinePointerSlot(pointer->index(), zone()); 1276864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { 1277864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org safepoint.DefinePointerRegister(ToRegister(pointer), zone()); 1278864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::RecordSafepoint(LPointerMap* pointers, 1284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Safepoint::DeoptMode mode) { 1285864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordSafepoint(pointers, Safepoint::kSimple, 0, mode); 1286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1287864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1288864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::RecordSafepoint(Safepoint::DeoptMode mode) { 1290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LPointerMap empty_pointers(zone()); 1291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordSafepoint(&empty_pointers, mode); 1292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1295864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, 1296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int arguments, 1297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Safepoint::DeoptMode mode) { 1298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments, mode); 1299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::RecordAndWritePosition(int position) { 1303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (position == RelocInfo::kNoPosition) return; 1304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org masm()->positions_recorder()->RecordPosition(position); 1305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org masm()->positions_recorder()->WriteRecordedPositions(); 1306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const char* LabelType(LLabel* label) { 1310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (label->is_loop_header()) return " (loop header)"; 1311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (label->is_osr_entry()) return " (OSR entry)"; 1312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return ""; 1313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoLabel(LLabel* label) { 1317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------", 1318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org current_instruction_, 1319864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org label->hydrogen_value()->id(), 1320864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org label->block_id(), 1321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LabelType(label)); 1322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(label->label()); 1323864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org current_block_ = label->block_id(); 132406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (label->block()->predecessors()->length() > 1) { 132506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // A join block's x87 stack is that of its last visited predecessor. 132606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // If the last visited predecessor block is unreachable, the stack state 132706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // will be wrong. In such case, use the x87 stack of reachable predecessor. 132806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87StackMap::const_iterator it = x87_stack_map_.find(current_block_); 132906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Restore x87 stack. 133006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (it != x87_stack_map_.end()) { 133106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org x87_stack_ = *(it->second); 133206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 133306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 1334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DoGap(label); 1335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoParallelMove(LParallelMove* move) { 1339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org resolver_.Resolve(move); 1340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1343864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoGap(LGap* gap) { 1344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = LGap::FIRST_INNER_POSITION; 1345864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org i <= LGap::LAST_INNER_POSITION; 1346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org i++) { 1347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LGap::InnerPosition inner_pos = static_cast<LGap::InnerPosition>(i); 1348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LParallelMove* move = gap->GetParallelMove(inner_pos); 1349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (move != NULL) DoParallelMove(move); 1350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoInstructionGap(LInstructionGap* instr) { 1355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DoGap(instr); 1356864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoParameter(LParameter* instr) { 1360864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Nothing to do. 1361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoCallStub(LCallStub* instr) { 1365e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 1366e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(eax)); 1367864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (instr->hydrogen()->major_key()) { 1368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case CodeStub::RegExpExec: { 1369864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RegExpExecStub stub(isolate()); 1370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case CodeStub::SubString: { 1374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SubStringStub stub(isolate()); 1375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case CodeStub::StringCompare: { 1379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org StringCompareStub stub(isolate()); 1380864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 1384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 1385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1387864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 1390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org GenerateOsrPrologue(); 1391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) { 1395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t divisor = instr->divisor(); 1397e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(dividend.is(ToRegister(instr->result()))); 1398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Theoretically, a variation of the branch-free code for integer division by 1400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // a power of 2 (calculating the remainder via an additional multiplication 1401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // (which gets simplified to an 'and') and subtraction) should be faster, and 1402864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // this is exactly what GCC and clang emit. Nevertheless, benchmarks seem to 1403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // indicate that positive dividends are heavily favored, so the branching 1404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // version performs better. 1405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HMod* hmod = instr->hydrogen(); 1406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); 1407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label dividend_is_not_negative, done; 1408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hmod->CheckFlag(HValue::kLeftCanBeNegative)) { 1409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(dividend, dividend); 1410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_sign, ÷nd_is_not_negative, Label::kNear); 1411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Note that this is correct even for kMinInt operands. 1412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ neg(dividend); 1413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ and_(dividend, mask); 1414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ neg(dividend); 1415864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1416b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(zero, instr, "minus zero"); 1417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 1419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(÷nd_is_not_negative); 1422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ and_(dividend, mask); 1423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 1424864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1425864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1426864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1427864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoModByConstI(LModByConstI* instr) { 1428864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1429864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t divisor = instr->divisor(); 1430e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(eax)); 1431864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (divisor == 0) { 1433b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(no_condition, instr, "division by zero"); 1434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 1435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TruncatingDiv(dividend, Abs(divisor)); 1438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ imul(edx, edx, Abs(divisor)); 1439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, dividend); 1440864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(eax, edx); 1441864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for negative zero. 1443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HMod* hmod = instr->hydrogen(); 1444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label remainder_not_zero; 1446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, &remainder_not_zero, Label::kNear); 1447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(dividend, Immediate(0)); 1448b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(less, instr, "minus zero"); 1449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&remainder_not_zero); 1450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoModI(LModI* instr) { 1455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HMod* hmod = instr->hydrogen(); 1456864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register left_reg = ToRegister(instr->left()); 1458e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(left_reg.is(eax)); 1459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register right_reg = ToRegister(instr->right()); 1460e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!right_reg.is(eax)); 1461e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!right_reg.is(edx)); 1462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result_reg = ToRegister(instr->result()); 1463e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result_reg.is(edx)); 1464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 1466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for x % 0, idiv would signal a divide error. We have to 1467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // deopt in this case because we can't return a NaN. 1468864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hmod->CheckFlag(HValue::kCanBeDivByZero)) { 1469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(right_reg, Operand(right_reg)); 1470b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(zero, instr, "division by zero"); 1471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1472864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for kMinInt % -1, idiv would signal a divide error. We 1474864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // have to deopt if we care about -0, because we can't return that. 1475864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hmod->CheckFlag(HValue::kCanOverflow)) { 1476864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label no_overflow_possible; 1477864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(left_reg, kMinInt); 1478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &no_overflow_possible, Label::kNear); 1479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(right_reg, -1); 1480864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1481b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(equal, instr, "minus zero"); 1482864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1483864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &no_overflow_possible, Label::kNear); 1484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(result_reg, Immediate(0)); 1485864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 1486864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1487864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&no_overflow_possible); 1488864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1489864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Sign extend dividend in eax into edx:eax. 1491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cdq(); 1492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1493864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If we care about -0, test if the dividend is <0 and the result is 0. 1494864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1495864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label positive_left; 1496864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(left_reg, Operand(left_reg)); 1497864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_sign, &positive_left, Label::kNear); 1498864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ idiv(right_reg); 1499864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(result_reg, Operand(result_reg)); 1500b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(zero, instr, "minus zero"); 1501864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 1502864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&positive_left); 1503864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1504864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ idiv(right_reg); 1505864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 1506864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1507864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1508864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1509864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { 1510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1511864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t divisor = instr->divisor(); 1512864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 15139aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor))); 1514e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!result.is(dividend)); 1515864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1516864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for (0 / -x) that will produce negative zero. 1517864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HDiv* hdiv = instr->hydrogen(); 1518864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1519864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(dividend, dividend); 1520b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(zero, instr, "minus zero"); 1521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1522864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for (kMinInt / -1). 1523864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) { 1524864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(dividend, kMinInt); 1525b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(zero, instr, "overflow"); 1526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1527864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Deoptimize if remainder will not be 0. 1528864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && 1529864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org divisor != 1 && divisor != -1) { 1530864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); 1531864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(dividend, Immediate(mask)); 1532b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_zero, instr, "lost precision"); 1533864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1534864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(result, dividend); 1535864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t shift = WhichPowerOf2Abs(divisor); 1536864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (shift > 0) { 1537864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The arithmetic shift is always OK, the 'if' is an optimization only. 1538864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (shift > 1) __ sar(result, 31); 1539864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shr(result, 32 - shift); 1540864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(result, dividend); 1541864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sar(result, shift); 1542864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1543864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (divisor < 0) __ neg(result); 1544864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1545864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1546864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1547864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDivByConstI(LDivByConstI* instr) { 1548864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1549864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t divisor = instr->divisor(); 1550e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(edx)); 1551864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1552864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (divisor == 0) { 1553b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(no_condition, instr, "division by zero"); 1554864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 1555864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1556864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for (0 / -x) that will produce negative zero. 1558864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HDiv* hdiv = instr->hydrogen(); 1559864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1560864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(dividend, dividend); 1561b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(zero, instr, "minus zero"); 1562864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1563864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1564864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TruncatingDiv(dividend, Abs(divisor)); 1565864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (divisor < 0) __ neg(edx); 1566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1567864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { 1568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, edx); 1569864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ imul(eax, eax, divisor); 1570864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(eax, dividend); 1571b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_equal, instr, "lost precision"); 1572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1573864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1574864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI. 1577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDivI(LDivI* instr) { 1578864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HBinaryOperation* hdiv = instr->hydrogen(); 1579864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1580864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register divisor = ToRegister(instr->divisor()); 1581864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register remainder = ToRegister(instr->temp()); 1582e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(dividend.is(eax)); 1583e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(remainder.is(edx)); 1584e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(eax)); 1585e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!divisor.is(eax)); 1586e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!divisor.is(edx)); 1587864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1588864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for x / 0. 1589864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { 1590864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(divisor, divisor); 1591b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(zero, instr, "division by zero"); 1592864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1593864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1594864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for (0 / -x) that will produce negative zero. 1595864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { 1596864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label dividend_not_zero; 1597864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(dividend, dividend); 1598864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, ÷nd_not_zero, Label::kNear); 1599864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(divisor, divisor); 1600b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(sign, instr, "minus zero"); 1601864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(÷nd_not_zero); 1602864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1603864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1604864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for (kMinInt / -1). 1605864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hdiv->CheckFlag(HValue::kCanOverflow)) { 1606864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label dividend_not_min_int; 1607864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(dividend, kMinInt); 1608864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, ÷nd_not_min_int, Label::kNear); 1609864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(divisor, -1); 1610b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(zero, instr, "overflow"); 1611864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(÷nd_not_min_int); 1612864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1613864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1614864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Sign extend to edx (= remainder). 1615864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cdq(); 1616864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ idiv(divisor); 1617864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1618864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { 1619864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Deoptimize if remainder is not 0. 1620864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(remainder, remainder); 1621b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_zero, instr, "lost precision"); 1622864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1623864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1625864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1626864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { 1627864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1628864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t divisor = instr->divisor(); 1629e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(dividend.is(ToRegister(instr->result()))); 1630864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1631864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the divisor is positive, things are easy: There can be no deopts and we 1632864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // can simply do an arithmetic right shift. 1633864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (divisor == 1) return; 1634864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t shift = WhichPowerOf2Abs(divisor); 1635864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (divisor > 1) { 1636864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sar(dividend, shift); 1637864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 1638864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1639864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1640864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the divisor is negative, we have to negate and handle edge cases. 1641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ neg(dividend); 1642864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1643b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(zero, instr, "minus zero"); 1644864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1645864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 164670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // Dividing by -1 is basically negation, unless we overflow. 164770d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (divisor == -1) { 164870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { 1649b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(overflow, instr, "overflow"); 165070d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org } 1651864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 1652864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 165470d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org // If the negation could not overflow, simply shifting is OK. 165570d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { 165670d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org __ sar(dividend, shift); 1657864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 1658864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1659864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1660864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label not_kmin_int, done; 1661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(no_overflow, ¬_kmin_int, Label::kNear); 1662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(dividend, Immediate(kMinInt / divisor)); 1663864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 1664864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(¬_kmin_int); 1665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sar(dividend, shift); 1666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 1667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1668864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1670864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { 1671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1672864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t divisor = instr->divisor(); 1673e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(edx)); 1674864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (divisor == 0) { 1676b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(no_condition, instr, "division by zero"); 1677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 1678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1679864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1680864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for (0 / -x) that will produce negative zero. 1681864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HMathFloorOfDiv* hdiv = instr->hydrogen(); 1682864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { 1683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(dividend, dividend); 1684b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(zero, instr, "minus zero"); 1685864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1686864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1687864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Easy case: We need no dynamic check for the dividend and the flooring 1688864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // division is the same as the truncating division. 1689864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) || 1690864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) { 1691864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TruncatingDiv(dividend, Abs(divisor)); 1692864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (divisor < 0) __ neg(edx); 1693864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 1694864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1695864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1696864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // In the general case we may need to adjust before and after the truncating 1697864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // division to get a flooring division. 1698864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp = ToRegister(instr->temp3()); 1699e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!temp.is(dividend) && !temp.is(eax) && !temp.is(edx)); 1700864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label needs_adjustment, done; 1701864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(dividend, Immediate(0)); 1702864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(divisor > 0 ? less : greater, &needs_adjustment, Label::kNear); 1703864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TruncatingDiv(dividend, Abs(divisor)); 1704864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (divisor < 0) __ neg(edx); 1705864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 1706864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&needs_adjustment); 1707864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(temp, Operand(dividend, divisor > 0 ? 1 : -1)); 1708864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TruncatingDiv(temp, Abs(divisor)); 1709864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (divisor < 0) __ neg(edx); 1710864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ dec(edx); 1711864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 1712864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1713864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1714864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1715864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// TODO(svenpanne) Refactor this to avoid code duplication with DoDivI. 1716864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { 1717864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HBinaryOperation* hdiv = instr->hydrogen(); 1718864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register dividend = ToRegister(instr->dividend()); 1719864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register divisor = ToRegister(instr->divisor()); 1720864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register remainder = ToRegister(instr->temp()); 1721864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 1722e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(dividend.is(eax)); 1723e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(remainder.is(edx)); 1724e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result.is(eax)); 1725e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!divisor.is(eax)); 1726e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!divisor.is(edx)); 1727864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1728864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for x / 0. 1729864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { 1730864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(divisor, divisor); 1731b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(zero, instr, "division by zero"); 1732864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1733864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1734864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for (0 / -x) that will produce negative zero. 1735864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { 1736864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label dividend_not_zero; 1737864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(dividend, dividend); 1738864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, ÷nd_not_zero, Label::kNear); 1739864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(divisor, divisor); 1740b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(sign, instr, "minus zero"); 1741864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(÷nd_not_zero); 1742864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1743864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1744864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for (kMinInt / -1). 1745864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hdiv->CheckFlag(HValue::kCanOverflow)) { 1746864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label dividend_not_min_int; 1747864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(dividend, kMinInt); 1748864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, ÷nd_not_min_int, Label::kNear); 1749864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(divisor, -1); 1750b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(zero, instr, "overflow"); 1751864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(÷nd_not_min_int); 1752864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1753864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1754864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Sign extend to edx (= remainder). 1755864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cdq(); 1756864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ idiv(divisor); 1757864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1758864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 1759864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(remainder, remainder); 1760864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(zero, &done, Label::kNear); 1761864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ xor_(remainder, divisor); 1762864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sar(remainder, 31); 1763864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(result, remainder); 1764864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 1765864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1766864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1768864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoMulI(LMulI* instr) { 1769864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register left = ToRegister(instr->left()); 1770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* right = instr->right(); 1771864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ToRegister(instr->temp()), left); 1774864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (right->IsConstantOperand()) { 1777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Try strength reductions on the multiplication. 1778864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // All replacement instructions are at most as long as the imul 1779864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // and have better latency. 1780864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int constant = ToInteger32(LConstantOperand::cast(right)); 1781864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (constant == -1) { 1782864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ neg(left); 1783864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (constant == 0) { 1784864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ xor_(left, Operand(left)); 1785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (constant == 2) { 1786864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(left, Operand(left)); 1787864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (!instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1788864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If we know that the multiplication can't overflow, it's safe to 1789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // use instructions that don't set the overflow flag for the 1790864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // multiplication. 1791864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (constant) { 1792864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 1: 1793864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Do nothing. 1794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 3: 1796864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(left, Operand(left, left, times_2, 0)); 1797864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1798864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 4: 1799864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shl(left, 2); 1800864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1801864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 5: 1802864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(left, Operand(left, left, times_4, 0)); 1803864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1804864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 8: 1805864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shl(left, 3); 1806864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1807864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 9: 1808864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(left, Operand(left, left, times_8, 0)); 1809864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1810864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case 16: 1811864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shl(left, 4); 1812864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1813864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 1814864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ imul(left, left, constant); 1815864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1816864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1817864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1818864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ imul(left, left, constant); 1819864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1820864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1821864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->representation().IsSmi()) { 1822864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(left); 1823864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1824864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ imul(left, ToOperand(right)); 1825864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1826864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1827864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1828b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(overflow, instr, "overflow"); 1829864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1830864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1831864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1832864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Bail out if the result is supposed to be negative zero. 1833864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 1834864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(left, Operand(left)); 183506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ j(not_zero, &done); 1836864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (right->IsConstantOperand()) { 1837864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (ToInteger32(LConstantOperand::cast(right)) < 0) { 1838b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(no_condition, instr, "minus zero"); 1839864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (ToInteger32(LConstantOperand::cast(right)) == 0) { 1840864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ToRegister(instr->temp()), Immediate(0)); 1841b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(less, instr, "minus zero"); 1842864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1843864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1844864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Test the non-zero operand for negative sign. 1845864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ or_(ToRegister(instr->temp()), ToOperand(right)); 1846b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(sign, instr, "minus zero"); 1847864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1848864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 1849864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1850864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1851864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1852864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1853864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoBitI(LBitI* instr) { 1854864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* left = instr->left(); 1855864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* right = instr->right(); 1856e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(left->Equals(instr->result())); 1857e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(left->IsRegister()); 1858864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1859864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (right->IsConstantOperand()) { 1860864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t right_operand = 1861864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ToRepresentation(LConstantOperand::cast(right), 1862864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->representation()); 1863864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (instr->op()) { 1864864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::BIT_AND: 1865864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ and_(ToRegister(left), right_operand); 1866864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1867864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::BIT_OR: 1868864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ or_(ToRegister(left), right_operand); 1869864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1870864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::BIT_XOR: 1871864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (right_operand == int32_t(~0)) { 1872864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ not_(ToRegister(left)); 1873864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1874864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ xor_(ToRegister(left), right_operand); 1875864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1876864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1877864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 1878864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 1879864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1880864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1881864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1882864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (instr->op()) { 1883864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::BIT_AND: 1884864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ and_(ToRegister(left), ToOperand(right)); 1885864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1886864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::BIT_OR: 1887864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ or_(ToRegister(left), ToOperand(right)); 1888864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1889864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::BIT_XOR: 1890864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ xor_(ToRegister(left), ToOperand(right)); 1891864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1892864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 1893864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 1894864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1895864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1896864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1897864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1898864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1899864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1900864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoShiftI(LShiftI* instr) { 1901864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* left = instr->left(); 1902864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* right = instr->right(); 1903e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(left->Equals(instr->result())); 1904e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(left->IsRegister()); 1905864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (right->IsRegister()) { 1906e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(right).is(ecx)); 1907864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1908864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (instr->op()) { 1909864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::ROR: 1910864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ror_cl(ToRegister(left)); 1911864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1912864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::SAR: 1913864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sar_cl(ToRegister(left)); 1914864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1915864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::SHR: 1916864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shr_cl(ToRegister(left)); 1917864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->can_deopt()) { 1918864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(ToRegister(left), ToRegister(left)); 1919b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(sign, instr, "negative value"); 1920864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1921864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1922864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::SHL: 1923864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shl_cl(ToRegister(left)); 1924864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1925864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 1926864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 1927864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1928864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1929864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1930864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int value = ToInteger32(LConstantOperand::cast(right)); 1931864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org uint8_t shift_count = static_cast<uint8_t>(value & 0x1F); 1932864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (instr->op()) { 1933864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::ROR: 1934864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (shift_count == 0 && instr->can_deopt()) { 1935864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(ToRegister(left), ToRegister(left)); 1936b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(sign, instr, "negative value"); 1937864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1938864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ror(ToRegister(left), shift_count); 1939864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1940864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1941864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::SAR: 1942864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (shift_count != 0) { 1943864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sar(ToRegister(left), shift_count); 1944864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1945864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1946864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::SHR: 1947864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (shift_count != 0) { 1948864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shr(ToRegister(left), shift_count); 1949864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (instr->can_deopt()) { 1950864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(ToRegister(left), ToRegister(left)); 1951b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(sign, instr, "negative value"); 1952864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1953864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1954864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::SHL: 1955864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (shift_count != 0) { 1956864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen_value()->representation().IsSmi() && 1957864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->can_deopt()) { 1958864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (shift_count != 1) { 1959864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shl(ToRegister(left), shift_count - 1); 1960864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1961864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiTag(ToRegister(left)); 1962b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(overflow, instr, "overflow"); 1963864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1964864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shl(ToRegister(left), shift_count); 1965864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1966864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1967864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1968864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 1969864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 1970864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1971864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1972864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1973864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1974864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1975864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1976864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoSubI(LSubI* instr) { 1977864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* left = instr->left(); 1978864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* right = instr->right(); 1979e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(left->Equals(instr->result())); 1980864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1981864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (right->IsConstantOperand()) { 1982864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(ToOperand(left), 1983864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ToImmediate(right, instr->hydrogen()->representation())); 1984864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1985864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(ToRegister(left), ToOperand(right)); 1986864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1987864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1988b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(overflow, instr, "overflow"); 1989864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1990864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1991864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1992864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1993864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoConstantI(LConstantI* instr) { 1994864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(ToRegister(instr->result()), Immediate(instr->value())); 1995864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1996864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1997864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1998864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoConstantS(LConstantS* instr) { 1999864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(ToRegister(instr->result()), Immediate(instr->value())); 2000864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2001864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2002864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2003864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoConstantD(LConstantD* instr) { 2004864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org double v = instr->value(); 2005e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org uint64_t int_val = bit_cast<uint64_t, double>(v); 2006864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t lower = static_cast<int32_t>(int_val); 2007864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); 2008e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->result()->IsDoubleRegister()); 2009864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2010864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(upper)); 2011864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(lower)); 2012864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register reg = ToX87Register(instr->result()); 2013864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Mov(reg, Operand(esp, 0)); 2014864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(Operand(esp), Immediate(kDoubleSize)); 2015864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2016864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2017864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2018864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoConstantE(LConstantE* instr) { 2019864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(ToRegister(instr->result()), Operand::StaticVariable(instr->value())); 2020864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2021864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2022864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2023864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoConstantT(LConstantT* instr) { 2024864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = ToRegister(instr->result()); 2025864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Object> object = instr->value(isolate()); 2026864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AllowDeferredHandleDereference smi_check; 2027864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadObject(reg, object); 2028864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2029864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2030864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2031864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { 2032864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 2033864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register map = ToRegister(instr->value()); 2034864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ EnumLength(result, map); 2035864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2036864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2037864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2038864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDateField(LDateField* instr) { 2039864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register object = ToRegister(instr->date()); 2040864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 2041864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch = ToRegister(instr->temp()); 2042864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Smi* index = instr->index(); 2043864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label runtime, done; 2044e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(object.is(result)); 2045e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(object.is(eax)); 2046864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2047864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(object, Immediate(kSmiTagMask)); 2048b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(zero, instr, "Smi"); 2049864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(object, JS_DATE_TYPE, scratch); 2050b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_equal, instr, "not a date object"); 2051864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2052864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (index->value() == 0) { 2053864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, FieldOperand(object, JSDate::kValueOffset)); 2054864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2055864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (index->value() < JSDate::kFirstUncachedField) { 2056864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference stamp = ExternalReference::date_cache_stamp(isolate()); 2057864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch, Operand::StaticVariable(stamp)); 2058864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(scratch, FieldOperand(object, JSDate::kCacheStampOffset)); 2059864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &runtime, Label::kNear); 2060864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, FieldOperand(object, JSDate::kValueOffset + 2061864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org kPointerSize * index->value())); 2062864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 2063864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2064864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&runtime); 2065864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ PrepareCallCFunction(2, scratch); 2066864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esp, 0), object); 2067864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esp, 1 * kPointerSize), Immediate(index)); 2068864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); 2069864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 2070864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2071864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2072864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2073864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2074864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgOperand LCodeGen::BuildSeqStringOperand(Register string, 2075864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* index, 2076864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org String::Encoding encoding) { 2077864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (index->IsConstantOperand()) { 2078864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int offset = ToRepresentation(LConstantOperand::cast(index), 2079864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Representation::Integer32()); 2080864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (encoding == String::TWO_BYTE_ENCODING) { 2081864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org offset *= kUC16Size; 2082864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2083864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(kCharSize == 1); 2084864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return FieldOperand(string, SeqString::kHeaderSize + offset); 2085864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2086864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return FieldOperand( 2087864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org string, ToRegister(index), 2088864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org encoding == String::ONE_BYTE_ENCODING ? times_1 : times_2, 2089864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SeqString::kHeaderSize); 2090864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2091864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2092864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2093864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoSeqStringGetChar(LSeqStringGetChar* instr) { 2094864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org String::Encoding encoding = instr->hydrogen()->encoding(); 2095864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 2096864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register string = ToRegister(instr->string()); 2097864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2098864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_debug_code) { 2099864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(string); 2100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(string, FieldOperand(string, HeapObject::kMapOffset)); 2101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ movzx_b(string, FieldOperand(string, Map::kInstanceTypeOffset)); 2102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ and_(string, Immediate(kStringRepresentationMask | kStringEncodingMask)); 2104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 2105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 2106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(string, Immediate(encoding == String::ONE_BYTE_ENCODING 2107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? one_byte_seq_type : two_byte_seq_type)); 2108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Check(equal, kUnexpectedStringType); 2109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(string); 2110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand operand = BuildSeqStringOperand(string, instr->index(), encoding); 2113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (encoding == String::ONE_BYTE_ENCODING) { 2114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ movzx_b(result, operand); 2115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ movzx_w(result, operand); 2117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) { 2122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org String::Encoding encoding = instr->hydrogen()->encoding(); 2123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register string = ToRegister(instr->string()); 2124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2125864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_debug_code) { 2126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register value = ToRegister(instr->value()); 2127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register index = ToRegister(instr->index()); 2128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 2129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 2130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int encoding_mask = 2131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->encoding() == String::ONE_BYTE_ENCODING 2132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? one_byte_seq_type : two_byte_seq_type; 2133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ EmitSeqStringSetCharCheck(string, index, value, encoding_mask); 2134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand operand = BuildSeqStringOperand(string, instr->index(), encoding); 2137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->value()->IsConstantOperand()) { 2138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int value = ToRepresentation(LConstantOperand::cast(instr->value()), 2139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Representation::Integer32()); 2140e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_LE(0, value); 2141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (encoding == String::ONE_BYTE_ENCODING) { 2142e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_LE(value, String::kMaxOneByteCharCode); 2143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov_b(operand, static_cast<int8_t>(value)); 2144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2145e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_LE(value, String::kMaxUtf16CodeUnit); 2146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov_w(operand, static_cast<int16_t>(value)); 2147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register value = ToRegister(instr->value()); 2150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (encoding == String::ONE_BYTE_ENCODING) { 2151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov_b(operand, value); 2152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov_w(operand, value); 2154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoAddI(LAddI* instr) { 2160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* left = instr->left(); 2161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* right = instr->right(); 2162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { 2164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (right->IsConstantOperand()) { 2165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t offset = ToRepresentation(LConstantOperand::cast(right), 2166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->representation()); 2167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(ToRegister(instr->result()), MemOperand(ToRegister(left), offset)); 2168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand address(ToRegister(left), ToRegister(right), times_1, 0); 2170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(ToRegister(instr->result()), address); 2171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (right->IsConstantOperand()) { 2174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(ToOperand(left), 2175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ToImmediate(right, instr->hydrogen()->representation())); 2176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(ToRegister(left), ToOperand(right)); 2178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 2180b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(overflow, instr, "overflow"); 2181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoMathMinMax(LMathMinMax* instr) { 2187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* left = instr->left(); 2188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* right = instr->right(); 2189e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(left->Equals(instr->result())); 2190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HMathMinMax::Operation operation = instr->hydrogen()->operation(); 2191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->representation().IsSmiOrInteger32()) { 2192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label return_left; 2193864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition condition = (operation == HMathMinMax::kMathMin) 2194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? less_equal 2195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : greater_equal; 2196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (right->IsConstantOperand()) { 2197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand left_op = ToOperand(left); 2198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate immediate = ToImmediate(LConstantOperand::cast(instr->right()), 2199864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->representation()); 2200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(left_op, immediate); 2201864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(condition, &return_left, Label::kNear); 2202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(left_op, immediate); 2203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register left_reg = ToRegister(left); 2205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand right_op = ToOperand(right); 2206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(left_reg, right_op); 2207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(condition, &return_left, Label::kNear); 2208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(left_reg, right_op); 2209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&return_left); 2211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 221206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DCHECK(instr->hydrogen()->representation().IsDouble()); 221306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label check_nan_left, check_zero, return_left, return_right; 221406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Condition condition = (operation == HMathMinMax::kMathMin) ? below : above; 221506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register left_reg = ToX87Register(left); 221606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register right_reg = ToX87Register(right); 221706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 221806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87PrepareBinaryOp(left_reg, right_reg, ToX87Register(instr->result())); 221906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld(1); 222006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld(1); 222106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ FCmp(); 222206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ j(parity_even, &check_nan_left, Label::kNear); // At least one NaN. 222306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ j(equal, &check_zero, Label::kNear); // left == right. 222406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ j(condition, &return_left, Label::kNear); 222506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ jmp(&return_right, Label::kNear); 222606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 222706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&check_zero); 222806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld(0); 222906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fldz(); 223006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ FCmp(); 223106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ j(not_equal, &return_left, Label::kNear); // left == right != 0. 223206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // At this point, both left and right are either 0 or -0. 223306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (operation == HMathMinMax::kMathMin) { 223406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Push st0 and st1 to stack, then pop them to temp registers and OR them, 223506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // load it to left. 223606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register scratch_reg = ToRegister(instr->temp()); 223706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld(1); 223806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld(1); 223906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ sub(esp, Immediate(2 * kPointerSize)); 224006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fstp_s(MemOperand(esp, 0)); 224106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fstp_s(MemOperand(esp, kPointerSize)); 224206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ pop(scratch_reg); 224306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ xor_(MemOperand(esp, 0), scratch_reg); 224406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Mov(left_reg, MemOperand(esp, 0), kX87FloatOperand); 224506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ pop(scratch_reg); // restore esp 224606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } else { 224706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Since we operate on +0 and/or -0, addsd and andsd have the same effect. 224806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Fxch(left_reg); 224906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fadd(1); 225006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 225106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ jmp(&return_left, Label::kNear); 225206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 225306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&check_nan_left); 225406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld(0); 225506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld(0); 225606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ FCmp(); // NaN check. 225706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ j(parity_even, &return_left, Label::kNear); // left == NaN. 225806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 225906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&return_right); 226006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Fxch(left_reg); 226106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Mov(left_reg, right_reg); 226206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 226306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&return_left); 2264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoArithmeticD(LArithmeticD* instr) { 2269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register left = ToX87Register(instr->left()); 2270864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register right = ToX87Register(instr->right()); 2271864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register result = ToX87Register(instr->result()); 2272864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->op() != Token::MOD) { 2273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87PrepareBinaryOp(left, right, result); 2274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 227579390123903f4a8b6e973f2d4e3743948b97aeb8weiliang.lin@intel.com // Set the precision control to double-precision. 227679390123903f4a8b6e973f2d4e3743948b97aeb8weiliang.lin@intel.com __ X87SetFPUCW(0x027F); 2277864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (instr->op()) { 2278864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::ADD: 2279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fadd_i(1); 2280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::SUB: 2282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fsub_i(1); 2283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::MUL: 2285864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fmul_i(1); 2286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2287864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::DIV: 2288864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fdiv_i(1); 2289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::MOD: { 2291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Pass two doubles as arguments on the stack. 2292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ PrepareCallCFunction(4, eax); 2293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Mov(Operand(esp, 1 * kDoubleSize), right); 2294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Mov(Operand(esp, 0), left); 2295864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Free(right); 2296e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(left.is(result)); 2297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87PrepareToWrite(result); 2298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallCFunction( 2299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference::mod_two_doubles_operation(isolate()), 2300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4); 2301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Return value is in st(0) on ia32. 2303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87CommitWrite(result); 2304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 2307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 2308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 231006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 231179390123903f4a8b6e973f2d4e3743948b97aeb8weiliang.lin@intel.com // Restore the default value of control word. 231279390123903f4a8b6e973f2d4e3743948b97aeb8weiliang.lin@intel.com __ X87SetFPUCW(0x037F); 2313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoArithmeticT(LArithmeticT* instr) { 2317e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 2318e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->left()).is(edx)); 2319e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->right()).is(eax)); 2320e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(eax)); 2321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2322b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Handle<Code> code = 2323b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org CodeFactory::BinaryOpIC(isolate(), instr->op(), NO_OVERWRITE).code(); 2324b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org CallCode(code, RelocInfo::CODE_TARGET, instr); 2325864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2327864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2328864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgtemplate<class InstrType> 2329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::EmitBranch(InstrType instr, Condition cc) { 2330864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int left_block = instr->TrueDestination(chunk_); 2331864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int right_block = instr->FalseDestination(chunk_); 2332864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int next_block = GetNextEmittedBlock(); 2334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (right_block == left_block || cc == no_condition) { 2336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitGoto(left_block); 2337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (left_block == next_block) { 2338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(NegateCondition(cc), chunk_->GetAssemblyLabel(right_block)); 2339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (right_block == next_block) { 2340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(cc, chunk_->GetAssemblyLabel(left_block)); 2341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(cc, chunk_->GetAssemblyLabel(left_block)); 2343864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(chunk_->GetAssemblyLabel(right_block)); 2344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2345864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgtemplate<class InstrType> 2349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::EmitFalseBranch(InstrType instr, Condition cc) { 2350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int false_block = instr->FalseDestination(chunk_); 2351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (cc == no_condition) { 2352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(chunk_->GetAssemblyLabel(false_block)); 2353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(cc, chunk_->GetAssemblyLabel(false_block)); 2355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2356864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoBranch(LBranch* instr) { 2360864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Representation r = instr->hydrogen()->value()->representation(); 2361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (r.IsSmiOrInteger32()) { 2362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = ToRegister(instr->value()); 2363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(reg, Operand(reg)); 2364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, not_zero); 2365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (r.IsDouble()) { 236606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register reg = ToX87Register(instr->value()); 236706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87LoadForUsage(reg); 236806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fldz(); 236906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ FCmp(); 237006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org EmitBranch(instr, not_zero); 2371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2372e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(r.IsTagged()); 2373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = ToRegister(instr->value()); 2374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HType type = instr->hydrogen()->value()->type(); 2375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (type.IsBoolean()) { 2376e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!info()->IsStub()); 2377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(reg, factory()->true_value()); 2378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, equal); 2379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (type.IsSmi()) { 2380e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!info()->IsStub()); 2381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(reg, Operand(reg)); 2382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, not_equal); 2383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (type.IsJSArray()) { 2384e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!info()->IsStub()); 2385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, no_condition); 2386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (type.IsHeapNumber()) { 2387864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 2388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (type.IsString()) { 2389e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!info()->IsStub()); 2390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); 2391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, not_equal); 2392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); 2394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); 2395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expected.Contains(ToBooleanStub::UNDEFINED)) { 2397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // undefined -> false. 2398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(reg, factory()->undefined_value()); 2399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, instr->FalseLabel(chunk_)); 2400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expected.Contains(ToBooleanStub::BOOLEAN)) { 2402864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // true -> true. 2403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(reg, factory()->true_value()); 2404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, instr->TrueLabel(chunk_)); 2405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // false -> false. 2406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(reg, factory()->false_value()); 2407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, instr->FalseLabel(chunk_)); 2408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expected.Contains(ToBooleanStub::NULL_TYPE)) { 2410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 'null' -> false. 2411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(reg, factory()->null_value()); 2412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, instr->FalseLabel(chunk_)); 2413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2415864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expected.Contains(ToBooleanStub::SMI)) { 2416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Smis: 0 -> false, all other -> true. 2417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(reg, Operand(reg)); 2418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, instr->FalseLabel(chunk_)); 2419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); 2420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (expected.NeedsMap()) { 2421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If we need a map later and have a Smi -> deopt. 2422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(reg, Immediate(kSmiTagMask)); 2423b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(zero, instr, "Smi"); 2424864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2425864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2426864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register map = no_reg; // Keep the compiler happy. 2427864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expected.NeedsMap()) { 2428864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org map = ToRegister(instr->temp()); 2429e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!map.is(reg)); 2430864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(map, FieldOperand(reg, HeapObject::kMapOffset)); 2431864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expected.CanBeUndetectable()) { 2433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Undetectable -> false. 2434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test_b(FieldOperand(map, Map::kBitFieldOffset), 2435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1 << Map::kIsUndetectable); 2436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, instr->FalseLabel(chunk_)); 2437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2440864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { 2441864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // spec object -> true. 2442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); 2443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(above_equal, instr->TrueLabel(chunk_)); 2444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expected.Contains(ToBooleanStub::STRING)) { 2447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // String value -> false iff empty. 2448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label not_string; 2449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); 2450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(above_equal, ¬_string, Label::kNear); 2451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); 2452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, instr->TrueLabel(chunk_)); 2453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(instr->FalseLabel(chunk_)); 2454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(¬_string); 2455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2456864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expected.Contains(ToBooleanStub::SYMBOL)) { 2458864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Symbol value -> true. 2459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpInstanceType(map, SYMBOL_TYPE); 2460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, instr->TrueLabel(chunk_)); 2461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2463864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { 2464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // heap number -> false iff +0, -0, or NaN. 2465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label not_heap_number; 2466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 2467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org factory()->heap_number_map()); 2468864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, ¬_heap_number, Label::kNear); 2469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fldz(); 2470864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); 2471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ FCmp(); 2472864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(zero, instr->FalseLabel(chunk_)); 2473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(instr->TrueLabel(chunk_)); 2474864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(¬_heap_number); 2475864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2476864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2477864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!expected.IsGeneric()) { 2478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We've seen something for the first time -> deopt. 2479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // This can only happen if we are not generic already. 2480b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(no_condition, instr, "unexpected object"); 2481864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2482864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2483864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2485864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2486864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2487864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::EmitGoto(int block) { 2488864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!IsNextEmittedBlock(block)) { 2489864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block))); 2490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2493864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2494864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoClobberDoubles(LClobberDoubles* instr) { 2495864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2496864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2497864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2498864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoGoto(LGoto* instr) { 2499864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitGoto(instr->block_id()); 2500864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2501864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2502864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2503864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgCondition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { 2504864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition cond = no_condition; 2505864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (op) { 2506864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::EQ: 2507864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::EQ_STRICT: 2508864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org cond = equal; 2509864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::NE: 2511864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::NE_STRICT: 2512864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org cond = not_equal; 2513864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2514864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::LT: 2515864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org cond = is_unsigned ? below : less; 2516864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2517864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::GT: 2518864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org cond = is_unsigned ? above : greater; 2519864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2520864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::LTE: 2521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org cond = is_unsigned ? below_equal : less_equal; 2522864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2523864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::GTE: 2524864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org cond = is_unsigned ? above_equal : greater_equal; 2525864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::IN: 2527864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::INSTANCEOF: 2528864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 2529864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 2530864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2531864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return cond; 2532864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2533864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2534864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2535864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) { 2536864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* left = instr->left(); 2537864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* right = instr->right(); 2538864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool is_unsigned = 25398ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org instr->is_double() || 25408ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org instr->hydrogen()->left()->CheckFlag(HInstruction::kUint32) || 25418ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org instr->hydrogen()->right()->CheckFlag(HInstruction::kUint32); 2542864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition cc = TokenToCondition(instr->op(), is_unsigned); 2543864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2544864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (left->IsConstantOperand() && right->IsConstantOperand()) { 2545864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We can statically evaluate the comparison. 2546864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org double left_val = ToDouble(LConstantOperand::cast(left)); 2547864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org double right_val = ToDouble(LConstantOperand::cast(right)); 2548864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int next_block = EvalComparison(instr->op(), left_val, right_val) ? 2549864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_); 2550864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitGoto(next_block); 2551864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2552864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->is_double()) { 2553864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87LoadForUsage(ToX87Register(right), ToX87Register(left)); 2554864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ FCmp(); 2555864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Don't base result on EFLAGS when a NaN is involved. Instead 2556864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // jump to the false block. 2557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(parity_even, instr->FalseLabel(chunk_)); 2558864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2559864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (right->IsConstantOperand()) { 2560864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ToOperand(left), 2561864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ToImmediate(right, instr->hydrogen()->representation())); 2562864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (left->IsConstantOperand()) { 2563864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ToOperand(right), 2564864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ToImmediate(left, instr->hydrogen()->representation())); 256538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // We commuted the operands, so commute the condition. 256638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org cc = CommuteCondition(cc); 2567864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ToRegister(left), ToOperand(right)); 2569864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2570864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, cc); 2572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2573864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2574864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 2577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register left = ToRegister(instr->left()); 2578864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2579864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->right()->IsConstantOperand()) { 2580864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right())); 2581864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObject(left, right); 2582864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2583864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand right = ToOperand(instr->right()); 2584864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(left, right); 2585864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2586864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, equal); 2587864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2588864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2589864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2590864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) { 2591864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->representation().IsTagged()) { 2592864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register input_reg = ToRegister(instr->object()); 2593864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(input_reg, factory()->the_hole_value()); 2594864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, equal); 2595864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 2596864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2597864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2598864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Put the value to the top of stack 2599864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register src = ToX87Register(instr->object()); 2600864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87LoadForUsage(src); 2601864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fld(0); 2602864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fld(0); 2603864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ FCmp(); 2604864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label ok; 2605864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(parity_even, &ok, Label::kNear); 2606864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fstp(0); 2607864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitFalseBranch(instr, no_condition); 2608864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&ok); 2609864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2610864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2611864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(esp, Immediate(kDoubleSize)); 2612864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fstp_d(MemOperand(esp, 0)); 2613864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2614864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(esp, Immediate(kDoubleSize)); 2615864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int offset = sizeof(kHoleNanUpper32); 2616864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(MemOperand(esp, -offset), Immediate(kHoleNanUpper32)); 2617864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, equal); 2618864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2619864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2620864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2621864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) { 2622864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Representation rep = instr->hydrogen()->value()->representation(); 2623e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!rep.IsInteger32()); 2624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2625864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (rep.IsDouble()) { 262606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register input = ToX87Register(instr->value()); 262706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87LoadForUsage(input); 262806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ FXamMinusZero(); 262906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org EmitBranch(instr, equal); 2630864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2631864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register value = ToRegister(instr->value()); 2632864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Map> map = masm()->isolate()->factory()->heap_number_map(); 2633864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CheckMap(value, map, instr->FalseLabel(chunk()), DO_SMI_CHECK); 2634864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(value, HeapNumber::kExponentOffset), 2635864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(0x1)); 2636864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitFalseBranch(instr, no_overflow); 2637864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(value, HeapNumber::kMantissaOffset), 2638864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(0x00000000)); 2639864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, equal); 2640864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2642864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2643864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2644864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgCondition LCodeGen::EmitIsObject(Register input, 2645864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp1, 2646864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* is_not_object, 2647864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* is_object) { 2648864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(input, is_not_object); 2649864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2650864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(input, isolate()->factory()->null_value()); 2651864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, is_object); 2652864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(temp1, FieldOperand(input, HeapObject::kMapOffset)); 2654864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Undetectable objects behave like undefined. 2655864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test_b(FieldOperand(temp1, Map::kBitFieldOffset), 2656864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1 << Map::kIsUndetectable); 2657864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, is_not_object); 2658864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2659864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ movzx_b(temp1, FieldOperand(temp1, Map::kInstanceTypeOffset)); 2660864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(temp1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); 2661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(below, is_not_object); 2662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(temp1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 2663864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return below_equal; 2664864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 2668864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = ToRegister(instr->value()); 2669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp = ToRegister(instr->temp()); 2670864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition true_cond = EmitIsObject( 2672864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org reg, temp, instr->FalseLabel(chunk_), instr->TrueLabel(chunk_)); 2673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2674864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, true_cond); 2675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2676864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgCondition LCodeGen::EmitIsString(Register input, 2679864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp1, 2680864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* is_not_string, 2681864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SmiCheck check_needed = INLINE_SMI_CHECK) { 2682864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (check_needed == INLINE_SMI_CHECK) { 2683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(input, is_not_string); 2684864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2685864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2686864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition cond = masm_->IsObjectStringType(input, temp1, temp1); 2687864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2688864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return cond; 2689864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2690864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2691864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2692864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { 2693864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = ToRegister(instr->value()); 2694864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp = ToRegister(instr->temp()); 2695864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2696864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SmiCheck check_needed = 2697eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org instr->hydrogen()->value()->type().IsHeapObject() 2698864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 2699864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2700864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition true_cond = EmitIsString( 2701864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org reg, temp, instr->FalseLabel(chunk_), check_needed); 2702864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2703864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, true_cond); 2704864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2705864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2706864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2707864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 2708864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand input = ToOperand(instr->value()); 2709864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2710864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(input, Immediate(kSmiTagMask)); 2711864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, zero); 2712864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2713864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2714864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2715864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 2716864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register input = ToRegister(instr->value()); 2717864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp = ToRegister(instr->temp()); 2718864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2719eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org if (!instr->hydrogen()->value()->type().IsHeapObject()) { 2720864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(kSmiTag == 0); 2721864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(input, instr->FalseLabel(chunk_)); 2722864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2723864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 2724864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test_b(FieldOperand(temp, Map::kBitFieldOffset), 2725864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1 << Map::kIsUndetectable); 2726864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, not_zero); 2727864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2728864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2729864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2730864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic Condition ComputeCompareCondition(Token::Value op) { 2731864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (op) { 2732864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::EQ_STRICT: 2733864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::EQ: 2734864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return equal; 2735864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::LT: 2736864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return less; 2737864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::GT: 2738864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return greater; 2739864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::LTE: 2740864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return less_equal; 2741864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::GTE: 2742864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return greater_equal; 2743864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 2744864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 2745864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return no_condition; 2746864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2747864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2748864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2749864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2750864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { 2751864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Token::Value op = instr->op(); 2752864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2753b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Handle<Code> ic = CodeFactory::CompareIC(isolate(), op).code(); 2754864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 2755864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2756864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition condition = ComputeCompareCondition(op); 2757864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(eax, Operand(eax)); 2758864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2759864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, condition); 2760864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2761864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2762864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2763864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic InstanceType TestType(HHasInstanceTypeAndBranch* instr) { 2764864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InstanceType from = instr->from(); 2765864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InstanceType to = instr->to(); 2766864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (from == FIRST_TYPE) return to; 2767e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(from == to || to == LAST_TYPE); 2768864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return from; 2769864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2771864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic Condition BranchCondition(HHasInstanceTypeAndBranch* instr) { 2773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InstanceType from = instr->from(); 2774864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InstanceType to = instr->to(); 2775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (from == to) return equal; 2776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (to == LAST_TYPE) return above_equal; 2777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (from == FIRST_TYPE) return below_equal; 2778864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 2779864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return equal; 2780864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2781864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2782864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2783864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 2784864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register input = ToRegister(instr->value()); 2785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp = ToRegister(instr->temp()); 2786864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2787eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org if (!instr->hydrogen()->value()->type().IsHeapObject()) { 2788864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(input, instr->FalseLabel(chunk_)); 2789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2790864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2791864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(input, TestType(instr->hydrogen()), temp); 2792864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, BranchCondition(instr->hydrogen())); 2793864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2796864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 2797864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register input = ToRegister(instr->value()); 2798864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 2799864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2800864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ AssertString(input); 2801864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2802864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, FieldOperand(input, String::kHashFieldOffset)); 2803864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ IndexFromHash(result, result); 2804864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2805864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2806864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2807864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoHasCachedArrayIndexAndBranch( 2808864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LHasCachedArrayIndexAndBranch* instr) { 2809864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register input = ToRegister(instr->value()); 2810864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2811864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(FieldOperand(input, String::kHashFieldOffset), 2812864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(String::kContainsCachedArrayIndexMask)); 2813864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, equal); 2814864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2815864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2816864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2817864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Branches to a label or falls through with the answer in the z flag. Trashes 2818864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// the temp registers, but not the input. 2819864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::EmitClassOfTest(Label* is_true, 2820864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* is_false, 2821864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<String>class_name, 2822864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register input, 2823864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp, 2824864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp2) { 2825e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!input.is(temp)); 2826e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!input.is(temp2)); 2827e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!temp.is(temp2)); 2828864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(input, is_false); 2829864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 28305e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org if (String::Equals(isolate()->factory()->Function_string(), class_name)) { 2831864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Assuming the following assertions, we can use the same compares to test 2832864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // for both being a function type and being in the object type range. 2833864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); 2834864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == 2835864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FIRST_SPEC_OBJECT_TYPE + 1); 2836864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == 2837864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LAST_SPEC_OBJECT_TYPE - 1); 2838864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); 2839864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(input, FIRST_SPEC_OBJECT_TYPE, temp); 2840864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(below, is_false); 2841864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, is_true); 2842864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpInstanceType(temp, LAST_SPEC_OBJECT_TYPE); 2843864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, is_true); 2844864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2845864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Faster code path to avoid two compares: subtract lower bound from the 2846864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // actual type and do a signed compare with the width of the type range. 2847864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 2848864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ movzx_b(temp2, FieldOperand(temp, Map::kInstanceTypeOffset)); 2849864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(Operand(temp2), Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 2850864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(Operand(temp2), Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - 2851864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 2852864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(above, is_false); 2853864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2854864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2855864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range. 2856864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if the constructor in the map is a function. 2857864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(temp, FieldOperand(temp, Map::kConstructorOffset)); 2858864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Objects with a non-function constructor have class 'Object'. 2859864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(temp, JS_FUNCTION_TYPE, temp2); 28605e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org if (String::Equals(class_name, isolate()->factory()->Object_string())) { 2861864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, is_true); 2862864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2863864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, is_false); 2864864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2865864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2866864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // temp now contains the constructor function. Grab the 2867864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // instance class name from there. 2868864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(temp, FieldOperand(temp, JSFunction::kSharedFunctionInfoOffset)); 2869864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(temp, FieldOperand(temp, 2870864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SharedFunctionInfo::kInstanceClassNameOffset)); 2871864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The class name we are testing against is internalized since it's a literal. 2872864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The name in the constructor is internalized because of the way the context 2873864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // is booted. This routine isn't expected to work for random API-created 2874864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // classes and it doesn't have to because you can't access it with natives 2875864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // syntax. Since both sides are internalized it is sufficient to use an 2876864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // identity comparison. 2877864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(temp, class_name); 2878864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // End with the answer in the z flag. 2879864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2880864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2881864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2882864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 2883864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register input = ToRegister(instr->value()); 2884864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp = ToRegister(instr->temp()); 2885864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp2 = ToRegister(instr->temp2()); 2886864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2887864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<String> class_name = instr->hydrogen()->class_name(); 2888864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2889864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), 2890864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org class_name, input, temp, temp2); 2891864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2892864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, equal); 2893864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2894864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2895864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2896864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 2897864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = ToRegister(instr->value()); 2898864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); 2899864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, equal); 2900864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2901864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2902864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2903864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoInstanceOf(LInstanceOf* instr) { 2904864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Object and function are in fixed registers defined by the stub. 2905e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 2906864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InstanceofStub stub(isolate(), InstanceofStub::kArgsInRegisters); 2907864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 2908864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2909864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label true_value, done; 2910864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(eax, Operand(eax)); 2911864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(zero, &true_value, Label::kNear); 2912864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ToRegister(instr->result()), factory()->false_value()); 2913864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 2914864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&true_value); 2915864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ToRegister(instr->result()), factory()->true_value()); 2916864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 2917864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2918864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2919864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2920864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { 2921ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredInstanceOfKnownGlobal FINAL : public LDeferredCode { 2922864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 2923864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredInstanceOfKnownGlobal(LCodeGen* codegen, 2924864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LInstanceOfKnownGlobal* instr, 2925864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const X87Stack& x87_stack) 2926864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : LDeferredCode(codegen, x87_stack), instr_(instr) { } 2927ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 2928864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_); 2929864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2930ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 2931864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* map_check() { return &map_check_; } 2932864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 2933864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LInstanceOfKnownGlobal* instr_; 2934864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label map_check_; 2935864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 2936864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2937864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredInstanceOfKnownGlobal* deferred; 2938864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr, x87_stack_); 2939864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2940864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done, false_result; 2941864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register object = ToRegister(instr->value()); 2942864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp = ToRegister(instr->temp()); 2943864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2944864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // A Smi is not an instance of anything. 2945864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(object, &false_result, Label::kNear); 2946864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2947864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // This is the inlined call site instanceof cache. The two occurences of the 2948864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // hole value will be patched to the last map/result pair generated by the 2949864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // instanceof stub. 2950864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label cache_miss; 2951864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register map = ToRegister(instr->temp()); 2952864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(map, FieldOperand(object, HeapObject::kMapOffset)); 2953864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(deferred->map_check()); // Label for calculating code patching. 2954864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Cell> cache_cell = factory()->NewCell(factory()->the_hole_value()); 2955864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(map, Operand::ForCell(cache_cell)); // Patched to cached map. 2956864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &cache_miss, Label::kNear); 2957864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, factory()->the_hole_value()); // Patched to either true or false. 2958864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 2959864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2960864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The inlined call site cache did not match. Check for null and string 2961864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // before calling the deferred code. 2962864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&cache_miss); 2963864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Null is not an instance of anything. 2964864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(object, factory()->null_value()); 2965864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &false_result, Label::kNear); 2966864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2967864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // String values are not instances of anything. 2968864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition is_string = masm_->IsObjectStringType(object, temp, temp); 2969864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(is_string, &false_result, Label::kNear); 2970864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2971864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Go to the deferred code. 2972864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(deferred->entry()); 2973864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2974864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&false_result); 2975864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ToRegister(instr->result()), factory()->false_value()); 2976864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2977864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Here result has either true or false. Deferred code also produces true or 2978864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // false object. 2979864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(deferred->exit()); 2980864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 2981864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2982864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2983864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2984864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, 2985864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* map_check) { 2986864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PushSafepointRegistersScope scope(this); 2987864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2988864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InstanceofStub::Flags flags = InstanceofStub::kNoFlags; 2989864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org flags = static_cast<InstanceofStub::Flags>( 2990864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org flags | InstanceofStub::kArgsInRegisters); 2991864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org flags = static_cast<InstanceofStub::Flags>( 2992864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org flags | InstanceofStub::kCallSiteInlineCheck); 2993864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org flags = static_cast<InstanceofStub::Flags>( 2994864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org flags | InstanceofStub::kReturnTrueFalseObject); 2995864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InstanceofStub stub(isolate(), flags); 2996864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2997864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the temp register reserved by the instruction. This needs to be a 2998864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // register which is pushed last by PushSafepointRegisters as top of the 2999864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // stack is used to pass the offset to the location of the map check to 3000864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the stub. 3001864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp = ToRegister(instr->temp()); 3002e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(MacroAssembler::SafepointRegisterStackIndex(temp) == 0); 3003864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadHeapObject(InstanceofStub::right(), instr->function()); 3004864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const int kAdditionalDelta = 13; 3005864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; 3006864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(temp, Immediate(delta)); 3007864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ StoreToSafepointRegisterSlot(temp, temp); 3008864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCodeGeneric(stub.GetCode(), 3009864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RelocInfo::CODE_TARGET, 3010864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr, 3011864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 3012864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the deoptimization index of the LLazyBailout-environment that 3013864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // corresponds to this instruction. 3014864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); 3015864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 3016864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3017864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Put the result value into the eax slot and restore all registers. 3018864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ StoreToSafepointRegisterSlot(eax, eax); 3019864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3020864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3021864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3022864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoCmpT(LCmpT* instr) { 3023864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Token::Value op = instr->op(); 3024864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3025b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Handle<Code> ic = CodeFactory::CompareIC(isolate(), op).code(); 3026864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 3027864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3028864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition condition = ComputeCompareCondition(op); 3029864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label true_value, done; 3030864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(eax, Operand(eax)); 3031864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(condition, &true_value, Label::kNear); 3032864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ToRegister(instr->result()), factory()->false_value()); 3033864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 3034864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&true_value); 3035864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ToRegister(instr->result()), factory()->true_value()); 3036864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 3037864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3038864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3039864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3040864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::EmitReturn(LReturn* instr, bool dynamic_frame_alignment) { 3041864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int extra_value_count = dynamic_frame_alignment ? 2 : 1; 3042864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3043864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->has_constant_parameter_count()) { 3044864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int parameter_count = ToInteger32(instr->constant_parameter_count()); 3045864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (dynamic_frame_alignment && FLAG_debug_code) { 3046864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(Operand(esp, 3047864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (parameter_count + extra_value_count) * kPointerSize), 3048864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(kAlignmentZapValue)); 3049864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Assert(equal, kExpectedAlignmentMarker); 3050864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3051864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Ret((parameter_count + extra_value_count) * kPointerSize, ecx); 3052864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 3053864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = ToRegister(instr->parameter_count()); 3054864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The argument count parameter is a smi 3055864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(reg); 3056864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register return_addr_reg = reg.is(ecx) ? ebx : ecx; 3057864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (dynamic_frame_alignment && FLAG_debug_code) { 3058e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(extra_value_count == 2); 3059864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(Operand(esp, reg, times_pointer_size, 3060864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org extra_value_count * kPointerSize), 3061864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(kAlignmentZapValue)); 3062864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Assert(equal, kExpectedAlignmentMarker); 3063864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3064864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3065864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // emit code to restore stack based on instr->parameter_count() 3066864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(return_addr_reg); // save return address 3067864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (dynamic_frame_alignment) { 3068864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ inc(reg); // 1 more for alignment 3069864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3070864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shl(reg, kPointerSizeLog2); 3071864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(esp, reg); 3072864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(return_addr_reg); 3073864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3074864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3075864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3076864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3077864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoReturn(LReturn* instr) { 3078864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_trace && info()->IsOptimizing()) { 3079864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Preserve the return value on the stack and rely on the runtime call 3080864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // to return the value in the same register. We're leaving the code 3081864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // managed by the register allocator and tearing down the frame, it's 3082864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // safe to write to the context register. 3083864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); 3084864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3085864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallRuntime(Runtime::kTraceExit, 1); 3086864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3087864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (dynamic_frame_alignment_) { 3088864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Fetch the state of the dynamic frame alignment. 3089864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, Operand(ebp, 3090864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org JavaScriptFrameConstants::kDynamicAlignmentStateOffset)); 3091864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3092864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int no_frame_start = -1; 3093864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (NeedsEagerFrame()) { 3094864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esp, ebp); 3095864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(ebp); 3096864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org no_frame_start = masm_->pc_offset(); 3097864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3098864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (dynamic_frame_alignment_) { 3099864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label no_padding; 3100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(edx, Immediate(kNoAlignmentPadding)); 3101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &no_padding, Label::kNear); 3102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitReturn(instr, true); 3104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&no_padding); 3105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitReturn(instr, false); 3108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (no_frame_start != -1) { 3109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org info()->AddNoFrameRange(no_frame_start, masm_->pc_offset()); 3110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { 3115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 3116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, Operand::ForCell(instr->hydrogen()->cell().handle())); 3117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 3118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(result, factory()->the_hole_value()); 3119b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(equal, instr, "hole"); 3120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3124fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgtemplate <class T> 3125fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgvoid LCodeGen::EmitVectorLoadICRegisters(T* instr) { 3126fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org DCHECK(FLAG_vector_ics); 3127fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org Register vector = ToRegister(instr->temp_vector()); 312842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org DCHECK(vector.is(VectorLoadICDescriptor::VectorRegister())); 3129fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org __ mov(vector, instr->hydrogen()->feedback_vector()); 3130fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org // No need to allocate this register. 313142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org DCHECK(VectorLoadICDescriptor::SlotRegister().is(eax)); 313242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(VectorLoadICDescriptor::SlotRegister(), 3133fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org Immediate(Smi::FromInt(instr->hydrogen()->slot()))); 3134fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org} 3135fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org 3136fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org 3137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { 3138e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 31397b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org DCHECK(ToRegister(instr->global_object()) 314042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org .is(LoadDescriptor::ReceiverRegister())); 3141e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(eax)); 3142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 314342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::NameRegister(), instr->name()); 31447c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org if (FLAG_vector_ics) { 3145fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr); 31467c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } 3147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; 3148b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Handle<Code> ic = CodeFactory::LoadIC(isolate(), mode).code(); 3149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 3150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { 3154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register value = ToRegister(instr->value()); 3155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<PropertyCell> cell_handle = instr->hydrogen()->cell().handle(); 3156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the cell we are storing to contains the hole it could have 3158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // been deleted from the property dictionary. In that case, we need 3159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // to update the property details in the property dictionary to mark 3160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // it as no longer deleted. We deoptimize in that case. 3161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 3162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(Operand::ForCell(cell_handle), factory()->the_hole_value()); 3163b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(equal, instr, "hole"); 3164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Store the value. 3167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand::ForCell(cell_handle), value); 3168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Cells are always rescanned, so no write barrier here. 3169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { 3173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register context = ToRegister(instr->context()); 3174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 3175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, ContextOperand(context, instr->slot_index())); 3176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 3178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(result, factory()->the_hole_value()); 3179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->DeoptimizesOnHole()) { 3180b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(equal, instr, "hole"); 3181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 3182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label is_not_hole; 3183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &is_not_hole, Label::kNear); 3184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, factory()->undefined_value()); 3185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&is_not_hole); 3186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { 3192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register context = ToRegister(instr->context()); 3193864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register value = ToRegister(instr->value()); 3194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label skip_assignment; 3196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand target = ContextOperand(context, instr->slot_index()); 3198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 3199864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(target, factory()->the_hole_value()); 3200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->DeoptimizesOnHole()) { 3201b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(equal, instr, "hole"); 3202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 3203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &skip_assignment, Label::kNear); 3204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(target, value); 3208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->NeedsWriteBarrier()) { 3209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SmiCheck check_needed = 3210eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org instr->hydrogen()->value()->type().IsHeapObject() 3211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 3212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp = ToRegister(instr->temp()); 3213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int offset = Context::SlotOffset(instr->slot_index()); 321406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ RecordWriteContextSlot(context, offset, value, temp, kSaveFPRegs, 321506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org EMIT_REMEMBERED_SET, check_needed); 3216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&skip_assignment); 3219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 3223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HObjectAccess access = instr->hydrogen()->access(); 3224864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int offset = access.offset(); 3225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3226864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (access.IsExternalMemory()) { 3227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 3228864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org MemOperand operand = instr->object()->IsConstantOperand() 3229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? MemOperand::StaticVariable(ToExternalReference( 3230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LConstantOperand::cast(instr->object()))) 3231864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : MemOperand(ToRegister(instr->object()), offset); 3232864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Load(result, operand, access.representation()); 3233864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 3234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3236864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register object = ToRegister(instr->object()); 3237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->representation().IsDouble()) { 3238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Mov(ToX87Register(instr->result()), FieldOperand(object, offset)); 3239864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 3240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3241864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3242864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 3243864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!access.IsInobject()) { 3244864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset)); 3245864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org object = result; 3246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Load(result, FieldOperand(object, offset), access.representation()); 3248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3249864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::EmitPushTaggedOperand(LOperand* operand) { 3252e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!operand->IsDoubleRegister()); 3253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (operand->IsConstantOperand()) { 3254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Object> object = ToHandle(LConstantOperand::cast(operand)); 3255864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AllowDeferredHandleDereference smi_check; 3256864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (object->IsSmi()) { 3257864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Push(Handle<Smi>::cast(object)); 3258864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 3259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ PushHeapObject(Handle<HeapObject>::cast(object)); 3260864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3261864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (operand->IsRegister()) { 3262864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(ToRegister(operand)); 3263864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 3264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(ToOperand(operand)); 3265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { 3270e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 327142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister())); 3272e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(eax)); 3273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 327442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::NameRegister(), instr->name()); 32757c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org if (FLAG_vector_ics) { 3276fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr); 32777c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } 3278b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Handle<Code> ic = CodeFactory::LoadIC(isolate(), NOT_CONTEXTUAL).code(); 3279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 3280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { 3284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register function = ToRegister(instr->function()); 3285864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp = ToRegister(instr->temp()); 3286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 3287864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3288864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the prototype or initial map from the function. 3289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, 3290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 3291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the function has a prototype or an initial map. 3293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(Operand(result), Immediate(factory()->the_hole_value())); 3294b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(equal, instr, "hole"); 3295864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the function does not have an initial map, we're done. 3297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 3298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(result, MAP_TYPE, temp); 3299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &done, Label::kNear); 3300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the prototype from the initial map. 3302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, FieldOperand(result, Map::kPrototypeOffset)); 3303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // All done. 3305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 3306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoLoadRoot(LLoadRoot* instr) { 3310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 3311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadRoot(result, instr->index()); 3312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 3316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register arguments = ToRegister(instr->arguments()); 3317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 3318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->length()->IsConstantOperand() && 3319864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->index()->IsConstantOperand()) { 3320864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int const_index = ToInteger32(LConstantOperand::cast(instr->index())); 3321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int const_length = ToInteger32(LConstantOperand::cast(instr->length())); 3322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int index = (const_length - const_index) + 1; 3323864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, Operand(arguments, index * kPointerSize)); 3324864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 3325864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register length = ToRegister(instr->length()); 3326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand index = ToOperand(instr->index()); 3327864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // There are two words between the frame pointer and the last argument. 3328864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Subtracting from length accounts for one of them add one more. 3329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(length, index); 3330864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, Operand(arguments, length, times_4, kPointerSize)); 3331864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3332864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { 3336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ElementsKind elements_kind = instr->elements_kind(); 3337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* key = instr->key(); 3338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!key->IsConstantOperand() && 3339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), 3340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org elements_kind)) { 3341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(ToRegister(key)); 3342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3343864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand operand(BuildFastArrayOperand( 3344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->elements(), 3345864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org key, 3346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->key()->representation(), 3347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org elements_kind, 3348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->base_offset())); 3349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || 3350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org elements_kind == FLOAT32_ELEMENTS) { 3351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Mov(ToX87Register(instr->result()), operand, kX87FloatOperand); 3352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || 3353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org elements_kind == FLOAT64_ELEMENTS) { 3354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Mov(ToX87Register(instr->result()), operand); 3355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 3356864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result(ToRegister(instr->result())); 3357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (elements_kind) { 3358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case EXTERNAL_INT8_ELEMENTS: 3359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case INT8_ELEMENTS: 3360864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ movsx_b(result, operand); 3361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 3362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case EXTERNAL_UINT8_CLAMPED_ELEMENTS: 3363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case EXTERNAL_UINT8_ELEMENTS: 3364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case UINT8_ELEMENTS: 3365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case UINT8_CLAMPED_ELEMENTS: 3366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ movzx_b(result, operand); 3367864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 3368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case EXTERNAL_INT16_ELEMENTS: 3369864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case INT16_ELEMENTS: 3370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ movsx_w(result, operand); 3371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 3372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case EXTERNAL_UINT16_ELEMENTS: 3373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case UINT16_ELEMENTS: 3374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ movzx_w(result, operand); 3375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 3376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case EXTERNAL_INT32_ELEMENTS: 3377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case INT32_ELEMENTS: 3378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, operand); 3379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 3380864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case EXTERNAL_UINT32_ELEMENTS: 3381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case UINT32_ELEMENTS: 3382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, operand); 3383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { 3384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(result, Operand(result)); 3385b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(negative, instr, "negative value"); 3386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3387864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 3388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case EXTERNAL_FLOAT32_ELEMENTS: 3389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case EXTERNAL_FLOAT64_ELEMENTS: 3390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case FLOAT32_ELEMENTS: 3391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case FLOAT64_ELEMENTS: 3392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case FAST_SMI_ELEMENTS: 3393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case FAST_ELEMENTS: 3394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case FAST_DOUBLE_ELEMENTS: 3395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case FAST_HOLEY_SMI_ELEMENTS: 3396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case FAST_HOLEY_ELEMENTS: 3397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case FAST_HOLEY_DOUBLE_ELEMENTS: 3398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case DICTIONARY_ELEMENTS: 3399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case SLOPPY_ARGUMENTS_ELEMENTS: 3400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 3401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 3402864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { 3408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 3409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand hole_check_operand = BuildFastArrayOperand( 3410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->elements(), instr->key(), 3411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->key()->representation(), 3412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FAST_DOUBLE_ELEMENTS, 3413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->base_offset() + sizeof(kHoleNanLower32)); 3414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(hole_check_operand, Immediate(kHoleNanUpper32)); 3415b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(equal, instr, "hole"); 3416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand double_load_operand = BuildFastArrayOperand( 3419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->elements(), 3420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->key(), 3421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->key()->representation(), 3422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FAST_DOUBLE_ELEMENTS, 3423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->base_offset()); 3424864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Mov(ToX87Register(instr->result()), double_load_operand); 3425864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3426864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3427864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3428864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 3429864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 3430864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3431864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load the result. 3432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, 3433b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org BuildFastArrayOperand(instr->elements(), instr->key(), 3434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->key()->representation(), 3435b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org FAST_ELEMENTS, instr->base_offset())); 3436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for the hole value. 3438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->RequiresHoleCheck()) { 3439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { 3440864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(result, Immediate(kSmiTagMask)); 3441b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_equal, instr, "not a Smi"); 3442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 3443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(result, factory()->the_hole_value()); 3444b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(equal, instr, "hole"); 3445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { 3451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->is_typed_elements()) { 3452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DoLoadKeyedExternalArray(instr); 3453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (instr->hydrogen()->representation().IsDouble()) { 3454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DoLoadKeyedFixedDoubleArray(instr); 3455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 3456864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DoLoadKeyedFixedArray(instr); 3457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3458864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgOperand LCodeGen::BuildFastArrayOperand( 3462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* elements_pointer, 3463864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* key, 3464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Representation key_representation, 3465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ElementsKind elements_kind, 3466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org uint32_t base_offset) { 3467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register elements_pointer_reg = ToRegister(elements_pointer); 3468864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int element_shift_size = ElementsKindToShiftSize(elements_kind); 3469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int shift_size = element_shift_size; 3470864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (key->IsConstantOperand()) { 3471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int constant_value = ToInteger32(LConstantOperand::cast(key)); 3472864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (constant_value & 0xF0000000) { 3473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Abort(kArrayIndexConstantValueTooBig); 3474864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3475864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return Operand(elements_pointer_reg, 3476864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ((constant_value) << shift_size) 3477864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org + base_offset); 3478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 3479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Take the tag bit into account while computing the shift size. 3480864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (key_representation.IsSmi() && (shift_size >= 1)) { 3481864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org shift_size -= kSmiTagSize; 3482864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3483864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); 3484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return Operand(elements_pointer_reg, 3485864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ToRegister(key), 3486864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org scale_factor, 3487864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org base_offset); 3488864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3489864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { 3493e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 349442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister())); 349542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org DCHECK(ToRegister(instr->key()).is(LoadDescriptor::NameRegister())); 3496864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 34977c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org if (FLAG_vector_ics) { 3498fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr); 34997c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } 35007c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org 3501b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); 3502864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 3503864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3504864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3505864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3506864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { 3507864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 3508864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3509864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->from_inlined()) { 3510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(result, Operand(esp, -2 * kPointerSize)); 3511864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 3512864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for arguments adapter frame. 3513864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done, adapted; 3514864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 3515864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, Operand(result, StandardFrameConstants::kContextOffset)); 3516864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(Operand(result), 3517864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 3518864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &adapted, Label::kNear); 3519864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3520864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // No arguments adaptor frame. 3521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, Operand(ebp)); 3522864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 3523864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3524864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Arguments adaptor frame present. 3525864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&adapted); 3526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 3527864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3528864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Result is the frame pointer for the frame if not adapted and for the real 3529864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // frame below the adaptor frame if adapted. 3530864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 3531864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3532864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3533864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3534864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3535864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { 3536864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand elem = ToOperand(instr->elements()); 3537864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 3538864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3539864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 3540864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3541864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If no arguments adaptor frame the number of arguments is fixed. 3542864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ebp, elem); 3543864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, Immediate(scope()->num_parameters())); 3544864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &done, Label::kNear); 3545864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3546864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Arguments adaptor frame present. Get argument length from there. 3547864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 3548864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, Operand(result, 3549864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ArgumentsAdaptorFrameConstants::kLengthOffset)); 3550864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(result); 3551864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3552864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Argument length is in result register. 3553864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 3554864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3555864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3556864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { 3558864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register receiver = ToRegister(instr->receiver()); 3559864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register function = ToRegister(instr->function()); 3560864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3561864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the receiver is null or undefined, we have to pass the global 3562864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // object as a receiver to normal functions. Values have to be 3563864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // passed unchanged to builtins and strict-mode functions. 3564864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label receiver_ok, global_object; 3565864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; 3566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch = ToRegister(instr->temp()); 3567864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!instr->hydrogen()->known_function()) { 3569864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Do not transform the receiver to object for strict mode 3570864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // functions. 3571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch, 3572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 3573864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test_b(FieldOperand(scratch, SharedFunctionInfo::kStrictModeByteOffset), 3574864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1 << SharedFunctionInfo::kStrictModeBitWithinByte); 3575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &receiver_ok, dist); 3576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Do not transform the receiver to object for builtins. 3578864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test_b(FieldOperand(scratch, SharedFunctionInfo::kNativeByteOffset), 3579864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1 << SharedFunctionInfo::kNativeBitWithinByte); 3580864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &receiver_ok, dist); 3581864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3582864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3583864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Normal function. Replace undefined or null with global receiver. 3584864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(receiver, factory()->null_value()); 3585864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &global_object, Label::kNear); 3586864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(receiver, factory()->undefined_value()); 3587864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &global_object, Label::kNear); 3588864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3589864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The receiver should be a JS object. 3590864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(receiver, Immediate(kSmiTagMask)); 3591b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(equal, instr, "Smi"); 3592864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, scratch); 3593b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(below, instr, "not a JavaScript object"); 3594864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3595864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&receiver_ok, Label::kNear); 3596864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&global_object); 3597864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(receiver, FieldOperand(function, JSFunction::kContextOffset)); 3598864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const int global_offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX); 3599864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(receiver, Operand(receiver, global_offset)); 3600d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org const int proxy_offset = GlobalObject::kGlobalProxyOffset; 3601d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org __ mov(receiver, FieldOperand(receiver, proxy_offset)); 3602864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&receiver_ok); 3603864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3604864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3605864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3606864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoApplyArguments(LApplyArguments* instr) { 3607864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register receiver = ToRegister(instr->receiver()); 3608864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register function = ToRegister(instr->function()); 3609864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register length = ToRegister(instr->length()); 3610864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register elements = ToRegister(instr->elements()); 3611e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(receiver.is(eax)); // Used for parameter count. 3612e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(function.is(edi)); // Required by InvokeFunction. 3613e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(eax)); 3614864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3615864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Copy the arguments to this function possibly from the 3616864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // adaptor frame below it. 3617864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const uint32_t kArgumentsLimit = 1 * KB; 3618864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(length, kArgumentsLimit); 3619b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(above, instr, "too many arguments"); 3620864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3621864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(receiver); 3622864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(receiver, length); 3623864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Loop through the arguments pushing them onto the execution 3625864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // stack. 3626864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label invoke, loop; 3627864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // length is a small non-negative integer, due to the test above. 3628864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(length, Operand(length)); 3629864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(zero, &invoke, Label::kNear); 3630864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&loop); 3631864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize)); 3632864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ dec(length); 3633864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, &loop); 3634864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3635864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Invoke the function. 3636864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&invoke); 3637e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->HasPointerMap()); 3638864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LPointerMap* pointers = instr->pointer_map(); 3639864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SafepointGenerator safepoint_generator( 3640864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org this, pointers, Safepoint::kLazyDeopt); 3641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ParameterCount actual(eax); 3642864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ InvokeFunction(function, actual, CALL_FUNCTION, safepoint_generator); 3643864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3644864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3645864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3646864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDebugBreak(LDebugBreak* instr) { 3647864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ int3(); 3648864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3649864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3650864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3651864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoPushArgument(LPushArgument* instr) { 3652864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* argument = instr->value(); 3653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitPushTaggedOperand(argument); 3654864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3655864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3656864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3657864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDrop(LDrop* instr) { 3658864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Drop(instr->count()); 3659864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3660864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoThisFunction(LThisFunction* instr) { 3663864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 3664864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 3665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3668864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoContext(LContext* instr) { 3669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 3670864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (info()->IsOptimizing()) { 3671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, Operand(ebp, StandardFrameConstants::kContextOffset)); 3672864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 3673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If there is no frame, the context must be in esi. 3674e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result.is(esi)); 3675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3676864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3679864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { 3680e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 3681864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(esi); // The context is the first argument. 3682864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(instr->hydrogen()->pairs())); 3683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(instr->hydrogen()->flags()))); 368447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org CallRuntime(Runtime::kDeclareGlobals, 3, instr); 3685864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3686864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3687864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3688864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::CallKnownFunction(Handle<JSFunction> function, 3689864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int formal_parameter_count, 3690864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int arity, 3691864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LInstruction* instr, 3692864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EDIState edi_state) { 3693864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool dont_adapt_arguments = 3694864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; 3695864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool can_invoke_directly = 3696864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org dont_adapt_arguments || formal_parameter_count == arity; 3697864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3698864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (can_invoke_directly) { 3699864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (edi_state == EDI_UNINITIALIZED) { 3700864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadHeapObject(edi, function); 3701864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3702864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3703864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Change context. 3704864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 3705864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3706864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Set eax to arguments count if adaption is not needed. Assumes that eax 3707864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // is available to write to at this point. 3708864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (dont_adapt_arguments) { 3709864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, arity); 3710864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3711864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3712864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Invoke function directly. 3713864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (function.is_identical_to(info()->closure())) { 3714864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallSelf(); 3715864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 3716864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset)); 3717864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3718864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 3719864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 3720864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We need to adapt arguments. 3721864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LPointerMap* pointers = instr->pointer_map(); 3722864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SafepointGenerator generator( 3723864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org this, pointers, Safepoint::kLazyDeopt); 3724864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ParameterCount count(arity); 3725864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ParameterCount expected(formal_parameter_count); 3726864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ InvokeFunction(function, expected, count, CALL_FUNCTION, generator); 3727864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3728864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3729864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3730864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3731b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.orgvoid LCodeGen::DoTailCallThroughMegamorphicCache( 3732b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org LTailCallThroughMegamorphicCache* instr) { 3733b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Register receiver = ToRegister(instr->receiver()); 3734b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Register name = ToRegister(instr->name()); 3735b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org DCHECK(receiver.is(LoadDescriptor::ReceiverRegister())); 3736b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org DCHECK(name.is(LoadDescriptor::NameRegister())); 3737b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org 3738b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Register scratch = ebx; 3739b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Register extra = eax; 3740b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org DCHECK(!scratch.is(receiver) && !scratch.is(name)); 3741b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org DCHECK(!extra.is(receiver) && !extra.is(name)); 3742b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org 3743b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // Important for the tail-call. 3744b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org bool must_teardown_frame = NeedsEagerFrame(); 3745b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org 3746b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // The probe will tail call to a handler if found. 3747b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(), 3748b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org must_teardown_frame, receiver, name, 3749b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org scratch, extra); 3750b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org 3751b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // Tail call to miss if we ended up here. 3752b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org if (must_teardown_frame) __ leave(); 3753b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org LoadIC::GenerateMiss(masm()); 3754b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org} 3755b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org 3756b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org 3757864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { 3758e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(eax)); 3759864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3760864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LPointerMap* pointers = instr->pointer_map(); 3761864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 3762864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3763864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->target()->IsConstantOperand()) { 3764864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LConstantOperand* target = LConstantOperand::cast(instr->target()); 3765864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Code> code = Handle<Code>::cast(ToHandle(target)); 3766864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET)); 3767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ call(code, RelocInfo::CODE_TARGET); 3768864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 3769e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->target()->IsRegister()); 3770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register target = ToRegister(instr->target()); 3771864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org generator.BeforeCall(__ CallSize(Operand(target))); 3772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(target, Immediate(Code::kHeaderSize - kHeapObjectTag)); 3773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ call(target); 3774864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org generator.AfterCall(); 3776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3778864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3779864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { 3780e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->function()).is(edi)); 3781e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(eax)); 3782864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3783864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->pass_argument_count()) { 3784864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, instr->arity()); 3785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3786864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3787864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Change context. 3788864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 3789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3790864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool is_self_call = false; 3791864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->function()->IsConstant()) { 3792864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HConstant* fun_const = HConstant::cast(instr->hydrogen()->function()); 3793864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<JSFunction> jsfun = 3794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<JSFunction>::cast(fun_const->handle(isolate())); 3795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org is_self_call = jsfun.is_identical_to(info()->closure()); 3796864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3797864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3798864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (is_self_call) { 3799864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallSelf(); 3800864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 3801864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset)); 3802864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3803864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3804864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 3805864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3806864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3807864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3808864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { 3809864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register input_reg = ToRegister(instr->value()); 3810864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 3811864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org factory()->heap_number_map()); 3812b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_equal, instr, "not a heap number"); 3813864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3814864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label slow, allocated, done; 3815864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register tmp = input_reg.is(eax) ? ecx : eax; 3816864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx; 3817864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3818864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Preserve the value of all registers. 3819864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PushSafepointRegistersScope scope(this); 3820864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3821864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 3822864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check the sign of the argument. If the argument is positive, just 3823864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // return it. We do not need to patch the stack since |input| and 3824864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // |result| are the same register and |input| will be restored 3825864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // unchanged by popping safepoint registers. 3826864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(tmp, Immediate(HeapNumber::kSignMask)); 3827864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(zero, &done, Label::kNear); 3828864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3829864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ AllocateHeapNumber(tmp, tmp2, no_reg, &slow); 3830864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&allocated, Label::kNear); 3831864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3832864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Slow case: Call the runtime system to do the number allocation. 3833864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&slow); 383447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, 3835864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr, instr->context()); 3836864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Set the pointer to the new heap number in tmp. 3837864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!tmp.is(eax)) __ mov(tmp, eax); 3838864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Restore input_reg after call to runtime. 3839864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadFromSafepointRegisterSlot(input_reg, input_reg); 3840864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3841864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&allocated); 3842864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 3843864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ and_(tmp2, ~HeapNumber::kSignMask); 3844864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(tmp, HeapNumber::kExponentOffset), tmp2); 3845864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kMantissaOffset)); 3846864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(tmp, HeapNumber::kMantissaOffset), tmp2); 3847864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ StoreToSafepointRegisterSlot(input_reg, tmp); 3848864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3849864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 3850864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3851864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3852864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3853864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { 3854864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register input_reg = ToRegister(instr->value()); 3855864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(input_reg, Operand(input_reg)); 3856864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label is_positive; 3857864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_sign, &is_positive, Label::kNear); 3858864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ neg(input_reg); // Sets flags. 3859b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(negative, instr, "overflow"); 3860864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&is_positive); 3861864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3862864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3863864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3864864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoMathAbs(LMathAbs* instr) { 3865864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Class for deferred case. 3866ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredMathAbsTaggedHeapNumber FINAL : public LDeferredCode { 3867864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 3868864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 3869864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LMathAbs* instr, 3870864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const X87Stack& x87_stack) 3871864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : LDeferredCode(codegen, x87_stack), instr_(instr) { } 3872ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 3873864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 3874864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3875ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 3876864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 3877864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LMathAbs* instr_; 3878864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 3879864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3880e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->value()->Equals(instr->result())); 3881864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Representation r = instr->hydrogen()->value()->representation(); 3882864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3883864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (r.IsDouble()) { 388406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register value = ToX87Register(instr->value()); 388506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Fxch(value); 388606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fabs(); 3887864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (r.IsSmiOrInteger32()) { 3888864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitIntegerMathAbs(instr); 3889864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { // Tagged case. 3890864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredMathAbsTaggedHeapNumber* deferred = 3891864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr, x87_stack_); 3892864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register input_reg = ToRegister(instr->value()); 3893864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Smi check. 3894864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfNotSmi(input_reg, deferred->entry()); 3895864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitIntegerMathAbs(instr); 3896864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(deferred->exit()); 3897864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3898864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3899864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3900864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3901864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoMathFloor(LMathFloor* instr) { 390206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register output_reg = ToRegister(instr->result()); 390306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register input_reg = ToX87Register(instr->value()); 390406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Fxch(input_reg); 390506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 390606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label not_minus_zero, done; 390706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Deoptimize on unordered. 390806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fldz(); 390906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld(1); 391006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ FCmp(); 3911b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(parity_even, instr, "NaN"); 391206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ j(below, ¬_minus_zero, Label::kNear); 391306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 391406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 391506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Check for negative zero. 391606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ j(not_equal, ¬_minus_zero, Label::kNear); 391706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // +- 0.0. 391806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld(0); 391906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ FXamSign(); 3920b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_zero, instr, "minus zero"); 392106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ Move(output_reg, Immediate(0)); 392206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ jmp(&done, Label::kFar); 392306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 392406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 392506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Positive input. 392606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // rc=01B, round down. 392706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(¬_minus_zero); 392806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fnclex(); 392906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ X87SetRC(0x0400); 393006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ sub(esp, Immediate(kPointerSize)); 393106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fist_s(Operand(esp, 0)); 393206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ pop(output_reg); 393306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ X87CheckIA(); 3934b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(equal, instr, "overflow"); 393506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fnclex(); 393606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ X87SetRC(0x0000); 393706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&done); 3938864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3939864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3940864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3941864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoMathRound(LMathRound* instr) { 394206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register input_reg = ToX87Register(instr->value()); 394306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register result = ToRegister(instr->result()); 394406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Fxch(input_reg); 394506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label below_one_half, below_minus_one_half, done; 394606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 394706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org ExternalReference one_half = ExternalReference::address_of_one_half(); 394806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org ExternalReference minus_one_half = 394906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org ExternalReference::address_of_minus_one_half(); 395006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 395106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld_d(Operand::StaticVariable(one_half)); 395206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld(1); 395306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ FCmp(); 395406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ j(carry, &below_one_half); 395506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 395606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Use rounds towards zero, since 0.5 <= x, we use floor(0.5 + x) 395706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld(0); 395806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fadd_d(Operand::StaticVariable(one_half)); 395906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // rc=11B, round toward zero. 396006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ X87SetRC(0x0c00); 396106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ sub(esp, Immediate(kPointerSize)); 396206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Clear exception bits. 396306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fnclex(); 396406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fistp_s(MemOperand(esp, 0)); 396506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Check overflow. 396606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ X87CheckIA(); 396706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ pop(result); 396806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(equal, instr, "conversion overflow"); 396906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fnclex(); 397006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Restore round mode. 397106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ X87SetRC(0x0000); 397206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ jmp(&done); 397306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 397406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&below_one_half); 397506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld_d(Operand::StaticVariable(minus_one_half)); 397606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld(1); 397706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ FCmp(); 397806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ j(carry, &below_minus_one_half); 397906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if 398006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // we can ignore the difference between a result of -0 and +0. 398106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 398206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // If the sign is positive, we return +0. 398306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld(0); 398406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ FXamSign(); 398506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_zero, instr, "minus zero"); 398606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 398706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ Move(result, Immediate(0)); 398806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ jmp(&done); 398906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 399006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&below_minus_one_half); 399106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld(0); 399206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fadd_d(Operand::StaticVariable(one_half)); 399306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // rc=01B, round down. 399406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ X87SetRC(0x0400); 399506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ sub(esp, Immediate(kPointerSize)); 399606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Clear exception bits. 399706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fnclex(); 399806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fistp_s(MemOperand(esp, 0)); 399906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Check overflow. 400006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ X87CheckIA(); 400106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ pop(result); 400206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(equal, instr, "conversion overflow"); 400306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fnclex(); 400406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Restore round mode. 400506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ X87SetRC(0x0000); 400606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 400706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&done); 4008864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4009864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4010864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4011f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.orgvoid LCodeGen::DoMathFround(LMathFround* instr) { 401206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register input_reg = ToX87Register(instr->value()); 401306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Fxch(input_reg); 401406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ sub(esp, Immediate(kPointerSize)); 401506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fstp_s(MemOperand(esp, 0)); 401606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Fld(MemOperand(esp, 0), kX87FloatOperand); 401706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ add(esp, Immediate(kPointerSize)); 4018f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org} 4019f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org 4020f116736e5fdd9974b8a15b5832b7022fe2e96634machenbach@chromium.org 4021864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoMathSqrt(LMathSqrt* instr) { 402234ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com X87Register input = ToX87Register(instr->value()); 402334ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com X87Register result_reg = ToX87Register(instr->result()); 402434ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com Register temp_result = ToRegister(instr->temp1()); 402534ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com Register temp = ToRegister(instr->temp2()); 402634ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com Label slow, done, smi, finish; 402734ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com DCHECK(result_reg.is(input)); 402834ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com 402934ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com // Store input into Heap number and call runtime function kMathExpRT. 403034ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com if (FLAG_inline_new) { 403134ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ AllocateHeapNumber(temp_result, temp, no_reg, &slow); 403234ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ jmp(&done, Label::kNear); 403334ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com } 403434ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com 403534ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com // Slow case: Call the runtime system to do the number allocation. 403634ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ bind(&slow); 403734ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com { 403834ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com // TODO(3095996): Put a valid pointer value in the stack slot where the 403934ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com // result register is stored, as this register is in the pointer map, but 404034ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com // contains an integer value. 404134ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ Move(temp_result, Immediate(0)); 404234ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com 404334ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com // Preserve the value of all registers. 404434ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com PushSafepointRegistersScope scope(this); 404534ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com 404634ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 404734ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 404834ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com RecordSafepointWithRegisters( 404934ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 405034ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ StoreToSafepointRegisterSlot(temp_result, eax); 405134ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com } 405234ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ bind(&done); 405334ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com X87LoadForUsage(input); 405434ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ fstp_d(FieldOperand(temp_result, HeapNumber::kValueOffset)); 405534ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com 405634ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com { 405734ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com // Preserve the value of all registers. 405834ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com PushSafepointRegistersScope scope(this); 405934ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com 406034ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 406134ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ push(temp_result); 406234ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ CallRuntimeSaveDoubles(Runtime::kMathSqrtRT); 4063ae4728945755838c8d6450f0a344eb4b583c4dd5weiliang.lin@intel.com RecordSafepointWithRegisters(instr->pointer_map(), 1, 4064ae4728945755838c8d6450f0a344eb4b583c4dd5weiliang.lin@intel.com Safepoint::kNoLazyDeopt); 406534ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ StoreToSafepointRegisterSlot(temp_result, eax); 406634ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com } 406734ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com X87PrepareToWrite(result_reg); 406834ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com // return value of MathExpRT is Smi or Heap Number. 406934ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ JumpIfSmi(temp_result, &smi); 407034ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com // Heap number(double) 407134ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ fld_d(FieldOperand(temp_result, HeapNumber::kValueOffset)); 407234ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ jmp(&finish); 407334ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com // SMI 407434ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ bind(&smi); 407534ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ SmiUntag(temp_result); 407634ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ push(temp_result); 407734ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ fild_s(MemOperand(esp, 0)); 407834ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ pop(temp_result); 407934ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ bind(&finish); 408034ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com X87CommitWrite(result_reg); 4081864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4082864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4083864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4084864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { 408506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register input_reg = ToX87Register(instr->value()); 408606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DCHECK(ToX87Register(instr->result()).is(input_reg)); 408706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Fxch(input_reg); 408806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Note that according to ECMA-262 15.8.2.13: 408906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Math.pow(-Infinity, 0.5) == Infinity 409006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Math.sqrt(-Infinity) == NaN 409106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label done, sqrt; 409206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Check base for -Infinity. C3 == 0, C2 == 1, C1 == 1 and C0 == 1 409306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fxam(); 409406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ push(eax); 409506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fnstsw_ax(); 409606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ and_(eax, Immediate(0x4700)); 409706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ cmp(eax, Immediate(0x0700)); 409806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ j(not_equal, &sqrt, Label::kNear); 409906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // If input is -Infinity, return Infinity. 410006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fchs(); 410106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ jmp(&done, Label::kNear); 410206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 410306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Square root. 410406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&sqrt); 410506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fldz(); 410606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ faddp(); // Convert -0 to +0. 410706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fsqrt(); 410806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&done); 410906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ pop(eax); 4110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoPower(LPower* instr) { 411406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Representation exponent_type = instr->hydrogen()->right()->representation(); 411506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register result = ToX87Register(instr->result()); 411606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Having marked this as a call, we can use any registers. 411706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register base = ToX87Register(instr->left()); 411806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org ExternalReference one_half = ExternalReference::address_of_one_half(); 411906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 412006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (exponent_type.IsSmi()) { 412106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register exponent = ToRegister(instr->right()); 412206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87LoadForUsage(base); 412306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ SmiUntag(exponent); 412406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ push(exponent); 412506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fild_s(MemOperand(esp, 0)); 412606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ pop(exponent); 412706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } else if (exponent_type.IsTagged()) { 412806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register exponent = ToRegister(instr->right()); 412906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register temp = exponent.is(ecx) ? eax : ecx; 413006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label no_deopt, done; 413106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87LoadForUsage(base); 413206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ JumpIfSmi(exponent, &no_deopt); 413306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ CmpObjectType(exponent, HEAP_NUMBER_TYPE, temp); 4134b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_equal, instr, "not a heap number"); 413506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Heap number(double) 413606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld_d(FieldOperand(exponent, HeapNumber::kValueOffset)); 413706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ jmp(&done); 413806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // SMI 413906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&no_deopt); 414006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ SmiUntag(exponent); 414106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ push(exponent); 414206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fild_s(MemOperand(esp, 0)); 414306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ pop(exponent); 414406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&done); 414506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } else if (exponent_type.IsInteger32()) { 414606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register exponent = ToRegister(instr->right()); 414706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87LoadForUsage(base); 414806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ push(exponent); 414906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fild_s(MemOperand(esp, 0)); 415006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ pop(exponent); 415106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } else { 415206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DCHECK(exponent_type.IsDouble()); 415306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register exponent_double = ToX87Register(instr->right()); 415406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87LoadForUsage(base, exponent_double); 415506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 415606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 415706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // FP data stack {base, exponent(TOS)}. 415806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Handle (exponent==+-0.5 && base == -0). 415906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label not_plus_0; 416006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld(0); 416106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fabs(); 416206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Fld(Operand::StaticVariable(one_half), kX87DoubleOperand); 416306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ FCmp(); 416406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ j(parity_even, ¬_plus_0, Label::kNear); // NaN. 416506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ j(not_equal, ¬_plus_0, Label::kNear); 416606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fldz(); 416706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // FP data stack {base, exponent(TOS), zero}. 416806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ faddp(2); 416906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(¬_plus_0); 417006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 417106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org { 417206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ PrepareCallCFunction(4, eax); 417306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fstp_d(MemOperand(esp, kDoubleSize)); // Exponent value. 417406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fstp_d(MemOperand(esp, 0)); // Base value. 417506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87PrepareToWrite(result); 417606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ CallCFunction(ExternalReference::power_double_double_function(isolate()), 417706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 4); 417806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Return value is in st(0) on ia32. 417906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87CommitWrite(result); 418006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 4181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoMathLog(LMathLog* instr) { 418506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DCHECK(instr->value()->Equals(instr->result())); 418606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register input_reg = ToX87Register(instr->value()); 418706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Fxch(input_reg); 418806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 418906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label positive, done, zero, nan_result; 419006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fldz(); 419106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld(1); 419206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ FCmp(); 419306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ j(below, &nan_result, Label::kNear); 419406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ j(equal, &zero, Label::kNear); 419506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Positive input. 419606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // {input, ln2}. 419706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fldln2(); 419806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // {ln2, input}. 419906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fxch(); 420006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // {result}. 420106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fyl2x(); 420206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ jmp(&done, Label::kNear); 420306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 420406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&nan_result); 420506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org ExternalReference nan = 420606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org ExternalReference::address_of_canonical_non_hole_nan(); 420706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87PrepareToWrite(input_reg); 420806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld_d(Operand::StaticVariable(nan)); 420906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87CommitWrite(input_reg); 421006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ jmp(&done, Label::kNear); 421106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 421206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&zero); 421306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org ExternalReference ninf = ExternalReference::address_of_negative_infinity(); 421406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87PrepareToWrite(input_reg); 421506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld_d(Operand::StaticVariable(ninf)); 421606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87CommitWrite(input_reg); 421706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 421806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&done); 4219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoMathClz32(LMathClz32* instr) { 422306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register input = ToRegister(instr->value()); 422406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register result = ToRegister(instr->result()); 422506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label not_zero_input; 422606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bsr(result, input); 422706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 422806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ j(not_zero, ¬_zero_input); 422906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ Move(result, Immediate(63)); // 63^31 == 32 423006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 423106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(¬_zero_input); 423206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ xor_(result, Immediate(31)); // for x in [0..31], 31^x == 31-x. 4233864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4236864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoMathExp(LMathExp* instr) { 423706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register input = ToX87Register(instr->value()); 423806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register result_reg = ToX87Register(instr->result()); 423906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register temp_result = ToRegister(instr->temp1()); 424006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register temp = ToRegister(instr->temp2()); 424106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label slow, done, smi, finish; 424206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DCHECK(result_reg.is(input)); 424306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 424406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Store input into Heap number and call runtime function kMathExpRT. 424506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (FLAG_inline_new) { 424606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ AllocateHeapNumber(temp_result, temp, no_reg, &slow); 424706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ jmp(&done, Label::kNear); 424806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 424906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 425006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Slow case: Call the runtime system to do the number allocation. 425106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&slow); 425206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org { 425306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // TODO(3095996): Put a valid pointer value in the stack slot where the 425406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // result register is stored, as this register is in the pointer map, but 425506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // contains an integer value. 425606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ Move(temp_result, Immediate(0)); 425706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 425806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Preserve the value of all registers. 425906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org PushSafepointRegistersScope scope(this); 426006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 426106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 426206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 426306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org RecordSafepointWithRegisters(instr->pointer_map(), 0, 426406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Safepoint::kNoLazyDeopt); 426506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ StoreToSafepointRegisterSlot(temp_result, eax); 426606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 426706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&done); 426806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87LoadForUsage(input); 426906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fstp_d(FieldOperand(temp_result, HeapNumber::kValueOffset)); 427006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 427106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org { 427206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Preserve the value of all registers. 427306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org PushSafepointRegistersScope scope(this); 427406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 427506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 427606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ push(temp_result); 427706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ CallRuntimeSaveDoubles(Runtime::kMathExpRT); 4278ae4728945755838c8d6450f0a344eb4b583c4dd5weiliang.lin@intel.com RecordSafepointWithRegisters(instr->pointer_map(), 1, 427906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Safepoint::kNoLazyDeopt); 428006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ StoreToSafepointRegisterSlot(temp_result, eax); 428106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 428206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87PrepareToWrite(result_reg); 428306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // return value of MathExpRT is Smi or Heap Number. 428406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ JumpIfSmi(temp_result, &smi); 428506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Heap number(double) 428606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld_d(FieldOperand(temp_result, HeapNumber::kValueOffset)); 428706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ jmp(&finish); 428806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // SMI 428906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&smi); 429006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ SmiUntag(temp_result); 429106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ push(temp_result); 429206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fild_s(MemOperand(esp, 0)); 429306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ pop(temp_result); 429406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ bind(&finish); 429506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87CommitWrite(result_reg); 4296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 4300e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 4301e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->function()).is(edi)); 4302e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->HasPointerMap()); 4303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<JSFunction> known_function = instr->hydrogen()->known_function(); 4305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (known_function.is_null()) { 4306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LPointerMap* pointers = instr->pointer_map(); 4307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SafepointGenerator generator( 4308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org this, pointers, Safepoint::kLazyDeopt); 4309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ParameterCount count(instr->arity()); 4310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ InvokeFunction(edi, count, CALL_FUNCTION, generator); 4311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallKnownFunction(known_function, 4313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->formal_parameter_count(), 4314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->arity(), 4315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr, 4316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EDI_CONTAINS_TARGET); 4317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4319864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4320864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoCallFunction(LCallFunction* instr) { 4322e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 4323e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->function()).is(edi)); 4324e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(eax)); 4325864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int arity = instr->arity(); 4327864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags()); 4328864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 4329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4330864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4331864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4332864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoCallNew(LCallNew* instr) { 4333e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 4334e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->constructor()).is(edi)); 4335e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(eax)); 4336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // No cell in ebx for construct type feedback in optimized code 4338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, isolate()->factory()->undefined_value()); 4339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallConstructStub stub(isolate(), NO_CALL_CONSTRUCTOR_FLAGS); 4340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(eax, Immediate(instr->arity())); 4341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 4342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4343864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4345864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoCallNewArray(LCallNewArray* instr) { 4346e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 4347e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->constructor()).is(edi)); 4348e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->result()).is(eax)); 4349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(eax, Immediate(instr->arity())); 4351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, isolate()->factory()->undefined_value()); 4352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ElementsKind kind = instr->hydrogen()->elements_kind(); 4353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AllocationSiteOverrideMode override_mode = 4354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) 4355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? DISABLE_ALLOCATION_SITES 4356864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : DONT_OVERRIDE; 4357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->arity() == 0) { 4359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ArrayNoArgumentConstructorStub stub(isolate(), kind, override_mode); 4360864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 4361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (instr->arity() == 1) { 4362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 4363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (IsFastPackedElementsKind(kind)) { 4364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label packed_case; 4365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We might need a change here 4366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // look at the first argument 4367864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, Operand(esp, 0)); 4368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(ecx, ecx); 4369864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(zero, &packed_case, Label::kNear); 4370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ElementsKind holey_kind = GetHoleyElementsKind(kind); 4372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ArraySingleArgumentConstructorStub stub(isolate(), 4373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org holey_kind, 4374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org override_mode); 4375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 4376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 4377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&packed_case); 4378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4380864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode); 4381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 4382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 4383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode); 4385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 4386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4387864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoCallRuntime(LCallRuntime* instr) { 4391e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 439206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles()); 4393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) { 4397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register function = ToRegister(instr->function()); 4398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register code_object = ToRegister(instr->code_object()); 4399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(code_object, FieldOperand(code_object, Code::kHeaderSize)); 4400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(function, JSFunction::kCodeEntryOffset), code_object); 4401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4402864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { 4405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 4406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register base = ToRegister(instr->base_object()); 4407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->offset()->IsConstantOperand()) { 4408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LConstantOperand* offset = LConstantOperand::cast(instr->offset()); 4409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(result, Operand(base, ToInteger32(offset))); 4410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register offset = ToRegister(instr->offset()); 4412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(result, Operand(base, offset, times_1, 0)); 4413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4415864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 4418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Representation representation = instr->hydrogen()->field_representation(); 4419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HObjectAccess access = instr->hydrogen()->access(); 4421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int offset = access.offset(); 4422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (access.IsExternalMemory()) { 4424e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->hydrogen()->NeedsWriteBarrier()); 4425864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org MemOperand operand = instr->object()->IsConstantOperand() 4426864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? MemOperand::StaticVariable( 4427864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ToExternalReference(LConstantOperand::cast(instr->object()))) 4428864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : MemOperand(ToRegister(instr->object()), offset); 4429864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->value()->IsConstantOperand()) { 4430864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 4431864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(operand, Immediate(ToInteger32(operand_value))); 4432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register value = ToRegister(instr->value()); 4434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Store(value, operand, representation); 4435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 4437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register object = ToRegister(instr->object()); 4440e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org __ AssertNotSmi(object); 4441e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!representation.IsSmi() || 4442e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org !instr->value()->IsConstantOperand() || 4443e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org IsSmi(LConstantOperand::cast(instr->value()))); 4444e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org if (representation.IsDouble()) { 4445e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(access.IsInobject()); 4446e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->hydrogen()->has_transition()); 4447e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->hydrogen()->NeedsWriteBarrier()); 4448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register value = ToX87Register(instr->value()); 4449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Mov(FieldOperand(object, offset), value); 4450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 4451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->has_transition()) { 4454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Map> transition = instr->hydrogen()->transition_map(); 4455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AddDeprecationDependency(transition); 445638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org __ mov(FieldOperand(object, HeapObject::kMapOffset), transition); 445738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org if (instr->hydrogen()->NeedsWriteBarrierForMap()) { 4458864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp = ToRegister(instr->temp()); 4459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp_map = ToRegister(instr->temp_map()); 4460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(temp_map, transition); 4461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map); 4462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Update the write barrier for the map field. 446306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ RecordWriteForMap(object, transition, temp_map, temp, kSaveFPRegs); 4464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Do the store. 4468864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register write_register = object; 4469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!access.IsInobject()) { 4470864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org write_register = ToRegister(instr->temp()); 4471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(write_register, FieldOperand(object, JSObject::kPropertiesOffset)); 4472864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4474864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org MemOperand operand = FieldOperand(write_register, offset); 4475864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->value()->IsConstantOperand()) { 4476864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 4477864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (operand_value->IsRegister()) { 4478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register value = ToRegister(operand_value); 4479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Store(value, operand, representation); 4480864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (representation.IsInteger32()) { 4481864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate immediate = ToImmediate(operand_value, representation); 4482e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->hydrogen()->NeedsWriteBarrier()); 4483864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(operand, immediate); 4484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4485864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Object> handle_value = ToHandle(operand_value); 4486e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->hydrogen()->NeedsWriteBarrier()); 4487864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(operand, handle_value); 4488864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4489864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register value = ToRegister(instr->value()); 4491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Store(value, operand, representation); 4492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4493864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4494864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->NeedsWriteBarrier()) { 4495864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register value = ToRegister(instr->value()); 4496864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object; 4497864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Update the write barrier for the object for in-object properties. 449806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ RecordWriteField(write_register, offset, value, temp, kSaveFPRegs, 4499864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EMIT_REMEMBERED_SET, 450038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org instr->hydrogen()->SmiCheckForWriteBarrier(), 450138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org instr->hydrogen()->PointersToHereCheckForValue()); 4502864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4503864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4504864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4505864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4506864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { 4507e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 450842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister())); 450942ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister())); 4510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 451142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(StoreDescriptor::NameRegister(), instr->name()); 4512864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode()); 4513864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 4514864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4515864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4516864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4517864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { 4518864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition cc = instr->hydrogen()->allow_equality() ? above : above_equal; 4519864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->index()->IsConstantOperand()) { 4520864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ToOperand(instr->length()), 4521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ToImmediate(LConstantOperand::cast(instr->index()), 4522864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->length()->representation())); 452338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org cc = CommuteCondition(cc); 4524864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (instr->length()->IsConstantOperand()) { 4525864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ToOperand(instr->index()), 4526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ToImmediate(LConstantOperand::cast(instr->length()), 4527864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->index()->representation())); 4528864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4529864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); 4530864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4531864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_debug_code && instr->hydrogen()->skip_check()) { 4532864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 4533864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(NegateCondition(cc), &done, Label::kNear); 4534864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ int3(); 4535864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 4536864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4537b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(cc, instr, "out of bounds"); 4538864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4539864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4540864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4541864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4542864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { 4543864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ElementsKind elements_kind = instr->elements_kind(); 4544864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* key = instr->key(); 4545864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!key->IsConstantOperand() && 4546864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), 4547864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org elements_kind)) { 4548864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(ToRegister(key)); 4549864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4550864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand operand(BuildFastArrayOperand( 4551864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->elements(), 4552864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org key, 4553864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->key()->representation(), 4554864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org elements_kind, 4555864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->base_offset())); 4556864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || 4557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org elements_kind == FLOAT32_ELEMENTS) { 455806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Mov(operand, ToX87Register(instr->value()), kX87FloatOperand); 4559864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || 4560864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org elements_kind == FLOAT64_ELEMENTS) { 4561864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Mov(operand, ToX87Register(instr->value())); 4562864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4563864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register value = ToRegister(instr->value()); 4564864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (elements_kind) { 4565864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case EXTERNAL_UINT8_CLAMPED_ELEMENTS: 4566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case EXTERNAL_UINT8_ELEMENTS: 4567864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case EXTERNAL_INT8_ELEMENTS: 4568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case UINT8_ELEMENTS: 4569864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case INT8_ELEMENTS: 4570864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case UINT8_CLAMPED_ELEMENTS: 4571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov_b(operand, value); 4572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4573864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case EXTERNAL_INT16_ELEMENTS: 4574864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case EXTERNAL_UINT16_ELEMENTS: 4575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case UINT16_ELEMENTS: 4576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case INT16_ELEMENTS: 4577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov_w(operand, value); 4578864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4579864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case EXTERNAL_INT32_ELEMENTS: 4580864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case EXTERNAL_UINT32_ELEMENTS: 4581864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case UINT32_ELEMENTS: 4582864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case INT32_ELEMENTS: 4583864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(operand, value); 4584864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4585864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case EXTERNAL_FLOAT32_ELEMENTS: 4586864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case EXTERNAL_FLOAT64_ELEMENTS: 4587864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case FLOAT32_ELEMENTS: 4588864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case FLOAT64_ELEMENTS: 4589864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case FAST_SMI_ELEMENTS: 4590864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case FAST_ELEMENTS: 4591864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case FAST_DOUBLE_ELEMENTS: 4592864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case FAST_HOLEY_SMI_ELEMENTS: 4593864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case FAST_HOLEY_ELEMENTS: 4594864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case FAST_HOLEY_DOUBLE_ELEMENTS: 4595864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case DICTIONARY_ELEMENTS: 4596864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case SLOPPY_ARGUMENTS_ELEMENTS: 4597864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 4598864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4599864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4600864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4601864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4602864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4603864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4604864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { 4605864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference canonical_nan_reference = 4606864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference::address_of_canonical_non_hole_nan(); 4607864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand double_store_operand = BuildFastArrayOperand( 4608864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->elements(), 4609864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->key(), 4610864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->key()->representation(), 4611864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FAST_DOUBLE_ELEMENTS, 4612864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->base_offset()); 4613864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4614864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Can't use SSE2 in the serializer 4615864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->IsConstantHoleStore()) { 4616864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // This means we should store the (double) hole. No floating point 4617864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // registers required. 4618864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org double nan_double = FixedDoubleArray::hole_nan_as_double(); 4619e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org uint64_t int_val = bit_cast<uint64_t, double>(nan_double); 4620864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t lower = static_cast<int32_t>(int_val); 4621864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); 4622864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4623864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(double_store_operand, Immediate(lower)); 4624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand double_store_operand2 = BuildFastArrayOperand( 4625864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->elements(), 4626864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->key(), 4627864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->key()->representation(), 4628864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FAST_DOUBLE_ELEMENTS, 4629864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->base_offset() + kPointerSize); 4630864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(double_store_operand2, Immediate(upper)); 4631864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4632864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label no_special_nan_handling; 4633864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register value = ToX87Register(instr->value()); 4634864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Fxch(value); 4635864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4636864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->NeedsCanonicalization()) { 4637864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fld(0); 4638864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fld(0); 4639864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ FCmp(); 4640864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(parity_odd, &no_special_nan_handling, Label::kNear); 4642864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(esp, Immediate(kDoubleSize)); 4643864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fst_d(MemOperand(esp, 0)); 4644864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(MemOperand(esp, sizeof(kHoleNanLower32)), 4645864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(kHoleNanUpper32)); 4646864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(esp, Immediate(kDoubleSize)); 4647864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label canonicalize; 4648864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &canonicalize, Label::kNear); 4649864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&no_special_nan_handling, Label::kNear); 4650864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&canonicalize); 4651864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fstp(0); 4652864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fld_d(Operand::StaticVariable(canonical_nan_reference)); 4653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4654864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4655864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&no_special_nan_handling); 4656864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fst_d(double_store_operand); 4657864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4658864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4659864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4660864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { 4662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register elements = ToRegister(instr->elements()); 4663864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; 4664864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand operand = BuildFastArrayOperand( 4666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->elements(), 4667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->key(), 4668864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->key()->representation(), 4669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FAST_ELEMENTS, 4670864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->base_offset()); 4671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->value()->IsRegister()) { 4672864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(operand, ToRegister(instr->value())); 4673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4674864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 4675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (IsSmi(operand_value)) { 4676864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate immediate = ToImmediate(operand_value, Representation::Smi()); 4677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(operand, immediate); 4678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4679e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!IsInteger32(operand_value)); 4680864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Object> handle_value = ToHandle(operand_value); 4681864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(operand, handle_value); 4682864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4684864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4685864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->NeedsWriteBarrier()) { 4686e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->value()->IsRegister()); 4687864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register value = ToRegister(instr->value()); 4688e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->key()->IsConstantOperand()); 4689864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SmiCheck check_needed = 4690eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org instr->hydrogen()->value()->type().IsHeapObject() 4691864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 4692864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Compute address of modified element and store it into key register. 4693864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(key, operand); 469406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ RecordWrite(elements, key, value, kSaveFPRegs, EMIT_REMEMBERED_SET, 469538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org check_needed, 469638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org instr->hydrogen()->PointersToHereCheckForValue()); 4697864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4698864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4699864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4700864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4701864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { 4702864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // By cases...external, fast-double, fast 4703864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->is_typed_elements()) { 4704864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DoStoreKeyedExternalArray(instr); 4705864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (instr->hydrogen()->value()->representation().IsDouble()) { 4706864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DoStoreKeyedFixedDoubleArray(instr); 4707864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4708864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DoStoreKeyedFixedArray(instr); 4709864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4710864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4711864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4712864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4713864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 4714e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 471542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister())); 471642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org DCHECK(ToRegister(instr->key()).is(StoreDescriptor::NameRegister())); 471742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister())); 4718864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4719b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Handle<Code> ic = 4720b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org CodeFactory::KeyedStoreIC(isolate(), instr->strict_mode()).code(); 4721864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(ic, RelocInfo::CODE_TARGET, instr); 4722864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4723864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4724864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4725864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { 4726864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register object = ToRegister(instr->object()); 4727864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp = ToRegister(instr->temp()); 4728864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label no_memento_found; 4729864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found); 4730b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(equal, instr, "memento found"); 4731864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&no_memento_found); 4732864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4733864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4734864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4735864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { 4736864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register object_reg = ToRegister(instr->object()); 4737864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4738864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Map> from_map = instr->original_map(); 4739864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Map> to_map = instr->transitioned_map(); 4740864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ElementsKind from_kind = instr->from_kind(); 4741864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ElementsKind to_kind = instr->to_kind(); 4742864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4743864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label not_applicable; 4744864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool is_simple_map_transition = 4745864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org IsSimpleMapChangeTransition(from_kind, to_kind); 4746864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance branch_distance = 4747864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org is_simple_map_transition ? Label::kNear : Label::kFar; 4748864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); 4749864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, ¬_applicable, branch_distance); 4750864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (is_simple_map_transition) { 4751864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register new_map_reg = ToRegister(instr->new_map_temp()); 4752864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(object_reg, HeapObject::kMapOffset), 4753864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(to_map)); 4754864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Write barrier. 4755e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_NE(instr->temp(), NULL); 4756864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ RecordWriteForMap(object_reg, to_map, new_map_reg, 475706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org ToRegister(instr->temp()), kDontSaveFPRegs); 4758864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4759e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 4760e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(object_reg.is(eax)); 4761864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PushSafepointRegistersScope scope(this); 4762864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, to_map); 4763864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE; 4764864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org TransitionElementsKindStub stub(isolate(), from_kind, to_kind, is_js_array); 4765864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&stub); 4766864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordSafepointWithLazyDeopt(instr, 4767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 4768864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4769864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(¬_applicable); 4770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4771864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { 4774ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredStringCharCodeAt FINAL : public LDeferredCode { 4775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 4776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredStringCharCodeAt(LCodeGen* codegen, 4777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LStringCharCodeAt* instr, 4778864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const X87Stack& x87_stack) 4779864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : LDeferredCode(codegen, x87_stack), instr_(instr) { } 4780ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 4781864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->DoDeferredStringCharCodeAt(instr_); 4782864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4783ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 4784864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 4785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LStringCharCodeAt* instr_; 4786864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 4787864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4788864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredStringCharCodeAt* deferred = 4789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org new(zone()) DeferredStringCharCodeAt(this, instr, x87_stack_); 4790864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4791864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org StringCharLoadGenerator::Generate(masm(), 4792864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org factory(), 4793864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ToRegister(instr->string()), 4794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ToRegister(instr->index()), 4795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ToRegister(instr->result()), 4796864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org deferred->entry()); 4797864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(deferred->exit()); 4798864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4799864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4800864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4801864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { 4802864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register string = ToRegister(instr->string()); 4803864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 4804864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4805864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 4806864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // result register contain a valid pointer because it is already 4807864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // contained in the register pointer map. 4808864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(result, Immediate(0)); 4809864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4810864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PushSafepointRegistersScope scope(this); 4811864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(string); 4812864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push the index as a smi. This is safe because of the checks in 4813864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // DoStringCharCodeAt above. 4814864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); 4815864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->index()->IsConstantOperand()) { 4816864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate immediate = ToImmediate(LConstantOperand::cast(instr->index()), 4817864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Representation::Smi()); 4818864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(immediate); 4819864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4820864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register index = ToRegister(instr->index()); 4821864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiTag(index); 4822864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(index); 4823864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 482447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org CallRuntimeFromDeferred(Runtime::kStringCharCodeAtRT, 2, 4825864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr, instr->context()); 4826864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ AssertSmi(eax); 4827864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(eax); 4828864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ StoreToSafepointRegisterSlot(result, eax); 4829864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4830864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4831864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4832864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { 4833ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredStringCharFromCode FINAL : public LDeferredCode { 4834864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 4835864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredStringCharFromCode(LCodeGen* codegen, 4836864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LStringCharFromCode* instr, 4837864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const X87Stack& x87_stack) 4838864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : LDeferredCode(codegen, x87_stack), instr_(instr) { } 4839ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 4840864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->DoDeferredStringCharFromCode(instr_); 4841864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4842ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 4843864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 4844864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LStringCharFromCode* instr_; 4845864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 4846864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4847864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredStringCharFromCode* deferred = 4848864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org new(zone()) DeferredStringCharFromCode(this, instr, x87_stack_); 4849864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4850e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->hydrogen()->value()->representation().IsInteger32()); 4851864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register char_code = ToRegister(instr->char_code()); 4852864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 4853e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!char_code.is(result)); 4854864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4855864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(char_code, String::kMaxOneByteCharCode); 4856864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(above, deferred->entry()); 4857864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(result, Immediate(factory()->single_character_string_cache())); 4858864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, FieldOperand(result, 4859864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org char_code, times_pointer_size, 4860864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FixedArray::kHeaderSize)); 4861864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(result, factory()->undefined_value()); 4862864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, deferred->entry()); 4863864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(deferred->exit()); 4864864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4865864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4866864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4867864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { 4868864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register char_code = ToRegister(instr->char_code()); 4869864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 4870864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4871864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 4872864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // result register contain a valid pointer because it is already 4873864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // contained in the register pointer map. 4874864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(result, Immediate(0)); 4875864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4876864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PushSafepointRegistersScope scope(this); 4877864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiTag(char_code); 4878864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(char_code); 4879864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context()); 4880864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ StoreToSafepointRegisterSlot(result, eax); 4881864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4882864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4883864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4884864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoStringAdd(LStringAdd* instr) { 4885e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 4886e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->left()).is(edx)); 4887e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->right()).is(eax)); 4888864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org StringAddStub stub(isolate(), 4889864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->flags(), 4890864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->pretenure_flag()); 4891864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 4892864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4893864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4894864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4895864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 4896864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* input = instr->value(); 4897864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* output = instr->result(); 4898e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input->IsRegister() || input->IsStackSlot()); 4899e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(output->IsDoubleRegister()); 4900864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (input->IsRegister()) { 4901864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register input_reg = ToRegister(input); 4902864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(input_reg); 4903864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Mov(ToX87Register(output), Operand(esp, 0), kX87IntOperand); 4904864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(input_reg); 4905864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4906864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Mov(ToX87Register(output), ToOperand(input), kX87IntOperand); 4907864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4908864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4909864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4910864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4911864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 4912864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* input = instr->value(); 4913864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* output = instr->result(); 4914864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register res = ToX87Register(output); 4915864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87PrepareToWrite(res); 4916864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadUint32NoSSE2(ToRegister(input)); 4917864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87CommitWrite(res); 4918864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4919864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4920864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4921864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4922ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredNumberTagI FINAL : public LDeferredCode { 4923864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 4924864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredNumberTagI(LCodeGen* codegen, 4925864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LNumberTagI* instr, 4926864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const X87Stack& x87_stack) 4927864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : LDeferredCode(codegen, x87_stack), instr_(instr) { } 4928ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 4929864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp(), 4930864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SIGNED_INT32); 4931864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4932ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 4933864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 4934864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LNumberTagI* instr_; 4935864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 4936864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4937864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* input = instr->value(); 4938e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input->IsRegister() && input->Equals(instr->result())); 4939864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = ToRegister(input); 4940864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4941864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredNumberTagI* deferred = 4942864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org new(zone()) DeferredNumberTagI(this, instr, x87_stack_); 4943864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiTag(reg); 4944864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(overflow, deferred->entry()); 4945864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(deferred->exit()); 4946864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4947864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4948864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4949864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoNumberTagU(LNumberTagU* instr) { 4950ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredNumberTagU FINAL : public LDeferredCode { 4951864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 4952864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredNumberTagU(LCodeGen* codegen, 4953864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LNumberTagU* instr, 4954864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const X87Stack& x87_stack) 4955864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : LDeferredCode(codegen, x87_stack), instr_(instr) { } 4956ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 4957864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp(), 4958864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNSIGNED_INT32); 4959864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4960ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 4961864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 4962864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LNumberTagU* instr_; 4963864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 4964864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4965864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* input = instr->value(); 4966e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input->IsRegister() && input->Equals(instr->result())); 4967864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = ToRegister(input); 4968864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4969864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredNumberTagU* deferred = 4970864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org new(zone()) DeferredNumberTagU(this, instr, x87_stack_); 4971864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(reg, Immediate(Smi::kMaxValue)); 4972864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(above, deferred->entry()); 4973864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiTag(reg); 4974864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(deferred->exit()); 4975864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4976864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4977864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4978864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDeferredNumberTagIU(LInstruction* instr, 4979864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* value, 4980864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* temp, 4981864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org IntegerSignedness signedness) { 4982864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done, slow; 4983864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = ToRegister(value); 4984864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register tmp = ToRegister(temp); 4985864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4986864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (signedness == SIGNED_INT32) { 4987864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // There was overflow, so bits 30 and 31 of the original integer 4988864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // disagree. Try to allocate a heap number in new space and store 4989864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the value in there. If that fails, call the runtime system. 4990864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(reg); 4991864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ xor_(reg, 0x80000000); 4992864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(reg); 4993864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fild_s(Operand(esp, 0)); 4994864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(reg); 4995864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4996864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // There's no fild variant for unsigned values, so zero-extend to a 64-bit 4997864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // int manually. 4998864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(0)); 4999864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(reg); 5000864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fild_d(Operand(esp, 0)); 5001864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(reg); 5002864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(reg); 5003864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5004864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5005864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_inline_new) { 5006864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ AllocateHeapNumber(reg, tmp, no_reg, &slow); 5007864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 5008864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5009864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5010864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Slow case: Call the runtime system to do the number allocation. 5011864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&slow); 5012864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { 5013864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // TODO(3095996): Put a valid pointer value in the stack slot where the 5014864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // result register is stored, as this register is in the pointer map, but 5015864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // contains an integer value. 5016864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(reg, Immediate(0)); 5017864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5018864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Preserve the value of all registers. 5019864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PushSafepointRegistersScope scope(this); 5020864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5021864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // NumberTagI and NumberTagD use the context from the frame, rather than 5022864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the environment's HContext or HInlinedContext value. 502347390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org // They only call Runtime::kAllocateHeapNumber. 5024864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The corresponding HChange instructions are added in a phase that does 5025864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // not have easy access to the local context. 5026864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 502706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 5028864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordSafepointWithRegisters( 5029864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 5030864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ StoreToSafepointRegisterSlot(reg, eax); 5031864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5032864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5033864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 5034864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); 5035864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5036864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5037864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5038864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoNumberTagD(LNumberTagD* instr) { 5039ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredNumberTagD FINAL : public LDeferredCode { 5040864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 5041864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredNumberTagD(LCodeGen* codegen, 5042864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LNumberTagD* instr, 5043864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const X87Stack& x87_stack) 5044864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : LDeferredCode(codegen, x87_stack), instr_(instr) { } 5045ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 5046864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->DoDeferredNumberTagD(instr_); 5047864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5048ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 5049864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 5050864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LNumberTagD* instr_; 5051864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 5052864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5053864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = ToRegister(instr->result()); 5054864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5055864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Put the value to the top of stack 5056864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register src = ToX87Register(instr->value()); 505706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Don't use X87LoadForUsage here, which is only used by Instruction which 505806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // clobbers fp registers. 505906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org x87_stack_.Fxch(src); 5060864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5061864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredNumberTagD* deferred = 5062864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org new(zone()) DeferredNumberTagD(this, instr, x87_stack_); 5063864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_inline_new) { 5064864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register tmp = ToRegister(instr->temp()); 5065864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry()); 5066864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5067864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(deferred->entry()); 5068864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5069864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(deferred->exit()); 507006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fst_d(FieldOperand(reg, HeapNumber::kValueOffset)); 5071864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5072864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5073864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5074864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 5075864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 5076864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // result register contain a valid pointer because it is already 5077864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // contained in the register pointer map. 5078864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = ToRegister(instr->result()); 5079864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(reg, Immediate(0)); 5080864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5081864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PushSafepointRegistersScope scope(this); 5082864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // NumberTagI and NumberTagD use the context from the frame, rather than 5083864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the environment's HContext or HInlinedContext value. 508447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org // They only call Runtime::kAllocateHeapNumber. 5085864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The corresponding HChange instructions are added in a phase that does 5086864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // not have easy access to the local context. 5087864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 508806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 5089864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordSafepointWithRegisters( 5090864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 5091864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ StoreToSafepointRegisterSlot(reg, eax); 5092864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5093864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5094864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5095864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoSmiTag(LSmiTag* instr) { 5096864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HChange* hchange = instr->hydrogen(); 5097864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register input = ToRegister(instr->value()); 5098864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hchange->CheckFlag(HValue::kCanOverflow) && 5099864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org hchange->value()->CheckFlag(HValue::kUint32)) { 5100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(input, Immediate(0xc0000000)); 5101b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_zero, instr, "overflow"); 5102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiTag(input); 5104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hchange->CheckFlag(HValue::kCanOverflow) && 5105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org !hchange->value()->CheckFlag(HValue::kUint32)) { 5106b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(overflow, instr, "overflow"); 5107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoSmiUntag(LSmiUntag* instr) { 5112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* input = instr->value(); 5113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(input); 5114e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input->IsRegister() && input->Equals(instr->result())); 5115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->needs_check()) { 5116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(result, Immediate(kSmiTagMask)); 5117b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_zero, instr, "not a Smi"); 5118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ AssertSmi(result); 5120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(result); 5122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5125a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgvoid LCodeGen::EmitNumberUntagDNoSSE2(LNumberUntagD* instr, Register input_reg, 5126a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Register temp_reg, X87Register res_reg, 5127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NumberUntagDMode mode) { 5128a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org bool can_convert_undefined_to_nan = 5129a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org instr->hydrogen()->can_convert_undefined_to_nan(); 5130a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero(); 5131a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 5132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label load_smi, done; 5133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87PrepareToWrite(res_reg); 5135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { 5136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Smi check. 513706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ JumpIfSmi(input_reg, &load_smi); 5138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Heap number map check. 5140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org factory()->heap_number_map()); 5142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!can_convert_undefined_to_nan) { 5143b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_equal, instr, "not a heap number"); 5144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label heap_number, convert; 514606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ j(equal, &heap_number); 5147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Convert undefined (or hole) to NaN. 5149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(input_reg, factory()->undefined_value()); 5150b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_equal, instr, "not a heap number/undefined"); 5151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&convert); 5153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference nan = 5154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference::address_of_canonical_non_hole_nan(); 5155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fld_d(Operand::StaticVariable(nan)); 5156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 5157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&heap_number); 5159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Heap number to x87 conversion. 5161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); 5162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (deoptimize_on_minus_zero) { 5163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fldz(); 5164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ FCmp(); 5165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); 5166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, &done, Label::kNear); 5167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Use general purpose registers to check if we have -0.0 5169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(temp_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 5170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(temp_reg, Immediate(HeapNumber::kSignMask)); 5171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(zero, &done, Label::kNear); 5172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Pop FPU stack before deoptimizing. 5174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fstp(0); 5175b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_zero, instr, "minus zero"); 5176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 5178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5179e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(mode == NUMBER_CANDIDATE_IS_SMI); 5180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&load_smi); 5183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Clobbering a temp is faster than re-tagging the 5184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // input register since we avoid dependencies. 5185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(temp_reg, input_reg); 5186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(temp_reg); // Untag smi before converting to float. 5187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(temp_reg); 5188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ fild_s(Operand(esp, 0)); 5189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(esp, Immediate(kPointerSize)); 5190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 5191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87CommitWrite(res_reg); 5192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5193864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) { 5196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register input_reg = ToRegister(instr->value()); 5197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The input was optimistically untagged; revert it. 5199864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(kSmiTagSize == 1); 5200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(input_reg, Operand(input_reg, times_2, kHeapObjectTag)); 5201864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->truncating()) { 5203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label no_heap_number, check_bools, check_false; 5204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Heap number map check. 5206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org factory()->heap_number_map()); 5208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &no_heap_number, Label::kNear); 5209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TruncateHeapNumberToI(input_reg, input_reg); 5210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(done); 5211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&no_heap_number); 5213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for Oddballs. Undefined/False is converted to zero and True to one 5214864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // for truncating conversions. 5215864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(input_reg, factory()->undefined_value()); 5216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &check_bools, Label::kNear); 5217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(input_reg, Immediate(0)); 5218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(done); 5219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&check_bools); 5221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(input_reg, factory()->true_value()); 5222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &check_false, Label::kNear); 5223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(input_reg, Immediate(1)); 5224864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(done); 5225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5226864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&check_false); 5227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(input_reg, factory()->false_value()); 5228b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_equal, instr, "not a heap number/undefined/true/false"); 5229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(input_reg, Immediate(0)); 5230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5231a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // TODO(olivf) Converting a number on the fpu is actually quite slow. We 5232a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // should first try a fast conversion and then bailout to this slow case. 5233a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5234a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org isolate()->factory()->heap_number_map()); 523506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_equal, instr, "not a heap number"); 5236a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 5237a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ sub(esp, Immediate(kPointerSize)); 5238a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); 5239a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 5240a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org if (instr->hydrogen()->GetMinusZeroMode() == FAIL_ON_MINUS_ZERO) { 5241a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Label no_precision_lost, not_nan, zero_check; 5242a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ fld(0); 5243a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 5244a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ fist_s(MemOperand(esp, 0)); 5245a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ fild_s(MemOperand(esp, 0)); 5246a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ FCmp(); 5247a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ pop(input_reg); 5248a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 5249a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ j(equal, &no_precision_lost, Label::kNear); 5250a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ fstp(0); 525106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(no_condition, instr, "lost precision"); 5252a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ bind(&no_precision_lost); 5253a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 5254a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ j(parity_odd, ¬_nan); 5255a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ fstp(0); 525606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(no_condition, instr, "NaN"); 5257a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ bind(¬_nan); 5258a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 5259a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ test(input_reg, Operand(input_reg)); 5260a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ j(zero, &zero_check, Label::kNear); 5261a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ fstp(0); 5262a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ jmp(done); 5263a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 5264a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ bind(&zero_check); 5265a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // To check for minus zero, we load the value again as float, and check 5266a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // if that is still 0. 5267a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ sub(esp, Immediate(kPointerSize)); 5268a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ fstp_s(Operand(esp, 0)); 5269a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ pop(input_reg); 5270a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ test(input_reg, Operand(input_reg)); 527106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_zero, instr, "minus zero"); 5272a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org } else { 5273a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ fist_s(MemOperand(esp, 0)); 5274a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ fild_s(MemOperand(esp, 0)); 5275a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ FCmp(); 5276a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ pop(input_reg); 527706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(not_equal, instr, "lost precision"); 527806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DeoptimizeIf(parity_even, instr, "NaN"); 5279a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org } 5280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoTaggedToI(LTaggedToI* instr) { 5285ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredTaggedToI FINAL : public LDeferredCode { 5286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 5287864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredTaggedToI(LCodeGen* codegen, 5288864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LTaggedToI* instr, 5289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const X87Stack& x87_stack) 5290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : LDeferredCode(codegen, x87_stack), instr_(instr) { } 5291ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 5292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->DoDeferredTaggedToI(instr_, done()); 5293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5294ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 5295864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 5296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LTaggedToI* instr_; 5297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 5298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* input = instr->value(); 5300e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input->IsRegister()); 5301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register input_reg = ToRegister(input); 5302e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input_reg.is(ToRegister(instr->result()))); 5303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->value()->representation().IsSmi()) { 5305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(input_reg); 5306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredTaggedToI* deferred = 5308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org new(zone()) DeferredTaggedToI(this, instr, x87_stack_); 5309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Optimistically untag the input. 5310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the input is a HeapObject, SmiUntag will set the carry flag. 5311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); 5312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(input_reg); 5313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Branch to deferred code if the input was tagged. 5314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The deferred code will take care of restoring the tag. 5315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(carry, deferred->entry()); 5316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(deferred->exit()); 5317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5319864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5320864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 5322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* input = instr->value(); 5323e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input->IsRegister()); 5324864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* temp = instr->temp(); 5325e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(temp->IsRegister()); 5326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* result = instr->result(); 5327e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result->IsDoubleRegister()); 5328864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register input_reg = ToRegister(input); 5330864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp_reg = ToRegister(temp); 5331864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5332864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org HValue* value = instr->hydrogen()->value(); 5333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NumberUntagDMode mode = value->representation().IsSmi() 5334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED; 5335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5336a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org EmitNumberUntagDNoSSE2(instr, input_reg, temp_reg, ToX87Register(result), 5337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org mode); 5338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDoubleToI(LDoubleToI* instr) { 5342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* input = instr->value(); 5343e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input->IsDoubleRegister()); 5344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* result = instr->result(); 5345e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result->IsRegister()); 5346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result_reg = ToRegister(result); 5347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->truncating()) { 5349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register input_reg = ToX87Register(input); 5350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Fxch(input_reg); 5351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ TruncateX87TOSToI(result_reg); 5352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5353b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org Label lost_precision, is_nan, minus_zero, done; 5354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register input_reg = ToX87Register(input); 5355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Fxch(input_reg); 535634ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; 5357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(), 535834ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com &lost_precision, &is_nan, &minus_zero, dist); 535934ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ jmp(&done); 5360b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org __ bind(&lost_precision); 5361b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(no_condition, instr, "lost precision"); 5362b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org __ bind(&is_nan); 5363b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(no_condition, instr, "NaN"); 5364b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org __ bind(&minus_zero); 5365b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(no_condition, instr, "minus zero"); 5366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 5367864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5369864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { 5372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* input = instr->value(); 5373e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input->IsDoubleRegister()); 5374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* result = instr->result(); 5375e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result->IsRegister()); 5376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result_reg = ToRegister(result); 5377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5378b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org Label lost_precision, is_nan, minus_zero, done; 5379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Register input_reg = ToX87Register(input); 5380864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org X87Fxch(input_reg); 538134ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; 5382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(), 538334ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com &lost_precision, &is_nan, &minus_zero, dist); 538434ce5fb5d3a71d1683724530e1cfca983c659ae7weiliang.lin@intel.com __ jmp(&done); 5385b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org __ bind(&lost_precision); 5386b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(no_condition, instr, "lost precision"); 5387b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org __ bind(&is_nan); 5388b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(no_condition, instr, "NaN"); 5389b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org __ bind(&minus_zero); 5390b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(no_condition, instr, "minus zero"); 5391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 5392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiTag(result_reg); 5393b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(overflow, instr, "overflow"); 5394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoCheckSmi(LCheckSmi* instr) { 5398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* input = instr->value(); 5399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(ToOperand(input), Immediate(kSmiTagMask)); 5400b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_zero, instr, "not a Smi"); 5401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5402864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 5405eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org if (!instr->hydrogen()->value()->type().IsHeapObject()) { 5406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* input = instr->value(); 5407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(ToOperand(input), Immediate(kSmiTagMask)); 5408b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(zero, instr, "Smi"); 5409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 5414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register input = ToRegister(instr->value()); 5415864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp = ToRegister(instr->temp()); 5416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 5418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->is_interval_check()) { 5420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InstanceType first; 5421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InstanceType last; 5422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->GetCheckInterval(&first, &last); 5423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5424864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), 5425864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static_cast<int8_t>(first)); 5426864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5427864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If there is only one type in the interval check for equality. 5428864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (first == last) { 5429b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_equal, instr, "wrong instance type"); 5430864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5431b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(below, instr, "wrong instance type"); 5432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Omit check for the last type. 5433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (last != LAST_TYPE) { 5434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), 5435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static_cast<int8_t>(last)); 5436b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(above, instr, "wrong instance type"); 5437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5440864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org uint8_t mask; 5441864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org uint8_t tag; 5442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag); 5443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 54449aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org if (base::bits::IsPowerOfTwo32(mask)) { 54459aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag)); 5446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test_b(FieldOperand(temp, Map::kInstanceTypeOffset), mask); 5447b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(tag == 0 ? not_zero : zero, instr, "wrong instance type"); 5448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset)); 5450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ and_(temp, mask); 5451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(temp, tag); 5452b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_equal, instr, "wrong instance type"); 5453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5456864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5458864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoCheckValue(LCheckValue* instr) { 5459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<HeapObject> object = instr->hydrogen()->object().handle(); 5460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->object_in_new_space()) { 5461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = ToRegister(instr->value()); 5462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Cell> cell = isolate()->factory()->NewCell(object); 5463864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(reg, Operand::ForCell(cell)); 5464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand operand = ToOperand(instr->value()); 5466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(operand, object); 5467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5468b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_equal, instr, "value mismatch"); 5469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5470864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5472864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { 5473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { 5474864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PushSafepointRegistersScope scope(this); 5475864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(object); 5476864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ xor_(esi, esi); 547706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance); 5478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordSafepointWithRegisters( 5479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->pointer_map(), 1, Safepoint::kNoLazyDeopt); 5480864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5481864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(eax, Immediate(kSmiTagMask)); 5482864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5483b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(zero, instr, "instance migration failed"); 5484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5485864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5486864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5487864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoCheckMaps(LCheckMaps* instr) { 5488ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredCheckMaps FINAL : public LDeferredCode { 5489864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 5490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredCheckMaps(LCodeGen* codegen, 5491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LCheckMaps* instr, 5492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register object, 5493864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const X87Stack& x87_stack) 5494864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : LDeferredCode(codegen, x87_stack), instr_(instr), object_(object) { 5495864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetExit(check_maps()); 5496864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5497ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 5498864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->DoDeferredInstanceMigration(instr_, object_); 5499864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5500864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* check_maps() { return &check_maps_; } 5501ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 5502864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 5503864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LCheckMaps* instr_; 5504864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label check_maps_; 5505864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register object_; 5506864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 5507864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5508864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->IsStabilityCheck()) { 5509864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const UniqueSet<Map>* maps = instr->hydrogen()->maps(); 5510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < maps->size(); ++i) { 5511864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AddStabilityDependency(maps->at(i).handle()); 5512864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5513864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 5514864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5515864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5516864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* input = instr->value(); 5517e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input->IsRegister()); 5518864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = ToRegister(input); 5519864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5520864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredCheckMaps* deferred = NULL; 5521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->HasMigrationTarget()) { 5522864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org deferred = new(zone()) DeferredCheckMaps(this, instr, reg, x87_stack_); 5523864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(deferred->check_maps()); 5524864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5525864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const UniqueSet<Map>* maps = instr->hydrogen()->maps(); 5527864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label success; 5528864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < maps->size() - 1; i++) { 5529864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Map> map = maps->at(i).handle(); 5530864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CompareMap(reg, map); 5531864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &success, Label::kNear); 5532864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5533864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5534864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Map> map = maps->at(maps->size() - 1).handle(); 5535864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CompareMap(reg, map); 5536864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->HasMigrationTarget()) { 5537864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, deferred->entry()); 5538864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5539b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_equal, instr, "wrong map"); 5540864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5541864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5542864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&success); 5543864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5544864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5545864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5546864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 554706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register value_reg = ToX87Register(instr->unclamped()); 554806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register result_reg = ToRegister(instr->result()); 554906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Fxch(value_reg); 555006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ ClampTOSToUint8(result_reg); 5551864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5552864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5553864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5554864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { 5555e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->unclamped()->Equals(instr->result())); 5556864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register value_reg = ToRegister(instr->result()); 5557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ClampUint8(value_reg); 5558864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5559864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5560864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5561864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoClampTToUint8NoSSE2(LClampTToUint8NoSSE2* instr) { 5562864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register input_reg = ToRegister(instr->unclamped()); 5563864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result_reg = ToRegister(instr->result()); 5564864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch = ToRegister(instr->scratch()); 5565864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch2 = ToRegister(instr->scratch2()); 5566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch3 = ToRegister(instr->scratch3()); 5567864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label is_smi, done, heap_number, valid_exponent, 5568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org largest_value, zero_result, maybe_nan_or_infinity; 5569864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5570864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(input_reg, &is_smi); 5571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for heap number 5573864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5574864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org factory()->heap_number_map()); 5575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &heap_number, Label::kNear); 5576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for undefined. Undefined is converted to zero for clamping 5578864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // conversions. 5579864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(input_reg, factory()->undefined_value()); 5580b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_equal, instr, "not a heap number/undefined"); 5581864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&zero_result, Label::kNear); 5582864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5583864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Heap number 5584864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&heap_number); 5585864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5586864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Surprisingly, all of the hand-crafted bit-manipulations below are much 5587864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // faster than the x86 FPU built-in instruction, especially since "banker's 5588864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // rounding" would be additionally very expensive 5589864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5590864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get exponent word. 5591864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 5592864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch3, FieldOperand(input_reg, HeapNumber::kMantissaOffset)); 5593864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5594864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Test for negative values --> clamp to zero 5595864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(scratch, scratch); 5596864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(negative, &zero_result, Label::kNear); 5597864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5598864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get exponent alone in scratch2. 5599864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch2, scratch); 5600864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ and_(scratch2, HeapNumber::kExponentMask); 5601864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shr(scratch2, HeapNumber::kExponentShift); 5602864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(zero, &zero_result, Label::kNear); 5603864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(scratch2, Immediate(HeapNumber::kExponentBias - 1)); 5604864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(negative, &zero_result, Label::kNear); 5605864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5606864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const uint32_t non_int8_exponent = 7; 5607864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(scratch2, Immediate(non_int8_exponent + 1)); 5608864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the exponent is too big, check for special values. 5609864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(greater, &maybe_nan_or_infinity, Label::kNear); 5610864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5611864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&valid_exponent); 5612864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Exponent word in scratch, exponent in scratch2. We know that 0 <= exponent 5613864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // < 7. The shift bias is the number of bits to shift the mantissa such that 5614864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // with an exponent of 7 such the that top-most one is in bit 30, allowing 5615864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // detection the rounding overflow of a 255.5 to 256 (bit 31 goes from 0 to 5616864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 1). 5617864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int shift_bias = (30 - HeapNumber::kExponentShift) - 7 - 1; 5618864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(result_reg, MemOperand(scratch2, shift_bias)); 5619864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Here result_reg (ecx) is the shift, scratch is the exponent word. Get the 5620864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // top bits of the mantissa. 5621864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ and_(scratch, HeapNumber::kMantissaMask); 5622864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Put back the implicit 1 of the mantissa 5623864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ or_(scratch, 1 << HeapNumber::kExponentShift); 5624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Shift up to round 5625864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shl_cl(scratch); 5626864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Use "banker's rounding" to spec: If fractional part of number is 0.5, then 5627864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // use the bit in the "ones" place and add it to the "halves" place, which has 5628864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the effect of rounding to even. 5629864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch2, scratch); 5630864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const uint32_t one_half_bit_shift = 30 - sizeof(uint8_t) * 8; 5631864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const uint32_t one_bit_shift = one_half_bit_shift + 1; 5632864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ and_(scratch2, Immediate((1 << one_bit_shift) - 1)); 5633864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(scratch2, Immediate(1 << one_half_bit_shift)); 5634864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label no_round; 5635864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(less, &no_round, Label::kNear); 5636864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label round_up; 5637864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch2, Immediate(1 << one_half_bit_shift)); 5638864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(greater, &round_up, Label::kNear); 5639864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(scratch3, scratch3); 5640864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, &round_up, Label::kNear); 5641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch2, scratch); 5642864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ and_(scratch2, Immediate(1 << one_bit_shift)); 5643864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shr(scratch2, 1); 5644864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&round_up); 5645864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(scratch, scratch2); 5646864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(overflow, &largest_value, Label::kNear); 5647864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&no_round); 5648864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shr(scratch, 23); 5649864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result_reg, scratch); 5650864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 5651864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5652864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&maybe_nan_or_infinity); 5653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for NaN/Infinity, all other values map to 255 5654864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(scratch2, Immediate(HeapNumber::kInfinityOrNanExponent + 1)); 5655864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &largest_value, Label::kNear); 5656864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5657864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for NaN, which differs from Infinity in that at least one mantissa 5658864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // bit is set. 5659864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ and_(scratch, HeapNumber::kMantissaMask); 5660864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ or_(scratch, FieldOperand(input_reg, HeapNumber::kMantissaOffset)); 5661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, &zero_result, Label::kNear); // M!=0 --> NaN 5662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Infinity -> Fall through to map to 255. 5663864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5664864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&largest_value); 5665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result_reg, Immediate(255)); 5666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 5667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5668864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&zero_result); 5669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ xor_(result_reg, result_reg); 5670864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 5671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5672864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // smi 5673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&is_smi); 5674864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!input_reg.is(result_reg)) { 5675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result_reg, input_reg); 5676864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(result_reg); 5678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ ClampUint8(result_reg); 5679864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 5680864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5681864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5682864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDoubleBits(LDoubleBits* instr) { 568406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register value_reg = ToX87Register(instr->value()); 568506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register result_reg = ToRegister(instr->result()); 568606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Fxch(value_reg); 568706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ sub(esp, Immediate(kDoubleSize)); 568806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fst_d(Operand(esp, 0)); 568906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (instr->hydrogen()->bits() == HDoubleBits::HIGH) { 569006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ mov(result_reg, Operand(esp, kPointerSize)); 569106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } else { 569206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ mov(result_reg, Operand(esp, 0)); 569306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 569406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ add(esp, Immediate(kDoubleSize)); 5695864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5696864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5697864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5698864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoConstructDouble(LConstructDouble* instr) { 569906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register hi_reg = ToRegister(instr->hi()); 570006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Register lo_reg = ToRegister(instr->lo()); 570106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87Register result_reg = ToX87Register(instr->result()); 570206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org // Follow below pattern to write a x87 fp register. 570306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87PrepareToWrite(result_reg); 570406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ sub(esp, Immediate(kDoubleSize)); 570506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ mov(Operand(esp, 0), lo_reg); 570606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ mov(Operand(esp, kPointerSize), hi_reg); 570706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ fld_d(Operand(esp, 0)); 570806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ add(esp, Immediate(kDoubleSize)); 570906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org X87CommitWrite(result_reg); 5710864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5711864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5712864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5713864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoAllocate(LAllocate* instr) { 5714ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredAllocate FINAL : public LDeferredCode { 5715864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 5716864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredAllocate(LCodeGen* codegen, 5717864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LAllocate* instr, 5718864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const X87Stack& x87_stack) 5719864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : LDeferredCode(codegen, x87_stack), instr_(instr) { } 5720ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 5721864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->DoDeferredAllocate(instr_); 5722864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5723ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 5724864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 5725864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LAllocate* instr_; 5726864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 5727864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5728864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredAllocate* deferred = 5729864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org new(zone()) DeferredAllocate(this, instr, x87_stack_); 5730864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5731864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 5732864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp = ToRegister(instr->temp()); 5733864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5734864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Allocate memory for the object. 5735864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AllocationFlags flags = TAG_OBJECT; 5736864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->MustAllocateDoubleAligned()) { 5737864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT); 5738864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5739864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { 5740e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->hydrogen()->IsOldDataSpaceAllocation()); 5741e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); 5742864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE); 5743864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { 5744e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); 5745864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_DATA_SPACE); 5746864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5747864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5748864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->size()->IsConstantOperand()) { 5749864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 5750864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (size <= Page::kMaxRegularHeapObjectSize) { 5751864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); 5752864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5753864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(deferred->entry()); 5754864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5755864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5756864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register size = ToRegister(instr->size()); 5757864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Allocate(size, result, temp, no_reg, deferred->entry(), flags); 5758864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5759864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5760864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(deferred->exit()); 5761864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5762864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->MustPrefillWithFiller()) { 5763864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->size()->IsConstantOperand()) { 5764864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 5765864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(temp, (size / kPointerSize) - 1); 5766864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org temp = ToRegister(instr->size()); 5768864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shr(temp, kPointerSizeLog2); 5769864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ dec(temp); 5770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5771864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label loop; 5772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&loop); 5773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(result, temp, times_pointer_size, 0), 5774864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org isolate()->factory()->one_pointer_filler_map()); 5775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ dec(temp); 5776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, &loop); 5777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5778864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5779864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5780864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5781864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDeferredAllocate(LAllocate* instr) { 5782864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 5783864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5784864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // TODO(3095996): Get rid of this. For now, we need to make the 5785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // result register contain a valid pointer because it is already 5786864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // contained in the register pointer map. 5787864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(result, Immediate(Smi::FromInt(0))); 5788864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PushSafepointRegistersScope scope(this); 5790864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->size()->IsRegister()) { 5791864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register size = ToRegister(instr->size()); 5792e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!size.is(result)); 5793864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiTag(ToRegister(instr->size())); 5794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(size); 5795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5796864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); 5797864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (size >= 0 && size <= Smi::kMaxValue) { 5798864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(size))); 5799864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5800864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We should never get here at runtime => abort 5801864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ int3(); 5802864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 5803864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5804864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5805864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5806864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int flags = AllocateDoubleAlignFlag::encode( 5807864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->hydrogen()->MustAllocateDoubleAligned()); 5808864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { 5809e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->hydrogen()->IsOldDataSpaceAllocation()); 5810e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); 5811864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org flags = AllocateTargetSpace::update(flags, OLD_POINTER_SPACE); 5812864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { 5813e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); 5814864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org flags = AllocateTargetSpace::update(flags, OLD_DATA_SPACE); 5815864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5816864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org flags = AllocateTargetSpace::update(flags, NEW_SPACE); 5817864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5818864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(flags))); 5819864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5820864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallRuntimeFromDeferred( 582147390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org Runtime::kAllocateInTargetSpace, 2, instr, instr->context()); 5822864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ StoreToSafepointRegisterSlot(result, eax); 5823864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5824864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5825864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5826864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoToFastProperties(LToFastProperties* instr) { 5827e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->value()).is(eax)); 5828864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); 5829864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallRuntime(Runtime::kToFastProperties, 1, instr); 5830864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5831864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5832864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5833864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { 5834e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 5835864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label materialized; 5836864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Registers will be used as follows: 5837864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ecx = literals array. 5838864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ebx = regexp literal. 5839864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // eax = regexp literal clone. 5840864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // esi = context. 5841864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int literal_offset = 5842864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); 5843864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadHeapObject(ecx, instr->hydrogen()->literals()); 5844864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, FieldOperand(ecx, literal_offset)); 5845864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ebx, factory()->undefined_value()); 5846864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &materialized, Label::kNear); 5847864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5848864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Create regexp literal using runtime function 5849864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Result will be in eax. 5850864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(ecx); 5851864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); 5852864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(instr->hydrogen()->pattern())); 5853864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(instr->hydrogen()->flags())); 585447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr); 5855864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, eax); 5856864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5857864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&materialized); 5858864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; 5859864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label allocated, runtime_allocate; 5860864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Allocate(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT); 5861864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&allocated, Label::kNear); 5862864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5863864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&runtime_allocate); 5864864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(ebx); 5865864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(size))); 586647390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); 5867864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(ebx); 5868864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5869864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&allocated); 5870864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Copy the content into the newly allocated memory. 5871864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // (Unroll copy loop once for better throughput). 5872864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) { 5873864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, FieldOperand(ebx, i)); 5874864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, FieldOperand(ebx, i + kPointerSize)); 5875864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(eax, i), edx); 5876864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(eax, i + kPointerSize), ecx); 5877864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5878864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if ((size % (2 * kPointerSize)) != 0) { 5879864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, FieldOperand(ebx, size - kPointerSize)); 5880864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(eax, size - kPointerSize), edx); 5881864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5882864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5883864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5884864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5885864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { 5886e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 5887864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Use the fast case closure allocation code that allocates in new 5888864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // space for nested functions that don't need literals cloning. 5889864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool pretenure = instr->hydrogen()->pretenure(); 5890864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!pretenure && instr->hydrogen()->has_no_literals()) { 58912c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org FastNewClosureStub stub(isolate(), instr->hydrogen()->strict_mode(), 58922c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org instr->hydrogen()->kind()); 5893864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, Immediate(instr->hydrogen()->shared_info())); 5894864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 5895864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5896864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(esi); 5897864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(instr->hydrogen()->shared_info())); 5898864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(pretenure ? factory()->true_value() 5899864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : factory()->false_value())); 590047390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org CallRuntime(Runtime::kNewClosure, 3, instr); 5901864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5902864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5903864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5904864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5905864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoTypeof(LTypeof* instr) { 5906e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 5907864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LOperand* input = instr->value(); 5908864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitPushTaggedOperand(input); 5909864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallRuntime(Runtime::kTypeof, 1, instr); 5910864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5911864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5912864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5913864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 5914864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register input = ToRegister(instr->value()); 5915864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition final_branch_condition = EmitTypeofIs(instr, input); 5916864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (final_branch_condition != no_condition) { 5917864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, final_branch_condition); 5918864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5919864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5920864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5921864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5922864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgCondition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) { 5923864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* true_label = instr->TrueLabel(chunk_); 5924864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* false_label = instr->FalseLabel(chunk_); 5925864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<String> type_name = instr->type_literal(); 5926864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int left_block = instr->TrueDestination(chunk_); 5927864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int right_block = instr->FalseDestination(chunk_); 5928864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int next_block = GetNextEmittedBlock(); 5929864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5930864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance true_distance = left_block == next_block ? Label::kNear 5931864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : Label::kFar; 5932864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance false_distance = right_block == next_block ? Label::kNear 5933864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : Label::kFar; 5934864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition final_branch_condition = no_condition; 5935864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (String::Equals(type_name, factory()->number_string())) { 5936864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(input, true_label, true_distance); 5937864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(input, HeapObject::kMapOffset), 5938864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org factory()->heap_number_map()); 5939864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org final_branch_condition = equal; 5940864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5941864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (String::Equals(type_name, factory()->string_string())) { 5942864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(input, false_label, false_distance); 5943864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input); 5944864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(above_equal, false_label, false_distance); 5945864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test_b(FieldOperand(input, Map::kBitFieldOffset), 5946864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1 << Map::kIsUndetectable); 5947864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org final_branch_condition = zero; 5948864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5949864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (String::Equals(type_name, factory()->symbol_string())) { 5950864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(input, false_label, false_distance); 5951864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(input, SYMBOL_TYPE, input); 5952864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org final_branch_condition = equal; 5953864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5954864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (String::Equals(type_name, factory()->boolean_string())) { 5955864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(input, factory()->true_value()); 5956864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, true_label, true_distance); 5957864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(input, factory()->false_value()); 5958864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org final_branch_condition = equal; 5959864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5960864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (String::Equals(type_name, factory()->undefined_string())) { 5961864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(input, factory()->undefined_value()); 5962864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, true_label, true_distance); 5963864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(input, false_label, false_distance); 5964864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for undetectable objects => true. 5965864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); 5966864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test_b(FieldOperand(input, Map::kBitFieldOffset), 5967864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1 << Map::kIsUndetectable); 5968864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org final_branch_condition = not_zero; 5969864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5970864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (String::Equals(type_name, factory()->function_string())) { 5971864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); 5972864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(input, false_label, false_distance); 5973864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(input, JS_FUNCTION_TYPE, input); 5974864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, true_label, true_distance); 5975864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpInstanceType(input, JS_FUNCTION_PROXY_TYPE); 5976864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org final_branch_condition = equal; 5977864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5978864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (String::Equals(type_name, factory()->object_string())) { 5979864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(input, false_label, false_distance); 59809d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org __ cmp(input, factory()->null_value()); 59819d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org __ j(equal, true_label, true_distance); 5982864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); 5983864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(below, false_label, false_distance); 5984864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 5985864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(above, false_label, false_distance); 5986864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for undetectable objects => false. 5987864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test_b(FieldOperand(input, Map::kBitFieldOffset), 5988864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1 << Map::kIsUndetectable); 5989864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org final_branch_condition = zero; 5990864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5991864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 5992864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(false_label, false_distance); 5993864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 5994864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return final_branch_condition; 5995864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 5996864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5997864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5998864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 5999864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp = ToRegister(instr->temp()); 6000864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6001864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitIsConstructCall(temp); 6002864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBranch(instr, equal); 6003864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 6004864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6005864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6006864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::EmitIsConstructCall(Register temp) { 6007864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the frame pointer for the calling frame. 6008864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(temp, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 6009864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6010864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Skip the arguments adaptor frame if it exists. 6011864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label check_frame_marker; 6012864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(Operand(temp, StandardFrameConstants::kContextOffset), 6013864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 6014864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &check_frame_marker, Label::kNear); 6015864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset)); 6016864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6017864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check the marker in the calling frame. 6018864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&check_frame_marker); 6019864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(Operand(temp, StandardFrameConstants::kMarkerOffset), 6020864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(Smi::FromInt(StackFrame::CONSTRUCT))); 6021864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 6022864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6023864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6024864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) { 6025864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!info()->IsStub()) { 6026864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Ensure that we have enough space after the previous lazy-bailout 6027864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // instruction for patching the code here. 6028864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int current_pc = masm()->pc_offset(); 6029864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (current_pc < last_lazy_deopt_pc_ + space_needed) { 6030864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; 6031864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Nop(padding_size); 6032864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 6033864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 6034864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org last_lazy_deopt_pc_ = masm()->pc_offset(); 6035864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 6036864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6037864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6038864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoLazyBailout(LLazyBailout* instr) { 6039864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org last_lazy_deopt_pc_ = masm()->pc_offset(); 6040e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->HasEnvironment()); 6041864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LEnvironment* env = instr->environment(); 6042864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 6043864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 6044864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 6045864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6046864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6047864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDeoptimize(LDeoptimize* instr) { 6048864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Deoptimizer::BailoutType type = instr->hydrogen()->type(); 6049864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the 6050864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // needed return address), even though the implementation of LAZY and EAGER is 6051864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // now identical. When LAZY is eventually completely folded into EAGER, remove 6052864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the special case below. 6053864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (info()->IsStub() && type == Deoptimizer::EAGER) { 6054864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org type = Deoptimizer::LAZY; 6055864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 6056a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org DeoptimizeIf(no_condition, instr, instr->hydrogen()->reason(), type); 6057864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 6058864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6059864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6060864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDummy(LDummy* instr) { 6061864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Nothing to see here, move on! 6062864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 6063864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6064864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6065864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDummyUse(LDummyUse* instr) { 6066864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Nothing to see here, move on! 6067864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 6068864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6069864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6070864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { 6071864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PushSafepointRegistersScope scope(this); 6072864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 607306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ CallRuntimeSaveDoubles(Runtime::kStackGuard); 6074864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordSafepointWithLazyDeopt( 6075864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 6076e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->HasEnvironment()); 6077864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LEnvironment* env = instr->environment(); 6078864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 6079864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 6080864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6081864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6082864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoStackCheck(LStackCheck* instr) { 6083ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredStackCheck FINAL : public LDeferredCode { 6084864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 6085864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredStackCheck(LCodeGen* codegen, 6086864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LStackCheck* instr, 6087864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const X87Stack& x87_stack) 6088864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : LDeferredCode(codegen, x87_stack), instr_(instr) { } 6089ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 6090864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->DoDeferredStackCheck(instr_); 6091864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 6092ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 6093864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 6094864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LStackCheck* instr_; 6095864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 6096864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6097e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->HasEnvironment()); 6098864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LEnvironment* env = instr->environment(); 6099864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // There is no LLazyBailout instruction for stack-checks. We have to 6100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // prepare for lazy deoptimization explicitly here. 6101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (instr->hydrogen()->is_function_entry()) { 6102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Perform stack overflow check. 6103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 6104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference stack_limit = 6105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference::address_of_stack_limit(isolate()); 6106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(esp, Operand::StaticVariable(stack_limit)); 6107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(above_equal, &done, Label::kNear); 6108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6109e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->context()->IsRegister()); 6110e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 6111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallCode(isolate()->builtins()->StackCheck(), 6112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RelocInfo::CODE_TARGET, 6113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr); 6114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 6115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 6116e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->hydrogen()->is_backwards_branch()); 6117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Perform stack overflow check if this goto needs it before jumping. 6118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredStackCheck* deferred_stack_check = 6119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org new(zone()) DeferredStackCheck(this, instr, x87_stack_); 6120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference stack_limit = 6121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference::address_of_stack_limit(isolate()); 6122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(esp, Operand::StaticVariable(stack_limit)); 6123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(below, deferred_stack_check->entry()); 6124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); 6125864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(instr->done_label()); 6126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org deferred_stack_check->SetExit(instr->done_label()); 6127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 6128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Don't record a deoptimization index for the safepoint here. 6129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // This will be done explicitly when emitting call and the safepoint in 6130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the deferred code. 6131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 6132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 6133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoOsrEntry(LOsrEntry* instr) { 6136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // This is a pseudo-instruction that ensures that the environment here is 6137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // properly registered for deoptimization and records the assembler's PC 6138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // offset. 6139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LEnvironment* environment = instr->environment(); 6140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the environment were already registered, we would have no way of 6142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // backpatching it with the spill slot operands. 6143e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!environment->HasBeenRegistered()); 6144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 6145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org GenerateOsrPrologue(); 6147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 6148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { 6151e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ToRegister(instr->context()).is(esi)); 6152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(eax, isolate()->factory()->undefined_value()); 6153b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(equal, instr, "undefined"); 6154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(eax, isolate()->factory()->null_value()); 6156b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(equal, instr, "null"); 6157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(eax, Immediate(kSmiTagMask)); 6159b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(zero, instr, "Smi"); 6160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 6162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(eax, LAST_JS_PROXY_TYPE, ecx); 6163b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(below_equal, instr, "wrong instance type"); 6164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label use_cache, call_runtime; 6166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CheckEnumCache(&call_runtime); 6167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset)); 6169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&use_cache, Label::kNear); 6170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the set of properties to enumerate. 6172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&call_runtime); 6173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); 6174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr); 6175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 6177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org isolate()->factory()->meta_map()); 6178b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_equal, instr, "wrong map"); 6179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&use_cache); 6180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 6181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { 6184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register map = ToRegister(instr->map()); 6185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = ToRegister(instr->result()); 6186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label load_cache, done; 6187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ EnumLength(result, map); 6188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(result, Immediate(Smi::FromInt(0))); 6189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &load_cache, Label::kNear); 6190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, isolate()->factory()->empty_fixed_array()); 6191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 6192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6193864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&load_cache); 6194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadInstanceDescriptors(map, result); 6195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, 6196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FieldOperand(result, DescriptorArray::kEnumCacheOffset)); 6197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, 6198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FieldOperand(result, FixedArray::SizeFor(instr->idx()))); 6199864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 6200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(result, result); 6201b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(equal, instr, "no cache"); 6202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 6203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { 6206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register object = ToRegister(instr->value()); 6207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ToRegister(instr->map()), 6208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FieldOperand(object, HeapObject::kMapOffset)); 6209b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org DeoptimizeIf(not_equal, instr, "wrong map"); 6210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 6211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr, 6214864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register object, 6215864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register index) { 6216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PushSafepointRegistersScope scope(this); 6217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(object); 6218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(index); 6219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ xor_(esi, esi); 622006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ CallRuntimeSaveDoubles(Runtime::kLoadMutableDouble); 6221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordSafepointWithRegisters( 6222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr->pointer_map(), 2, Safepoint::kNoLazyDeopt); 6223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ StoreToSafepointRegisterSlot(object, eax); 6224864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 6225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6226864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) { 6228ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class DeferredLoadMutableDouble FINAL : public LDeferredCode { 6229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 6230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredLoadMutableDouble(LCodeGen* codegen, 6231864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LLoadFieldByIndex* instr, 6232864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register object, 6233864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register index, 6234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const X87Stack& x87_stack) 6235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : LDeferredCode(codegen, x87_stack), 6236864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org instr_(instr), 6237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org object_(object), 6238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org index_(index) { 6239864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 6240ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual void Generate() OVERRIDE { 6241864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->DoDeferredLoadMutableDouble(instr_, object_, index_); 6242864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 6243ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org virtual LInstruction* instr() OVERRIDE { return instr_; } 6244864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 6245864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LLoadFieldByIndex* instr_; 6246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register object_; 6247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register index_; 6248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org }; 6249864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register object = ToRegister(instr->object()); 6251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register index = ToRegister(instr->index()); 6252864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org DeferredLoadMutableDouble* deferred; 6254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org deferred = new(zone()) DeferredLoadMutableDouble( 6255864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org this, instr, object, index, x87_stack_); 6256864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6257864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label out_of_object, done; 6258864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(index, Immediate(Smi::FromInt(1))); 6259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, deferred->entry()); 6260864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6261864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sar(index, 1); 6262864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6263864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(index, Immediate(0)); 6264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(less, &out_of_object, Label::kNear); 6265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(object, FieldOperand(object, 6266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org index, 6267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org times_half_pointer_size, 6268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org JSObject::kHeaderSize)); 6269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 6270864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6271864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&out_of_object); 6272864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(object, FieldOperand(object, JSObject::kPropertiesOffset)); 6273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ neg(index); 6274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Index is now equal to out of object property index plus 1. 6275864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(object, FieldOperand(object, 6276864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org index, 6277864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org times_half_pointer_size, 6278864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FixedArray::kHeaderSize - kPointerSize)); 6279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(deferred->exit()); 6280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 6281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 6282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6284e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.orgvoid LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) { 6285e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Register context = ToRegister(instr->context()); 6286e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), context); 6287e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org} 6288e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org 6289e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org 6290e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.orgvoid LCodeGen::DoAllocateBlockContext(LAllocateBlockContext* instr) { 6291e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Handle<ScopeInfo> scope_info = instr->scope_info(); 6292e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ Push(scope_info); 6293e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ push(ToRegister(instr->function())); 629447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org CallRuntime(Runtime::kPushBlockContext, 2, instr); 6295e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org RecordSafepoint(Safepoint::kNoLazyDeopt); 6296e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org} 6297e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org 6298e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org 6299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#undef __ 6300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} } // namespace v8::internal 6302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 6303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif // V8_TARGET_ARCH_X87 6304