From d9ba8ed8a1cc663a14490c69a2b935299372b47e Mon Sep 17 00:00:00 2001 From: "jkummerow@chromium.org" Date: Fri, 16 Nov 2012 08:54:01 +0000 Subject: [PATCH] Fix register confusion in non-VFP3 BinaryOpStubs on ARM Review URL: https://codereview.chromium.org/11413014 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12980 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/code-stubs-arm.cc | 117 +++++++++++++++++++++++--------------- src/arm/stub-cache-arm.cc | 14 ++--- 2 files changed, 79 insertions(+), 52 deletions(-) diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index 51a69ab8ba..2c2589cf3c 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -729,13 +729,13 @@ void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm, Register int_scratch, Destination destination, DwVfpRegister double_dst, - Register dst1, - Register dst2, + Register dst_mantissa, + Register dst_exponent, Register scratch2, SwVfpRegister single_scratch) { ASSERT(!int_scratch.is(scratch2)); - ASSERT(!int_scratch.is(dst1)); - ASSERT(!int_scratch.is(dst2)); + ASSERT(!int_scratch.is(dst_mantissa)); + ASSERT(!int_scratch.is(dst_exponent)); Label done; @@ -744,56 +744,57 @@ void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm, __ vmov(single_scratch, int_scratch); __ vcvt_f64_s32(double_dst, single_scratch); if (destination == kCoreRegisters) { - __ vmov(dst1, dst2, double_dst); + __ vmov(dst_mantissa, dst_exponent, double_dst); } } else { Label fewer_than_20_useful_bits; // Expected output: - // | dst2 | dst1 | + // | dst_exponent | dst_mantissa | // | s | exp | mantissa | // Check for zero. __ cmp(int_scratch, Operand::Zero()); - __ mov(dst2, int_scratch); - __ mov(dst1, int_scratch); + __ mov(dst_exponent, int_scratch); + __ mov(dst_mantissa, int_scratch); __ b(eq, &done); // Preload the sign of the value. - __ and_(dst2, int_scratch, Operand(HeapNumber::kSignMask), SetCC); + __ and_(dst_exponent, int_scratch, Operand(HeapNumber::kSignMask), SetCC); // Get the absolute value of the object (as an unsigned integer). __ rsb(int_scratch, int_scratch, Operand::Zero(), SetCC, mi); // Get mantissa[51:20]. // Get the position of the first set bit. - __ CountLeadingZeros(dst1, int_scratch, scratch2); - __ rsb(dst1, dst1, Operand(31)); + __ CountLeadingZeros(dst_mantissa, int_scratch, scratch2); + __ rsb(dst_mantissa, dst_mantissa, Operand(31)); // Set the exponent. - __ add(scratch2, dst1, Operand(HeapNumber::kExponentBias)); - __ Bfi(dst2, scratch2, scratch2, + __ add(scratch2, dst_mantissa, Operand(HeapNumber::kExponentBias)); + __ Bfi(dst_exponent, scratch2, scratch2, HeapNumber::kExponentShift, HeapNumber::kExponentBits); // Clear the first non null bit. __ mov(scratch2, Operand(1)); - __ bic(int_scratch, int_scratch, Operand(scratch2, LSL, dst1)); + __ bic(int_scratch, int_scratch, Operand(scratch2, LSL, dst_mantissa)); - __ cmp(dst1, Operand(HeapNumber::kMantissaBitsInTopWord)); + __ cmp(dst_mantissa, Operand(HeapNumber::kMantissaBitsInTopWord)); // Get the number of bits to set in the lower part of the mantissa. - __ sub(scratch2, dst1, Operand(HeapNumber::kMantissaBitsInTopWord), SetCC); + __ sub(scratch2, dst_mantissa, Operand(HeapNumber::kMantissaBitsInTopWord), + SetCC); __ b(mi, &fewer_than_20_useful_bits); // Set the higher 20 bits of the mantissa. - __ orr(dst2, dst2, Operand(int_scratch, LSR, scratch2)); + __ orr(dst_exponent, dst_exponent, Operand(int_scratch, LSR, scratch2)); __ rsb(scratch2, scratch2, Operand(32)); - __ mov(dst1, Operand(int_scratch, LSL, scratch2)); + __ mov(dst_mantissa, Operand(int_scratch, LSL, scratch2)); __ b(&done); __ bind(&fewer_than_20_useful_bits); - __ rsb(scratch2, dst1, Operand(HeapNumber::kMantissaBitsInTopWord)); + __ rsb(scratch2, dst_mantissa, Operand(HeapNumber::kMantissaBitsInTopWord)); __ mov(scratch2, Operand(int_scratch, LSL, scratch2)); - __ orr(dst2, dst2, scratch2); + __ orr(dst_exponent, dst_exponent, scratch2); // Set dst1 to 0. - __ mov(dst1, Operand::Zero()); + __ mov(dst_mantissa, Operand::Zero()); } __ bind(&done); } @@ -804,8 +805,8 @@ void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, Destination destination, DwVfpRegister double_dst, DwVfpRegister double_scratch, - Register dst1, - Register dst2, + Register dst_mantissa, + Register dst_exponent, Register heap_number_map, Register scratch1, Register scratch2, @@ -821,8 +822,8 @@ void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, __ JumpIfNotSmi(object, &obj_is_not_smi); __ SmiUntag(scratch1, object); - ConvertIntToDouble(masm, scratch1, destination, double_dst, dst1, dst2, - scratch2, single_scratch); + ConvertIntToDouble(masm, scratch1, destination, double_dst, dst_mantissa, + dst_exponent, scratch2, single_scratch); __ b(&done); __ bind(&obj_is_not_smi); @@ -849,26 +850,52 @@ void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, __ b(ne, not_int32); if (destination == kCoreRegisters) { - __ vmov(dst1, dst2, double_dst); + __ vmov(dst_mantissa, dst_exponent, double_dst); } } else { ASSERT(!scratch1.is(object) && !scratch2.is(object)); - // Load the double value in the destination registers.. - __ Ldrd(dst1, dst2, FieldMemOperand(object, HeapNumber::kValueOffset)); + // Load the double value in the destination registers. + bool save_registers = object.is(dst_mantissa) || object.is(dst_exponent); + if (save_registers) { + // Save both output registers, because the other one probably holds + // an important value too. + __ Push(dst_exponent, dst_mantissa); + } + __ Ldrd(dst_mantissa, dst_exponent, + FieldMemOperand(object, HeapNumber::kValueOffset)); // Check for 0 and -0. - __ bic(scratch1, dst1, Operand(HeapNumber::kSignMask)); - __ orr(scratch1, scratch1, Operand(dst2)); + Label zero; + __ bic(scratch1, dst_exponent, Operand(HeapNumber::kSignMask)); + __ orr(scratch1, scratch1, Operand(dst_mantissa)); __ cmp(scratch1, Operand::Zero()); - __ b(eq, &done); + __ b(eq, &zero); // Check that the value can be exactly represented by a 32-bit integer. // Jump to not_int32 if that's not the case. - DoubleIs32BitInteger(masm, dst1, dst2, scratch1, scratch2, not_int32); + Label restore_input_and_miss; + DoubleIs32BitInteger(masm, dst_exponent, dst_mantissa, scratch1, scratch2, + &restore_input_and_miss); - // dst1 and dst2 were trashed. Reload the double value. - __ Ldrd(dst1, dst2, FieldMemOperand(object, HeapNumber::kValueOffset)); + // dst_* were trashed. Reload the double value. + if (save_registers) { + __ Pop(dst_exponent, dst_mantissa); + } + __ Ldrd(dst_mantissa, dst_exponent, + FieldMemOperand(object, HeapNumber::kValueOffset)); + __ b(&done); + + __ bind(&restore_input_and_miss); + if (save_registers) { + __ Pop(dst_exponent, dst_mantissa); + } + __ b(not_int32); + + __ bind(&zero); + if (save_registers) { + __ Drop(2); + } } __ bind(&done); @@ -960,14 +987,14 @@ void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm, void FloatingPointHelper::DoubleIs32BitInteger(MacroAssembler* masm, - Register src1, - Register src2, + Register src_exponent, + Register src_mantissa, Register dst, Register scratch, Label* not_int32) { // Get exponent alone in scratch. __ Ubfx(scratch, - src1, + src_exponent, HeapNumber::kExponentShift, HeapNumber::kExponentBits); @@ -987,11 +1014,11 @@ void FloatingPointHelper::DoubleIs32BitInteger(MacroAssembler* masm, // Another way to put it is that if (exponent - signbit) > 30 then the // number cannot be represented as an int32. Register tmp = dst; - __ sub(tmp, scratch, Operand(src1, LSR, 31)); + __ sub(tmp, scratch, Operand(src_exponent, LSR, 31)); __ cmp(tmp, Operand(30)); __ b(gt, not_int32); // - Bits [21:0] in the mantissa are not null. - __ tst(src2, Operand(0x3fffff)); + __ tst(src_mantissa, Operand(0x3fffff)); __ b(ne, not_int32); // Otherwise the exponent needs to be big enough to shift left all the @@ -1002,19 +1029,19 @@ void FloatingPointHelper::DoubleIs32BitInteger(MacroAssembler* masm, // Get the 32 higher bits of the mantissa in dst. __ Ubfx(dst, - src2, + src_mantissa, HeapNumber::kMantissaBitsInTopWord, 32 - HeapNumber::kMantissaBitsInTopWord); __ orr(dst, dst, - Operand(src1, LSL, HeapNumber::kNonMantissaBitsInTopWord)); + Operand(src_exponent, LSL, HeapNumber::kNonMantissaBitsInTopWord)); // Create the mask and test the lower bits (of the higher bits). __ rsb(scratch, scratch, Operand(32)); - __ mov(src2, Operand(1)); - __ mov(src1, Operand(src2, LSL, scratch)); - __ sub(src1, src1, Operand(1)); - __ tst(dst, src1); + __ mov(src_mantissa, Operand(1)); + __ mov(src_exponent, Operand(src_mantissa, LSL, scratch)); + __ sub(src_exponent, src_exponent, Operand(1)); + __ tst(dst, src_exponent); __ b(ne, not_int32); } diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index b58dcfe781..60a2129a60 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -3856,20 +3856,20 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ AllocateHeapNumber(r5, r3, r4, r6, &slow, TAG_RESULT); // Now we can use r0 for the result as key is not needed any more. __ mov(r0, r5); - Register dst1 = r1; - Register dst2 = r3; + Register dst_mantissa = r1; + Register dst_exponent = r3; FloatingPointHelper::Destination dest = FloatingPointHelper::kCoreRegisters; FloatingPointHelper::ConvertIntToDouble(masm, value, dest, d0, - dst1, - dst2, + dst_mantissa, + dst_exponent, r9, s0); - __ str(dst1, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); - __ str(dst2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); + __ str(dst_mantissa, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); + __ str(dst_exponent, FieldMemOperand(r0, HeapNumber::kExponentOffset)); __ Ret(); } } else if (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { @@ -4138,7 +4138,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( } FloatingPointHelper::ConvertIntToDouble( masm, r5, destination, - d0, r6, r7, // These are: double_dst, dst1, dst2. + d0, r6, r7, // These are: double_dst, dst_mantissa, dst_exponent. r4, s2); // These are: scratch2, single_scratch. if (destination == FloatingPointHelper::kVFPRegisters) { CpuFeatures::Scope scope(VFP2);