Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Unified Diff: src/arm/stub-cache-arm.cc

Issue 5188006: Push version 2.5.7 to trunk.... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm/macro-assembler-arm.h ('k') | src/arm/virtual-frame-arm.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/stub-cache-arm.cc
===================================================================
--- src/arm/stub-cache-arm.cc (revision 5846)
+++ src/arm/stub-cache-arm.cc (working copy)
@@ -1676,8 +1676,143 @@
JSGlobalPropertyCell* cell,
JSFunction* function,
String* name) {
- // TODO(872): implement this.
- return Heap::undefined_value();
+ // ----------- S t a t e -------------
+ // -- r2 : function name
+ // -- lr : return address
+ // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
+ // -- ...
+ // -- sp[argc * 4] : receiver
+ // -----------------------------------
+
+ if (!CpuFeatures::IsSupported(VFP3)) return Heap::undefined_value();
+ CpuFeatures::Scope scope_vfp3(VFP3);
+
+ const int argc = arguments().immediate();
+
+ // If the object is not a JSObject or we got an unexpected number of
+ // arguments, bail out to the regular call.
+ if (!object->IsJSObject() || argc != 1) return Heap::undefined_value();
+
+ Label miss, slow;
+ GenerateNameCheck(name, &miss);
+
+ if (cell == NULL) {
+ __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
+
+ STATIC_ASSERT(kSmiTag == 0);
+ __ BranchOnSmi(r1, &miss);
+
+ CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name,
+ &miss);
+ } else {
+ ASSERT(cell->value() == function);
+ GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss);
+ GenerateLoadFunctionFromCell(cell, function, &miss);
+ }
+
+ // Load the (only) argument into r0.
+ __ ldr(r0, MemOperand(sp, 0 * kPointerSize));
+
+ // If the argument is a smi, just return.
+ STATIC_ASSERT(kSmiTag == 0);
+ __ tst(r0, Operand(kSmiTagMask));
+ __ Drop(argc + 1, eq);
+ __ Ret(eq);
+
+ __ CheckMap(r0, r1, Heap::kHeapNumberMapRootIndex, &slow, true);
+
+ Label wont_fit_smi, no_vfp_exception, restore_fpscr_and_return;
+
+ // If vfp3 is enabled, we use the fpu rounding with the RM (round towards
+ // minus infinity) mode.
+
+ // Load the HeapNumber value.
+ // We will need access to the value in the core registers, so we load it
+ // with ldrd and move it to the fpu. It also spares a sub instruction for
+ // updating the HeapNumber value address, as vldr expects a multiple
+ // of 4 offset.
+ __ Ldrd(r4, r5, FieldMemOperand(r0, HeapNumber::kValueOffset));
+ __ vmov(d1, r4, r5);
+
+ // Backup FPSCR.
+ __ vmrs(r3);
+ // Set custom FPCSR:
+ // - Set rounding mode to "Round towards Minus Infinity"
+ // (ie bits [23:22] = 0b10).
+ // - Clear vfp cumulative exception flags (bits [3:0]).
+ // - Make sure Flush-to-zero mode control bit is unset (bit 22).
+ __ bic(r9, r3,
+ Operand(kVFPExceptionMask | kVFPRoundingModeMask | kVFPFlushToZeroMask));
+ __ orr(r9, r9, Operand(kVFPRoundToMinusInfinityBits));
+ __ vmsr(r9);
+
+ // Convert the argument to an integer.
+ __ vcvt_s32_f64(s0, d1, Assembler::FPSCRRounding, al);
+
+ // Use vcvt latency to start checking for special cases.
+ // Get the argument exponent and clear the sign bit.
+ __ bic(r6, r5, Operand(HeapNumber::kSignMask));
+ __ mov(r6, Operand(r6, LSR, HeapNumber::kMantissaBitsInTopWord));
+
+ // Retrieve FPSCR and check for vfp exceptions.
+ __ vmrs(r9);
+ __ tst(r9, Operand(kVFPExceptionMask));
+ __ b(&no_vfp_exception, eq);
+
+ // Check for NaN, Infinity, and -Infinity.
+ // They are invariant through a Math.Floor call, so just
+ // return the original argument.
+ __ sub(r7, r6, Operand(HeapNumber::kExponentMask
+ >> HeapNumber::kMantissaBitsInTopWord), SetCC);
+ __ b(&restore_fpscr_and_return, eq);
+ // We had an overflow or underflow in the conversion. Check if we
+ // have a big exponent.
+ __ cmp(r7, Operand(HeapNumber::kMantissaBits));
+ // If greater or equal, the argument is already round and in r0.
+ __ b(&restore_fpscr_and_return, ge);
+ __ b(&slow);
+
+ __ bind(&no_vfp_exception);
+ // Move the result back to general purpose register r0.
+ __ vmov(r0, s0);
+ // Check if the result fits into a smi.
+ __ add(r1, r0, Operand(0x40000000), SetCC);
+ __ b(&wont_fit_smi, mi);
+ // Tag the result.
+ STATIC_ASSERT(kSmiTag == 0);
+ __ mov(r0, Operand(r0, LSL, kSmiTagSize));
+
+ // Check for -0.
+ __ cmp(r0, Operand(0));
+ __ b(&restore_fpscr_and_return, ne);
+ // r5 already holds the HeapNumber exponent.
+ __ tst(r5, Operand(HeapNumber::kSignMask));
+ // If our HeapNumber is negative it was -0, so load its address and return.
+ // Else r0 is loaded with 0, so we can also just return.
+ __ ldr(r0, MemOperand(sp, 0 * kPointerSize), ne);
+
+ __ bind(&restore_fpscr_and_return);
+ // Restore FPSCR and return.
+ __ vmsr(r3);
+ __ Drop(argc + 1);
+ __ Ret();
+
+ __ bind(&wont_fit_smi);
+ __ bind(&slow);
+ // Restore FPCSR and fall to slow case.
+ __ vmsr(r3);
+
+ // Tail call the full function. We do not have to patch the receiver
+ // because the function makes no use of it.
+ __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+
+ __ bind(&miss);
+ // r2: function name.
+ MaybeObject* obj = GenerateMissBranch();
+ if (obj->IsFailure()) return obj;
+
+ // Return the generated code.
+ return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name);
}
« no previous file with comments | « src/arm/macro-assembler-arm.h ('k') | src/arm/virtual-frame-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698