Commit ad55fbc3 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

MIPS: port Prevent deopt on double value assignment to typed arrays

Ported r8077 (defc4f9b) to mips.

BUG=
TEST=

Review URL: http://codereview.chromium.org//7027023

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8135 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent bbfd202c
......@@ -1044,6 +1044,51 @@ void MacroAssembler::EmitOutOfInt32RangeTruncate(Register result,
}
void MacroAssembler::EmitECMATruncate(Register result,
FPURegister double_input,
FPURegister single_scratch,
Register scratch,
Register input_high,
Register input_low) {
CpuFeatures::Scope scope(FPU);
ASSERT(!input_high.is(result));
ASSERT(!input_low.is(result));
ASSERT(!input_low.is(input_high));
ASSERT(!scratch.is(result) &&
!scratch.is(input_high) &&
!scratch.is(input_low));
ASSERT(!single_scratch.is(double_input));
Label done;
Label manual;
// Clear cumulative exception flags and save the FCSR.
Register scratch2 = input_high;
cfc1(scratch2, FCSR);
ctc1(zero_reg, FCSR);
// Try a conversion to a signed integer.
trunc_w_d(single_scratch, double_input);
mfc1(result, single_scratch);
// Retrieve and restore the FCSR.
cfc1(scratch, FCSR);
ctc1(scratch2, FCSR);
// Check for overflow and NaNs.
And(scratch,
scratch,
kFCSROverflowFlagMask | kFCSRUnderflowFlagMask | kFCSRInvalidOpFlagMask);
// If we had no exceptions we are done.
Branch(&done, eq, scratch, Operand(zero_reg));
// Load the double value and perform a manual truncation.
Move(input_low, input_high, double_input);
EmitOutOfInt32RangeTruncate(result,
input_high,
input_low,
scratch);
bind(&done);
}
void MacroAssembler::GetLeastBitsFromSmi(Register dst,
Register src,
int num_least_bits) {
......
......@@ -573,6 +573,16 @@ DECLARE_NOTARGET_PROTOTYPE(Ret)
Register input_low,
Register scratch);
// Performs a truncating conversion of a floating point number as used by
// the JS bitwise operations. See ECMA-262 9.5: ToInt32.
// Exits with 'result' holding the answer and all other registers clobbered.
void EmitECMATruncate(Register result,
FPURegister double_input,
FPURegister single_scratch,
Register scratch,
Register scratch2,
Register scratch3);
// -------------------------------------------------------------------------
// Activation frames.
......
......@@ -3934,27 +3934,8 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
__ addu(t8, a3, t8);
__ sdc1(f0, MemOperand(t8, 0));
} else {
Label done;
// Need to perform float-to-int conversion.
// Test whether exponent equal to 0x7FF (infinity or NaN).
__ mfc1(t3, f1); // Move exponent word of double to t3 (as raw bits).
__ li(t1, Operand(0x7FF00000));
__ And(t3, t3, Operand(t1));
__ Branch(USE_DELAY_SLOT, &done, eq, t3, Operand(t1));
__ mov(t3, zero_reg); // In delay slot.
// Not infinity or NaN simply convert to int.
if (IsElementTypeSigned(array_type)) {
__ trunc_w_d(f0, f0);
__ mfc1(t3, f0);
} else {
__ Trunc_uw_d(f0, t3);
}
__ EmitECMATruncate(t3, f0, f2, t2, t1, t5);
// t3: HeapNumber converted to integer
__ bind(&done);
switch (array_type) {
case kExternalByteArray:
case kExternalUnsignedByteArray:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment