Chromium Code Reviews| Index: src/a64/macro-assembler-a64.cc |
| diff --git a/src/a64/macro-assembler-a64.cc b/src/a64/macro-assembler-a64.cc |
| index b51e9277c4e4969212417284b84033a4dc60c1e4..0ea779cd77cae900f69c7364c9cc2503efcfa190 100644 |
| --- a/src/a64/macro-assembler-a64.cc |
| +++ b/src/a64/macro-assembler-a64.cc |
| @@ -2473,26 +2473,20 @@ void MacroAssembler::InvokeFunction(Handle<JSFunction> function, |
| } |
| -void MacroAssembler::ECMA262ToInt32(Register result, |
| - DoubleRegister input, |
| - Register scratch1, |
| - Register scratch2, |
| - ECMA262ToInt32Result format) { |
| - ASSERT(!AreAliased(result, scratch1, scratch2)); |
| - ASSERT(result.Is64Bits() && scratch1.Is64Bits() && scratch2.Is64Bits()); |
| +void MacroAssembler::TryInlineTruncateDoubleToI(Register result, |
| + DoubleRegister double_input, |
| + Label* done) { |
| STATIC_ASSERT(kSmiTag == 0); |
| STATIC_ASSERT(kSmiValueSize == 32); |
| - Label done, tag, manual_conversion; |
| - |
| - // 1. Try to convert with a FPU convert instruction. It's trivial to compute |
| - // the modulo operation on an integer register so we convert to a 64-bit |
| - // integer, then find the 32-bit result from that. |
| + // Try to convert with a FPU convert instruction. It's trivial to compute |
| + // the modulo operation on an integer register so we convert to a 64-bit |
| + // integer, then find the 32-bit result from that. |
| // |
| // Fcvtzs will saturate to INT64_MIN (0x800...00) or INT64_MAX (0x7ff...ff) |
| // when the double is out of range. NaNs and infinities will be converted to 0 |
| // (as ECMA-262 requires). |
| - Fcvtzs(result, input); |
| + Fcvtzs(result, double_input); |
| // The values INT64_MIN (0x800...00) or INT64_MAX (0x7ff...ff) are not |
| // representable using a double, so if the result is one of those then we know |
| @@ -2502,83 +2496,60 @@ void MacroAssembler::ECMA262ToInt32(Register result, |
| // 1 will cause signed overflow. |
| Cmp(result, 1); |
| Ccmp(result, -1, VFlag, vc); |
| - B(vc, &tag); |
| - // 2. Manually convert the input to an int32. |
| - Fmov(result, input); |
| + B(vc, done); |
| +} |
| - // Extract the exponent. |
| - Register exponent = scratch1; |
| - Ubfx(exponent, result, HeapNumber::kMantissaBits, HeapNumber::kExponentBits); |
| - // It the exponent is >= 84 (kMantissaBits + 32), the result is always 0 since |
| - // the mantissa gets shifted completely out of the int32_t result. |
| - Cmp(exponent, HeapNumber::kExponentBias + HeapNumber::kMantissaBits + 32); |
| - CzeroX(result, ge); |
| - B(ge, &done); |
| +void MacroAssembler::TruncateDoubleToI(Register result, |
| + DoubleRegister double_input) { |
| + Label done; |
| + ASSERT(jssp.Is(StackPointer())); |
| - // The Fcvtzs sequence handles all cases except where the conversion causes |
| - // signed overflow in the int64_t target. Since we've already handled |
| - // exponents >= 84, we can guarantee that 63 <= exponent < 84. |
| + TryInlineTruncateDoubleToI(result, double_input, &done); |
| - if (emit_debug_code()) { |
| - Cmp(exponent, HeapNumber::kExponentBias + 63); |
| - // Exponents less than this should have been handled by the Fcvt case. |
| - Check(ge, kUnexpectedValue); |
| - } |
| - |
| - // Isolate the mantissa bits, and set the implicit '1'. |
| - Register mantissa = scratch2; |
| - Ubfx(mantissa, result, 0, HeapNumber::kMantissaBits); |
| - Orr(mantissa, mantissa, 1UL << HeapNumber::kMantissaBits); |
| - |
| - // Negate the mantissa if necessary. |
| - Tst(result, kXSignMask); |
| - Cneg(mantissa, mantissa, ne); |
| - |
| - // Shift the mantissa bits in the correct place. We know that we have to shift |
| - // it left here, because exponent >= 63 >= kMantissaBits. |
| - Sub(exponent, exponent, |
| - HeapNumber::kExponentBias + HeapNumber::kMantissaBits); |
| - Lsl(result, mantissa, exponent); |
| - |
| - Bind(&tag); |
| - switch (format) { |
| - case INT32_IN_W: |
| - // There is nothing to do; the upper 32 bits are undefined. |
| - if (emit_debug_code()) { |
| - __ Mov(scratch1, 0x55555555); |
| - __ Bfi(result, scratch1, 32, 32); |
| - } |
| - break; |
| - case INT32_IN_X: |
| - Sxtw(result, result); |
| - break; |
| - case SMI: |
| - SmiTag(result); |
| - break; |
| - } |
| + // If we fell through then inline version didn't succeed - call stub instead. |
| + Push(lr); |
| + Push(double_input); // Put input on stack. |
| + |
| + DoubleToIStub stub(jssp, result, 0, true, true); |
|
jbramley
2014/02/13 14:20:14
Please use comments to label those bools (or make
|
| + CallStub(&stub); |
| + |
| + Drop(1, kDoubleSize); // Drop the double input on the stack. |
| + Pop(lr); |
| Bind(&done); |
| + |
| + // TODO(rmcilroy): Remove this Sxtw once the following bug is fixed: |
| + // https://code.google.com/p/v8/issues/detail?id=3149 |
| + Sxtw(result, result); |
|
jbramley
2014/02/13 14:20:14
Use Sxtw(result, result.W());
This enables a more
rmcilroy
2014/02/14 12:45:07
Done.
|
| } |
| -void MacroAssembler::HeapNumberECMA262ToInt32(Register result, |
| - Register heap_number, |
| - Register scratch1, |
| - Register scratch2, |
| - DoubleRegister double_scratch, |
| - ECMA262ToInt32Result format) { |
| - if (emit_debug_code()) { |
| - // Verify we indeed have a HeapNumber. |
| - Label ok; |
| - JumpIfHeapNumber(heap_number, &ok); |
| - Abort(kExpectedHeapNumber); |
| - Bind(&ok); |
| - } |
| +void MacroAssembler::TruncateHeapNumberToI(Register result, |
| + Register object) { |
| + Label done; |
| + ASSERT(!result.is(object)); |
| + ASSERT(jssp.Is(StackPointer())); |
| + |
| + Ldr(fp_scratch, FieldMemOperand(object, HeapNumber::kValueOffset)); |
| + TryInlineTruncateDoubleToI(result, fp_scratch, &done); |
| + |
| + // If we fell through then inline version didn't succeed - call stub instead. |
| + Push(lr); |
| + DoubleToIStub stub(object, |
| + result, |
| + HeapNumber::kValueOffset - kHeapObjectTag, |
| + true, |
| + true); |
| + CallStub(&stub); |
| + Pop(lr); |
| + |
| + bind(&done); |
|
jbramley
2014/02/13 14:20:14
Bind(&done);
rmcilroy
2014/02/14 12:45:07
Done.
|
| - Ldr(double_scratch, FieldMemOperand(heap_number, HeapNumber::kValueOffset)); |
| - ECMA262ToInt32(result, double_scratch, scratch1, scratch2, format); |
| + // TODO(rmcilroy): Remove this Sxtw once the following bug is fixed: |
| + // https://code.google.com/p/v8/issues/detail?id=3149 |
| + Sxtw(result, result); |
| } |