From 6e56e41205d843d13971dd7ac04f3fa768f7ee1e Mon Sep 17 00:00:00 2001 From: "plind44@gmail.com" Date: Fri, 5 Apr 2013 02:16:58 +0000 Subject: [PATCH] MIPS: Resolved the rest of soft-float bugs. TEST=mjsunit/mul-exhaustive-part9, mjsunit/bit-not, mjsunit/greedy, mjsunit/math-floor-of-div-nosudiv, mjsunit/math-floor-of-div, mjsunit/numops-fuzz-part2 BUG= Review URL: https://codereview.chromium.org/13455006 Patch from Dusan Milosavljevic . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14145 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/mips/code-stubs-mips.cc | 64 ++++++++++++++++++++++++++----------- src/mips/codegen-mips.cc | 2 +- 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index 37d7720c8..91a821720 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -684,8 +684,6 @@ void FloatingPointHelper::LoadNumber(MacroAssembler* masm, Register scratch1, Register scratch2, Label* not_number) { - ASSERT(!object.is(dst1) && !object.is(dst2)); - __ AssertRootValue(heap_number_map, Heap::kHeapNumberMapRootIndex, "HeapNumberMap register clobbered."); @@ -842,7 +840,7 @@ void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm, // Get the number of bits to set in the lower part of the mantissa. __ Subu(scratch2, dst_mantissa, Operand(HeapNumber::kMantissaBitsInTopWord)); - __ Branch(&fewer_than_20_useful_bits, lt, scratch2, Operand(zero_reg)); + __ Branch(&fewer_than_20_useful_bits, le, scratch2, Operand(zero_reg)); // Set the higher 20 bits of the mantissa. __ srlv(at, int_scratch, scratch2); __ or_(dst_exponent, dst_exponent, at); @@ -880,10 +878,6 @@ void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, ASSERT(!heap_number_map.is(object) && !heap_number_map.is(scratch1) && !heap_number_map.is(scratch2)); - // ARM uses pop/push and Ldlr to save dst_* and probably object registers in - // softfloat path. On MIPS there is no ldlr, 1st lw instruction may overwrite - // object register making the 2nd lw invalid. - ASSERT(!object.is(dst_mantissa) && !object.is(dst_exponent)); Label done, obj_is_not_smi; @@ -920,24 +914,60 @@ void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, if (destination == kCoreRegisters) { __ Move(dst_mantissa, dst_exponent, double_dst); } + } else { + ASSERT(!scratch1.is(object) && !scratch2.is(object)); // Load the double value in the destination registers. - __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset)); - __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset)); + 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); + } + if (object.is(dst_mantissa)) { + __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset)); + __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset)); + } else { + __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset)); + __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset)); + } // Check for 0 and -0. + Label zero; __ And(scratch1, dst_exponent, Operand(~HeapNumber::kSignMask)); __ Or(scratch1, scratch1, Operand(dst_mantissa)); - __ Branch(&done, eq, scratch1, Operand(zero_reg)); + __ Branch(&zero, eq, scratch1, Operand(zero_reg)); // Check that the value can be exactly represented by a 32-bit integer. // Jump to not_int32 if that's not the case. + Label restore_input_and_miss; DoubleIs32BitInteger(masm, dst_exponent, dst_mantissa, scratch1, scratch2, - not_int32); + &restore_input_and_miss); // dst_* were trashed. Reload the double value. - __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset)); - __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset)); + if (save_registers) { + __ Pop(dst_exponent, dst_mantissa); + } + if (object.is(dst_mantissa)) { + __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset)); + __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset)); + } else { + __ lw(dst_mantissa, FieldMemOperand(object, HeapNumber::kMantissaOffset)); + __ lw(dst_exponent, FieldMemOperand(object, HeapNumber::kExponentOffset)); + } + + __ Branch(&done); + + __ bind(&restore_input_and_miss); + if (save_registers) { + __ Pop(dst_exponent, dst_mantissa); + } + __ Branch(not_int32); + + __ bind(&zero); + if (save_registers) { + __ Drop(2); + } } __ bind(&done); @@ -2688,20 +2718,16 @@ void BinaryOpStub_GenerateFPOperation(MacroAssembler* masm, masm, destination, right, f14, a2, a3, heap_number_map, scratch1, scratch2, fail); } - // Use scratch3 as left in LoadNumber functions to avoid overwriting of - // left (a0) register. - __ mov(scratch3, left); - // Load left operand to f12 or a0/a1. This keeps a0/a1 intact if it // jumps to |miss|. if (left_type == BinaryOpIC::INT32) { FloatingPointHelper::LoadNumberAsInt32Double( - masm, scratch3, destination, f12, f16, a0, a1, heap_number_map, + masm, left, destination, f12, f16, a0, a1, heap_number_map, scratch1, scratch2, f2, miss); } else { Label* fail = (left_type == BinaryOpIC::NUMBER) ? miss : not_numbers; FloatingPointHelper::LoadNumber( - masm, destination, scratch3, f12, a0, a1, heap_number_map, + masm, destination, left, f12, a0, a1, heap_number_map, scratch1, scratch2, fail); } } diff --git a/src/mips/codegen-mips.cc b/src/mips/codegen-mips.cc index bd403cee6..23b080ff4 100644 --- a/src/mips/codegen-mips.cc +++ b/src/mips/codegen-mips.cc @@ -94,7 +94,7 @@ UnaryMathFunction CreateExpFunction() { if (!IsMipsSoftFloatABI) { // Result is already in f0, nothing to do. } else { - __ Move(a0, a1, result); + __ Move(v0, v1, result); } __ Ret(); } -- 2.34.1