13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 23ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Redistribution and use in source and binary forms, with or without 33ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// modification, are permitted provided that the following conditions are 43ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// met: 53ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 63ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// * Redistributions of source code must retain the above copyright 73ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// notice, this list of conditions and the following disclaimer. 83ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// * Redistributions in binary form must reproduce the above 93ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// copyright notice, this list of conditions and the following 103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// disclaimer in the documentation and/or other materials provided 113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// with the distribution. 123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// * Neither the name of Google Inc. nor the names of its 133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// contributors may be used to endorse or promote products derived 143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// from this software without specific prior written permission. 153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "v8.h" 293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "mips/lithium-codegen-mips.h" 313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "mips/lithium-gap-resolver-mips.h" 323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "code-stubs.h" 333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "stub-cache.h" 343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochnamespace v8 { 363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochnamespace internal { 373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass SafepointGenerator : public CallWrapper { 403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SafepointGenerator(LCodeGen* codegen, 423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LPointerMap* pointers, 433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Safepoint::DeoptMode mode) 443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : codegen_(codegen), 453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch pointers_(pointers), 463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch deopt_mode_(mode) { } 473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual ~SafepointGenerator() { } 483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void BeforeCall(int call_size) const { } 503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void AfterCall() const { 523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch codegen_->RecordSafepoint(pointers_, deopt_mode_); 533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LCodeGen* codegen_; 573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LPointerMap* pointers_; 583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Safepoint::DeoptMode deopt_mode_; 593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define __ masm()-> 633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool LCodeGen::GenerateCode() { 653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HPhase phase("Z_Code generation", chunk()); 663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(is_unused()); 673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch status_ = GENERATING; 683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CpuFeatures::Scope scope(FPU); 693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CodeStub::GenerateFPStubs(); 713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Open a frame scope to indicate that there is a frame on the stack. The 733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // NONE indicates that the scope shouldn't actually generate code to set up 743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the frame (that is done in GeneratePrologue). 753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FrameScope frame_scope(masm_, StackFrame::NONE); 763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return GeneratePrologue() && 783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GenerateBody() && 793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GenerateDeferredCode() && 803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GenerateSafepointTable(); 813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::FinishCode(Handle<Code> code) { 853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(is_done()); 863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->set_stack_slots(GetStackSlotCount()); 873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); 883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PopulateDeoptimizationData(code); 893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::Abort(const char* format, ...) { 933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_trace_bailout) { 943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SmartArrayPointer<char> name( 953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info()->shared_info()->DebugName()->ToCString()); 963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("Aborting LCodeGen in @\"%s\": ", *name); 973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch va_list arguments; 983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch va_start(arguments, format); 993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch OS::VPrint(format, arguments); 1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch va_end(arguments); 1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF("\n"); 1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch status_ = ABORTED; 1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::Comment(const char* format, ...) { 1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!FLAG_code_comments) return; 1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch char buffer[4 * KB]; 1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StringBuilder builder(buffer, ARRAY_SIZE(buffer)); 1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch va_list arguments; 1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch va_start(arguments, format); 1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch builder.AddFormattedList(format, arguments); 1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch va_end(arguments); 1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Copy the string before recording it in the assembler to avoid 1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // issues when the stack allocated buffer goes out of scope. 1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch size_t length = builder.position(); 1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Vector<char> copy = Vector<char>::New(length + 1); 1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch memcpy(copy.start(), builder.Finalize(), copy.length()); 1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm()->RecordComment(copy.start()); 1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool LCodeGen::GeneratePrologue() { 1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(is_generating()); 1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (strlen(FLAG_stop_at) > 0 && 1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info_->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { 1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ stop("stop_at"); 1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // a1: Callee's JS function. 1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // cp: Callee's context. 1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // fp: Caller's frame pointer. 1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // lr: Caller's pc. 1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Strict mode functions and builtins need to replace the receiver 1413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // with undefined when called as functions (without an explicit 1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // receiver object). r5 is zero for method calls and non-zero for 1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // function calls. 1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!info_->is_classic_mode() || info_->is_native()) { 1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label ok; 1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&ok, eq, t1, Operand(zero_reg)); 1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int receiver_offset = scope()->num_parameters() * kPointerSize; 1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); 1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(a2, MemOperand(sp, receiver_offset)); 1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&ok); 1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Push(ra, fp, cp, a1); 1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(fp, sp, Operand(2 * kPointerSize)); // Adj. FP to point to saved FP. 1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Reserve space for the stack slots needed by the code. 1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int slots = GetStackSlotCount(); 1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (slots > 0) { 1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_debug_code) { 1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a0, Operand(slots)); 1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a2, Operand(kSlotsZapValue)); 1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label loop; 1643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&loop); 1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(a2); 1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Subu(a0, a0, 1); 1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&loop, ne, a0, Operand(zero_reg)); 1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Subu(sp, sp, Operand(slots * kPointerSize)); 1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Possibly allocate a local context. 1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (heap_slots > 0) { 1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Comment(";;; Allocate local context"); 1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Argument to NewContext is the function, which is in a1. 1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(a1); 1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (heap_slots <= FastNewContextStub::kMaximumSlots) { 1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FastNewContextStub stub(heap_slots); 1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CallStub(&stub); 1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 1833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CallRuntime(Runtime::kNewFunctionContext, 1); 1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordSafepoint(Safepoint::kNoLazyDeopt); 1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Context is returned in both v0 and cp. It replaces the context 1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // passed to us. It's saved in the stack and kept live in cp. 1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Copy any necessary parameters into the context. 1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int num_parameters = scope()->num_parameters(); 1913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < num_parameters; i++) { 1923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Variable* var = scope()->parameter(i); 1933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (var->IsContextSlot()) { 1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int parameter_offset = StandardFrameConstants::kCallerSPOffset + 1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (num_parameters - 1 - i) * kPointerSize; 1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load parameter from stack. 1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(a0, MemOperand(fp, parameter_offset)); 1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Store it in the context. 1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemOperand target = ContextOperand(cp, var->index()); 2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(a0, target); 2013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Update the write barrier. This clobbers a3 and a0. 2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ RecordWriteContextSlot( 2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cp, target.offset(), a0, a3, kRAHasBeenSaved, kSaveFPRegs); 2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Comment(";;; End allocate local context"); 2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Trace the call. 2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_trace) { 2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CallRuntime(Runtime::kTraceEnter, 0); 2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EnsureSpaceForLazyDeopt(); 2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return !is_aborted(); 2153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool LCodeGen::GenerateBody() { 2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(is_generating()); 2203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool emit_instructions = true; 2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (current_instruction_ = 0; 2223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !is_aborted() && current_instruction_ < instructions_->length(); 2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch current_instruction_++) { 2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LInstruction* instr = instructions_->at(current_instruction_); 2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->IsLabel()) { 2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LLabel* label = LLabel::cast(instr); 2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch emit_instructions = !label->HasReplacement(); 2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (emit_instructions) { 2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Comment(";;; @%d: %s.", current_instruction_, instr->Mnemonic()); 2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->CompileToNative(this); 2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return !is_aborted(); 2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool LCodeGen::GenerateDeferredCode() { 2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(is_generating()); 2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (deferred_.length() > 0) { 2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { 2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LDeferredCode* code = deferred_[i]; 2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(code->entry()); 2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Comment(";;; Deferred code @%d: %s.", 2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->instruction_index(), 2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->instr()->Mnemonic()); 2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->Generate(); 2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ jmp(code->exit()); 2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Deferred code is the last part of the instruction sequence. Mark 2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the generated code as done unless we bailed out. 2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!is_aborted()) status_ = DONE; 2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return !is_aborted(); 2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool LCodeGen::GenerateDeoptJumpTable() { 2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(plind): not clear that this will have advantage for MIPS. 2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Skipping it for now. Raised issue #100 for this. 2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Abort("Unimplemented: %s", "GenerateDeoptJumpTable"); 2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return false; 2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool LCodeGen::GenerateSafepointTable() { 2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(is_done()); 2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch safepoints_.Emit(masm(), GetStackSlotCount()); 2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return !is_aborted(); 2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2743ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochRegister LCodeGen::ToRegister(int index) const { 2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Register::FromAllocationIndex(index); 2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochDoubleRegister LCodeGen::ToDoubleRegister(int index) const { 2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return DoubleRegister::FromAllocationIndex(index); 2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochRegister LCodeGen::ToRegister(LOperand* op) const { 2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(op->IsRegister()); 2863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ToRegister(op->index()); 2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochRegister LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) { 2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (op->IsRegister()) { 2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ToRegister(op->index()); 2933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (op->IsConstantOperand()) { 2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LConstantOperand* const_op = LConstantOperand::cast(op); 2953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> literal = chunk_->LookupLiteral(const_op); 2963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Representation r = chunk_->LookupLiteralRepresentation(const_op); 2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (r.IsInteger32()) { 2983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(literal->IsNumber()); 2993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(scratch, Operand(static_cast<int32_t>(literal->Number()))); 3003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (r.IsDouble()) { 3013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Abort("EmitLoadRegister: Unsupported double immediate."); 3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(r.IsTagged()); 3043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (literal->IsSmi()) { 3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(scratch, Operand(literal)); 3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadHeapObject(scratch, Handle<HeapObject>::cast(literal)); 3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return scratch; 3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (op->IsStackSlot() || op->IsArgument()) { 3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch, ToMemOperand(op)); 3133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return scratch; 3143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return scratch; 3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochDoubleRegister LCodeGen::ToDoubleRegister(LOperand* op) const { 3213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(op->IsDoubleRegister()); 3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ToDoubleRegister(op->index()); 3233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3263ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochDoubleRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op, 3273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FloatRegister flt_scratch, 3283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister dbl_scratch) { 3293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (op->IsDoubleRegister()) { 3303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ToDoubleRegister(op->index()); 3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (op->IsConstantOperand()) { 3323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LConstantOperand* const_op = LConstantOperand::cast(op); 3333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> literal = chunk_->LookupLiteral(const_op); 3343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Representation r = chunk_->LookupLiteralRepresentation(const_op); 3353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (r.IsInteger32()) { 3363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(literal->IsNumber()); 3373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(at, Operand(static_cast<int32_t>(literal->Number()))); 3383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mtc1(at, flt_scratch); 3393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ cvt_d_w(dbl_scratch, flt_scratch); 3403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return dbl_scratch; 3413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (r.IsDouble()) { 3423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Abort("unsupported double immediate"); 3433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (r.IsTagged()) { 3443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Abort("unsupported tagged immediate"); 3453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (op->IsStackSlot() || op->IsArgument()) { 3473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemOperand mem_op = ToMemOperand(op); 3483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ ldc1(dbl_scratch, mem_op); 3493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return dbl_scratch; 3503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 3523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return dbl_scratch; 3533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3563ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { 3573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> literal = chunk_->LookupLiteral(op); 3583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged()); 3593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return literal; 3603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool LCodeGen::IsInteger32(LConstantOperand* op) const { 3643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return chunk_->LookupLiteralRepresentation(op).IsInteger32(); 3653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint LCodeGen::ToInteger32(LConstantOperand* op) const { 3693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> value = chunk_->LookupLiteral(op); 3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger32()); 3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(static_cast<double>(static_cast<int32_t>(value->Number())) == 3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch value->Number()); 3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return static_cast<int32_t>(value->Number()); 3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochdouble LCodeGen::ToDouble(LConstantOperand* op) const { 3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> value = chunk_->LookupLiteral(op); 3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return value->Number(); 3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochOperand LCodeGen::ToOperand(LOperand* op) { 3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (op->IsConstantOperand()) { 3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LConstantOperand* const_op = LConstantOperand::cast(op); 3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> literal = chunk_->LookupLiteral(const_op); 3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Representation r = chunk_->LookupLiteralRepresentation(const_op); 3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (r.IsInteger32()) { 3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(literal->IsNumber()); 3903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Operand(static_cast<int32_t>(literal->Number())); 3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (r.IsDouble()) { 3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Abort("ToOperand Unsupported double immediate."); 3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(r.IsTagged()); 3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Operand(literal); 3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (op->IsRegister()) { 3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Operand(ToRegister(op)); 3983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (op->IsDoubleRegister()) { 3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Abort("ToOperand IsDoubleRegister unimplemented"); 4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Operand(0); 4013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Stack slots not implemented, use ToMemOperand instead. 4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Operand(0); 4053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMemOperand LCodeGen::ToMemOperand(LOperand* op) const { 4093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!op->IsRegister()); 4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!op->IsDoubleRegister()); 4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot()); 4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int index = op->index(); 4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (index >= 0) { 4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Local or spill slot. Skip the frame pointer, function, and 4153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // context in the fixed part of the frame. 4163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return MemOperand(fp, -(index + 3) * kPointerSize); 4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 4183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Incoming parameter. Skip the return address. 4193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return MemOperand(fp, -(index - 1) * kPointerSize); 4203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4243ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMemOperand LCodeGen::ToHighMemOperand(LOperand* op) const { 4253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(op->IsDoubleStackSlot()); 4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int index = op->index(); 4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (index >= 0) { 4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Local or spill slot. Skip the frame pointer, function, context, 4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // and the first word of the double in the fixed part of the frame. 4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return MemOperand(fp, -(index + 3) * kPointerSize + kPointerSize); 4313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 4323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Incoming parameter. Skip the return address and the first word of 4333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the double. 4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return MemOperand(fp, -(index - 1) * kPointerSize + kPointerSize); 4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::WriteTranslation(LEnvironment* environment, 4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Translation* translation) { 4413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (environment == NULL) return; 4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The translation includes one command per value in the environment. 4443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int translation_size = environment->values()->length(); 4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The output frame height does not include the parameters. 4463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int height = translation_size - environment->parameter_count(); 4473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch WriteTranslation(environment->outer(), translation); 4493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int closure_id = DefineDeoptimizationLiteral(environment->closure()); 4503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (environment->frame_type()) { 4513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case JS_FUNCTION: 4523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch translation->BeginJSFrame(environment->ast_id(), closure_id, height); 4533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 4543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case JS_CONSTRUCT: 4553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch translation->BeginConstructStubFrame(closure_id, translation_size); 4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case ARGUMENTS_ADAPTOR: 4583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch translation->BeginArgumentsAdaptorFrame(closure_id, translation_size); 4593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 4603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 4623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < translation_size; ++i) { 4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* value = environment->values()->at(i); 4653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // spilled_registers_ and spilled_double_registers_ are either 4663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // both NULL or both set. 4673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (environment->spilled_registers() != NULL && value != NULL) { 4683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (value->IsRegister() && 4693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch environment->spilled_registers()[value->index()] != NULL) { 4703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch translation->MarkDuplicate(); 4713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AddToTranslation(translation, 4723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch environment->spilled_registers()[value->index()], 4733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch environment->HasTaggedValueAt(i)); 4743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if ( 4753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch value->IsDoubleRegister() && 4763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch environment->spilled_double_registers()[value->index()] != NULL) { 4773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch translation->MarkDuplicate(); 4783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AddToTranslation( 4793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch translation, 4803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch environment->spilled_double_registers()[value->index()], 4813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch false); 4823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AddToTranslation(translation, value, environment->HasTaggedValueAt(i)); 4863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::AddToTranslation(Translation* translation, 4913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* op, 4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool is_tagged) { 4933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (op == NULL) { 4943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(twuerthinger): Introduce marker operands to indicate that this value 4953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // is not present and must be reconstructed from the deoptimizer. Currently 4963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // this is only used for the arguments object. 4973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch translation->StoreArgumentsObject(); 4983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (op->IsStackSlot()) { 4993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (is_tagged) { 5003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch translation->StoreStackSlot(op->index()); 5013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 5023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch translation->StoreInt32StackSlot(op->index()); 5033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (op->IsDoubleStackSlot()) { 5053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch translation->StoreDoubleStackSlot(op->index()); 5063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (op->IsArgument()) { 5073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(is_tagged); 5083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int src_index = GetStackSlotCount() + op->index(); 5093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch translation->StoreStackSlot(src_index); 5103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (op->IsRegister()) { 5113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = ToRegister(op); 5123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (is_tagged) { 5133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch translation->StoreRegister(reg); 5143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 5153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch translation->StoreInt32Register(reg); 5163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (op->IsDoubleRegister()) { 5183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister reg = ToDoubleRegister(op); 5193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch translation->StoreDoubleRegister(reg); 5203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (op->IsConstantOperand()) { 5213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> literal = chunk()->LookupLiteral(LConstantOperand::cast(op)); 5223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int src_index = DefineDeoptimizationLiteral(literal); 5233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch translation->StoreLiteral(src_index); 5243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 5253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 5263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 5283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::CallCode(Handle<Code> code, 5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RelocInfo::Mode mode, 5323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LInstruction* instr) { 5333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT); 5343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 5353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::CallCodeGeneric(Handle<Code> code, 5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RelocInfo::Mode mode, 5393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LInstruction* instr, 5403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SafepointMode safepoint_mode) { 5413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(instr != NULL); 5423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LPointerMap* pointers = instr->pointer_map(); 5433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordPosition(pointers->position()); 5443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Call(code, mode); 5453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordSafepointWithLazyDeopt(instr, safepoint_mode); 5463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 5473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::CallRuntime(const Runtime::Function* function, 5503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int num_arguments, 5513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LInstruction* instr) { 5523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(instr != NULL); 5533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LPointerMap* pointers = instr->pointer_map(); 5543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(pointers != NULL); 5553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordPosition(pointers->position()); 5563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CallRuntime(function, num_arguments); 5583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 5593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 5603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, 5633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int argc, 5643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LInstruction* instr) { 5653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CallRuntimeSaveDoubles(id); 5663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordSafepointWithRegisters( 5673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->pointer_map(), argc, Safepoint::kNoLazyDeopt); 5683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 5693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment, 5723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Safepoint::DeoptMode mode) { 5733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!environment->HasBeenRegistered()) { 5743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Physical stack frame layout: 5753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // -x ............. -4 0 ..................................... y 5763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // [incoming arguments] [spill slots] [pushed outgoing arguments] 5773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Layout of the environment: 5793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 0 ..................................................... size-1 5803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // [parameters] [locals] [expression stack including arguments] 5813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Layout of the translation: 5833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 0 ........................................................ size - 1 + 4 5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // [expression stack including arguments] [locals] [4 words] [parameters] 5853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // |>------------ translation_size ------------<| 5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int frame_count = 0; 5883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int jsframe_count = 0; 5893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (LEnvironment* e = environment; e != NULL; e = e->outer()) { 5903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ++frame_count; 5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (e->frame_type() == JS_FUNCTION) { 5923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ++jsframe_count; 5933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Translation translation(&translations_, frame_count, jsframe_count); 5963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch WriteTranslation(environment, &translation); 5973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int deoptimization_index = deoptimizations_.length(); 5983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int pc_offset = masm()->pc_offset(); 5993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch environment->Register(deoptimization_index, 6003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch translation.index(), 6013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); 6023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch deoptimizations_.Add(environment); 6033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 6053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DeoptimizeIf(Condition cc, 6083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LEnvironment* environment, 6093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register src1, 6103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const Operand& src2) { 6113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 6123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(environment->HasBeenRegistered()); 6133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int id = environment->deoptimization_index(); 6143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address entry = Deoptimizer::GetDeoptimizationEntry(id, Deoptimizer::EAGER); 6153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (entry == NULL) { 6163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Abort("bailout was not prepared"); 6173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return; 6183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on MIPS. 6213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_deopt_every_n_times == 1 && 6233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info_->shared_info()->opt_count() == id) { 6243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Jump(entry, RelocInfo::RUNTIME_ENTRY); 6253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return; 6263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_trap_on_deopt) { 6293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label skip; 6303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (cc != al) { 6313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&skip, NegateCondition(cc), src1, src2); 6323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ stop("trap_on_deopt"); 6343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&skip); 6353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(plind): The Arm port is a little different here, due to their 6383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // DeOpt jump table, which is not used for Mips yet. 6393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Jump(entry, RelocInfo::RUNTIME_ENTRY, cc, src1, src2); 6403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 6413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { 6443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int length = deoptimizations_.length(); 6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (length == 0) return; 6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<DeoptimizationInputData> data = 6473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewDeoptimizationInputData(length, TENURED); 6483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<ByteArray> translations = translations_.CreateByteArray(); 6503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch data->SetTranslationByteArray(*translations); 6513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); 6523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<FixedArray> literals = 6543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); 6553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < deoptimization_literals_.length(); i++) { 6563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch literals->set(i, *deoptimization_literals_[i]); 6573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch data->SetLiteralArray(*literals); 6593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id())); 6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); 6623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Populate the deoptimization entries. 6643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < length; i++) { 6653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LEnvironment* env = deoptimizations_[i]; 6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch data->SetAstId(i, Smi::FromInt(env->ast_id())); 6673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); 6683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch data->SetArgumentsStackHeight(i, 6693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Smi::FromInt(env->arguments_stack_height())); 6703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch data->SetPc(i, Smi::FromInt(env->pc_offset())); 6713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->set_deoptimization_data(*data); 6733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 6743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint LCodeGen::DefineDeoptimizationLiteral(Handle<Object> literal) { 6773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int result = deoptimization_literals_.length(); 6783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < deoptimization_literals_.length(); ++i) { 6793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (deoptimization_literals_[i].is_identical_to(literal)) return i; 6803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch deoptimization_literals_.Add(literal); 6823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return result; 6833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 6843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::PopulateDeoptimizationLiteralsWithInlinedFunctions() { 6873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(deoptimization_literals_.length() == 0); 6883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const ZoneList<Handle<JSFunction> >* inlined_closures = 6903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch chunk()->inlined_closures(); 6913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0, length = inlined_closures->length(); 6933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i < length; 6943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i++) { 6953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DefineDeoptimizationLiteral(inlined_closures->at(i)); 6963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inlined_function_count_ = deoptimization_literals_.length(); 6993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 7003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::RecordSafepointWithLazyDeopt( 7033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LInstruction* instr, SafepointMode safepoint_mode) { 7043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) { 7053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt); 7063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 7073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 7083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordSafepointWithRegisters( 7093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->pointer_map(), 0, Safepoint::kLazyDeopt); 7103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 7123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::RecordSafepoint( 7153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LPointerMap* pointers, 7163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Safepoint::Kind kind, 7173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int arguments, 7183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Safepoint::DeoptMode deopt_mode) { 7193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(expected_safepoint_kind_ == kind); 7203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const ZoneList<LOperand*>* operands = pointers->GetNormalizedOperands(); 7223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Safepoint safepoint = safepoints_.DefineSafepoint(masm(), 7233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kind, arguments, deopt_mode); 7243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < operands->length(); i++) { 7253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* pointer = operands->at(i); 7263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (pointer->IsStackSlot()) { 7273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch safepoint.DefinePointerSlot(pointer->index()); 7283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { 7293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch safepoint.DefinePointerRegister(ToRegister(pointer)); 7303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (kind & Safepoint::kWithRegisters) { 7333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Register cp always contains a pointer to the context. 7343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch safepoint.DefinePointerRegister(cp); 7353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 7373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::RecordSafepoint(LPointerMap* pointers, 7403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Safepoint::DeoptMode deopt_mode) { 7413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordSafepoint(pointers, Safepoint::kSimple, 0, deopt_mode); 7423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 7433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::RecordSafepoint(Safepoint::DeoptMode deopt_mode) { 7463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LPointerMap empty_pointers(RelocInfo::kNoPosition); 7473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordSafepoint(&empty_pointers, deopt_mode); 7483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 7493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, 7523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int arguments, 7533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Safepoint::DeoptMode deopt_mode) { 7543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordSafepoint( 7553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch pointers, Safepoint::kWithRegisters, arguments, deopt_mode); 7563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 7573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::RecordSafepointWithRegistersAndDoubles( 7603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LPointerMap* pointers, 7613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int arguments, 7623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Safepoint::DeoptMode deopt_mode) { 7633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordSafepoint( 7643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch pointers, Safepoint::kWithRegistersAndDoubles, arguments, deopt_mode); 7653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 7663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::RecordPosition(int position) { 7693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (position == RelocInfo::kNoPosition) return; 7703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm()->positions_recorder()->RecordPosition(position); 7713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 7723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoLabel(LLabel* label) { 7753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (label->is_loop_header()) { 7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Comment(";;; B%d - LOOP entry", label->block_id()); 7773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 7783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Comment(";;; B%d", label->block_id()); 7793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(label->label()); 7813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch current_block_ = label->block_id(); 7823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoGap(label); 7833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 7843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoParallelMove(LParallelMove* move) { 7873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch resolver_.Resolve(move); 7883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 7893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoGap(LGap* gap) { 7923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = LGap::FIRST_INNER_POSITION; 7933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i <= LGap::LAST_INNER_POSITION; 7943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch i++) { 7953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LGap::InnerPosition inner_pos = static_cast<LGap::InnerPosition>(i); 7963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LParallelMove* move = gap->GetParallelMove(inner_pos); 7973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (move != NULL) DoParallelMove(move); 7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 8003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoInstructionGap(LInstructionGap* instr) { 8033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoGap(instr); 8043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 8053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoParameter(LParameter* instr) { 8083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Nothing to do. 8093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 8103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCallStub(LCallStub* instr) { 8133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->result()).is(v0)); 8143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (instr->hydrogen()->major_key()) { 8153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CodeStub::RegExpConstructResult: { 8163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RegExpConstructResultStub stub; 8173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 8183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 8193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CodeStub::RegExpExec: { 8213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RegExpExecStub stub; 8223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 8233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 8243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CodeStub::SubString: { 8263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SubStringStub stub; 8273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 8283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 8293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CodeStub::NumberToString: { 8313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NumberToStringStub stub; 8323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 8333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 8343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CodeStub::StringAdd: { 8363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StringAddStub stub(NO_STRING_ADD_FLAGS); 8373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 8383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 8393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CodeStub::StringCompare: { 8413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StringCompareStub stub; 8423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 8433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 8443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CodeStub::TranscendentalCache: { 8463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(a0, MemOperand(sp, 0)); 8473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TranscendentalCacheStub stub(instr->transcendental_type(), 8483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TranscendentalCacheStub::TAGGED); 8493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 8503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 8513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 8533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 8543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 8563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 8593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Nothing to do. 8603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 8613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoModI(LModI* instr) { 8643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 8653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const Register left = ToRegister(instr->InputAt(0)); 8663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const Register result = ToRegister(instr->result()); 8673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 8693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->HasPowerOf2Divisor()) { 8713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 8723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!left.is(scratch)); 8733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(scratch, left); 8743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int32_t p2constant = HConstant::cast( 8753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->hydrogen()->right())->Integer32Value(); 8763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(p2constant != 0); 8773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Result always takes the sign of the dividend (left). 8783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch p2constant = abs(p2constant); 8793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label positive_dividend; 8813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(USE_DELAY_SLOT, &positive_dividend, ge, left, Operand(zero_reg)); 8823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ subu(result, zero_reg, left); 8833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(result, result, p2constant - 1); 8843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 8853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg)); 8863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(USE_DELAY_SLOT, &done); 8883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ subu(result, zero_reg, result); 8893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&positive_dividend); 8903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(result, scratch, p2constant - 1); 8913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 8923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // div runs in the background while we check for special cases. 8933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register right = EmitLoadRegister(instr->InputAt(1), scratch); 8943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ div(left, right); 8953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check for x % 0. 8973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 8983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg)); 8993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 9003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(USE_DELAY_SLOT, &done, ge, left, Operand(zero_reg)); 9023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mfhi(result); 9033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 9053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg)); 9063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 9073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 9083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 9093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 9103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoDivI(LDivI* instr) { 9133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const Register left = ToRegister(instr->InputAt(0)); 9143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const Register right = ToRegister(instr->InputAt(1)); 9153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const Register result = ToRegister(instr->result()); 9163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // On MIPS div is asynchronous - it will run in the background while we 9183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // check for special cases. 9193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ div(left, right); 9203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check for x / 0. 9223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { 9233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg)); 9243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 9253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check for (0 / -x) that will produce negative zero. 9273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 9283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label left_not_zero; 9293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&left_not_zero, ne, left, Operand(zero_reg)); 9303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(lt, instr->environment(), right, Operand(zero_reg)); 9313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&left_not_zero); 9323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 9333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check for (-kMinInt / -1). 9353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 9363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label left_not_min_int; 9373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&left_not_min_int, ne, left, Operand(kMinInt)); 9383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), right, Operand(-1)); 9393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&left_not_min_int); 9403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 9413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mfhi(result); 9433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), result, Operand(zero_reg)); 9443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mflo(result); 9453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 9463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoMulI(LMulI* instr) { 9493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 9503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 9513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Note that result may alias left. 9523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register left = ToRegister(instr->InputAt(0)); 9533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* right_op = instr->InputAt(1); 9543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 9563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool bailout_on_minus_zero = 9573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); 9583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (right_op->IsConstantOperand() && !can_overflow) { 9603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Use optimized code for specific constants. 9613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); 9623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (bailout_on_minus_zero && (constant < 0)) { 9643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The case of a null constant will be handled separately. 9653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If constant is negative and left is null, the result should be -0. 9663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), left, Operand(zero_reg)); 9673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 9683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (constant) { 9703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case -1: 9713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Subu(result, zero_reg, left); 9723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 9733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case 0: 9743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (bailout_on_minus_zero) { 9753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If left is strictly negative and the constant is null, the 9763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // result is -0. Deoptimize if required, otherwise return 0. 9773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(lt, instr->environment(), left, Operand(zero_reg)); 9783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 9793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(result, zero_reg); 9803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 9813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case 1: 9823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Nothing to do. 9833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Move(result, left); 9843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 9853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 9863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Multiplying by powers of two and powers of two plus or minus 9873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // one can be done faster with shifted operands. 9883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // For other constants we emit standard code. 9893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int32_t mask = constant >> 31; 9903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t constant_abs = (constant + mask) ^ mask; 9913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 9923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (IsPowerOf2(constant_abs) || 9933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch IsPowerOf2(constant_abs - 1) || 9943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch IsPowerOf2(constant_abs + 1)) { 9953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (IsPowerOf2(constant_abs)) { 9963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int32_t shift = WhichPowerOf2(constant_abs); 9973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sll(result, left, shift); 9983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (IsPowerOf2(constant_abs - 1)) { 9993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int32_t shift = WhichPowerOf2(constant_abs - 1); 10003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sll(result, left, shift); 10013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(result, result, left); 10023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (IsPowerOf2(constant_abs + 1)) { 10033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int32_t shift = WhichPowerOf2(constant_abs + 1); 10043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sll(result, left, shift); 10053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Subu(result, result, left); 10063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Correct the sign of the result is the constant is negative. 10093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (constant < 0) { 10103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Subu(result, zero_reg, result); 10113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 10143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Generate standard code. 10153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(at, constant); 10163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Mul(result, left, at); 10173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 10213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register right = EmitLoadRegister(right_op, scratch); 10223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (bailout_on_minus_zero) { 10233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Or(ToRegister(instr->TempAt(0)), left, right); 10243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (can_overflow) { 10273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // hi:lo = left * right. 10283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mult(left, right); 10293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mfhi(scratch); 10303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mflo(result); 10313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sra(at, result, 31); 10323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), scratch, Operand(at)); 10333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 10343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Mul(result, left, right); 10353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (bailout_on_minus_zero) { 10383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Bail out if the result is supposed to be negative zero. 10393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 10403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done, ne, result, Operand(zero_reg)); 10413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(lt, 10423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->environment(), 10433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ToRegister(instr->TempAt(0)), 10443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(zero_reg)); 10453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 10463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 10493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoBitI(LBitI* instr) { 10523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* left_op = instr->InputAt(0); 10533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* right_op = instr->InputAt(1); 10543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(left_op->IsRegister()); 10553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register left = ToRegister(left_op); 10563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 10573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand right(no_reg); 10583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (right_op->IsStackSlot() || right_op->IsArgument()) { 10603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch right = Operand(EmitLoadRegister(right_op, at)); 10613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 10623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(right_op->IsRegister() || right_op->IsConstantOperand()); 10633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch right = ToOperand(right_op); 10643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (instr->op()) { 10673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::BIT_AND: 10683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(result, left, right); 10693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 10703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::BIT_OR: 10713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Or(result, left, right); 10723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 10733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::BIT_XOR: 10743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Xor(result, left, right); 10753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 10763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 10773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 10783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 10793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 10813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoShiftI(LShiftI* instr) { 10843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Both 'left' and 'right' are "used at start" (see LCodeGen::DoShift), so 10853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // result may alias either of them. 10863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* right_op = instr->InputAt(1); 10873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register left = ToRegister(instr->InputAt(0)); 10883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 10893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (right_op->IsRegister()) { 10913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // No need to mask the right operand on MIPS, it is built into the variable 10923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // shift instructions. 10933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (instr->op()) { 10943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::SAR: 10953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ srav(result, left, ToRegister(right_op)); 10963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 10973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::SHR: 10983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ srlv(result, left, ToRegister(right_op)); 10993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->can_deopt()) { 11003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg)); 11013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 11033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::SHL: 11043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sllv(result, left, ToRegister(right_op)); 11053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 11063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 11073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 11083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 11093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 11113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Mask the right_op operand. 11123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int value = ToInteger32(LConstantOperand::cast(right_op)); 11133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint8_t shift_count = static_cast<uint8_t>(value & 0x1F); 11143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (instr->op()) { 11153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::SAR: 11163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (shift_count != 0) { 11173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sra(result, left, shift_count); 11183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 11193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Move(result, left); 11203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 11223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::SHR: 11233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (shift_count != 0) { 11243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ srl(result, left, shift_count); 11253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 11263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->can_deopt()) { 11273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(at, left, Operand(0x80000000)); 11283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); 11293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Move(result, left); 11313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 11333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::SHL: 11343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (shift_count != 0) { 11353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sll(result, left, shift_count); 11363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 11373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Move(result, left); 11383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 11403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 11413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 11423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 11433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 11463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoSubI(LSubI* instr) { 11493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* left = instr->InputAt(0); 11503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* right = instr->InputAt(1); 11513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* result = instr->result(); 11523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 11533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!can_overflow) { 11553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (right->IsStackSlot() || right->IsArgument()) { 11563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register right_reg = EmitLoadRegister(right, at); 11573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Subu(ToRegister(result), ToRegister(left), Operand(right_reg)); 11583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 11593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(right->IsRegister() || right->IsConstantOperand()); 11603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Subu(ToRegister(result), ToRegister(left), ToOperand(right)); 11613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { // can_overflow. 11633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register overflow = scratch0(); 11643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch1(); 11653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (right->IsStackSlot() || 11663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch right->IsArgument() || 11673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch right->IsConstantOperand()) { 11683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register right_reg = EmitLoadRegister(right, scratch); 11693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ SubuAndCheckForOverflow(ToRegister(result), 11703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ToRegister(left), 11713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch right_reg, 11723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch overflow); // Reg at also used as scratch. 11733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 11743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(right->IsRegister()); 11753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Due to overflow check macros not supporting constant operands, 11763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // handling the IsConstantOperand case was moved to prev if clause. 11773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ SubuAndCheckForOverflow(ToRegister(result), 11783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ToRegister(left), 11793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ToRegister(right), 11803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch overflow); // Reg at also used as scratch. 11813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(lt, instr->environment(), overflow, Operand(zero_reg)); 11833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 11853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoConstantI(LConstantI* instr) { 11883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(instr->result()->IsRegister()); 11893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(ToRegister(instr->result()), Operand(instr->value())); 11903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 11913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoConstantD(LConstantD* instr) { 11943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(instr->result()->IsDoubleRegister()); 11953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister result = ToDoubleRegister(instr->result()); 11963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double v = instr->value(); 11973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Move(result, v); 11983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 11993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoConstantT(LConstantT* instr) { 12023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> value = instr->value(); 12033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (value->IsSmi()) { 12043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(ToRegister(instr->result()), Operand(value)); 12053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 12063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadHeapObject(ToRegister(instr->result()), 12073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<HeapObject>::cast(value)); 12083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 12103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { 12133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 12143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register array = ToRegister(instr->InputAt(0)); 12153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(array, JSArray::kLengthOffset)); 12163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 12173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) { 12203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 12213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register array = ToRegister(instr->InputAt(0)); 12223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(array, FixedArrayBase::kLengthOffset)); 12233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 12243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoElementsKind(LElementsKind* instr) { 12273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 12283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input = ToRegister(instr->InputAt(0)); 12293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load map into |result|. 12313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(input, HeapObject::kMapOffset)); 12323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load the map's "bit field 2" into |result|. We only need the first byte, 12333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // but the following bit field extraction takes care of that anyway. 12343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lbu(result, FieldMemOperand(result, Map::kBitField2Offset)); 12353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Retrieve elements_kind from bit field 2. 12363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Ext(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount); 12373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 12383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoValueOf(LValueOf* instr) { 12413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input = ToRegister(instr->InputAt(0)); 12423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 12433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register map = ToRegister(instr->TempAt(0)); 12443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 12453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If the object is a smi return the object. 12473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Move(result, input); 12483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ JumpIfSmi(input, &done); 12493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If the object is not a value type, return the object. 12513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ GetObjectType(input, map, map); 12523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done, ne, map, Operand(JS_VALUE_TYPE)); 12533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(input, JSValue::kValueOffset)); 12543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 12563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 12573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoDateField(LDateField* instr) { 12603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object = ToRegister(instr->InputAt(0)); 12613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 12623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = ToRegister(instr->TempAt(0)); 12633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Smi* index = instr->index(); 12643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label runtime, done; 12653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(object.is(a0)); 12663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(result.is(v0)); 12673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!scratch.is(scratch0())); 12683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!scratch.is(object)); 12693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 12713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ AbortIfSmi(object); 12723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ GetObjectType(object, scratch, scratch); 12733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Assert(eq, "Trying to get date field from non-date.", 12743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch, Operand(JS_DATE_TYPE)); 12753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 12763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (index->value() == 0) { 12783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(object, JSDate::kValueOffset)); 12793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 12803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (index->value() < JSDate::kFirstUncachedField) { 12813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExternalReference stamp = ExternalReference::date_cache_stamp(isolate()); 12823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(scratch, Operand(stamp)); 12833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch, MemOperand(scratch)); 12843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch0(), FieldMemOperand(object, JSDate::kCacheStampOffset)); 12853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&runtime, ne, scratch, Operand(scratch0())); 12863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(object, JSDate::kValueOffset + 12873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kPointerSize * index->value())); 12883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ jmp(&done); 12893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&runtime); 12913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ PrepareCallCFunction(2, scratch); 12923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a1, Operand(index)); 12933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); 12943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 12953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 12973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoBitNotI(LBitNotI* instr) { 13003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input = ToRegister(instr->InputAt(0)); 13013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 13023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Nor(result, zero_reg, Operand(input)); 13033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 13043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoThrow(LThrow* instr) { 13073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input_reg = EmitLoadRegister(instr->InputAt(0), at); 13083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(input_reg); 13093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntime(Runtime::kThrow, 1, instr); 13103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_debug_code) { 13123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ stop("Unreachable code."); 13133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 13143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 13153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoAddI(LAddI* instr) { 13183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* left = instr->InputAt(0); 13193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* right = instr->InputAt(1); 13203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* result = instr->result(); 13213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); 13223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!can_overflow) { 13243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (right->IsStackSlot() || right->IsArgument()) { 13253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register right_reg = EmitLoadRegister(right, at); 13263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(ToRegister(result), ToRegister(left), Operand(right_reg)); 13273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 13283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(right->IsRegister() || right->IsConstantOperand()); 13293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(ToRegister(result), ToRegister(left), ToOperand(right)); 13303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 13313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { // can_overflow. 13323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register overflow = scratch0(); 13333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch1(); 13343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (right->IsStackSlot() || 13353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch right->IsArgument() || 13363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch right->IsConstantOperand()) { 13373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register right_reg = EmitLoadRegister(right, scratch); 13383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ AdduAndCheckForOverflow(ToRegister(result), 13393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ToRegister(left), 13403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch right_reg, 13413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch overflow); // Reg at also used as scratch. 13423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 13433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(right->IsRegister()); 13443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Due to overflow check macros not supporting constant operands, 13453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // handling the IsConstantOperand case was moved to prev if clause. 13463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ AdduAndCheckForOverflow(ToRegister(result), 13473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ToRegister(left), 13483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ToRegister(right), 13493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch overflow); // Reg at also used as scratch. 13503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 13513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(lt, instr->environment(), overflow, Operand(zero_reg)); 13523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 13533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 13543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoArithmeticD(LArithmeticD* instr) { 13573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister left = ToDoubleRegister(instr->InputAt(0)); 13583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister right = ToDoubleRegister(instr->InputAt(1)); 13593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister result = ToDoubleRegister(instr->result()); 13603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (instr->op()) { 13613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::ADD: 13623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ add_d(result, left, right); 13633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 13643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::SUB: 13653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sub_d(result, left, right); 13663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 13673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::MUL: 13683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mul_d(result, left, right); 13693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 13703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::DIV: 13713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ div_d(result, left, right); 13723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 13733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::MOD: { 13743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Save a0-a3 on the stack. 13753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RegList saved_regs = a0.bit() | a1.bit() | a2.bit() | a3.bit(); 13763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ MultiPush(saved_regs); 13773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ PrepareCallCFunction(0, 2, scratch0()); 13793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ SetCallCDoubleArguments(left, right); 13803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CallCFunction( 13813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExternalReference::double_fp_operation(Token::MOD, isolate()), 13823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 0, 2); 13833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Move the result in the double result register. 13843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ GetCFunctionDoubleResult(result); 13853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Restore saved register. 13873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ MultiPop(saved_regs); 13883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 13893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 13903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 13913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 13923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 13933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 13943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 13953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoArithmeticT(LArithmeticT* instr) { 13983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->InputAt(0)).is(a1)); 13993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->InputAt(1)).is(a0)); 14003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->result()).is(v0)); 14013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch BinaryOpStub stub(instr->op(), NO_OVERWRITE); 14033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 14043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Other arch use a nop here, to signal that there is no inlined 14053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // patchable code. Mips does not need the nop, since our marker 14063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // instruction (andi zero_reg) will never be used in normal code. 14073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 14083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint LCodeGen::GetNextEmittedBlock(int block) { 14113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = block + 1; i < graph()->blocks()->length(); ++i) { 14123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LLabel* label = chunk_->GetLabel(i); 14133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!label->HasReplacement()) return i; 14143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 14153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return -1; 14163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 14173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::EmitBranch(int left_block, int right_block, 14203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition cc, Register src1, const Operand& src2) { 14213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int next_block = GetNextEmittedBlock(current_block_); 14223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch right_block = chunk_->LookupDestination(right_block); 14233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch left_block = chunk_->LookupDestination(left_block); 14243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (right_block == left_block) { 14253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitGoto(left_block); 14263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (left_block == next_block) { 14273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(chunk_->GetAssemblyLabel(right_block), 14283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NegateCondition(cc), src1, src2); 14293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (right_block == next_block) { 14303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(chunk_->GetAssemblyLabel(left_block), cc, src1, src2); 14313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 14323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(chunk_->GetAssemblyLabel(left_block), cc, src1, src2); 14333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(chunk_->GetAssemblyLabel(right_block)); 14343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 14353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 14363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::EmitBranchF(int left_block, int right_block, 14393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition cc, FPURegister src1, FPURegister src2) { 14403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int next_block = GetNextEmittedBlock(current_block_); 14413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch right_block = chunk_->LookupDestination(right_block); 14423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch left_block = chunk_->LookupDestination(left_block); 14433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (right_block == left_block) { 14443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitGoto(left_block); 14453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (left_block == next_block) { 14463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ BranchF(chunk_->GetAssemblyLabel(right_block), NULL, 14473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NegateCondition(cc), src1, src2); 14483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (right_block == next_block) { 14493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ BranchF(chunk_->GetAssemblyLabel(left_block), NULL, cc, src1, src2); 14503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 14513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ BranchF(chunk_->GetAssemblyLabel(left_block), NULL, cc, src1, src2); 14523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(chunk_->GetAssemblyLabel(right_block)); 14533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 14543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 14553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoBranch(LBranch* instr) { 14583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int true_block = chunk_->LookupDestination(instr->true_block_id()); 14593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int false_block = chunk_->LookupDestination(instr->false_block_id()); 14603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Representation r = instr->hydrogen()->value()->representation(); 14623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (r.IsInteger32()) { 14633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = ToRegister(instr->InputAt(0)); 14643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg)); 14653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (r.IsDouble()) { 14663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister reg = ToDoubleRegister(instr->InputAt(0)); 14673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Test the double value. Zero and NaN are false. 14683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranchF(true_block, false_block, ne, reg, kDoubleRegZero); 14693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 14703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(r.IsTagged()); 14713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = ToRegister(instr->InputAt(0)); 14723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HType type = instr->hydrogen()->value()->type(); 14733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (type.IsBoolean()) { 14743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kTrueValueRootIndex); 14753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranch(true_block, false_block, eq, reg, Operand(at)); 14763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (type.IsSmi()) { 14773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg)); 14783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 14793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* true_label = chunk_->GetAssemblyLabel(true_block); 14803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* false_label = chunk_->GetAssemblyLabel(false_block); 14813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); 14833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Avoid deopts in the case where we've never executed this path before. 14843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (expected.IsEmpty()) expected = ToBooleanStub::all_types(); 14853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (expected.Contains(ToBooleanStub::UNDEFINED)) { 14873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // undefined -> false. 14883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 14893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(false_label, eq, reg, Operand(at)); 14903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 14913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (expected.Contains(ToBooleanStub::BOOLEAN)) { 14923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Boolean -> its value. 14933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kTrueValueRootIndex); 14943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(true_label, eq, reg, Operand(at)); 14953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kFalseValueRootIndex); 14963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(false_label, eq, reg, Operand(at)); 14973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 14983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (expected.Contains(ToBooleanStub::NULL_TYPE)) { 14993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 'null' -> false. 15003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kNullValueRootIndex); 15013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(false_label, eq, reg, Operand(at)); 15023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (expected.Contains(ToBooleanStub::SMI)) { 15053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Smis: 0 -> false, all other -> true. 15063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(false_label, eq, reg, Operand(zero_reg)); 15073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ JumpIfSmi(reg, true_label); 15083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (expected.NeedsMap()) { 15093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If we need a map later and have a Smi -> deopt. 15103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(at, reg, Operand(kSmiTagMask)); 15113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 15123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const Register map = scratch0(); 15153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (expected.NeedsMap()) { 15163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(map, FieldMemOperand(reg, HeapObject::kMapOffset)); 15173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (expected.CanBeUndetectable()) { 15183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Undetectable -> false. 15193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset)); 15203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(at, at, Operand(1 << Map::kIsUndetectable)); 15213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(false_label, ne, at, Operand(zero_reg)); 15223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { 15263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // spec object -> true. 15273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset)); 15283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(true_label, ge, at, Operand(FIRST_SPEC_OBJECT_TYPE)); 15293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (expected.Contains(ToBooleanStub::STRING)) { 15323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // String value -> false iff empty. 15333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label not_string; 15343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset)); 15353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(¬_string, ge , at, Operand(FIRST_NONSTRING_TYPE)); 15363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(at, FieldMemOperand(reg, String::kLengthOffset)); 15373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(true_label, ne, at, Operand(zero_reg)); 15383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(false_label); 15393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(¬_string); 15403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { 15433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // heap number -> false iff +0, -0, or NaN. 15443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister dbl_scratch = double_scratch0(); 15453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label not_heap_number; 15463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 15473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(¬_heap_number, ne, map, Operand(at)); 15483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); 15493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ BranchF(true_label, false_label, ne, dbl_scratch, kDoubleRegZero); 15503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Falls through if dbl_scratch == 0. 15513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(false_label); 15523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(¬_heap_number); 15533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We've seen something for the first time -> deopt. 15563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(al, instr->environment(), zero_reg, Operand(zero_reg)); 15573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 15603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::EmitGoto(int block) { 15633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch block = chunk_->LookupDestination(block); 15643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int next_block = GetNextEmittedBlock(current_block_); 15653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (block != next_block) { 15663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ jmp(chunk_->GetAssemblyLabel(block)); 15673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 15693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoGoto(LGoto* instr) { 15723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitGoto(instr->block_id()); 15733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 15743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 15763ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochCondition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { 15773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition cond = kNoCondition; 15783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (op) { 15793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::EQ: 15803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::EQ_STRICT: 15813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cond = eq; 15823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 15833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::LT: 15843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cond = is_unsigned ? lo : lt; 15853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 15863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::GT: 15873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cond = is_unsigned ? hi : gt; 15883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 15893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::LTE: 15903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cond = is_unsigned ? ls : le; 15913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 15923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::GTE: 15933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cond = is_unsigned ? hs : ge; 15943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 15953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::IN: 15963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::INSTANCEOF: 15973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 15983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 15993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 16003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return cond; 16013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 16023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { 16053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* left = instr->InputAt(0); 16063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* right = instr->InputAt(1); 16073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int false_block = chunk_->LookupDestination(instr->false_block_id()); 16083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int true_block = chunk_->LookupDestination(instr->true_block_id()); 16093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition cond = TokenToCondition(instr->op(), false); 16113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (left->IsConstantOperand() && right->IsConstantOperand()) { 16133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We can statically evaluate the comparison. 16143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double left_val = ToDouble(LConstantOperand::cast(left)); 16153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double right_val = ToDouble(LConstantOperand::cast(right)); 16163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int next_block = 16173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EvalComparison(instr->op(), left_val, right_val) ? true_block 16183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : false_block; 16193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitGoto(next_block); 16203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 16213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->is_double()) { 16223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Compare left and right as doubles and load the 16233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // resulting flags into the normal status register. 16243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FPURegister left_reg = ToDoubleRegister(left); 16253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FPURegister right_reg = ToDoubleRegister(right); 16263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If a NaN is involved, i.e. the result is unordered, 16283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // jump to false block label. 16293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ BranchF(NULL, chunk_->GetAssemblyLabel(false_block), eq, 16303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch left_reg, right_reg); 16313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranchF(true_block, false_block, cond, left_reg, right_reg); 16333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 16343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register cmp_left; 16353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand cmp_right = Operand(0); 16363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (right->IsConstantOperand()) { 16383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp_left = ToRegister(left); 16393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp_right = Operand(ToInteger32(LConstantOperand::cast(right))); 16403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (left->IsConstantOperand()) { 16413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp_left = ToRegister(right); 16423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp_right = Operand(ToInteger32(LConstantOperand::cast(left))); 16433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We transposed the operands. Reverse the condition. 16443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cond = ReverseCondition(cond); 16453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 16463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp_left = ToRegister(left); 16473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp_right = Operand(ToRegister(right)); 16483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 16493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranch(true_block, false_block, cond, cmp_left, cmp_right); 16513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 16523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 16533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 16543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { 16573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register left = ToRegister(instr->InputAt(0)); 16583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register right = ToRegister(instr->InputAt(1)); 16593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int false_block = chunk_->LookupDestination(instr->false_block_id()); 16603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int true_block = chunk_->LookupDestination(instr->true_block_id()); 16613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranch(true_block, false_block, eq, left, Operand(right)); 16633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 16643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { 16673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register left = ToRegister(instr->InputAt(0)); 16683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int true_block = chunk_->LookupDestination(instr->true_block_id()); 16693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int false_block = chunk_->LookupDestination(instr->false_block_id()); 16703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranch(true_block, false_block, eq, left, 16723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(instr->hydrogen()->right())); 16733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 16743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoIsNilAndBranch(LIsNilAndBranch* instr) { 16783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 16793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = ToRegister(instr->InputAt(0)); 16803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int false_block = chunk_->LookupDestination(instr->false_block_id()); 16813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If the expression is known to be untagged or a smi, then it's definitely 16833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // not null, and it can't be a an undetectable object. 16843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->representation().IsSpecialization() || 16853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->hydrogen()->type().IsSmi()) { 16863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitGoto(false_block); 16873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return; 16883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 16893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int true_block = chunk_->LookupDestination(instr->true_block_id()); 16913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 16923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Heap::RootListIndex nil_value = instr->nil() == kNullValue ? 16933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Heap::kNullValueRootIndex : 16943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Heap::kUndefinedValueRootIndex; 16953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, nil_value); 16963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->kind() == kStrictEquality) { 16973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranch(true_block, false_block, eq, reg, Operand(at)); 16983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 16993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Heap::RootListIndex other_nil_value = instr->nil() == kNullValue ? 17003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Heap::kUndefinedValueRootIndex : 17013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Heap::kNullValueRootIndex; 17023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* true_label = chunk_->GetAssemblyLabel(true_block); 17033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* false_label = chunk_->GetAssemblyLabel(false_block); 17043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(USE_DELAY_SLOT, true_label, eq, reg, Operand(at)); 17053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, other_nil_value); // In the delay slot. 17063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(USE_DELAY_SLOT, true_label, eq, reg, Operand(at)); 17073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ JumpIfSmi(reg, false_label); // In the delay slot. 17083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check for undetectable objects by looking in the bit field in 17093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the map. The object has already been smi checked. 17103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); 17113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lbu(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset)); 17123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(scratch, scratch, 1 << Map::kIsUndetectable); 17133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranch(true_block, false_block, ne, scratch, Operand(zero_reg)); 17143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 17153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 17163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17183ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochCondition LCodeGen::EmitIsObject(Register input, 17193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp1, 17203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp2, 17213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* is_not_object, 17223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* is_object) { 17233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ JumpIfSmi(input, is_not_object); 17243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(temp2, Heap::kNullValueRootIndex); 17263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(is_object, eq, input, Operand(temp2)); 17273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load map. 17293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(temp1, FieldMemOperand(input, HeapObject::kMapOffset)); 17303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Undetectable objects behave like undefined. 17313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lbu(temp2, FieldMemOperand(temp1, Map::kBitFieldOffset)); 17323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(temp2, temp2, Operand(1 << Map::kIsUndetectable)); 17333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(is_not_object, ne, temp2, Operand(zero_reg)); 17343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load instance type and check that it is in object type range. 17363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lbu(temp2, FieldMemOperand(temp1, Map::kInstanceTypeOffset)); 17373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(is_not_object, 17383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch lt, temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 17393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return le; 17413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 17423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 17453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = ToRegister(instr->InputAt(0)); 17463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp1 = ToRegister(instr->TempAt(0)); 17473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp2 = scratch0(); 17483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int true_block = chunk_->LookupDestination(instr->true_block_id()); 17503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int false_block = chunk_->LookupDestination(instr->false_block_id()); 17513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* true_label = chunk_->GetAssemblyLabel(true_block); 17523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* false_label = chunk_->GetAssemblyLabel(false_block); 17533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition true_cond = 17553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitIsObject(reg, temp1, temp2, false_label, true_label); 17563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranch(true_block, false_block, true_cond, temp2, 17583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); 17593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 17603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17623ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochCondition LCodeGen::EmitIsString(Register input, 17633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp1, 17643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* is_not_string) { 17653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ JumpIfSmi(input, is_not_string); 17663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ GetObjectType(input, temp1, temp1); 17673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return lt; 17693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 17703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { 17733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = ToRegister(instr->InputAt(0)); 17743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp1 = ToRegister(instr->TempAt(0)); 17753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int true_block = chunk_->LookupDestination(instr->true_block_id()); 17773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int false_block = chunk_->LookupDestination(instr->false_block_id()); 17783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* false_label = chunk_->GetAssemblyLabel(false_block); 17793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition true_cond = 17813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitIsString(reg, temp1, false_label); 17823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranch(true_block, false_block, true_cond, temp1, 17843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(FIRST_NONSTRING_TYPE)); 17853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 17863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 17893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int true_block = chunk_->LookupDestination(instr->true_block_id()); 17903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int false_block = chunk_->LookupDestination(instr->false_block_id()); 17913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input_reg = EmitLoadRegister(instr->InputAt(0), at); 17933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(at, input_reg, kSmiTagMask); 17943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranch(true_block, false_block, eq, at, Operand(zero_reg)); 17953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 17963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 17993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input = ToRegister(instr->InputAt(0)); 18003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp = ToRegister(instr->TempAt(0)); 18013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int true_block = chunk_->LookupDestination(instr->true_block_id()); 18033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int false_block = chunk_->LookupDestination(instr->false_block_id()); 18043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); 18063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(temp, FieldMemOperand(input, HeapObject::kMapOffset)); 18073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lbu(temp, FieldMemOperand(temp, Map::kBitFieldOffset)); 18083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(at, temp, Operand(1 << Map::kIsUndetectable)); 18093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranch(true_block, false_block, ne, at, Operand(zero_reg)); 18103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 18113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic Condition ComputeCompareCondition(Token::Value op) { 18143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (op) { 18153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::EQ_STRICT: 18163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::EQ: 18173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return eq; 18183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::LT: 18193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return lt; 18203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::GT: 18213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return gt; 18223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::LTE: 18233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return le; 18243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Token::GTE: 18253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ge; 18263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 18273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 18283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return kNoCondition; 18293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 18303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 18313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { 18343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Token::Value op = instr->op(); 18353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int true_block = chunk_->LookupDestination(instr->true_block_id()); 18363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int false_block = chunk_->LookupDestination(instr->false_block_id()); 18373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> ic = CompareIC::GetUninitialized(op); 18393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(ic, RelocInfo::CODE_TARGET, instr); 18403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition condition = ComputeCompareCondition(op); 18423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranch(true_block, false_block, condition, v0, Operand(zero_reg)); 18443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 18453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic InstanceType TestType(HHasInstanceTypeAndBranch* instr) { 18483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InstanceType from = instr->from(); 18493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InstanceType to = instr->to(); 18503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (from == FIRST_TYPE) return to; 18513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(from == to || to == LAST_TYPE); 18523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return from; 18533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 18543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic Condition BranchCondition(HHasInstanceTypeAndBranch* instr) { 18573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InstanceType from = instr->from(); 18583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InstanceType to = instr->to(); 18593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (from == to) return eq; 18603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (to == LAST_TYPE) return hs; 18613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (from == FIRST_TYPE) return ls; 18623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 18633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return eq; 18643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 18653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 18683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 18693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input = ToRegister(instr->InputAt(0)); 18703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int true_block = chunk_->LookupDestination(instr->true_block_id()); 18723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int false_block = chunk_->LookupDestination(instr->false_block_id()); 18733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* false_label = chunk_->GetAssemblyLabel(false_block); 18753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ JumpIfSmi(input, false_label); 18773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ GetObjectType(input, scratch, scratch); 18793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranch(true_block, 18803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch false_block, 18813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch BranchCondition(instr->hydrogen()), 18823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch, 18833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(TestType(instr->hydrogen()))); 18843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 18853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 18883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input = ToRegister(instr->InputAt(0)); 18893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 18903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_debug_code) { 18923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ AbortIfNotString(input); 18933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 18943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(input, String::kHashFieldOffset)); 18963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ IndexFromHash(result, result); 18973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 18983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 18993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoHasCachedArrayIndexAndBranch( 19013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LHasCachedArrayIndexAndBranch* instr) { 19023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input = ToRegister(instr->InputAt(0)); 19033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 19043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int true_block = chunk_->LookupDestination(instr->true_block_id()); 19063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int false_block = chunk_->LookupDestination(instr->false_block_id()); 19073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch, 19093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FieldMemOperand(input, String::kHashFieldOffset)); 19103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(at, scratch, Operand(String::kContainsCachedArrayIndexMask)); 19113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranch(true_block, false_block, eq, at, Operand(zero_reg)); 19123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 19133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Branches to a label or falls through with the answer in flags. Trashes 19163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// the temp registers, but not the input. 19173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::EmitClassOfTest(Label* is_true, 19183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* is_false, 19193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String>class_name, 19203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input, 19213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp, 19223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp2) { 19233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!input.is(temp)); 19243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!input.is(temp2)); 19253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!temp.is(temp2)); 19263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ JumpIfSmi(input, is_false); 19283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (class_name->IsEqualTo(CStrVector("Function"))) { 19303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Assuming the following assertions, we can use the same compares to test 19313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // for both being a function type and being in the object type range. 19323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); 19333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == 19343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FIRST_SPEC_OBJECT_TYPE + 1); 19353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == 19363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LAST_SPEC_OBJECT_TYPE - 1); 19373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); 19383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ GetObjectType(input, temp, temp2); 19403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(is_false, lt, temp2, Operand(FIRST_SPEC_OBJECT_TYPE)); 19413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(is_true, eq, temp2, Operand(FIRST_SPEC_OBJECT_TYPE)); 19423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(is_true, eq, temp2, Operand(LAST_SPEC_OBJECT_TYPE)); 19433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 19443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Faster code path to avoid two compares: subtract lower bound from the 19453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // actual type and do a signed compare with the width of the type range. 19463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ GetObjectType(input, temp, temp2); 19473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Subu(temp2, temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 19483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(is_false, gt, temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE - 19493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 19503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 19513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range. 19533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check if the constructor in the map is a function. 19543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(temp, FieldMemOperand(temp, Map::kConstructorOffset)); 19553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Objects with a non-function constructor have class 'Object'. 19573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ GetObjectType(temp, temp2, temp2); 19583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (class_name->IsEqualTo(CStrVector("Object"))) { 19593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(is_true, ne, temp2, Operand(JS_FUNCTION_TYPE)); 19603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 19613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(is_false, ne, temp2, Operand(JS_FUNCTION_TYPE)); 19623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 19633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // temp now contains the constructor function. Grab the 19653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // instance class name from there. 19663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(temp, FieldMemOperand(temp, JSFunction::kSharedFunctionInfoOffset)); 19673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(temp, FieldMemOperand(temp, 19683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SharedFunctionInfo::kInstanceClassNameOffset)); 19693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The class name we are testing against is a symbol because it's a literal. 19703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The name in the constructor is a symbol because of the way the context is 19713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // booted. This routine isn't expected to work for random API-created 19723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // classes and it doesn't have to because you can't access it with natives 19733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // syntax. Since both sides are symbols it is sufficient to use an identity 19743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // comparison. 19753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // End with the address of this class_name instance in temp register. 19773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // On MIPS, the caller must do the comparison with Handle<String>class_name. 19783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 19793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 19823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input = ToRegister(instr->InputAt(0)); 19833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp = scratch0(); 19843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp2 = ToRegister(instr->TempAt(0)); 19853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> class_name = instr->hydrogen()->class_name(); 19863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int true_block = chunk_->LookupDestination(instr->true_block_id()); 19883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int false_block = chunk_->LookupDestination(instr->false_block_id()); 19893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* true_label = chunk_->GetAssemblyLabel(true_block); 19913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* false_label = chunk_->GetAssemblyLabel(false_block); 19923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2); 19943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranch(true_block, false_block, eq, temp, Operand(class_name)); 19963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 19973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 19993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 20003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = ToRegister(instr->InputAt(0)); 20013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp = ToRegister(instr->TempAt(0)); 20023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int true_block = instr->true_block_id(); 20033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int false_block = instr->false_block_id(); 20043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(temp, FieldMemOperand(reg, HeapObject::kMapOffset)); 20063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranch(true_block, false_block, eq, temp, Operand(instr->map())); 20073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 20083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoInstanceOf(LInstanceOf* instr) { 20113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label true_label, done; 20123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->InputAt(0)).is(a0)); // Object is in a0. 20133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->InputAt(1)).is(a1)); // Function is in a1. 20143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 20153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(result.is(v0)); 20163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InstanceofStub stub(InstanceofStub::kArgsInRegisters); 20183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 20193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&true_label, eq, result, Operand(zero_reg)); 20213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(result, Operand(factory()->false_value())); 20223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done); 20233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&true_label); 20243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(result, Operand(factory()->true_value())); 20253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 20263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 20273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { 20303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class DeferredInstanceOfKnownGlobal: public LDeferredCode { 20313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 20323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredInstanceOfKnownGlobal(LCodeGen* codegen, 20333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LInstanceOfKnownGlobal* instr) 20343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : LDeferredCode(codegen), instr_(instr) { } 20353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void Generate() { 20363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_); 20373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 20383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual LInstruction* instr() { return instr_; } 20393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* map_check() { return &map_check_; } 20403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 20423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LInstanceOfKnownGlobal* instr_; 20433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label map_check_; 20443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 20453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredInstanceOfKnownGlobal* deferred; 20473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch deferred = new DeferredInstanceOfKnownGlobal(this, instr); 20483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done, false_result; 20503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object = ToRegister(instr->InputAt(0)); 20513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp = ToRegister(instr->TempAt(0)); 20523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 20533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(object.is(a0)); 20553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(result.is(v0)); 20563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // A Smi is not instance of anything. 20583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ JumpIfSmi(object, &false_result); 20593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // This is the inlined call site instanceof cache. The two occurences of the 20613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // hole value will be patched to the last map/result pair generated by the 20623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // instanceof stub. 20633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label cache_miss; 20643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register map = temp; 20653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(map, FieldMemOperand(object, HeapObject::kMapOffset)); 20663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 20683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(deferred->map_check()); // Label for calculating code patching. 20693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We use Factory::the_hole_value() on purpose instead of loading from the 20703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // root array to force relocation to be able to later patch with 20713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the cached map. 20723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSGlobalPropertyCell> cell = 20733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch factory()->NewJSGlobalPropertyCell(factory()->the_hole_value()); 20743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(at, Operand(Handle<Object>(cell))); 20753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(at, FieldMemOperand(at, JSGlobalPropertyCell::kValueOffset)); 20763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&cache_miss, ne, map, Operand(at)); 20773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We use Factory::the_hole_value() on purpose instead of loading from the 20783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // root array to force relocation to be able to later patch 20793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // with true or false. 20803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(result, Operand(factory()->the_hole_value()), CONSTANT_SIZE); 20813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done); 20823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The inlined call site cache did not match. Check null and string before 20843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // calling the deferred code. 20853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&cache_miss); 20863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Null is not instance of anything. 20873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(temp, Heap::kNullValueRootIndex); 20883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&false_result, eq, object, Operand(temp)); 20893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // String values is not instance of anything. 20913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition cc = __ IsObjectStringType(object, temp, temp); 20923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&false_result, cc, temp, Operand(zero_reg)); 20933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Go to the deferred code. 20953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(deferred->entry()); 20963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 20973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&false_result); 20983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(result, Heap::kFalseValueRootIndex); 20993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 21003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Here result has either true or false. Deferred code also produces true or 21013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // false object. 21023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(deferred->exit()); 21033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 21043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 21053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 21063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 21073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, 21083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* map_check) { 21093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 21103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(result.is(v0)); 21113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 21123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InstanceofStub::Flags flags = InstanceofStub::kNoFlags; 21133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch flags = static_cast<InstanceofStub::Flags>( 21143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch flags | InstanceofStub::kArgsInRegisters); 21153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch flags = static_cast<InstanceofStub::Flags>( 21163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch flags | InstanceofStub::kCallSiteInlineCheck); 21173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch flags = static_cast<InstanceofStub::Flags>( 21183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch flags | InstanceofStub::kReturnTrueFalseObject); 21193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InstanceofStub stub(flags); 21203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 21213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 21223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 21233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Get the temp register reserved by the instruction. This needs to be t0 as 21243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // its slot of the pushing of safepoint registers is used to communicate the 21253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // offset to the location of the map check. 21263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp = ToRegister(instr->TempAt(0)); 21273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(temp.is(t0)); 21283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadHeapObject(InstanceofStub::right(), instr->function()); 21293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const int kAdditionalDelta = 7; 21303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta; 21313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label before_push_delta; 21323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&before_push_delta); 21333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { 21343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 21353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(temp, Operand(delta * kPointerSize), CONSTANT_SIZE); 21363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ StoreToSafepointRegisterSlot(temp, temp); 21373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 21383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCodeGeneric(stub.GetCode(), 21393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RelocInfo::CODE_TARGET, 21403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr, 21413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 21423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(instr->HasDeoptimizationEnvironment()); 21433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LEnvironment* env = instr->deoptimization_environment(); 21443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 21453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Put the result value into the result register slot and 21463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // restore all registers. 21473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ StoreToSafepointRegisterSlot(result, result); 21483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 21493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 21503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 21513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCmpT(LCmpT* instr) { 21523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Token::Value op = instr->op(); 21533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 21543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> ic = CompareIC::GetUninitialized(op); 21553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(ic, RelocInfo::CODE_TARGET, instr); 21563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // On MIPS there is no need for a "no inlined smi code" marker (nop). 21573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 21583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition condition = ComputeCompareCondition(op); 21593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // A minor optimization that relies on LoadRoot always emitting one 21603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // instruction. 21613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm()); 21623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 21633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(USE_DELAY_SLOT, &done, condition, v0, Operand(zero_reg)); 21643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex); 21653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); 21663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_EQ(3, masm()->InstructionsGeneratedSince(&done)); 21673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 21683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 21693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 21703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 21713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoReturn(LReturn* instr) { 21723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_trace) { 21733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Push the return value on the stack as the parameter. 21743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Runtime::TraceExit returns its parameter in v0. 21753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(v0); 21763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CallRuntime(Runtime::kTraceExit, 1); 21773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 21783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int32_t sp_delta = (GetParameterCount() + 1) * kPointerSize; 21793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(sp, fp); 21803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Pop(ra, fp); 21813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(sp, sp, Operand(sp_delta)); 21823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Jump(ra); 21833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 21843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 21853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 21863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { 21873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 21883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(at, Operand(Handle<Object>(instr->hydrogen()->cell()))); 21893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(at, JSGlobalPropertyCell::kValueOffset)); 21903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->RequiresHoleCheck()) { 21913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 21923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), result, Operand(at)); 21933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 21943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 21953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 21963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 21973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { 21983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->global_object()).is(a0)); 21993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->result()).is(v0)); 22003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a2, Operand(instr->name())); 22023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET 22033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : RelocInfo::CODE_TARGET_CONTEXT; 22043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 22053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(ic, mode, instr); 22063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 22073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { 22103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register value = ToRegister(instr->value()); 22113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register cell = scratch0(); 22123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load the cell. 22143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(cell, Operand(instr->hydrogen()->cell())); 22153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If the cell we are storing to contains the hole it could have 22173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // been deleted from the property dictionary. In that case, we need 22183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // to update the property details in the property dictionary to mark 22193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // it as no longer deleted. 22203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->RequiresHoleCheck()) { 22213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We use a temp to check the payload. 22223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register payload = ToRegister(instr->TempAt(0)); 22233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(payload, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset)); 22243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 22253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), payload, Operand(at)); 22263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 22273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Store the value. 22293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(value, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset)); 22303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Cells are always rescanned, so no write barrier here. 22313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 22323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { 22353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->global_object()).is(a1)); 22363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->value()).is(a0)); 22373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a2, Operand(instr->name())); 22393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 22403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? isolate()->builtins()->StoreIC_Initialize_Strict() 22413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : isolate()->builtins()->StoreIC_Initialize(); 22423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); 22433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 22443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { 22473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register context = ToRegister(instr->context()); 22483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 22493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, ContextOperand(context, instr->slot_index())); 22513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->RequiresHoleCheck()) { 22523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 22533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->DeoptimizesOnHole()) { 22553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), result, Operand(at)); 22563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 22573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label is_not_hole; 22583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&is_not_hole, ne, result, Operand(at)); 22593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(result, Heap::kUndefinedValueRootIndex); 22603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&is_not_hole); 22613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 22623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 22633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 22643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { 22673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register context = ToRegister(instr->context()); 22683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register value = ToRegister(instr->value()); 22693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 22703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemOperand target = ContextOperand(context, instr->slot_index()); 22713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label skip_assignment; 22733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->RequiresHoleCheck()) { 22753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch, target); 22763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 22773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->DeoptimizesOnHole()) { 22793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), scratch, Operand(at)); 22803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 22813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&skip_assignment, ne, scratch, Operand(at)); 22823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 22833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 22843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 22853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(value, target); 22863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->NeedsWriteBarrier()) { 22873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HType type = instr->hydrogen()->value()->type(); 22883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SmiCheck check_needed = 22893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 22903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ RecordWriteContextSlot(context, 22913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch target.offset(), 22923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch value, 22933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch0(), 22943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kRAHasBeenSaved, 22953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kSaveFPRegs, 22963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EMIT_REMEMBERED_SET, 22973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch check_needed); 22983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 22993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 23003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&skip_assignment); 23013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 23023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 23033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 23043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 23053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object = ToRegister(instr->InputAt(0)); 23063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 23073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->is_in_object()) { 23083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(object, instr->hydrogen()->offset())); 23093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 23103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 23113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(result, instr->hydrogen()->offset())); 23123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 23133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 23143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 23153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 23163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::EmitLoadFieldOrConstantFunction(Register result, 23173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object, 23183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Map> type, 23193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name) { 23203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LookupResult lookup(isolate()); 23213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch type->LookupInDescriptors(NULL, *name, &lookup); 23223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(lookup.IsFound() && 23233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (lookup.type() == FIELD || lookup.type() == CONSTANT_FUNCTION)); 23243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (lookup.type() == FIELD) { 23253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int index = lookup.GetLocalFieldIndexFromMap(*type); 23263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int offset = index * kPointerSize; 23273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (index < 0) { 23283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Negative property indices are in-object properties, indexed 23293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // from the end of the fixed part of the object. 23303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(object, offset + type->instance_size())); 23313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 23323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Non-negative property indices are in the properties array. 23333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 23343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(result, offset + FixedArray::kHeaderSize)); 23353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 23363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 23373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type)); 23383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadHeapObject(result, function); 23393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 23403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 23413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 23423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 23433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) { 23443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object = ToRegister(instr->object()); 23453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 23463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 23473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int map_count = instr->hydrogen()->types()->length(); 23483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name = instr->hydrogen()->name(); 23493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (map_count == 0) { 23503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(instr->hydrogen()->need_generic()); 23513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a2, Operand(name)); 23523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 23533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(ic, RelocInfo::CODE_TARGET, instr); 23543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 23553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 23563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); 23573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < map_count - 1; ++i) { 23583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Map> map = instr->hydrogen()->types()->at(i); 23593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label next; 23603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&next, ne, scratch, Operand(map)); 23613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitLoadFieldOrConstantFunction(result, object, map, name); 23623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done); 23633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&next); 23643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 23653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Map> map = instr->hydrogen()->types()->last(); 23663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->need_generic()) { 23673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label generic; 23683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&generic, ne, scratch, Operand(map)); 23693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitLoadFieldOrConstantFunction(result, object, map, name); 23703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done); 23713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&generic); 23723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a2, Operand(name)); 23733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 23743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(ic, RelocInfo::CODE_TARGET, instr); 23753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 23763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), scratch, Operand(map)); 23773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitLoadFieldOrConstantFunction(result, object, map, name); 23783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 23793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 23803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 23813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 23823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 23833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 23843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { 23853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->object()).is(a0)); 23863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->result()).is(v0)); 23873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 23883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Name is always in a2. 23893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a2, Operand(instr->name())); 23903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 23913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(ic, RelocInfo::CODE_TARGET, instr); 23923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 23933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 23943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 23953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { 23963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 23973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register function = ToRegister(instr->function()); 23983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 23993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 24003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check that the function really is a function. Load map into the 24013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // result register. 24023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ GetObjectType(function, result, scratch); 24033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), scratch, Operand(JS_FUNCTION_TYPE)); 24043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 24053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Make sure that the function has an instance prototype. 24063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label non_instance; 24073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lbu(scratch, FieldMemOperand(result, Map::kBitFieldOffset)); 24083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(scratch, scratch, Operand(1 << Map::kHasNonInstancePrototype)); 24093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&non_instance, ne, scratch, Operand(zero_reg)); 24103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 24113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Get the prototype or initial map from the function. 24123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, 24133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 24143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 24153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check that the function has a prototype or an initial map. 24163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 24173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), result, Operand(at)); 24183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 24193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If the function does not have an initial map, we're done. 24203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 24213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ GetObjectType(result, scratch, scratch); 24223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done, ne, scratch, Operand(MAP_TYPE)); 24233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 24243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Get the prototype from the initial map. 24253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(result, Map::kPrototypeOffset)); 24263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done); 24273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 24283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Non-instance prototype: Fetch prototype from constructor field 24293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // in initial map. 24303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&non_instance); 24313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(result, Map::kConstructorOffset)); 24323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 24333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // All done. 24343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 24353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 24363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 24373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 24383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoLoadElements(LLoadElements* instr) { 24393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 24403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input = ToRegister(instr->InputAt(0)); 24413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 24423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 24433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(input, JSObject::kElementsOffset)); 24443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_debug_code) { 24453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done, fail; 24463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch, FieldMemOperand(result, HeapObject::kMapOffset)); 24473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kFixedArrayMapRootIndex); 24483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(USE_DELAY_SLOT, &done, eq, scratch, Operand(at)); 24493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kFixedCOWArrayMapRootIndex); // In the delay slot. 24503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done, eq, scratch, Operand(at)); 24513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // |scratch| still contains |input|'s map. 24523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lbu(scratch, FieldMemOperand(scratch, Map::kBitField2Offset)); 24533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Ext(scratch, scratch, Map::kElementsKindShift, 24543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Map::kElementsKindBitCount); 24553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done, eq, scratch, 24563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(FAST_ELEMENTS)); 24573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&fail, lt, scratch, 24583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND)); 24593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done, le, scratch, 24603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND)); 24613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&fail); 24623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Abort("Check for fast or external elements failed."); 24633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 24643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 24653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 24663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 24673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 24683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoLoadExternalArrayPointer( 24693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LLoadExternalArrayPointer* instr) { 24703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register to_reg = ToRegister(instr->result()); 24713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register from_reg = ToRegister(instr->InputAt(0)); 24723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(to_reg, FieldMemOperand(from_reg, 24733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExternalArray::kExternalPointerOffset)); 24743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 24753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 24763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 24773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 24783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register arguments = ToRegister(instr->arguments()); 24793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register length = ToRegister(instr->length()); 24803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register index = ToRegister(instr->index()); 24813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 24823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 24833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Bailout index is not a valid argument index. Use unsigned check to get 24843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // negative check for free. 24853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 24863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(plind): Shoud be optimized to do the sub before the DeoptimizeIf(), 24873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // as they do in Arm. It will save us an instruction. 24883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ls, instr->environment(), length, Operand(index)); 24893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 24903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // There are two words between the frame pointer and the last argument. 24913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Subtracting from length accounts for one of them, add one more. 24923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ subu(length, length, index); 24933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(length, length, Operand(1)); 24943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sll(length, length, kPointerSizeLog2); 24953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(at, arguments, Operand(length)); 24963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, MemOperand(at, 0)); 24973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 24983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 24993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { 25013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register elements = ToRegister(instr->elements()); 25023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register key = EmitLoadRegister(instr->key(), scratch0()); 25033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 25043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 25053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load the result. 25073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sll(scratch, key, kPointerSizeLog2); // Key indexes words. 25083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ addu(scratch, elements, scratch); 25093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(scratch, FixedArray::kHeaderSize)); 25103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check for the hole value. 25123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->RequiresHoleCheck()) { 25133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); 25143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), result, Operand(scratch)); 25153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 25163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 25173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoLoadKeyedFastDoubleElement( 25203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LLoadKeyedFastDoubleElement* instr) { 25213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register elements = ToRegister(instr->elements()); 25223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool key_is_constant = instr->key()->IsConstantOperand(); 25233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register key = no_reg; 25243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister result = ToDoubleRegister(instr->result()); 25253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 25263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int shift_size = 25283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); 25293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int constant_key = 0; 25303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (key_is_constant) { 25313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 25323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (constant_key & 0xF0000000) { 25333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Abort("array index constant value too big."); 25343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 25353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 25363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch key = ToRegister(instr->key()); 25373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 25383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (key_is_constant) { 25403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(elements, elements, Operand(constant_key * (1 << shift_size) + 25413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedDoubleArray::kHeaderSize - kHeapObjectTag)); 25423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 25433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sll(scratch, key, shift_size); 25443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(elements, elements, Operand(scratch)); 25453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(elements, elements, 25463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); 25473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 25483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); 25503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32)); 25513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ ldc1(result, MemOperand(elements)); 25533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 25543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoLoadKeyedSpecializedArrayElement( 25573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LLoadKeyedSpecializedArrayElement* instr) { 25583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register external_pointer = ToRegister(instr->external_pointer()); 25593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register key = no_reg; 25603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind elements_kind = instr->elements_kind(); 25613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool key_is_constant = instr->key()->IsConstantOperand(); 25623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int constant_key = 0; 25633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (key_is_constant) { 25643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 25653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (constant_key & 0xF0000000) { 25663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Abort("array index constant value too big."); 25673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 25683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 25693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch key = ToRegister(instr->key()); 25703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 25713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int shift_size = ElementsKindToShiftSize(elements_kind); 25723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 25743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 25753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FPURegister result = ToDoubleRegister(instr->result()); 25763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (key_is_constant) { 25773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(scratch0(), external_pointer, constant_key * (1 << shift_size)); 25783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 25793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sll(scratch0(), key, shift_size); 25803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(scratch0(), scratch0(), external_pointer); 25813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 25823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 25843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lwc1(result, MemOperand(scratch0())); 25853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ cvt_d_s(result, result); 25863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS 25873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ ldc1(result, MemOperand(scratch0())); 25883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 25893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 25903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 25913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 25923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemOperand mem_operand(zero_reg); 25933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (key_is_constant) { 25943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mem_operand = MemOperand(external_pointer, 25953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch constant_key * (1 << shift_size)); 25963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 25973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sll(scratch, key, shift_size); 25983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(scratch, scratch, external_pointer); 25993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mem_operand = MemOperand(scratch); 26003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 26013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (elements_kind) { 26023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case EXTERNAL_BYTE_ELEMENTS: 26033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lb(result, mem_operand); 26043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 26053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case EXTERNAL_PIXEL_ELEMENTS: 26063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 26073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lbu(result, mem_operand); 26083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 26093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case EXTERNAL_SHORT_ELEMENTS: 26103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lh(result, mem_operand); 26113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 26123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 26133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lhu(result, mem_operand); 26143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 26153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case EXTERNAL_INT_ELEMENTS: 26163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, mem_operand); 26173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 26183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case EXTERNAL_UNSIGNED_INT_ELEMENTS: 26193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, mem_operand); 26203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(danno): we could be more clever here, perhaps having a special 26213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // version of the stub that detects if the overflow case actually 26223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // happens, and generate code that returns a double rather than int. 26233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(Ugreater_equal, instr->environment(), 26243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result, Operand(0x80000000)); 26253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 26263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case EXTERNAL_FLOAT_ELEMENTS: 26273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case EXTERNAL_DOUBLE_ELEMENTS: 26283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case FAST_DOUBLE_ELEMENTS: 26293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case FAST_ELEMENTS: 26303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case FAST_SMI_ONLY_ELEMENTS: 26313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case DICTIONARY_ELEMENTS: 26323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case NON_STRICT_ARGUMENTS_ELEMENTS: 26333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 26343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 26353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 26363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 26373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 26383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { 26413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->object()).is(a1)); 26423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->key()).is(a0)); 26433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 26453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(ic, RelocInfo::CODE_TARGET, instr); 26463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 26473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { 26503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 26513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp = scratch1(); 26523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 26533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check if the calling frame is an arguments adaptor frame. 26553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done, adapted; 26563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 26573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, MemOperand(scratch, StandardFrameConstants::kContextOffset)); 26583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Xor(temp, result, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 26593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Result is the frame pointer for the frame if not adapted and for the real 26613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // frame below the adaptor frame if adapted. 26623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Movn(result, fp, temp); // Move only if temp is not equal to zero (ne). 26633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Movz(result, scratch, temp); // Move only if temp is equal to zero (eq). 26643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 26653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { 26683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register elem = ToRegister(instr->InputAt(0)); 26693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 26703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 26723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If no arguments adaptor frame the number of arguments is fixed. 26743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(result, zero_reg, Operand(scope()->num_parameters())); 26753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done, eq, fp, Operand(elem)); 26763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Arguments adaptor frame present. Get argument length from there. 26783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 26793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, 26803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemOperand(result, ArgumentsAdaptorFrameConstants::kLengthOffset)); 26813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ SmiUntag(result); 26823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Argument length is in result register. 26843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 26853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 26863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { 26893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register receiver = ToRegister(instr->receiver()); 26903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register function = ToRegister(instr->function()); 26913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 26923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If the receiver is null or undefined, we have to pass the global 26943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // object as a receiver to normal functions. Values have to be 26953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // passed unchanged to builtins and strict-mode functions. 26963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label global_object, receiver_ok; 26973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Do not transform the receiver to object for strict mode 26993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // functions. 27003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch, 27013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); 27023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch, 27033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset)); 27043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Do not transform the receiver to object for builtins. 27063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int32_t strict_mode_function_mask = 27073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1 << (SharedFunctionInfo::kStrictModeFunction + kSmiTagSize); 27083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int32_t native_mask = 1 << (SharedFunctionInfo::kNative + kSmiTagSize); 27093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(scratch, scratch, Operand(strict_mode_function_mask | native_mask)); 27103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&receiver_ok, ne, scratch, Operand(zero_reg)); 27113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Normal function. Replace undefined or null with global receiver. 27133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(scratch, Heap::kNullValueRootIndex); 27143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&global_object, eq, receiver, Operand(scratch)); 27153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); 27163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&global_object, eq, receiver, Operand(scratch)); 27173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Deoptimize if the receiver is not a JS object. 27193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(scratch, receiver, Operand(kSmiTagMask)); 27203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); 27213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ GetObjectType(receiver, scratch, scratch); 27233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(lt, instr->environment(), 27243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch, Operand(FIRST_SPEC_OBJECT_TYPE)); 27253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&receiver_ok); 27263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&global_object); 27283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(receiver, GlobalObjectOperand()); 27293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(receiver, 27303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FieldMemOperand(receiver, JSGlobalObject::kGlobalReceiverOffset)); 27313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&receiver_ok); 27323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 27333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoApplyArguments(LApplyArguments* instr) { 27353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register receiver = ToRegister(instr->receiver()); 27363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register function = ToRegister(instr->function()); 27373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register length = ToRegister(instr->length()); 27383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register elements = ToRegister(instr->elements()); 27393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 27403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(receiver.is(a0)); // Used for parameter count. 27413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(function.is(a1)); // Required by InvokeFunction. 27423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->result()).is(v0)); 27433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Copy the arguments to this function possibly from the 27453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // adaptor frame below it. 27463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const uint32_t kArgumentsLimit = 1 * KB; 27473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(hi, instr->environment(), length, Operand(kArgumentsLimit)); 27483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Push the receiver and use the register to keep the original 27503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // number of arguments. 27513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(receiver); 27523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Move(receiver, length); 27533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The arguments are at a one pointer size offset from elements. 27543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(elements, elements, Operand(1 * kPointerSize)); 27553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Loop through the arguments pushing them onto the execution 27573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // stack. 27583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label invoke, loop; 27593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // length is a small non-negative integer, due to the test above. 27603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(USE_DELAY_SLOT, &invoke, eq, length, Operand(zero_reg)); 27613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sll(scratch, length, 2); 27623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&loop); 27633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(scratch, elements, scratch); 27643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch, MemOperand(scratch)); 27653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(scratch); 27663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Subu(length, length, Operand(1)); 27673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(USE_DELAY_SLOT, &loop, ne, length, Operand(zero_reg)); 27683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sll(scratch, length, 2); 27693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&invoke); 27713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); 27723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LPointerMap* pointers = instr->pointer_map(); 27733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordPosition(pointers->position()); 27743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SafepointGenerator safepoint_generator( 27753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch this, pointers, Safepoint::kLazyDeopt); 27763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The number of arguments is stored in receiver which is a0, as expected 27773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // by InvokeFunction. 27783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ParameterCount actual(receiver); 27793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ InvokeFunction(function, actual, CALL_FUNCTION, 27803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch safepoint_generator, CALL_AS_METHOD); 27813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 27823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 27833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoPushArgument(LPushArgument* instr) { 27863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* argument = instr->InputAt(0); 27873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) { 27883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Abort("DoPushArgument not implemented for double type."); 27893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 27903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register argument_reg = EmitLoadRegister(argument, at); 27913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(argument_reg); 27923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 27933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 27943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoThisFunction(LThisFunction* instr) { 27973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 27983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadHeapObject(result, instr->hydrogen()->closure()); 27993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 28003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoContext(LContext* instr) { 28033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 28043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(result, cp); 28053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 28063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoOuterContext(LOuterContext* instr) { 28093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register context = ToRegister(instr->context()); 28103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 28113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, 28123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemOperand(context, Context::SlotOffset(Context::PREVIOUS_INDEX))); 28133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 28143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { 28173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadHeapObject(scratch0(), instr->hydrogen()->pairs()); 28183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(scratch1(), Operand(Smi::FromInt(instr->hydrogen()->flags()))); 28193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The context is the first argument. 28203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Push(cp, scratch0(), scratch1()); 28213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntime(Runtime::kDeclareGlobals, 3, instr); 28223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 28233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoGlobalObject(LGlobalObject* instr) { 28263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 28273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, ContextOperand(cp, Context::GLOBAL_INDEX)); 28283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 28293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { 28323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register global = ToRegister(instr->global()); 28333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 28343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); 28353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 28363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::CallKnownFunction(Handle<JSFunction> function, 28393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int arity, 28403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LInstruction* instr, 28413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallKind call_kind) { 28423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool can_invoke_directly = !function->NeedsArgumentsAdaption() || 28433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function->shared()->formal_parameter_count() == arity; 28443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LPointerMap* pointers = instr->pointer_map(); 28463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordPosition(pointers->position()); 28473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (can_invoke_directly) { 28493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadHeapObject(a1, function); 28503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Change context if needed. 28513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool change_context = 28523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (info()->closure()->context() != function->context()) || 28533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope()->contains_with() || 28543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (scope()->num_heap_slots() > 0); 28553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (change_context) { 28563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); 28573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 28583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set r0 to arguments count if adaption is not needed. Assumes that r0 28603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // is available to write to at this point. 28613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!function->NeedsArgumentsAdaption()) { 28623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a0, Operand(arity)); 28633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 28643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Invoke function. 28663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ SetCallKind(t1, call_kind); 28673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(at, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); 28683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Call(at); 28693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up deoptimization. 28713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 28723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 28733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 28743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ParameterCount count(arity); 28753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ InvokeFunction(function, count, CALL_FUNCTION, generator, call_kind); 28763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 28773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Restore context. 28793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 28803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 28813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 28843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->result()).is(v0)); 28853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(a0, v0); 28863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallKnownFunction(instr->function(), instr->arity(), instr, CALL_AS_METHOD); 28873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 28883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 28913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input = ToRegister(instr->InputAt(0)); 28923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 28933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 28943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Deoptimize if not a heap number. 28963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 28973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 28983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), scratch, Operand(at)); 28993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 29013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register exponent = scratch0(); 29023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch = no_reg; 29033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); 29043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check the sign of the argument. If the argument is positive, just 29053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // return it. 29063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Move(result, input); 29073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(at, exponent, Operand(HeapNumber::kSignMask)); 29083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done, eq, at, Operand(zero_reg)); 29093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Input is negative. Reverse its sign. 29113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Preserve the value of all registers. 29123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { 29133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 29143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Registers were saved at the safepoint, so we can use 29163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // many scratch registers. 29173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register tmp1 = input.is(a1) ? a0 : a1; 29183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register tmp2 = input.is(a2) ? a0 : a2; 29193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register tmp3 = input.is(a3) ? a0 : a3; 29203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register tmp4 = input.is(t0) ? a0 : t0; 29213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // exponent: floating point exponent value. 29233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label allocated, slow; 29253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(tmp4, Heap::kHeapNumberMapRootIndex); 29263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ AllocateHeapNumber(tmp1, tmp2, tmp3, tmp4, &slow); 29273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&allocated); 29283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Slow case: Call the runtime system to do the number allocation. 29303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&slow); 29313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 29333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set the pointer to the new heap number in tmp. 29343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!tmp1.is(v0)) 29353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(tmp1, v0); 29363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Restore input_reg after call to runtime. 29373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadFromSafepointRegisterSlot(input, input); 29383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); 29393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&allocated); 29413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // exponent: floating point exponent value. 29423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // tmp1: allocated heap number. 29433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(exponent, exponent, Operand(~HeapNumber::kSignMask)); 29443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(exponent, FieldMemOperand(tmp1, HeapNumber::kExponentOffset)); 29453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset)); 29463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset)); 29473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ StoreToSafepointRegisterSlot(tmp1, result); 29493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 29503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 29523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 29533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { 29563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input = ToRegister(instr->InputAt(0)); 29573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 29583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); 29593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 29603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg)); 29613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(result, input); 29623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_EQ(2, masm()->InstructionsGeneratedSince(&done)); 29633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ subu(result, zero_reg, input); 29643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Overflow if result is still negative, i.e. 0x80000000. 29653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg)); 29663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 29673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 29683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 29713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Class for deferred case. 29723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 29733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 29743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 29753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LUnaryMathOperation* instr) 29763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : LDeferredCode(codegen), instr_(instr) { } 29773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void Generate() { 29783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 29793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 29803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual LInstruction* instr() { return instr_; } 29813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 29823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LUnaryMathOperation* instr_; 29833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 29843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 29853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Representation r = instr->hydrogen()->value()->representation(); 29863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (r.IsDouble()) { 29873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FPURegister input = ToDoubleRegister(instr->InputAt(0)); 29883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FPURegister result = ToDoubleRegister(instr->result()); 29893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ abs_d(result, input); 29903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (r.IsInteger32()) { 29913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitIntegerMathAbs(instr); 29923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 29933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Representation is tagged. 29943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredMathAbsTaggedHeapNumber* deferred = 29953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new DeferredMathAbsTaggedHeapNumber(this, instr); 29963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input = ToRegister(instr->InputAt(0)); 29973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Smi check. 29983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ JumpIfNotSmi(input, deferred->entry()); 29993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If smi, handle it directly. 30003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitIntegerMathAbs(instr); 30013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(deferred->exit()); 30023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 30033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 30043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 30073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); 30083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 30093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FPURegister single_scratch = double_scratch0().low(); 30103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch1 = scratch0(); 30113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register except_flag = ToRegister(instr->TempAt(0)); 30123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ EmitFPUTruncate(kRoundToMinusInf, 30143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch single_scratch, 30153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch input, 30163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch1, 30173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch except_flag); 30183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Deopt if the operation did not succeed. 30203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 30213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load the result. 30233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mfc1(result, single_scratch); 30243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 30263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Test for -0. 30273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 30283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done, ne, result, Operand(zero_reg)); 30293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mfc1(scratch1, input.high()); 30303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 30313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); 30323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 30333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 30343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 30353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 30383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); 30393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 30403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 30413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done, check_sign_on_zero; 30423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Extract exponent bits. 30443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mfc1(result, input.high()); 30453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Ext(scratch, 30463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result, 30473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapNumber::kExponentShift, 30483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapNumber::kExponentBits); 30493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If the number is in ]-0.5, +0.5[, the result is +/- 0. 30513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label skip1; 30523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&skip1, gt, scratch, Operand(HeapNumber::kExponentBias - 2)); 30533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(result, zero_reg); 30543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 30553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&check_sign_on_zero); 30563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 30573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done); 30583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 30593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&skip1); 30603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The following conversion will not work with numbers 30623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // outside of ]-2^32, 2^32[. 30633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ge, instr->environment(), scratch, 30643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(HeapNumber::kExponentBias + 32)); 30653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Save the original sign for later comparison. 30673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(scratch, result, Operand(HeapNumber::kSignMask)); 30683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Move(double_scratch0(), 0.5); 30703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ add_d(double_scratch0(), input, double_scratch0()); 30713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check sign of the result: if the sign changed, the input 30733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // value was in ]0.5, 0[ and the result should be -0. 30743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mfc1(result, double_scratch0().high()); 30753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Xor(result, result, Operand(scratch)); 30763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 30773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ARM uses 'mi' here, which is 'lt' 30783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(lt, instr->environment(), result, 30793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(zero_reg)); 30803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 30813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label skip2; 30823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ARM uses 'mi' here, which is 'lt' 30833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Negating it results in 'ge' 30843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&skip2, ge, result, Operand(zero_reg)); 30853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(result, zero_reg); 30863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done); 30873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&skip2); 30883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 30893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register except_flag = scratch; 30913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ EmitFPUTruncate(kRoundToMinusInf, 30933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double_scratch0().low(), 30943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double_scratch0(), 30953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result, 30963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch except_flag); 30973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 30993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 31003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mfc1(result, double_scratch0().low()); 31013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 31023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 31033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Test for -0. 31043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done, ne, result, Operand(zero_reg)); 31053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&check_sign_on_zero); 31063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mfc1(scratch, input.high()); 31073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(scratch, scratch, Operand(HeapNumber::kSignMask)); 31083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); 31093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 31103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 31113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 31123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 31133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 31143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 31153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); 31163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister result = ToDoubleRegister(instr->result()); 31173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sqrt_d(result, input); 31183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 31193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 31203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 31213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 31223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); 31233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister result = ToDoubleRegister(instr->result()); 31243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister temp = ToDoubleRegister(instr->TempAt(0)); 31253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 31263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!input.is(result)); 31273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 31283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Note that according to ECMA-262 15.8.2.13: 31293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Math.pow(-Infinity, 0.5) == Infinity 31303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Math.sqrt(-Infinity) == NaN 31313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 31323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Move(temp, -V8_INFINITY); 31333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ BranchF(USE_DELAY_SLOT, &done, NULL, eq, temp, input); 31343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up Infinity in the delay slot. 31353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // result is overwritten if the branch is not taken. 31363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ neg_d(result, temp); 31373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 31383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Add +0 to convert -0 to +0. 31393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ add_d(result, input, kDoubleRegZero); 31403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sqrt_d(result, result); 31413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 31423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 31433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 31443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 31453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoPower(LPower* instr) { 31463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Representation exponent_type = instr->hydrogen()->right()->representation(); 31473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Having marked this as a call, we can use any registers. 31483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Just make sure that the input/output registers are the expected ones. 31493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!instr->InputAt(1)->IsDoubleRegister() || 31503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ToDoubleRegister(instr->InputAt(1)).is(f4)); 31513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!instr->InputAt(1)->IsRegister() || 31523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ToRegister(instr->InputAt(1)).is(a2)); 31533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToDoubleRegister(instr->InputAt(0)).is(f2)); 31543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToDoubleRegister(instr->result()).is(f0)); 31553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 31563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (exponent_type.IsTagged()) { 31573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label no_deopt; 31583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ JumpIfSmi(a2, &no_deopt); 31593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(t3, FieldMemOperand(a2, HeapObject::kMapOffset)); 31603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), t3, Operand(at)); 31613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&no_deopt); 31623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MathPowStub stub(MathPowStub::TAGGED); 31633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CallStub(&stub); 31643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (exponent_type.IsInteger32()) { 31653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MathPowStub stub(MathPowStub::INTEGER); 31663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CallStub(&stub); 31673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 31683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(exponent_type.IsDouble()); 31693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MathPowStub stub(MathPowStub::DOUBLE); 31703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CallStub(&stub); 31713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 31723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 31733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 31743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 31753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoRandom(LRandom* instr) { 31763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class DeferredDoRandom: public LDeferredCode { 31773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 31783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredDoRandom(LCodeGen* codegen, LRandom* instr) 31793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : LDeferredCode(codegen), instr_(instr) { } 31803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void Generate() { codegen()->DoDeferredRandom(instr_); } 31813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual LInstruction* instr() { return instr_; } 31823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 31833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LRandom* instr_; 31843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 31853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 31863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredDoRandom* deferred = new DeferredDoRandom(this, instr); 31873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Having marked this instruction as a call we can use any 31883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // registers. 31893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToDoubleRegister(instr->result()).is(f0)); 31903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->InputAt(0)).is(a0)); 31913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 31923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const int kSeedSize = sizeof(uint32_t); 31933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(kPointerSize == kSeedSize); 31943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 31953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalContextOffset)); 31963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const int kRandomSeedOffset = 31973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray::kHeaderSize + Context::RANDOM_SEED_INDEX * kPointerSize; 31983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(a2, FieldMemOperand(a0, kRandomSeedOffset)); 31993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // a2: FixedArray of the global context's random seeds 32003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load state[0]. 32023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(a1, FieldMemOperand(a2, ByteArray::kHeaderSize)); 32033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(deferred->entry(), eq, a1, Operand(zero_reg)); 32043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load state[1]. 32053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(a0, FieldMemOperand(a2, ByteArray::kHeaderSize + kSeedSize)); 32063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // a1: state[0]. 32073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // a0: state[1]. 32083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // state[0] = 18273 * (state[0] & 0xFFFF) + (state[0] >> 16) 32103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(a3, a1, Operand(0xFFFF)); 32113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(t0, Operand(18273)); 32127a930e02c0b52d70d022ed255db551895dfe1157Ben Murdoch __ Mul(a3, a3, t0); 32133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ srl(a1, a1, 16); 32143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(a1, a3, a1); 32153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Save state[0]. 32163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(a1, FieldMemOperand(a2, ByteArray::kHeaderSize)); 32173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // state[1] = 36969 * (state[1] & 0xFFFF) + (state[1] >> 16) 32193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(a3, a0, Operand(0xFFFF)); 32203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(t0, Operand(36969)); 32217a930e02c0b52d70d022ed255db551895dfe1157Ben Murdoch __ Mul(a3, a3, t0); 32223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ srl(a0, a0, 16), 32233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(a0, a3, a0); 32243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Save state[1]. 32253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(a0, FieldMemOperand(a2, ByteArray::kHeaderSize + kSeedSize)); 32263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Random bit pattern = (state[0] << 14) + (state[1] & 0x3FFFF) 32283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(a0, a0, Operand(0x3FFFF)); 32293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sll(a1, a1, 14); 32303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(v0, a0, a1); 32313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(deferred->exit()); 32333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // 0x41300000 is the top half of 1.0 x 2^20 as a double. 32353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a2, Operand(0x41300000)); 32363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Move 0x41300000xxxxxxxx (x = random bits in v0) to FPU. 32373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Move(f12, v0, a2); 32383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Move 0x4130000000000000 to FPU. 32393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Move(f14, zero_reg, a2); 32403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Subtract to get the result. 32413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sub_d(f0, f12, f14); 32423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 32433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoDeferredRandom(LRandom* instr) { 32453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ PrepareCallCFunction(1, scratch0()); 32463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); 32473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Return value is in v0. 32483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 32493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoMathLog(LUnaryMathOperation* instr) { 32523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToDoubleRegister(instr->result()).is(f4)); 32533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TranscendentalCacheStub stub(TranscendentalCache::LOG, 32543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TranscendentalCacheStub::UNTAGGED); 32553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 32563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 32573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoMathTan(LUnaryMathOperation* instr) { 32603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToDoubleRegister(instr->result()).is(f4)); 32613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TranscendentalCacheStub stub(TranscendentalCache::TAN, 32623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TranscendentalCacheStub::UNTAGGED); 32633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 32643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 32653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoMathCos(LUnaryMathOperation* instr) { 32683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToDoubleRegister(instr->result()).is(f4)); 32693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TranscendentalCacheStub stub(TranscendentalCache::COS, 32703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TranscendentalCacheStub::UNTAGGED); 32713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 32723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 32733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoMathSin(LUnaryMathOperation* instr) { 32763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToDoubleRegister(instr->result()).is(f4)); 32773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TranscendentalCacheStub stub(TranscendentalCache::SIN, 32783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TranscendentalCacheStub::UNTAGGED); 32793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 32803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 32813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { 32843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (instr->op()) { 32853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case kMathAbs: 32863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoMathAbs(instr); 32873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 32883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case kMathFloor: 32893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoMathFloor(instr); 32903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 32913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case kMathRound: 32923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoMathRound(instr); 32933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 32943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case kMathSqrt: 32953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoMathSqrt(instr); 32963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 32973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case kMathPowHalf: 32983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoMathPowHalf(instr); 32993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 33003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case kMathCos: 33013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoMathCos(instr); 33023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 33033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case kMathSin: 33043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoMathSin(instr); 33053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 33063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case kMathTan: 33073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoMathTan(instr); 33083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 33093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case kMathLog: 33103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoMathLog(instr); 33113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 33123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 33133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Abort("Unimplemented type of LUnaryMathOperation."); 33143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 33153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 33163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 33173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 33203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->function()).is(a1)); 33213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(instr->HasPointerMap()); 33223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(instr->HasDeoptimizationEnvironment()); 33233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LPointerMap* pointers = instr->pointer_map(); 33243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordPosition(pointers->position()); 33253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 33263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ParameterCount count(instr->arity()); 33273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ InvokeFunction(a1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); 33283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 33293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 33303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCallKeyed(LCallKeyed* instr) { 33333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->result()).is(v0)); 33343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int arity = instr->arity(); 33363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> ic = 33373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate()->stub_cache()->ComputeKeyedCallInitialize(arity); 33383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(ic, RelocInfo::CODE_TARGET, instr); 33393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 33403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 33413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCallNamed(LCallNamed* instr) { 33443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->result()).is(v0)); 33453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int arity = instr->arity(); 33473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RelocInfo::Mode mode = RelocInfo::CODE_TARGET; 33483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> ic = 33493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate()->stub_cache()->ComputeCallInitialize(arity, mode); 33503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a2, Operand(instr->name())); 33513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(ic, mode, instr); 33523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Restore context register. 33533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 33543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 33553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCallFunction(LCallFunction* instr) { 33583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->function()).is(a1)); 33593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->result()).is(v0)); 33603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int arity = instr->arity(); 33623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS); 33633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 33643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 33653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 33663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCallGlobal(LCallGlobal* instr) { 33693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->result()).is(v0)); 33703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int arity = instr->arity(); 33723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; 33733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> ic = 33743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate()->stub_cache()->ComputeCallInitialize(arity, mode); 33753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a2, Operand(instr->name())); 33763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(ic, mode, instr); 33773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 33783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 33793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { 33823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->result()).is(v0)); 33833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); 33843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 33853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCallNew(LCallNew* instr) { 33883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->InputAt(0)).is(a1)); 33893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->result()).is(v0)); 33903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); 33923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a0, Operand(instr->arity())); 33933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); 33943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 33953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 33973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCallRuntime(LCallRuntime* instr) { 33983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntime(instr->function(), instr->arity(), instr); 33993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 34003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 34013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 34023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 34033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object = ToRegister(instr->object()); 34043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register value = ToRegister(instr->value()); 34053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 34063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int offset = instr->offset(); 34073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 34083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!object.is(value)); 34093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 34103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!instr->transition().is_null()) { 34113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(scratch, Operand(instr->transition())); 34123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); 34133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 34143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 34153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Do the store. 34163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HType type = instr->hydrogen()->value()->type(); 34173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SmiCheck check_needed = 34183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 34193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->is_in_object()) { 34203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(value, FieldMemOperand(object, offset)); 34213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->NeedsWriteBarrier()) { 34223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Update the write barrier for the object for in-object properties. 34233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ RecordWriteField(object, 34243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch offset, 34253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch value, 34263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch, 34273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kRAHasBeenSaved, 34283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kSaveFPRegs, 34293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EMIT_REMEMBERED_SET, 34303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch check_needed); 34313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 34323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 34333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset)); 34343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(value, FieldMemOperand(scratch, offset)); 34353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->NeedsWriteBarrier()) { 34363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Update the write barrier for the properties array. 34373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // object is used as a scratch register. 34383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ RecordWriteField(scratch, 34393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch offset, 34403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch value, 34413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object, 34423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kRAHasBeenSaved, 34433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kSaveFPRegs, 34443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EMIT_REMEMBERED_SET, 34453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch check_needed); 34463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 34473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 34483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 34493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 34503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 34513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { 34523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->object()).is(a1)); 34533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->value()).is(a0)); 34543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 34553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Name is always in a2. 34563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a2, Operand(instr->name())); 34573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 34583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? isolate()->builtins()->StoreIC_Initialize_Strict() 34593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : isolate()->builtins()->StoreIC_Initialize(); 34603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(ic, RelocInfo::CODE_TARGET, instr); 34613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 34623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 34633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 34643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { 34653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(hs, 34663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->environment(), 34673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ToRegister(instr->index()), 34683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(ToRegister(instr->length()))); 34693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 34703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 34713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 34723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { 34733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register value = ToRegister(instr->value()); 34743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register elements = ToRegister(instr->object()); 34753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; 34763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 34773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 34783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Do the store. 34793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->key()->IsConstantOperand()) { 34803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 34813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); 34823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int offset = 34833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; 34843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(value, FieldMemOperand(elements, offset)); 34853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 34863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sll(scratch, key, kPointerSizeLog2); 34873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ addu(scratch, elements, scratch); 34883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(value, FieldMemOperand(scratch, FixedArray::kHeaderSize)); 34893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 34903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 34913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->NeedsWriteBarrier()) { 34923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HType type = instr->hydrogen()->value()->type(); 34933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SmiCheck check_needed = 34943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 34953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Compute address of modified element and store it into key register. 34963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 34973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ RecordWrite(elements, 34983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch key, 34993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch value, 35003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kRAHasBeenSaved, 35013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kSaveFPRegs, 35023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EMIT_REMEMBERED_SET, 35033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch check_needed); 35043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 35053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 35063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoStoreKeyedFastDoubleElement( 35093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LStoreKeyedFastDoubleElement* instr) { 35103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister value = ToDoubleRegister(instr->value()); 35113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register elements = ToRegister(instr->elements()); 35123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register key = no_reg; 35133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 35143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool key_is_constant = instr->key()->IsConstantOperand(); 35153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int constant_key = 0; 35163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label not_nan; 35173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Calculate the effective address of the slot in the array to store the 35193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // double value. 35203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (key_is_constant) { 35213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 35223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (constant_key & 0xF0000000) { 35233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Abort("array index constant value too big."); 35243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 35253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 35263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch key = ToRegister(instr->key()); 35273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 35283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int shift_size = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); 35293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (key_is_constant) { 35303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(scratch, elements, Operand(constant_key * (1 << shift_size) + 35313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedDoubleArray::kHeaderSize - kHeapObjectTag)); 35323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 35333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sll(scratch, key, shift_size); 35343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(scratch, elements, Operand(scratch)); 35353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(scratch, scratch, 35363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); 35373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 35383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label is_nan; 35403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check for NaN. All NaNs must be canonicalized. 35413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ BranchF(NULL, &is_nan, eq, value, value); 35423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(¬_nan); 35433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Only load canonical NaN if the comparison above set the overflow. 35453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&is_nan); 35463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Move(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double()); 35473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(¬_nan); 35493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sdc1(value, MemOperand(scratch)); 35503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 35513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoStoreKeyedSpecializedArrayElement( 35543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LStoreKeyedSpecializedArrayElement* instr) { 35553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register external_pointer = ToRegister(instr->external_pointer()); 35573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register key = no_reg; 35583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind elements_kind = instr->elements_kind(); 35593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool key_is_constant = instr->key()->IsConstantOperand(); 35603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int constant_key = 0; 35613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (key_is_constant) { 35623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 35633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (constant_key & 0xF0000000) { 35643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Abort("array index constant value too big."); 35653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 35663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 35673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch key = ToRegister(instr->key()); 35683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 35693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int shift_size = ElementsKindToShiftSize(elements_kind); 35703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 35723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 35733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FPURegister value(ToDoubleRegister(instr->value())); 35743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (key_is_constant) { 35753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(scratch0(), external_pointer, constant_key * (1 << shift_size)); 35763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 35773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sll(scratch0(), key, shift_size); 35783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(scratch0(), scratch0(), external_pointer); 35793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 35803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 35823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ cvt_s_d(double_scratch0(), value); 35833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ swc1(double_scratch0(), MemOperand(scratch0())); 35843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS 35853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sdc1(value, MemOperand(scratch0())); 35863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 35873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 35883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register value(ToRegister(instr->value())); 35893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemOperand mem_operand(zero_reg); 35903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 35913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (key_is_constant) { 35923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mem_operand = MemOperand(external_pointer, 35933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch constant_key * (1 << shift_size)); 35943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 35953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sll(scratch, key, shift_size); 35963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(scratch, scratch, external_pointer); 35973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch mem_operand = MemOperand(scratch); 35983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 35993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (elements_kind) { 36003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case EXTERNAL_PIXEL_ELEMENTS: 36013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case EXTERNAL_BYTE_ELEMENTS: 36023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 36033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sb(value, mem_operand); 36043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 36053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case EXTERNAL_SHORT_ELEMENTS: 36063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 36073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sh(value, mem_operand); 36083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 36093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case EXTERNAL_INT_ELEMENTS: 36103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case EXTERNAL_UNSIGNED_INT_ELEMENTS: 36113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(value, mem_operand); 36123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 36133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case EXTERNAL_FLOAT_ELEMENTS: 36143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case EXTERNAL_DOUBLE_ELEMENTS: 36153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case FAST_DOUBLE_ELEMENTS: 36163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case FAST_ELEMENTS: 36173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case FAST_SMI_ONLY_ELEMENTS: 36183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case DICTIONARY_ELEMENTS: 36193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case NON_STRICT_ARGUMENTS_ELEMENTS: 36203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 36213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 36223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 36233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 36243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 36253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 36273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->object()).is(a2)); 36283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->key()).is(a1)); 36293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->value()).is(a0)); 36303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 36323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 36333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : isolate()->builtins()->KeyedStoreIC_Initialize(); 36343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(ic, RelocInfo::CODE_TARGET, instr); 36353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 36363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { 36393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object_reg = ToRegister(instr->object()); 36403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register new_map_reg = ToRegister(instr->new_map_reg()); 36413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 36423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Map> from_map = instr->original_map(); 36443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Map> to_map = instr->transitioned_map(); 36453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind from_kind = from_map->elements_kind(); 36463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind to_kind = to_map->elements_kind(); 36473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(ToRegister(instr->result()), object_reg); 36493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label not_applicable; 36513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch, FieldMemOperand(object_reg, HeapObject::kMapOffset)); 36523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(¬_applicable, ne, scratch, Operand(from_map)); 36533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(new_map_reg, Operand(to_map)); 36553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (from_kind == FAST_SMI_ONLY_ELEMENTS && to_kind == FAST_ELEMENTS) { 36563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset)); 36573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Write barrier. 36583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, 36593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch, kRAHasBeenSaved, kDontSaveFPRegs); 36603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (from_kind == FAST_SMI_ONLY_ELEMENTS && 36613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to_kind == FAST_DOUBLE_ELEMENTS) { 36623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register fixed_object_reg = ToRegister(instr->temp_reg()); 36633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(fixed_object_reg.is(a2)); 36643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(new_map_reg.is(a3)); 36653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(fixed_object_reg, object_reg); 36663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), 36673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RelocInfo::CODE_TARGET, instr); 36683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (from_kind == FAST_DOUBLE_ELEMENTS && to_kind == FAST_ELEMENTS) { 36693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register fixed_object_reg = ToRegister(instr->temp_reg()); 36703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(fixed_object_reg.is(a2)); 36713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(new_map_reg.is(a3)); 36723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(fixed_object_reg, object_reg); 36733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), 36743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RelocInfo::CODE_TARGET, instr); 36753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 36763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 36773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 36783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(¬_applicable); 36793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 36803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoStringAdd(LStringAdd* instr) { 36833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(ToRegister(instr->left())); 36843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(ToRegister(instr->right())); 36853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StringAddStub stub(NO_STRING_CHECK_IN_STUB); 36863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 36873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 36883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { 36913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class DeferredStringCharCodeAt: public LDeferredCode { 36923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 36933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) 36943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : LDeferredCode(codegen), instr_(instr) { } 36953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } 36963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual LInstruction* instr() { return instr_; } 36973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 36983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LStringCharCodeAt* instr_; 36993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 37003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredStringCharCodeAt* deferred = 37023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new DeferredStringCharCodeAt(this, instr); 37033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StringCharLoadGenerator::Generate(masm(), 37043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ToRegister(instr->string()), 37053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ToRegister(instr->index()), 37063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ToRegister(instr->result()), 37073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch deferred->entry()); 37083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(deferred->exit()); 37093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 37103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { 37133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register string = ToRegister(instr->string()); 37143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 37153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 37163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(3095996): Get rid of this. For now, we need to make the 37183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // result register contain a valid pointer because it is already 37193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // contained in the register pointer map. 37203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(result, zero_reg); 37213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 37233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(string); 37243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Push the index as a smi. This is safe because of the checks in 37253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // DoStringCharCodeAt above. 37263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->index()->IsConstantOperand()) { 37273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int const_index = ToInteger32(LConstantOperand::cast(instr->index())); 37283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(scratch, zero_reg, Operand(Smi::FromInt(const_index))); 37293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(scratch); 37303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 37313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register index = ToRegister(instr->index()); 37323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ SmiTag(index); 37333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(index); 37343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 37353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr); 37363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_debug_code) { 37373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ AbortIfNotSmi(v0); 37383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 37393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ SmiUntag(v0); 37403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ StoreToSafepointRegisterSlot(v0, result); 37413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 37423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { 37453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class DeferredStringCharFromCode: public LDeferredCode { 37463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 37473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) 37483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : LDeferredCode(codegen), instr_(instr) { } 37493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); } 37503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual LInstruction* instr() { return instr_; } 37513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 37523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LStringCharFromCode* instr_; 37533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 37543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredStringCharFromCode* deferred = 37563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new DeferredStringCharFromCode(this, instr); 37573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); 37593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register char_code = ToRegister(instr->char_code()); 37603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 37613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 37623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!char_code.is(result)); 37633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(deferred->entry(), hi, 37653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch char_code, Operand(String::kMaxAsciiCharCode)); 37663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex); 37673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sll(scratch, char_code, kPointerSizeLog2); 37683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(result, result, scratch); 37693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(result, FixedArray::kHeaderSize)); 37703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); 37713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(deferred->entry(), eq, result, Operand(scratch)); 37723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(deferred->exit()); 37733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 37743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { 37773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register char_code = ToRegister(instr->char_code()); 37783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 37793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(3095996): Get rid of this. For now, we need to make the 37813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // result register contain a valid pointer because it is already 37823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // contained in the register pointer map. 37833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(result, zero_reg); 37843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 37863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ SmiTag(char_code); 37873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(char_code); 37883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr); 37893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ StoreToSafepointRegisterSlot(v0, result); 37903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 37913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoStringLength(LStringLength* instr) { 37943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register string = ToRegister(instr->InputAt(0)); 37953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 37963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(string, String::kLengthOffset)); 37973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 37983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 38013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* input = instr->InputAt(0); 38023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(input->IsRegister() || input->IsStackSlot()); 38033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* output = instr->result(); 38043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(output->IsDoubleRegister()); 38053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FPURegister single_scratch = double_scratch0().low(); 38063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (input->IsStackSlot()) { 38073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 38083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch, ToMemOperand(input)); 38093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mtc1(scratch, single_scratch); 38103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 38113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mtc1(ToRegister(input), single_scratch); 38123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 38133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ cvt_d_w(ToDoubleRegister(output), single_scratch); 38143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 38153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoNumberTagI(LNumberTagI* instr) { 38183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class DeferredNumberTagI: public LDeferredCode { 38193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 38203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) 38213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : LDeferredCode(codegen), instr_(instr) { } 38223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); } 38233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual LInstruction* instr() { return instr_; } 38243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 38253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LNumberTagI* instr_; 38263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 38273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register src = ToRegister(instr->InputAt(0)); 38293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register dst = ToRegister(instr->result()); 38303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register overflow = scratch0(); 38313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr); 38333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ SmiTagCheckOverflow(dst, src, overflow); 38343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ BranchOnOverflow(deferred->entry(), overflow); 38353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(deferred->exit()); 38363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 38373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { 38403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label slow; 38413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register src = ToRegister(instr->InputAt(0)); 38423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register dst = ToRegister(instr->result()); 38433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FPURegister dbl_scratch = double_scratch0(); 38443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Preserve the value of all registers. 38463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 38473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // There was overflow, so bits 30 and 31 of the original integer 38493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // disagree. Try to allocate a heap number in new space and store 38503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the value in there. If that fails, call the runtime system. 38513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 38523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (dst.is(src)) { 38533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ SmiUntag(src, dst); 38543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Xor(src, src, Operand(0x80000000)); 38553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 38563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mtc1(src, dbl_scratch); 38573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ cvt_d_w(dbl_scratch, dbl_scratch); 38583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_inline_new) { 38593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(t2, Heap::kHeapNumberMapRootIndex); 38603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ AllocateHeapNumber(t1, a3, t0, t2, &slow); 38613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Move(dst, t1); 38623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done); 38633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 38643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Slow case: Call the runtime system to do the number allocation. 38663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&slow); 38673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(3095996): Put a valid pointer value in the stack slot where the result 38693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // register is stored, as this register is in the pointer map, but contains an 38703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // integer value. 38713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ StoreToSafepointRegisterSlot(zero_reg, dst); 38723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 38733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Move(dst, v0); 38743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Done. Put the value in dbl_scratch into the value of the allocated heap 38763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // number. 38773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 38783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sdc1(dbl_scratch, FieldMemOperand(dst, HeapNumber::kValueOffset)); 38793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ StoreToSafepointRegisterSlot(dst, dst); 38803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 38813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoNumberTagD(LNumberTagD* instr) { 38843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class DeferredNumberTagD: public LDeferredCode { 38853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 38863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 38873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : LDeferredCode(codegen), instr_(instr) { } 38883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 38893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual LInstruction* instr() { return instr_; } 38903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 38913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LNumberTagD* instr_; 38923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 38933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 38953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 38963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = ToRegister(instr->result()); 38973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp1 = ToRegister(instr->TempAt(0)); 38983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp2 = ToRegister(instr->TempAt(1)); 38993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr); 39013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_inline_new) { 39023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); 39033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry()); 39043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 39053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(deferred->entry()); 39063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 39073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(deferred->exit()); 39083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sdc1(input_reg, FieldMemOperand(reg, HeapNumber::kValueOffset)); 39093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 39103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 39133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(3095996): Get rid of this. For now, we need to make the 39143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // result register contain a valid pointer because it is already 39153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // contained in the register pointer map. 39163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = ToRegister(instr->result()); 39173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(reg, zero_reg); 39183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 39203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 39213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ StoreToSafepointRegisterSlot(v0, reg); 39223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 39233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoSmiTag(LSmiTag* instr) { 39263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); 39273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ SmiTag(ToRegister(instr->result()), ToRegister(instr->InputAt(0))); 39283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 39293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoSmiUntag(LSmiUntag* instr) { 39323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 39333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input = ToRegister(instr->InputAt(0)); 39343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 39353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->needs_check()) { 39363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(kHeapObjectTag == 1); 39373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If the input is a HeapObject, value of scratch won't be zero. 39383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(scratch, input, Operand(kHeapObjectTag)); 39393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ SmiUntag(result, input); 39403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); 39413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 39423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ SmiUntag(result, input); 39433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 39443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 39453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::EmitNumberUntagD(Register input_reg, 39483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister result_reg, 39493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool deoptimize_on_undefined, 39503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool deoptimize_on_minus_zero, 39513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LEnvironment* env) { 39523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 39533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label load_smi, heap_number, done; 39553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Smi check. 39573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); 39583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Heap number map check. 39603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 39613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 39623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (deoptimize_on_undefined) { 39633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, env, scratch, Operand(at)); 39643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 39653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label heap_number; 39663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&heap_number, eq, scratch, Operand(at)); 39673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 39693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, env, input_reg, Operand(at)); 39703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Convert undefined to NaN. 39723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kNanValueRootIndex); 39733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ ldc1(result_reg, FieldMemOperand(at, HeapNumber::kValueOffset)); 39743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done); 39753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&heap_number); 39773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 39783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Heap number to double register conversion. 39793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ ldc1(result_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset)); 39803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (deoptimize_on_minus_zero) { 39813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mfc1(at, result_reg.low()); 39823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done, ne, at, Operand(zero_reg)); 39833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mfc1(scratch, result_reg.high()); 39843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, env, scratch, Operand(HeapNumber::kSignMask)); 39853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 39863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done); 39873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Smi to double register conversion 39893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&load_smi); 39903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // scratch: untagged value of input_reg 39913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mtc1(scratch, result_reg); 39923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ cvt_d_w(result_reg, result_reg); 39933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 39943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 39953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 39983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input_reg = ToRegister(instr->InputAt(0)); 39993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch1 = scratch0(); 40003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch2 = ToRegister(instr->TempAt(0)); 40013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister double_scratch = double_scratch0(); 40023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FPURegister single_scratch = double_scratch.low(); 40033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2)); 40053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1)); 40063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 40083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The input is a tagged HeapObject. 40103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Heap number map check. 40113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 40123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 40133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // This 'at' value and scratch1 map value are used for tests in both clauses 40143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // of the if. 40153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->truncating()) { 40173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch3 = ToRegister(instr->TempAt(1)); 40183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister double_scratch2 = ToDoubleRegister(instr->TempAt(2)); 40193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!scratch3.is(input_reg) && 40203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !scratch3.is(scratch1) && 40213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !scratch3.is(scratch2)); 40223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Performs a truncating conversion of a floating point number as used by 40233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the JS bitwise operations. 40243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label heap_number; 40253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&heap_number, eq, scratch1, Operand(at)); // HeapNumber map? 40263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check for undefined. Undefined is converted to zero for truncating 40273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // conversions. 40283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 40293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), input_reg, Operand(at)); 40303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->result()).is(input_reg)); 40313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(input_reg, zero_reg); 40323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done); 40333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&heap_number); 40353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ ldc1(double_scratch2, 40363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FieldMemOperand(input_reg, HeapNumber::kValueOffset)); 40373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ EmitECMATruncate(input_reg, 40383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double_scratch2, 40393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch single_scratch, 40403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch1, 40413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch2, 40423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch3); 40433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 40443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Deoptimize if we don't have a heap number. 40453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), scratch1, Operand(at)); 40463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load the double value. 40483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ ldc1(double_scratch, 40493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FieldMemOperand(input_reg, HeapNumber::kValueOffset)); 40503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register except_flag = scratch2; 40523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ EmitFPUTruncate(kRoundToZero, 40533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch single_scratch, 40543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double_scratch, 40553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch1, 40563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch except_flag, 40573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kCheckForInexactConversion); 40583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Deopt if the operation did not succeed. 40603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 40613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load the result. 40633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mfc1(input_reg, single_scratch); 40643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 40663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done, ne, input_reg, Operand(zero_reg)); 40673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mfc1(scratch1, double_scratch.high()); 40693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); 40703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); 40713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 40723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 40733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 40743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 40753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoTaggedToI(LTaggedToI* instr) { 40783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class DeferredTaggedToI: public LDeferredCode { 40793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 40803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) 40813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : LDeferredCode(codegen), instr_(instr) { } 40823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } 40833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual LInstruction* instr() { return instr_; } 40843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 40853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LTaggedToI* instr_; 40863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 40873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* input = instr->InputAt(0); 40893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(input->IsRegister()); 40903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(input->Equals(instr->result())); 40913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input_reg = ToRegister(input); 40933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr); 40953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Let the deferred code handle the HeapObject case. 40973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ JumpIfNotSmi(input_reg, deferred->entry()); 40983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Smi to int32 conversion. 41003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ SmiUntag(input_reg); 41013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(deferred->exit()); 41023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 41033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 41063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* input = instr->InputAt(0); 41073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(input->IsRegister()); 41083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* result = instr->result(); 41093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(result->IsDoubleRegister()); 41103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input_reg = ToRegister(input); 41123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister result_reg = ToDoubleRegister(result); 41133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitNumberUntagD(input_reg, result_reg, 41153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->hydrogen()->deoptimize_on_undefined(), 41163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->hydrogen()->deoptimize_on_minus_zero(), 41173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->environment()); 41183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 41193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoDoubleToI(LDoubleToI* instr) { 41223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result_reg = ToRegister(instr->result()); 41233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch1 = scratch0(); 41243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch2 = ToRegister(instr->TempAt(0)); 41253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister double_input = ToDoubleRegister(instr->InputAt(0)); 41263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FPURegister single_scratch = double_scratch0().low(); 41273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->truncating()) { 41293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch3 = ToRegister(instr->TempAt(1)); 41303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ EmitECMATruncate(result_reg, 41313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double_input, 41323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch single_scratch, 41333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch1, 41343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch2, 41353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch3); 41363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 41373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register except_flag = scratch2; 41383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ EmitFPUTruncate(kRoundToMinusInf, 41403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch single_scratch, 41413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch double_input, 41423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch1, 41433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch except_flag, 41443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kCheckForInexactConversion); 41453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Deopt if the operation did not succeed (except_flag != 0). 41473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); 41483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load the result. 41503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mfc1(result_reg, single_scratch); 41513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 41523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 41533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCheckSmi(LCheckSmi* instr) { 41563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* input = instr->InputAt(0); 41573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(at, ToRegister(input), Operand(kSmiTagMask)); 41583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); 41593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 41603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 41633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* input = instr->InputAt(0); 41643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(at, ToRegister(input), Operand(kSmiTagMask)); 41653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 41663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 41673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 41703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input = ToRegister(instr->InputAt(0)); 41713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 41723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ GetObjectType(input, scratch, scratch); 41743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->is_interval_check()) { 41763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InstanceType first; 41773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InstanceType last; 41783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->hydrogen()->GetCheckInterval(&first, &last); 41793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If there is only one type in the interval check for equality. 41813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (first == last) { 41823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), scratch, Operand(first)); 41833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 41843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(lo, instr->environment(), scratch, Operand(first)); 41853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Omit check for the last type. 41863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (last != LAST_TYPE) { 41873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(hi, instr->environment(), scratch, Operand(last)); 41883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 41893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 41903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 41913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint8_t mask; 41923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint8_t tag; 41933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag); 41943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 41953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (IsPowerOf2(mask)) { 41963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(tag == 0 || IsPowerOf2(tag)); 41973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(at, scratch, mask); 41983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(tag == 0 ? ne : eq, instr->environment(), 41993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch at, Operand(zero_reg)); 42003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 42013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(scratch, scratch, Operand(mask)); 42023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), scratch, Operand(tag)); 42033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 42043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 42053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 42063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCheckFunction(LCheckFunction* instr) { 42093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = ToRegister(instr->value()); 42103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSFunction> target = instr->hydrogen()->target(); 42113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (isolate()->heap()->InNewSpace(*target)) { 42123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = ToRegister(instr->value()); 42133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSGlobalPropertyCell> cell = 42143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate()->factory()->NewJSGlobalPropertyCell(target); 42153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(at, Operand(Handle<Object>(cell))); 42163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(at, FieldMemOperand(at, JSGlobalPropertyCell::kValueOffset)); 42173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), reg, 42183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(at)); 42193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 42203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), reg, 42213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(target)); 42223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 42233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 42243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCheckMapCommon(Register reg, 42273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch, 42283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Map> map, 42293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompareMapMode mode, 42303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LEnvironment* env) { 42313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label success; 42323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CompareMapAndBranch(reg, scratch, map, &success, eq, &success, mode); 42333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(al, env); 42343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&success); 42353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 42363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCheckMap(LCheckMap* instr) { 42393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 42403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOperand* input = instr->InputAt(0); 42413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(input->IsRegister()); 42423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = ToRegister(input); 42433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Map> map = instr->hydrogen()->map(); 42443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoCheckMapCommon(reg, scratch, map, instr->hydrogen()->mode(), 42453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->environment()); 42463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 42473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 42503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister value_reg = ToDoubleRegister(instr->unclamped()); 42513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result_reg = ToRegister(instr->result()); 42523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister temp_reg = ToDoubleRegister(instr->TempAt(0)); 42533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ ClampDoubleToUint8(result_reg, value_reg, temp_reg); 42543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 42553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { 42583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register unclamped_reg = ToRegister(instr->unclamped()); 42593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result_reg = ToRegister(instr->result()); 42603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ ClampUint8(result_reg, unclamped_reg); 42613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 42623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { 42653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 42663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input_reg = ToRegister(instr->unclamped()); 42673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result_reg = ToRegister(instr->result()); 42683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoubleRegister temp_reg = ToDoubleRegister(instr->TempAt(0)); 42693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label is_smi, done, heap_number; 42703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Both smi and heap number cases are handled. 42723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ UntagAndJumpIfSmi(scratch, input_reg, &is_smi); 42733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check for heap number 42753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 42763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&heap_number, eq, scratch, Operand(factory()->heap_number_map())); 42773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check for undefined. Undefined is converted to zero for clamping 42793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // conversions. 42803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), input_reg, 42813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(factory()->undefined_value())); 42823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(result_reg, zero_reg); 42833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ jmp(&done); 42843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Heap number 42863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&heap_number); 42873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ ldc1(double_scratch0(), FieldMemOperand(input_reg, 42883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HeapNumber::kValueOffset)); 42893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ ClampDoubleToUint8(result_reg, double_scratch0(), temp_reg); 42903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ jmp(&done); 42913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&is_smi); 42933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ ClampUint8(result_reg, scratch); 42943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 42963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 42973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { 43003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp1 = ToRegister(instr->TempAt(0)); 43013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp2 = ToRegister(instr->TempAt(1)); 43023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> holder = instr->holder(); 43043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> current_prototype = instr->prototype(); 43053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load prototype object. 43073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadHeapObject(temp1, current_prototype); 43083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check prototype maps up to the holder. 43103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (!current_prototype.is_identical_to(holder)) { 43113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoCheckMapCommon(temp1, temp2, 43123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Map>(current_prototype->map()), 43133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ALLOW_ELEMENT_TRANSITION_MAPS, instr->environment()); 43143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch current_prototype = 43153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype())); 43163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load next prototype object. 43173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadHeapObject(temp1, current_prototype); 43183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 43193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check the holder map. 43213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DoCheckMapCommon(temp1, temp2, 43223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Map>(current_prototype->map()), 43233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ALLOW_ELEMENT_TRANSITION_MAPS, instr->environment()); 43243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 43253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoAllocateObject(LAllocateObject* instr) { 43283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class DeferredAllocateObject: public LDeferredCode { 43293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 43303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredAllocateObject(LCodeGen* codegen, LAllocateObject* instr) 43313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : LDeferredCode(codegen), instr_(instr) { } 43323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); } 43333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual LInstruction* instr() { return instr_; } 43343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 43353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LAllocateObject* instr_; 43363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 43373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredAllocateObject* deferred = new DeferredAllocateObject(this, instr); 43393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 43413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = ToRegister(instr->TempAt(0)); 43423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch2 = ToRegister(instr->TempAt(1)); 43433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSFunction> constructor = instr->hydrogen()->constructor(); 43443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Map> initial_map(constructor->initial_map()); 43453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int instance_size = initial_map->instance_size(); 43463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(initial_map->pre_allocated_property_fields() + 43473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch initial_map->unused_property_fields() - 43483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch initial_map->inobject_properties() == 0); 43493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Allocate memory for the object. The initial map might change when 43513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the constructor's prototype changes, but instance size and property 43523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // counts remain unchanged (if slack tracking finished). 43533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!constructor->shared()->IsInobjectSlackTrackingInProgress()); 43543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ AllocateInNewSpace(instance_size, 43553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result, 43563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch, 43573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch2, 43583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch deferred->entry(), 43593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TAG_OBJECT); 43603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load the initial map. 43623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register map = scratch; 43633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadHeapObject(map, constructor); 43643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(map, FieldMemOperand(map, JSFunction::kPrototypeOrInitialMapOffset)); 43653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Initialize map and fields of the newly allocated object. 43673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE); 43683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(map, FieldMemOperand(result, JSObject::kMapOffset)); 43693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(scratch, Heap::kEmptyFixedArrayRootIndex); 43703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(scratch, FieldMemOperand(result, JSObject::kElementsOffset)); 43713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(scratch, FieldMemOperand(result, JSObject::kPropertiesOffset)); 43723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (initial_map->inobject_properties() != 0) { 43733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); 43743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < initial_map->inobject_properties(); i++) { 43753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int property_offset = JSObject::kHeaderSize + i * kPointerSize; 43763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(scratch, FieldMemOperand(result, property_offset)); 43773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 43783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 43793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(deferred->exit()); 43813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 43823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { 43853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 43863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSFunction> constructor = instr->hydrogen()->constructor(); 43873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(3095996): Get rid of this. For now, we need to make the 43893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // result register contain a valid pointer because it is already 43903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // contained in the register pointer map. 43913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(result, zero_reg); 43923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 43943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadHeapObject(a0, constructor); 43953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(a0); 43963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntimeFromDeferred(Runtime::kNewObject, 1, instr); 43973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ StoreToSafepointRegisterSlot(v0, result); 43983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 43993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 44003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 44013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { 44023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Heap* heap = isolate()->heap(); 44033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind boilerplate_elements_kind = 44043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->hydrogen()->boilerplate_elements_kind(); 44053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 44063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Deopt if the array literal boilerplate ElementsKind is of a type different 44073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // than the expected one. The check isn't necessary if the boilerplate has 44083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // already been converted to FAST_ELEMENTS. 44093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (boilerplate_elements_kind != FAST_ELEMENTS) { 44103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadHeapObject(a1, instr->hydrogen()->boilerplate_object()); 44113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load map into a2. 44123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(a2, FieldMemOperand(a1, HeapObject::kMapOffset)); 44133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load the map's "bit field 2". 44143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lbu(a2, FieldMemOperand(a2, Map::kBitField2Offset)); 44153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Retrieve elements_kind from bit field 2. 44163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Ext(a2, a2, Map::kElementsKindShift, Map::kElementsKindBitCount); 44173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, 44183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->environment(), 44193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch a2, 44203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(boilerplate_elements_kind)); 44213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 44223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 44233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); 44243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a2, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); 44253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Boilerplate already exists, constant elements are never accessed. 44263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Pass an empty fixed array. 44273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a1, Operand(Handle<FixedArray>(heap->empty_fixed_array()))); 44283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Push(a3, a2, a1); 44293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 44303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Pick the right runtime function or stub to call. 44313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int length = instr->hydrogen()->length(); 44323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->IsCopyOnWrite()) { 44333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(instr->hydrogen()->depth() == 1); 44343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FastCloneShallowArrayStub::Mode mode = 44353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS; 44363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FastCloneShallowArrayStub stub(mode, length); 44373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 44383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (instr->hydrogen()->depth() > 1) { 44393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntime(Runtime::kCreateArrayLiteral, 3, instr); 44403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { 44413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntime(Runtime::kCreateArrayLiteralShallow, 3, instr); 44423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 44433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FastCloneShallowArrayStub::Mode mode = 44443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch boilerplate_elements_kind == FAST_DOUBLE_ELEMENTS 44453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS 44463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : FastCloneShallowArrayStub::CLONE_ELEMENTS; 44473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FastCloneShallowArrayStub stub(mode, length); 44483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 44493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 44503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 44513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 44523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 44533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::EmitDeepCopy(Handle<JSObject> object, 44543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result, 44553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register source, 44563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int* offset) { 44573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!source.is(a2)); 44583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!result.is(a2)); 44593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 44603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Only elements backing stores for non-COW arrays need to be copied. 44613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<FixedArrayBase> elements(object->elements()); 44623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool has_elements = elements->length() > 0 && 44633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elements->map() != isolate()->heap()->fixed_cow_array_map(); 44643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 44653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Increase the offset so that subsequent objects end up right after 44663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // this object and its backing store. 44673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int object_offset = *offset; 44683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int object_size = object->map()->instance_size(); 44693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int elements_offset = *offset + object_size; 44703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int elements_size = has_elements ? elements->Size() : 0; 44713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *offset += object_size + elements_size; 44723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 44733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Copy object header. 44743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(object->properties()->length() == 0); 44753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int inobject_properties = object->map()->inobject_properties(); 44763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int header_size = object_size - inobject_properties * kPointerSize; 44773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < header_size; i += kPointerSize) { 44783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (has_elements && i == JSObject::kElementsOffset) { 44793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(a2, result, Operand(elements_offset)); 44803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 44813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(a2, FieldMemOperand(source, i)); 44823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 44833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(a2, FieldMemOperand(result, object_offset + i)); 44843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 44853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 44863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Copy in-object properties. 44873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < inobject_properties; i++) { 44883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int total_offset = object_offset + object->GetInObjectPropertyOffset(i); 44893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> value = Handle<Object>(object->InObjectPropertyAt(i)); 44903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (value->IsJSObject()) { 44913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> value_object = Handle<JSObject>::cast(value); 44923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(a2, result, Operand(*offset)); 44933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(a2, FieldMemOperand(result, total_offset)); 44943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadHeapObject(source, value_object); 44953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitDeepCopy(value_object, result, source, offset); 44963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (value->IsHeapObject()) { 44973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadHeapObject(a2, Handle<HeapObject>::cast(value)); 44983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(a2, FieldMemOperand(result, total_offset)); 44993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 45003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a2, Operand(value)); 45013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(a2, FieldMemOperand(result, total_offset)); 45023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 45033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 45043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 45053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 45063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (has_elements) { 45073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Copy elements backing store header. 45083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadHeapObject(source, elements); 45093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < FixedArray::kHeaderSize; i += kPointerSize) { 45103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(a2, FieldMemOperand(source, i)); 45113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(a2, FieldMemOperand(result, elements_offset + i)); 45123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 45133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 45143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Copy elements backing store content. 45153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int elements_length = has_elements ? elements->length() : 0; 45163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (elements->IsFixedDoubleArray()) { 45173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<FixedDoubleArray> double_array = 45183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<FixedDoubleArray>::cast(elements); 45193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < elements_length; i++) { 45203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int64_t value = double_array->get_representation(i); 45213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We only support little endian mode... 45223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int32_t value_low = value & 0xFFFFFFFF; 45233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int32_t value_high = value >> 32; 45243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int total_offset = 45253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch elements_offset + FixedDoubleArray::OffsetOfElementAt(i); 45263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a2, Operand(value_low)); 45273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(a2, FieldMemOperand(result, total_offset)); 45283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a2, Operand(value_high)); 45293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(a2, FieldMemOperand(result, total_offset + 4)); 45303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 45313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (elements->IsFixedArray()) { 45323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < elements_length; i++) { 45333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int total_offset = elements_offset + FixedArray::OffsetOfElementAt(i); 45343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> value = JSObject::GetElement(object, i); 45353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (value->IsJSObject()) { 45363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> value_object = Handle<JSObject>::cast(value); 45373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(a2, result, Operand(*offset)); 45383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(a2, FieldMemOperand(result, total_offset)); 45393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadHeapObject(source, value_object); 45403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitDeepCopy(value_object, result, source, offset); 45413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (value->IsHeapObject()) { 45423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadHeapObject(a2, Handle<HeapObject>::cast(value)); 45433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(a2, FieldMemOperand(result, total_offset)); 45443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 45453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a2, Operand(value)); 45463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(a2, FieldMemOperand(result, total_offset)); 45473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 45483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 45493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 45503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 45513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 45523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 45533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 45543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 45553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 45563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoFastLiteral(LFastLiteral* instr) { 45573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int size = instr->hydrogen()->total_size(); 45583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 45593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Allocate all objects that are part of the literal in one big 45603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // allocation. This avoids multiple limit checks. 45613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label allocated, runtime_allocate; 45623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ AllocateInNewSpace(size, v0, a2, a3, &runtime_allocate, TAG_OBJECT); 45633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ jmp(&allocated); 45643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 45653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&runtime_allocate); 45663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a0, Operand(Smi::FromInt(size))); 45673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(a0); 45683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); 45693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 45703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&allocated); 45713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int offset = 0; 45723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadHeapObject(a1, instr->hydrogen()->boilerplate()); 45733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitDeepCopy(instr->hydrogen()->boilerplate(), v0, a1, &offset); 45743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_EQ(size, offset); 45753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 45763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 45773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 45783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { 45793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->result()).is(v0)); 45803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<FixedArray> literals(instr->environment()->closure()->literals()); 45813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<FixedArray> constant_properties = 45823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->hydrogen()->constant_properties(); 45833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 45843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up the parameters to the stub/runtime call. 45853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadHeapObject(t0, literals); 45863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a3, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); 45873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a2, Operand(constant_properties)); 45883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int flags = instr->hydrogen()->fast_elements() 45893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? ObjectLiteral::kFastElements 45903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : ObjectLiteral::kNoFlags; 45913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a1, Operand(Smi::FromInt(flags))); 45923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Push(t0, a3, a2, a1); 45933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 45943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Pick the right runtime function or stub to call. 45953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int properties_count = constant_properties->length() / 2; 45963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->depth() > 1) { 45973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntime(Runtime::kCreateObjectLiteral, 4, instr); 45983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (flags != ObjectLiteral::kFastElements || 45993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { 46003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr); 46013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 46023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FastCloneShallowObjectStub stub(properties_count); 46033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 46043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 46053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 46063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 46073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 46083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoToFastProperties(LToFastProperties* instr) { 46093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->InputAt(0)).is(a0)); 46103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->result()).is(v0)); 46113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(a0); 46123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntime(Runtime::kToFastProperties, 1, instr); 46133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 46143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 46153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 46163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { 46173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label materialized; 46183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Registers will be used as follows: 46193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // a3 = JS function. 46203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // t3 = literals array. 46213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // a1 = regexp literal. 46223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // a0 = regexp literal clone. 46233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // a2 and t0-t2 are used as temporaries. 46243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 46253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(t3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); 46263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int literal_offset = FixedArray::kHeaderSize + 46273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->hydrogen()->literal_index() * kPointerSize; 46283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(a1, FieldMemOperand(t3, literal_offset)); 46293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 46303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&materialized, ne, a1, Operand(at)); 46313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 46323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Create regexp literal using runtime function 46333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Result will be in v0. 46343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(t2, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); 46353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(t1, Operand(instr->hydrogen()->pattern())); 46363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(t0, Operand(instr->hydrogen()->flags())); 46373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Push(t3, t2, t1, t0); 46383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr); 46393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(a1, v0); 46403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 46413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&materialized); 46423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; 46433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label allocated, runtime_allocate; 46443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 46453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ AllocateInNewSpace(size, v0, a2, a3, &runtime_allocate, TAG_OBJECT); 46463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ jmp(&allocated); 46473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 46483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&runtime_allocate); 46493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a0, Operand(Smi::FromInt(size))); 46503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Push(a1, a0); 46513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); 46523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ pop(a1); 46533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 46543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&allocated); 46553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Copy the content into the newly allocated memory. 46563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // (Unroll copy loop once for better throughput). 46573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) { 46583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(a3, FieldMemOperand(a1, i)); 46593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(a2, FieldMemOperand(a1, i + kPointerSize)); 46603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(a3, FieldMemOperand(v0, i)); 46613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(a2, FieldMemOperand(v0, i + kPointerSize)); 46623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 46633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if ((size % (2 * kPointerSize)) != 0) { 46643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(a3, FieldMemOperand(a1, size - kPointerSize)); 46653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sw(a3, FieldMemOperand(v0, size - kPointerSize)); 46663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 46673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 46683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 46693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 46703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { 46713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Use the fast case closure allocation code that allocates in new 46723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // space for nested functions that don't need literals cloning. 46733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<SharedFunctionInfo> shared_info = instr->shared_info(); 46743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool pretenure = instr->hydrogen()->pretenure(); 46753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!pretenure && shared_info->num_literals() == 0) { 46763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FastNewClosureStub stub(shared_info->language_mode()); 46773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a1, Operand(shared_info)); 46783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(a1); 46793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 46803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 46813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a2, Operand(shared_info)); 46823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(a1, Operand(pretenure 46833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? factory()->true_value() 46843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : factory()->false_value())); 46853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Push(cp, a2, a1); 46863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntime(Runtime::kNewClosure, 3, instr); 46873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 46883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 46893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 46903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 46913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoTypeof(LTypeof* instr) { 46923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ToRegister(instr->result()).is(v0)); 46933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input = ToRegister(instr->InputAt(0)); 46943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(input); 46953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntime(Runtime::kTypeof, 1, instr); 46963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 46973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 46983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 46993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { 47003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input = ToRegister(instr->InputAt(0)); 47013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int true_block = chunk_->LookupDestination(instr->true_block_id()); 47023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int false_block = chunk_->LookupDestination(instr->false_block_id()); 47033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* true_label = chunk_->GetAssemblyLabel(true_block); 47043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* false_label = chunk_->GetAssemblyLabel(false_block); 47053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 47063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register cmp1 = no_reg; 47073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand cmp2 = Operand(no_reg); 47083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 47093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition final_branch_condition = EmitTypeofIs(true_label, 47103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch false_label, 47113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch input, 47123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->type_literal(), 47133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp1, 47143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp2); 47153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 47163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(cmp1.is_valid()); 47173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!cmp2.is_reg() || cmp2.rm().is_valid()); 47183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 47193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (final_branch_condition != kNoCondition) { 47203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranch(true_block, false_block, final_branch_condition, cmp1, cmp2); 47213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 47223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 47233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 47243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 47253ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochCondition LCodeGen::EmitTypeofIs(Label* true_label, 47263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* false_label, 47273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register input, 47283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> type_name, 47293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register& cmp1, 47303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand& cmp2) { 47313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // This function utilizes the delay slot heavily. This is used to load 47323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // values that are always usable without depending on the type of the input 47333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // register. 47343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition final_branch_condition = kNoCondition; 47353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 47363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (type_name->Equals(heap()->number_symbol())) { 47373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ JumpIfSmi(input, true_label); 47383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(input, FieldMemOperand(input, HeapObject::kMapOffset)); 47393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 47403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp1 = input; 47413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp2 = Operand(at); 47423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch final_branch_condition = eq; 47433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 47443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (type_name->Equals(heap()->string_symbol())) { 47453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ JumpIfSmi(input, false_label); 47463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ GetObjectType(input, input, scratch); 47473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(USE_DELAY_SLOT, false_label, 47483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ge, scratch, Operand(FIRST_NONSTRING_TYPE)); 47493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // input is an object so we can load the BitFieldOffset even if we take the 47503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // other branch. 47513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lbu(at, FieldMemOperand(input, Map::kBitFieldOffset)); 47523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(at, at, 1 << Map::kIsUndetectable); 47533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp1 = at; 47543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp2 = Operand(zero_reg); 47553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch final_branch_condition = eq; 47563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 47573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (type_name->Equals(heap()->boolean_symbol())) { 47583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kTrueValueRootIndex); 47593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input)); 47603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kFalseValueRootIndex); 47613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp1 = at; 47623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp2 = Operand(input); 47633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch final_branch_condition = eq; 47643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 47653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_symbol())) { 47663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kNullValueRootIndex); 47673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp1 = at; 47683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp2 = Operand(input); 47693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch final_branch_condition = eq; 47703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 47713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (type_name->Equals(heap()->undefined_symbol())) { 47723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 47733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input)); 47743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The first instruction of JumpIfSmi is an And - it is safe in the delay 47753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // slot. 47763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ JumpIfSmi(input, false_label); 47773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check for undetectable objects => true. 47783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(input, FieldMemOperand(input, HeapObject::kMapOffset)); 47793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lbu(at, FieldMemOperand(input, Map::kBitFieldOffset)); 47803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(at, at, 1 << Map::kIsUndetectable); 47813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp1 = at; 47823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp2 = Operand(zero_reg); 47833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch final_branch_condition = ne; 47843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 47853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (type_name->Equals(heap()->function_symbol())) { 47863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); 47873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ JumpIfSmi(input, false_label); 47883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ GetObjectType(input, scratch, input); 47893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(true_label, eq, input, Operand(JS_FUNCTION_TYPE)); 47903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp1 = input; 47913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp2 = Operand(JS_FUNCTION_PROXY_TYPE); 47923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch final_branch_condition = eq; 47933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 47943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (type_name->Equals(heap()->object_symbol())) { 47953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ JumpIfSmi(input, false_label); 47963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!FLAG_harmony_typeof) { 47973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kNullValueRootIndex); 47983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input)); 47993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 48003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // input is an object, it is safe to use GetObjectType in the delay slot. 48013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ GetObjectType(input, input, scratch); 48023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(USE_DELAY_SLOT, false_label, 48033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch lt, scratch, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); 48043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Still an object, so the InstanceType can be loaded. 48053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lbu(scratch, FieldMemOperand(input, Map::kInstanceTypeOffset)); 48063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(USE_DELAY_SLOT, false_label, 48073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch gt, scratch, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); 48083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Still an object, so the BitField can be loaded. 48093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check for undetectable objects => false. 48103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lbu(at, FieldMemOperand(input, Map::kBitFieldOffset)); 48113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(at, at, 1 << Map::kIsUndetectable); 48123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp1 = at; 48133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp2 = Operand(zero_reg); 48143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch final_branch_condition = eq; 48153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 48173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp1 = at; 48183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmp2 = Operand(zero_reg); // Set to valid regs, to avoid caller assertion. 48193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(false_label); 48203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 48213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return final_branch_condition; 48233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 48243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 48273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register temp1 = ToRegister(instr->TempAt(0)); 48283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int true_block = chunk_->LookupDestination(instr->true_block_id()); 48293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int false_block = chunk_->LookupDestination(instr->false_block_id()); 48303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitIsConstructCall(temp1, scratch0()); 48323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EmitBranch(true_block, false_block, eq, temp1, 48343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(Smi::FromInt(StackFrame::CONSTRUCT))); 48353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 48363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) { 48393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!temp1.is(temp2)); 48403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Get the frame pointer for the calling frame. 48413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 48423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Skip the arguments adaptor frame if it exists. 48443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label check_frame_marker; 48453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(temp2, MemOperand(temp1, StandardFrameConstants::kContextOffset)); 48463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&check_frame_marker, ne, temp2, 48473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 48483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset)); 48493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check the marker in the calling frame. 48513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&check_frame_marker); 48523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset)); 48533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 48543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::EnsureSpaceForLazyDeopt() { 48573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Ensure that we have enough space after the previous lazy-bailout 48583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // instruction for patching the code here. 48593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int current_pc = masm()->pc_offset(); 48603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int patch_size = Deoptimizer::patch_size(); 48613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (current_pc < last_lazy_deopt_pc_ + patch_size) { 48623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int padding_size = last_lazy_deopt_pc_ + patch_size - current_pc; 48633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_EQ(0, padding_size % Assembler::kInstrSize); 48643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (padding_size > 0) { 48653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ nop(); 48663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch padding_size -= Assembler::kInstrSize; 48673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 48683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 48693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch last_lazy_deopt_pc_ = masm()->pc_offset(); 48703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 48713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoLazyBailout(LLazyBailout* instr) { 48743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EnsureSpaceForLazyDeopt(); 48753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(instr->HasEnvironment()); 48763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LEnvironment* env = instr->environment(); 48773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 48783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 48793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 48803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoDeoptimize(LDeoptimize* instr) { 48833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(al, instr->environment(), zero_reg, Operand(zero_reg)); 48843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 48853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 48873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoDeleteProperty(LDeleteProperty* instr) { 48883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object = ToRegister(instr->object()); 48893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register key = ToRegister(instr->key()); 48903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register strict = scratch0(); 48913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ li(strict, Operand(Smi::FromInt(strict_mode_flag()))); 48923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Push(object, key, strict); 48933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); 48943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LPointerMap* pointers = instr->pointer_map(); 48953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordPosition(pointers->position()); 48963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SafepointGenerator safepoint_generator( 48973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch this, pointers, Safepoint::kLazyDeopt); 48983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator); 48993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 49003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 49013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 49023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoIn(LIn* instr) { 49033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register obj = ToRegister(instr->object()); 49043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register key = ToRegister(instr->key()); 49053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Push(key, obj); 49063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); 49073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LPointerMap* pointers = instr->pointer_map(); 49083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordPosition(pointers->position()); 49093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SafepointGenerator safepoint_generator(this, pointers, Safepoint::kLazyDeopt); 49103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); 49113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 49123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 49133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 49143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { 49153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 49163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CallRuntimeSaveDoubles(Runtime::kStackGuard); 49173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RecordSafepointWithLazyDeopt( 49183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 49193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(instr->HasEnvironment()); 49203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LEnvironment* env = instr->environment(); 49213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 49223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 49233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 49243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 49253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoStackCheck(LStackCheck* instr) { 49263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class DeferredStackCheck: public LDeferredCode { 49273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 49283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr) 49293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : LDeferredCode(codegen), instr_(instr) { } 49303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); } 49313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual LInstruction* instr() { return instr_; } 49323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 49333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LStackCheck* instr_; 49343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 49353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 49363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(instr->HasEnvironment()); 49373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LEnvironment* env = instr->environment(); 49383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // There is no LLazyBailout instruction for stack-checks. We have to 49393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // prepare for lazy deoptimization explicitly here. 49403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (instr->hydrogen()->is_function_entry()) { 49413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Perform stack overflow check. 49423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 49433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kStackLimitRootIndex); 49443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done, hs, sp, Operand(at)); 49453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StackCheckStub stub; 49463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 49473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EnsureSpaceForLazyDeopt(); 49483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 49493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 49503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 49513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 49523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(instr->hydrogen()->is_backwards_branch()); 49533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Perform stack overflow check if this goto needs it before jumping. 49543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeferredStackCheck* deferred_stack_check = 49553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new DeferredStackCheck(this, instr); 49563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kStackLimitRootIndex); 49573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(deferred_stack_check->entry(), lo, sp, Operand(at)); 49583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EnsureSpaceForLazyDeopt(); 49593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(instr->done_label()); 49603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch deferred_stack_check->SetExit(instr->done_label()); 49613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 49623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Don't record a deoptimization index for the safepoint here. 49633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // This will be done explicitly when emitting call and the safepoint in 49643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the deferred code. 49653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 49663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 49673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 49683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 49693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoOsrEntry(LOsrEntry* instr) { 49703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // This is a pseudo-instruction that ensures that the environment here is 49713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // properly registered for deoptimization and records the assembler's PC 49723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // offset. 49733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LEnvironment* environment = instr->environment(); 49743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch environment->SetSpilledRegisters(instr->SpilledRegisterArray(), 49753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch instr->SpilledDoubleRegisterArray()); 49763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 49773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If the environment were already registered, we would have no way of 49783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // backpatching it with the spill slot operands. 49793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!environment->HasBeenRegistered()); 49803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 49813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(osr_pc_offset_ == -1); 49823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch osr_pc_offset_ = masm()->pc_offset(); 49833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 49843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 49853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 49863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { 49873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 49883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object = ToRegister(instr->object()); 49893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kUndefinedValueRootIndex); 49903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), object, Operand(at)); 49913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 49923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register null_value = t1; 49933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(null_value, Heap::kNullValueRootIndex); 49943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), object, Operand(null_value)); 49953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 49963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ And(at, object, kSmiTagMask); 49973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); 49983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 49993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 50003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ GetObjectType(object, a1, a1); 50013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(le, instr->environment(), a1, Operand(LAST_JS_PROXY_TYPE)); 50023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label use_cache, call_runtime; 50043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(object.is(a0)); 50053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CheckEnumCache(null_value, &call_runtime); 50063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(object, HeapObject::kMapOffset)); 50083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&use_cache); 50093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Get the set of properties to enumerate. 50113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&call_runtime); 50123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ push(object); 50133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr); 50143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); 50163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(result.is(v0)); 50173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadRoot(at, Heap::kMetaMapRootIndex); 50183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), a1, Operand(at)); 50193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&use_cache); 50203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 50213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { 50243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register map = ToRegister(instr->map()); 50253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 50263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ LoadInstanceDescriptors(map, result); 50273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, 50283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FieldMemOperand(result, DescriptorArray::kEnumerationIndexOffset)); 50293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, 50303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FieldMemOperand(result, FixedArray::SizeFor(instr->idx()))); 50313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg)); 50323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 50333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { 50363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object = ToRegister(instr->value()); 50373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register map = ToRegister(instr->map()); 50383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(scratch0(), FieldMemOperand(object, HeapObject::kMapOffset)); 50393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DeoptimizeIf(ne, instr->environment(), map, Operand(scratch0())); 50403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 50413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) { 50443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object = ToRegister(instr->object()); 50453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register index = ToRegister(instr->index()); 50463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register result = ToRegister(instr->result()); 50473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch = scratch0(); 50483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label out_of_object, done; 50503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(USE_DELAY_SLOT, &out_of_object, lt, index, Operand(zero_reg)); 50513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ sll(scratch, index, kPointerSizeLog2 - kSmiTagSize); // In delay slot. 50523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(kPointerSizeLog2 > kSmiTagSize); 50543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Addu(scratch, object, scratch); 50553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(scratch, JSObject::kHeaderSize)); 50563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Branch(&done); 50583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&out_of_object); 50603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 50613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Index is equal to negated out of object property index plus 1. 50623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ Subu(scratch, result, scratch); 50633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ lw(result, FieldMemOperand(scratch, 50643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray::kHeaderSize - kPointerSize)); 50653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ bind(&done); 50663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 50673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef __ 50703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} } // namespace v8::internal 5072