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
parent d5f58980
...@@ -729,13 +729,13 @@ void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm, ...@@ -729,13 +729,13 @@ void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm,
Register int_scratch, Register int_scratch,
Destination destination, Destination destination,
DwVfpRegister double_dst, DwVfpRegister double_dst,
Register dst1, Register dst_mantissa,
Register dst2, Register dst_exponent,
Register scratch2, Register scratch2,
SwVfpRegister single_scratch) { SwVfpRegister single_scratch) {
ASSERT(!int_scratch.is(scratch2)); ASSERT(!int_scratch.is(scratch2));
ASSERT(!int_scratch.is(dst1)); ASSERT(!int_scratch.is(dst_mantissa));
ASSERT(!int_scratch.is(dst2)); ASSERT(!int_scratch.is(dst_exponent));
Label done; Label done;
...@@ -744,56 +744,57 @@ void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm, ...@@ -744,56 +744,57 @@ void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm,
__ vmov(single_scratch, int_scratch); __ vmov(single_scratch, int_scratch);
__ vcvt_f64_s32(double_dst, single_scratch); __ vcvt_f64_s32(double_dst, single_scratch);
if (destination == kCoreRegisters) { if (destination == kCoreRegisters) {
__ vmov(dst1, dst2, double_dst); __ vmov(dst_mantissa, dst_exponent, double_dst);
} }
} else { } else {
Label fewer_than_20_useful_bits; Label fewer_than_20_useful_bits;
// Expected output: // Expected output:
// | dst2 | dst1 | // | dst_exponent | dst_mantissa |
// | s | exp | mantissa | // | s | exp | mantissa |
// Check for zero. // Check for zero.
__ cmp(int_scratch, Operand::Zero()); __ cmp(int_scratch, Operand::Zero());
__ mov(dst2, int_scratch); __ mov(dst_exponent, int_scratch);
__ mov(dst1, int_scratch); __ mov(dst_mantissa, int_scratch);
__ b(eq, &done); __ b(eq, &done);
// Preload the sign of the value. // 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). // Get the absolute value of the object (as an unsigned integer).
__ rsb(int_scratch, int_scratch, Operand::Zero(), SetCC, mi); __ rsb(int_scratch, int_scratch, Operand::Zero(), SetCC, mi);
// Get mantissa[51:20]. // Get mantissa[51:20].
// Get the position of the first set bit. // Get the position of the first set bit.
__ CountLeadingZeros(dst1, int_scratch, scratch2); __ CountLeadingZeros(dst_mantissa, int_scratch, scratch2);
__ rsb(dst1, dst1, Operand(31)); __ rsb(dst_mantissa, dst_mantissa, Operand(31));
// Set the exponent. // Set the exponent.
__ add(scratch2, dst1, Operand(HeapNumber::kExponentBias)); __ add(scratch2, dst_mantissa, Operand(HeapNumber::kExponentBias));
__ Bfi(dst2, scratch2, scratch2, __ Bfi(dst_exponent, scratch2, scratch2,
HeapNumber::kExponentShift, HeapNumber::kExponentBits); HeapNumber::kExponentShift, HeapNumber::kExponentBits);
// Clear the first non null bit. // Clear the first non null bit.
__ mov(scratch2, Operand(1)); __ 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. // 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); __ b(mi, &fewer_than_20_useful_bits);
// Set the higher 20 bits of the mantissa. // 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)); __ rsb(scratch2, scratch2, Operand(32));
__ mov(dst1, Operand(int_scratch, LSL, scratch2)); __ mov(dst_mantissa, Operand(int_scratch, LSL, scratch2));
__ b(&done); __ b(&done);
__ bind(&fewer_than_20_useful_bits); __ 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)); __ mov(scratch2, Operand(int_scratch, LSL, scratch2));
__ orr(dst2, dst2, scratch2); __ orr(dst_exponent, dst_exponent, scratch2);
// Set dst1 to 0. // Set dst1 to 0.
__ mov(dst1, Operand::Zero()); __ mov(dst_mantissa, Operand::Zero());
} }
__ bind(&done); __ bind(&done);
} }
...@@ -804,8 +805,8 @@ void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, ...@@ -804,8 +805,8 @@ void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm,
Destination destination, Destination destination,
DwVfpRegister double_dst, DwVfpRegister double_dst,
DwVfpRegister double_scratch, DwVfpRegister double_scratch,
Register dst1, Register dst_mantissa,
Register dst2, Register dst_exponent,
Register heap_number_map, Register heap_number_map,
Register scratch1, Register scratch1,
Register scratch2, Register scratch2,
...@@ -821,8 +822,8 @@ void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, ...@@ -821,8 +822,8 @@ void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm,
__ JumpIfNotSmi(object, &obj_is_not_smi); __ JumpIfNotSmi(object, &obj_is_not_smi);
__ SmiUntag(scratch1, object); __ SmiUntag(scratch1, object);
ConvertIntToDouble(masm, scratch1, destination, double_dst, dst1, dst2, ConvertIntToDouble(masm, scratch1, destination, double_dst, dst_mantissa,
scratch2, single_scratch); dst_exponent, scratch2, single_scratch);
__ b(&done); __ b(&done);
__ bind(&obj_is_not_smi); __ bind(&obj_is_not_smi);
...@@ -849,26 +850,52 @@ void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, ...@@ -849,26 +850,52 @@ void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm,
__ b(ne, not_int32); __ b(ne, not_int32);
if (destination == kCoreRegisters) { if (destination == kCoreRegisters) {
__ vmov(dst1, dst2, double_dst); __ vmov(dst_mantissa, dst_exponent, double_dst);
} }
} else { } else {
ASSERT(!scratch1.is(object) && !scratch2.is(object)); ASSERT(!scratch1.is(object) && !scratch2.is(object));
// Load the double value in the destination registers.. // Load the double value in the destination registers.
__ Ldrd(dst1, dst2, FieldMemOperand(object, HeapNumber::kValueOffset)); 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. // Check for 0 and -0.
__ bic(scratch1, dst1, Operand(HeapNumber::kSignMask)); Label zero;
__ orr(scratch1, scratch1, Operand(dst2)); __ bic(scratch1, dst_exponent, Operand(HeapNumber::kSignMask));
__ orr(scratch1, scratch1, Operand(dst_mantissa));
__ cmp(scratch1, Operand::Zero()); __ cmp(scratch1, Operand::Zero());
__ b(eq, &done); __ b(eq, &zero);
// Check that the value can be exactly represented by a 32-bit integer. // Check that the value can be exactly represented by a 32-bit integer.
// Jump to not_int32 if that's not the case. // 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. // dst_* were trashed. Reload the double value.
__ Ldrd(dst1, dst2, FieldMemOperand(object, HeapNumber::kValueOffset)); 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); __ bind(&done);
...@@ -960,14 +987,14 @@ void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm, ...@@ -960,14 +987,14 @@ void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm,
void FloatingPointHelper::DoubleIs32BitInteger(MacroAssembler* masm, void FloatingPointHelper::DoubleIs32BitInteger(MacroAssembler* masm,
Register src1, Register src_exponent,
Register src2, Register src_mantissa,
Register dst, Register dst,
Register scratch, Register scratch,
Label* not_int32) { Label* not_int32) {
// Get exponent alone in scratch. // Get exponent alone in scratch.
__ Ubfx(scratch, __ Ubfx(scratch,
src1, src_exponent,
HeapNumber::kExponentShift, HeapNumber::kExponentShift,
HeapNumber::kExponentBits); HeapNumber::kExponentBits);
...@@ -987,11 +1014,11 @@ void FloatingPointHelper::DoubleIs32BitInteger(MacroAssembler* masm, ...@@ -987,11 +1014,11 @@ void FloatingPointHelper::DoubleIs32BitInteger(MacroAssembler* masm,
// Another way to put it is that if (exponent - signbit) > 30 then the // Another way to put it is that if (exponent - signbit) > 30 then the
// number cannot be represented as an int32. // number cannot be represented as an int32.
Register tmp = dst; Register tmp = dst;
__ sub(tmp, scratch, Operand(src1, LSR, 31)); __ sub(tmp, scratch, Operand(src_exponent, LSR, 31));
__ cmp(tmp, Operand(30)); __ cmp(tmp, Operand(30));
__ b(gt, not_int32); __ b(gt, not_int32);
// - Bits [21:0] in the mantissa are not null. // - Bits [21:0] in the mantissa are not null.
__ tst(src2, Operand(0x3fffff)); __ tst(src_mantissa, Operand(0x3fffff));
__ b(ne, not_int32); __ b(ne, not_int32);
// Otherwise the exponent needs to be big enough to shift left all the // Otherwise the exponent needs to be big enough to shift left all the
...@@ -1002,19 +1029,19 @@ void FloatingPointHelper::DoubleIs32BitInteger(MacroAssembler* masm, ...@@ -1002,19 +1029,19 @@ void FloatingPointHelper::DoubleIs32BitInteger(MacroAssembler* masm,
// Get the 32 higher bits of the mantissa in dst. // Get the 32 higher bits of the mantissa in dst.
__ Ubfx(dst, __ Ubfx(dst,
src2, src_mantissa,
HeapNumber::kMantissaBitsInTopWord, HeapNumber::kMantissaBitsInTopWord,
32 - HeapNumber::kMantissaBitsInTopWord); 32 - HeapNumber::kMantissaBitsInTopWord);
__ orr(dst, __ orr(dst,
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). // Create the mask and test the lower bits (of the higher bits).
__ rsb(scratch, scratch, Operand(32)); __ rsb(scratch, scratch, Operand(32));
__ mov(src2, Operand(1)); __ mov(src_mantissa, Operand(1));
__ mov(src1, Operand(src2, LSL, scratch)); __ mov(src_exponent, Operand(src_mantissa, LSL, scratch));
__ sub(src1, src1, Operand(1)); __ sub(src_exponent, src_exponent, Operand(1));
__ tst(dst, src1); __ tst(dst, src_exponent);
__ b(ne, not_int32); __ b(ne, not_int32);
} }
......
...@@ -3856,20 +3856,20 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( ...@@ -3856,20 +3856,20 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
__ AllocateHeapNumber(r5, r3, r4, r6, &slow, TAG_RESULT); __ AllocateHeapNumber(r5, r3, r4, r6, &slow, TAG_RESULT);
// Now we can use r0 for the result as key is not needed any more. // Now we can use r0 for the result as key is not needed any more.
__ mov(r0, r5); __ mov(r0, r5);
Register dst1 = r1; Register dst_mantissa = r1;
Register dst2 = r3; Register dst_exponent = r3;
FloatingPointHelper::Destination dest = FloatingPointHelper::Destination dest =
FloatingPointHelper::kCoreRegisters; FloatingPointHelper::kCoreRegisters;
FloatingPointHelper::ConvertIntToDouble(masm, FloatingPointHelper::ConvertIntToDouble(masm,
value, value,
dest, dest,
d0, d0,
dst1, dst_mantissa,
dst2, dst_exponent,
r9, r9,
s0); s0);
__ str(dst1, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); __ str(dst_mantissa, FieldMemOperand(r0, HeapNumber::kMantissaOffset));
__ str(dst2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); __ str(dst_exponent, FieldMemOperand(r0, HeapNumber::kExponentOffset));
__ Ret(); __ Ret();
} }
} else if (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { } else if (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) {
...@@ -4138,7 +4138,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( ...@@ -4138,7 +4138,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
} }
FloatingPointHelper::ConvertIntToDouble( FloatingPointHelper::ConvertIntToDouble(
masm, r5, destination, 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. r4, s2); // These are: scratch2, single_scratch.
if (destination == FloatingPointHelper::kVFPRegisters) { if (destination == FloatingPointHelper::kVFPRegisters) {
CpuFeatures::Scope scope(VFP2); CpuFeatures::Scope scope(VFP2);
......
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