From: plind44@gmail.com Date: Thu, 29 Aug 2013 03:29:24 +0000 (+0000) Subject: MIPS: Sync structure to r14382. X-Git-Tag: upstream/4.7.83~12762 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e0428617fe305cebd4311a2e4ab7f45d31a3098b;p=platform%2Fupstream%2Fv8.git MIPS: Sync structure to r14382. Port r14382 (5ef0d87) Original commit message: ARM: VFP cleanup now that VFP2 is the baseline BUG=none TEST=none R=plind44@gmail.com Review URL: https://codereview.chromium.org/23534011 Patch from Balazs Kilvady . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16408 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index 2c42001..710901e 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -521,290 +521,6 @@ void ConvertToDoubleStub::Generate(MacroAssembler* masm) { } -void FloatingPointHelper::LoadSmis(MacroAssembler* masm, - FloatingPointHelper::Destination destination, - Register scratch1, - Register scratch2) { - __ sra(scratch1, a0, kSmiTagSize); - __ mtc1(scratch1, f14); - __ cvt_d_w(f14, f14); - __ sra(scratch1, a1, kSmiTagSize); - __ mtc1(scratch1, f12); - __ cvt_d_w(f12, f12); - if (destination == kCoreRegisters) { - __ Move(a2, a3, f14); - __ Move(a0, a1, f12); - } -} - - -void FloatingPointHelper::LoadNumber(MacroAssembler* masm, - Destination destination, - Register object, - FPURegister dst, - Register dst1, - Register dst2, - Register heap_number_map, - Register scratch1, - Register scratch2, - Label* not_number) { - __ AssertRootValue(heap_number_map, - Heap::kHeapNumberMapRootIndex, - kHeapNumberMapRegisterClobbered); - - Label is_smi, done; - - // Smi-check - __ UntagAndJumpIfSmi(scratch1, object, &is_smi); - // Heap number check - __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number); - - // Handle loading a double from a heap number. - if (destination == kFPURegisters) { - // Load the double from tagged HeapNumber to double register. - - // ARM uses a workaround here because of the unaligned HeapNumber - // kValueOffset. On MIPS this workaround is built into ldc1 so there's no - // point in generating even more instructions. - __ ldc1(dst, FieldMemOperand(object, HeapNumber::kValueOffset)); - } else { - ASSERT(destination == kCoreRegisters); - // Load the double from heap number to dst1 and dst2 in double format. - __ lw(dst1, FieldMemOperand(object, HeapNumber::kValueOffset)); - __ lw(dst2, FieldMemOperand(object, - HeapNumber::kValueOffset + kPointerSize)); - } - __ Branch(&done); - - // Handle loading a double from a smi. - __ bind(&is_smi); - // Convert smi to double using FPU instructions. - __ mtc1(scratch1, dst); - __ cvt_d_w(dst, dst); - if (destination == kCoreRegisters) { - // Load the converted smi to dst1 and dst2 in double format. - __ Move(dst1, dst2, dst); - } - __ bind(&done); -} - - -void FloatingPointHelper::ConvertNumberToInt32(MacroAssembler* masm, - Register object, - Register dst, - Register heap_number_map, - Register scratch1, - Register scratch2, - Register scratch3, - FPURegister double_scratch, - Label* not_number) { - __ AssertRootValue(heap_number_map, - Heap::kHeapNumberMapRootIndex, - kHeapNumberMapRegisterClobbered); - Label done; - Label not_in_int32_range; - - __ UntagAndJumpIfSmi(dst, object, &done); - __ lw(scratch1, FieldMemOperand(object, HeapNumber::kMapOffset)); - __ Branch(not_number, ne, scratch1, Operand(heap_number_map)); - __ ConvertToInt32(object, - dst, - scratch1, - scratch2, - double_scratch, - ¬_in_int32_range); - __ jmp(&done); - - __ bind(¬_in_int32_range); - __ lw(scratch1, FieldMemOperand(object, HeapNumber::kExponentOffset)); - __ lw(scratch2, FieldMemOperand(object, HeapNumber::kMantissaOffset)); - - __ EmitOutOfInt32RangeTruncate(dst, - scratch1, - scratch2, - scratch3); - - __ bind(&done); -} - - -void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm, - Register int_scratch, - Destination destination, - FPURegister double_dst, - Register dst_mantissa, - Register dst_exponent, - Register scratch2, - FPURegister single_scratch) { - ASSERT(!int_scratch.is(scratch2)); - ASSERT(!int_scratch.is(dst_mantissa)); - ASSERT(!int_scratch.is(dst_exponent)); - - __ mtc1(int_scratch, single_scratch); - __ cvt_d_w(double_dst, single_scratch); - if (destination == kCoreRegisters) { - __ Move(dst_mantissa, dst_exponent, double_dst); - } -} - - -void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, - Register object, - Destination destination, - DoubleRegister double_dst, - DoubleRegister double_scratch, - Register dst_mantissa, - Register dst_exponent, - Register heap_number_map, - Register scratch1, - Register scratch2, - FPURegister single_scratch, - Label* not_int32) { - ASSERT(!scratch1.is(object) && !scratch2.is(object)); - ASSERT(!scratch1.is(scratch2)); - ASSERT(!heap_number_map.is(object) && - !heap_number_map.is(scratch1) && - !heap_number_map.is(scratch2)); - - Label done, obj_is_not_smi; - - __ JumpIfNotSmi(object, &obj_is_not_smi); - __ SmiUntag(scratch1, object); - ConvertIntToDouble(masm, scratch1, destination, double_dst, dst_mantissa, - dst_exponent, scratch2, single_scratch); - __ Branch(&done); - - __ bind(&obj_is_not_smi); - __ AssertRootValue(heap_number_map, - Heap::kHeapNumberMapRootIndex, - kHeapNumberMapRegisterClobbered); - __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32); - - // Load the number. - // Load the double value. - __ ldc1(double_dst, FieldMemOperand(object, HeapNumber::kValueOffset)); - - Register except_flag = scratch2; - __ EmitFPUTruncate(kRoundToZero, - scratch1, - double_dst, - at, - double_scratch, - except_flag, - kCheckForInexactConversion); - - // Jump to not_int32 if the operation did not succeed. - __ Branch(not_int32, ne, except_flag, Operand(zero_reg)); - if (destination == kCoreRegisters) { - __ Move(dst_mantissa, dst_exponent, double_dst); - } - __ bind(&done); -} - - -void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm, - Register object, - Register dst, - Register heap_number_map, - Register scratch1, - Register scratch2, - Register scratch3, - DoubleRegister double_scratch0, - DoubleRegister double_scratch1, - Label* not_int32) { - ASSERT(!dst.is(object)); - ASSERT(!scratch1.is(object) && !scratch2.is(object) && !scratch3.is(object)); - ASSERT(!scratch1.is(scratch2) && - !scratch1.is(scratch3) && - !scratch2.is(scratch3)); - - Label done, maybe_undefined; - - __ UntagAndJumpIfSmi(dst, object, &done); - - __ AssertRootValue(heap_number_map, - Heap::kHeapNumberMapRootIndex, - kHeapNumberMapRegisterClobbered); - - __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, &maybe_undefined); - - // Object is a heap number. - // Convert the floating point value to a 32-bit integer. - // Load the double value. - __ ldc1(double_scratch0, FieldMemOperand(object, HeapNumber::kValueOffset)); - - Register except_flag = scratch2; - __ EmitFPUTruncate(kRoundToZero, - dst, - double_scratch0, - scratch1, - double_scratch1, - except_flag, - kCheckForInexactConversion); - - // Jump to not_int32 if the operation did not succeed. - __ Branch(not_int32, ne, except_flag, Operand(zero_reg)); - __ Branch(&done); - - __ bind(&maybe_undefined); - __ LoadRoot(at, Heap::kUndefinedValueRootIndex); - __ Branch(not_int32, ne, object, Operand(at)); - // |undefined| is truncated to 0. - __ li(dst, Operand(Smi::FromInt(0))); - // Fall through. - - __ bind(&done); -} - - -void FloatingPointHelper::CallCCodeForDoubleOperation( - MacroAssembler* masm, - Token::Value op, - Register heap_number_result, - Register scratch) { - // Using core registers: - // a0: Left value (least significant part of mantissa). - // a1: Left value (sign, exponent, top of mantissa). - // a2: Right value (least significant part of mantissa). - // a3: Right value (sign, exponent, top of mantissa). - - // Assert that heap_number_result is saved. - // We currently always use s0 to pass it. - ASSERT(heap_number_result.is(s0)); - - // Push the current return address before the C call. - __ push(ra); - __ PrepareCallCFunction(4, scratch); // Two doubles are 4 arguments. - if (!IsMipsSoftFloatABI) { - // We are not using MIPS FPU instructions, and parameters for the runtime - // function call are prepaired in a0-a3 registers, but function we are - // calling is compiled with hard-float flag and expecting hard float ABI - // (parameters in f12/f14 registers). We need to copy parameters from - // a0-a3 registers to f12/f14 register pairs. - __ Move(f12, a0, a1); - __ Move(f14, a2, a3); - } - { - AllowExternalCallThatCantCauseGC scope(masm); - __ CallCFunction( - ExternalReference::double_fp_operation(op, masm->isolate()), 0, 2); - } - // Store answer in the overwritable heap number. - if (!IsMipsSoftFloatABI) { - // Double returned in register f0. - __ sdc1(f0, FieldMemOperand(heap_number_result, HeapNumber::kValueOffset)); - } else { - // Double returned in registers v0 and v1. - __ sw(v1, FieldMemOperand(heap_number_result, HeapNumber::kExponentOffset)); - __ sw(v0, FieldMemOperand(heap_number_result, HeapNumber::kMantissaOffset)); - } - // Place heap_number_result in v0 and return to the pushed return address. - __ pop(ra); - __ Ret(USE_DELAY_SLOT); - __ mov(v0, heap_number_result); -} - - bool WriteInt32ToHeapNumberStub::IsPregenerated() { // These variants are compiled ahead of time. See next method. if (the_int_.is(a1) && @@ -1472,6 +1188,42 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { } +// Generates code to call a C function to do a double operation. +// This code never falls through, but returns with a heap number containing +// the result in v0. +// Register heap_number_result must be a heap number in which the +// result of the operation will be stored. +// Requires the following layout on entry: +// a0: Left value (least significant part of mantissa). +// a1: Left value (sign, exponent, top of mantissa). +// a2: Right value (least significant part of mantissa). +// a3: Right value (sign, exponent, top of mantissa). +static void CallCCodeForDoubleOperation(MacroAssembler* masm, + Token::Value op, + Register heap_number_result, + Register scratch) { + // Assert that heap_number_result is saved. + // We currently always use s0 to pass it. + ASSERT(heap_number_result.is(s0)); + + // Push the current return address before the C call. + __ push(ra); + __ PrepareCallCFunction(4, scratch); // Two doubles are 4 arguments. + { + AllowExternalCallThatCantCauseGC scope(masm); + __ CallCFunction( + ExternalReference::double_fp_operation(op, masm->isolate()), 0, 2); + } + // Store answer in the overwritable heap number. + // Double returned in register f0. + __ sdc1(f0, FieldMemOperand(heap_number_result, HeapNumber::kValueOffset)); + // Place heap_number_result in v0 and return to the pushed return address. + __ pop(ra); + __ Ret(USE_DELAY_SLOT); + __ mov(v0, heap_number_result); +} + + void BinaryOpStub::Initialize() { platform_specific_bit_ = true; // FPU is a base requirement for V8. } @@ -1699,49 +1451,41 @@ void BinaryOpStub_GenerateFPOperation(MacroAssembler* masm, case Token::MUL: case Token::DIV: case Token::MOD: { - // Load left and right operands into f12 and f14 or a0/a1 and a2/a3 - // depending on operation. - FloatingPointHelper::Destination destination = - op != Token::MOD ? - FloatingPointHelper::kFPURegisters : - FloatingPointHelper::kCoreRegisters; - // Allocate new heap number for result. Register result = s0; BinaryOpStub_GenerateHeapResultAllocation( masm, result, heap_number_map, scratch1, scratch2, gc_required, mode); - // Load the operands. + // Load left and right operands into f12 and f14. if (smi_operands) { - FloatingPointHelper::LoadSmis(masm, destination, scratch1, scratch2); + __ SmiUntag(scratch1, a0); + __ mtc1(scratch1, f14); + __ cvt_d_w(f14, f14); + __ SmiUntag(scratch1, a1); + __ mtc1(scratch1, f12); + __ cvt_d_w(f12, f12); } else { - // Load right operand to f14 or a2/a3. + // Load right operand to f14. if (right_type == BinaryOpIC::INT32) { - FloatingPointHelper::LoadNumberAsInt32Double( - masm, right, destination, f14, f16, a2, a3, heap_number_map, - scratch1, scratch2, f2, miss); + __ LoadNumberAsInt32Double( + right, f14, heap_number_map, scratch1, scratch2, f2, miss); } else { Label* fail = (right_type == BinaryOpIC::NUMBER) ? miss : not_numbers; - FloatingPointHelper::LoadNumber( - masm, destination, right, f14, a2, a3, heap_number_map, - scratch1, scratch2, fail); + __ LoadNumber(right, f14, heap_number_map, scratch1, fail); } // 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, left, destination, f12, f16, a0, a1, heap_number_map, - scratch1, scratch2, f2, miss); + __ LoadNumberAsInt32Double( + left, f12, heap_number_map, scratch1, scratch2, f2, miss); } else { Label* fail = (left_type == BinaryOpIC::NUMBER) ? miss : not_numbers; - FloatingPointHelper::LoadNumber( - masm, destination, left, f12, a0, a1, heap_number_map, - scratch1, scratch2, fail); + __ LoadNumber(left, f12, heap_number_map, scratch1, fail); } } // Calculate the result. - if (destination == FloatingPointHelper::kFPURegisters) { + if (op != Token::MOD) { // Using FPU registers: // f12: Left value. // f14: Right value. @@ -1770,10 +1514,7 @@ void BinaryOpStub_GenerateFPOperation(MacroAssembler* masm, __ mov(v0, result); } else { // Call the C function to handle the double operation. - FloatingPointHelper::CallCCodeForDoubleOperation(masm, - op, - result, - scratch1); + CallCCodeForDoubleOperation(masm, op, result, scratch1); if (FLAG_debug_code) { __ stop("Unreachable code."); } @@ -1791,24 +1532,12 @@ void BinaryOpStub_GenerateFPOperation(MacroAssembler* masm, __ SmiUntag(a2, right); } else { // Convert operands to 32-bit integers. Right in a2 and left in a3. - FloatingPointHelper::ConvertNumberToInt32(masm, - left, - a3, - heap_number_map, - scratch1, - scratch2, - scratch3, - f0, - not_numbers); - FloatingPointHelper::ConvertNumberToInt32(masm, - right, - a2, - heap_number_map, - scratch1, - scratch2, - scratch3, - f0, - not_numbers); + __ ConvertNumberToInt32( + left, a3, heap_number_map, + scratch1, scratch2, scratch3, f0, not_numbers); + __ ConvertNumberToInt32( + right, a2, heap_number_map, + scratch1, scratch2, scratch3, f0, not_numbers); } Label result_not_a_smi; switch (op) { @@ -2042,36 +1771,13 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { // Load both operands and check that they are 32-bit integer. // Jump to type transition if they are not. The registers a0 and a1 (right // and left) are preserved for the runtime call. - FloatingPointHelper::Destination destination = (op_ != Token::MOD) - ? FloatingPointHelper::kFPURegisters - : FloatingPointHelper::kCoreRegisters; - - FloatingPointHelper::LoadNumberAsInt32Double(masm, - right, - destination, - f14, - f16, - a2, - a3, - heap_number_map, - scratch1, - scratch2, - f2, - &transition); - FloatingPointHelper::LoadNumberAsInt32Double(masm, - left, - destination, - f12, - f16, - t0, - t1, - heap_number_map, - scratch1, - scratch2, - f2, - &transition); - - if (destination == FloatingPointHelper::kFPURegisters) { + + __ LoadNumberAsInt32Double( + right, f14, heap_number_map, scratch1, scratch2, f2, &transition); + __ LoadNumberAsInt32Double( + left, f12, heap_number_map, scratch1, scratch2, f2, &transition); + + if (op_ != Token::MOD) { Label return_heap_number; switch (op_) { case Token::ADD: @@ -2148,10 +1854,6 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { __ BranchF(&transition, NULL, ne, f14, f16); } - // We preserved a0 and a1 to be able to call runtime. - // Save the left value on the stack. - __ Push(t1, t0); - Label pop_and_call_runtime; // Allocate a heap number to store the result. @@ -2164,12 +1866,8 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { &pop_and_call_runtime, mode_); - // Load the left value from the value saved on the stack. - __ Pop(a1, a0); - // Call the C function to handle the double operation. - FloatingPointHelper::CallCCodeForDoubleOperation( - masm, op_, heap_number_result, scratch1); + CallCCodeForDoubleOperation(masm, op_, heap_number_result, scratch1); if (FLAG_debug_code) { __ stop("Unreachable code."); } @@ -2189,30 +1887,13 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { case Token::SHR: case Token::SHL: { Label return_heap_number; - Register scratch3 = t1; // Convert operands to 32-bit integers. Right in a2 and left in a3. The // registers a0 and a1 (right and left) are preserved for the runtime // call. - FloatingPointHelper::LoadNumberAsInt32(masm, - left, - a3, - heap_number_map, - scratch1, - scratch2, - scratch3, - f0, - f2, - &transition); - FloatingPointHelper::LoadNumberAsInt32(masm, - right, - a2, - heap_number_map, - scratch1, - scratch2, - scratch3, - f0, - f2, - &transition); + __ LoadNumberAsInt32( + left, a3, heap_number_map, scratch1, scratch2, f0, f2, &transition); + __ LoadNumberAsInt32( + right, a2, heap_number_map, scratch1, scratch2, f0, f2, &transition); // The ECMA-262 standard specifies that, for shift operations, only the // 5 least significant bits of the shift value should be used. @@ -7097,10 +6778,7 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) { // Array literal has ElementsKind of FAST_*_DOUBLE_ELEMENTS. __ bind(&double_elements); __ lw(t1, FieldMemOperand(a1, JSObject::kElementsOffset)); - __ StoreNumberToDoubleElements(a0, a3, - // Overwrites all regs after this. - t1, t2, t3, t5, a2, - &slow_elements); + __ StoreNumberToDoubleElements(a0, a3, t1, t3, t5, a2, &slow_elements); __ Ret(USE_DELAY_SLOT); __ mov(v0, a0); } diff --git a/src/mips/code-stubs-mips.h b/src/mips/code-stubs-mips.h index 1ae1d34..221b344 100644 --- a/src/mips/code-stubs-mips.h +++ b/src/mips/code-stubs-mips.h @@ -527,119 +527,6 @@ class DirectCEntryStub: public PlatformCodeStub { bool NeedsImmovableCode() { return true; } }; -class FloatingPointHelper : public AllStatic { - public: - enum Destination { - kFPURegisters, - kCoreRegisters - }; - - - // Loads smis from a0 and a1 (right and left in binary operations) into - // floating point registers. Depending on the destination the values ends up - // either f14 and f12 or in a2/a3 and a0/a1 respectively. If the destination - // is floating point registers FPU must be supported. If core registers are - // requested when FPU is supported f12 and f14 will be scratched. - static void LoadSmis(MacroAssembler* masm, - Destination destination, - Register scratch1, - Register scratch2); - - // Convert the smi or heap number in object to an int32 using the rules - // for ToInt32 as described in ECMAScript 9.5.: the value is truncated - // and brought into the range -2^31 .. +2^31 - 1. - static void ConvertNumberToInt32(MacroAssembler* masm, - Register object, - Register dst, - Register heap_number_map, - Register scratch1, - Register scratch2, - Register scratch3, - FPURegister double_scratch, - Label* not_int32); - - // Converts the integer (untagged smi) in |int_scratch| to a double, storing - // the result either in |double_dst| or |dst2:dst1|, depending on - // |destination|. - // Warning: The value in |int_scratch| will be changed in the process! - static void ConvertIntToDouble(MacroAssembler* masm, - Register int_scratch, - Destination destination, - FPURegister double_dst, - Register dst1, - Register dst2, - Register scratch2, - FPURegister single_scratch); - - // Load the number from object into double_dst in the double format. - // Control will jump to not_int32 if the value cannot be exactly represented - // by a 32-bit integer. - // Floating point value in the 32-bit integer range that are not exact integer - // won't be loaded. - static void LoadNumberAsInt32Double(MacroAssembler* masm, - Register object, - Destination destination, - FPURegister double_dst, - FPURegister double_scratch, - Register dst1, - Register dst2, - Register heap_number_map, - Register scratch1, - Register scratch2, - FPURegister single_scratch, - Label* not_int32); - - // Loads the number from object into dst as a 32-bit integer. - // Control will jump to not_int32 if the object cannot be exactly represented - // by a 32-bit integer. - // Floating point value in the 32-bit integer range that are not exact integer - // won't be converted. - // scratch3 is not used when FPU is supported. - static void LoadNumberAsInt32(MacroAssembler* masm, - Register object, - Register dst, - Register heap_number_map, - Register scratch1, - Register scratch2, - Register scratch3, - FPURegister double_scratch0, - FPURegister double_scratch1, - Label* not_int32); - - // Generates code to call a C function to do a double operation using core - // registers. (Used when FPU is not supported.) - // This code never falls through, but returns with a heap number containing - // the result in v0. - // Register heapnumber_result must be a heap number in which the - // result of the operation will be stored. - // Requires the following layout on entry: - // a0: Left value (least significant part of mantissa). - // a1: Left value (sign, exponent, top of mantissa). - // a2: Right value (least significant part of mantissa). - // a3: Right value (sign, exponent, top of mantissa). - static void CallCCodeForDoubleOperation(MacroAssembler* masm, - Token::Value op, - Register heap_number_result, - Register scratch); - - // Loads the objects from |object| into floating point registers. - // Depending on |destination| the value ends up either in |dst| or - // in |dst1|/|dst2|. If |destination| is kFPURegisters, then FPU - // must be supported. If kCoreRegisters are requested and FPU is - // supported, |dst| will be scratched. If |object| is neither smi nor - // heap number, |not_number| is jumped to with |object| still intact. - static void LoadNumber(MacroAssembler* masm, - FloatingPointHelper::Destination destination, - Register object, - FPURegister dst, - Register dst1, - Register dst2, - Register heap_number_map, - Register scratch1, - Register scratch2, - Label* not_number); -}; - class NameDictionaryLookupStub: public PlatformCodeStub { public: diff --git a/src/mips/ic-mips.cc b/src/mips/ic-mips.cc index eb730bb..847dea0 100644 --- a/src/mips/ic-mips.cc +++ b/src/mips/ic-mips.cc @@ -1238,7 +1238,6 @@ static void KeyedStoreGenerateGenericHelper( a3, // Scratch regs... t0, t1, - t2, &transition_double_elements); if (increment_length == kIncrementLength) { // Add 1 to receiver->length. diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc index ace7323..2738900 100644 --- a/src/mips/macro-assembler-mips.cc +++ b/src/mips/macro-assembler-mips.cc @@ -3266,7 +3266,7 @@ void MacroAssembler::AllocateHeapNumber(Register result, tagging_mode == TAG_RESULT ? TAG_OBJECT : NO_ALLOCATION_FLAGS); // Store heap number map in the allocated object. - AssertRegisterIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); + AssertIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); if (tagging_mode == TAG_RESULT) { sw(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset)); } else { @@ -3428,7 +3428,6 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg, Register scratch1, Register scratch2, Register scratch3, - Register scratch4, Label* fail, int elements_offset) { Label smi_value, maybe_nan, have_double_value, is_nan, done; @@ -3485,25 +3484,11 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg, Addu(scratch1, scratch1, scratch2); // scratch1 is now effective address of the double element - FloatingPointHelper::Destination destination; - destination = FloatingPointHelper::kFPURegisters; - Register untagged_value = elements_reg; SmiUntag(untagged_value, value_reg); - FloatingPointHelper::ConvertIntToDouble(this, - untagged_value, - destination, - f0, - mantissa_reg, - exponent_reg, - scratch4, - f2); - if (destination == FloatingPointHelper::kFPURegisters) { - sdc1(f0, MemOperand(scratch1, 0)); - } else { - sw(mantissa_reg, MemOperand(scratch1, 0)); - sw(exponent_reg, MemOperand(scratch1, Register::kSizeInBytes)); - } + mtc1(untagged_value, f2); + cvt_d_w(f0, f2); + sdc1(f0, MemOperand(scratch1, 0)); bind(&done); } @@ -4400,15 +4385,6 @@ void MacroAssembler::Assert(Condition cc, BailoutReason reason, } -void MacroAssembler::AssertRegisterIsRoot(Register reg, - Heap::RootListIndex index) { - if (emit_debug_code()) { - LoadRoot(at, index); - Check(eq, kRegisterDidNotMatchExpectedRoot, reg, Operand(at)); - } -} - - void MacroAssembler::AssertFastElements(Register elements) { if (emit_debug_code()) { ASSERT(!elements.is(at)); @@ -4601,6 +4577,150 @@ void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, } +void MacroAssembler::ConvertNumberToInt32(Register object, + Register dst, + Register heap_number_map, + Register scratch1, + Register scratch2, + Register scratch3, + FPURegister double_scratch, + Label* not_number) { + Label done; + Label not_in_int32_range; + + UntagAndJumpIfSmi(dst, object, &done); + JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number); + ConvertToInt32(object, + dst, + scratch1, + scratch2, + double_scratch, + ¬_in_int32_range); + jmp(&done); + + bind(¬_in_int32_range); + lw(scratch1, FieldMemOperand(object, HeapNumber::kExponentOffset)); + lw(scratch2, FieldMemOperand(object, HeapNumber::kMantissaOffset)); + + EmitOutOfInt32RangeTruncate(dst, + scratch1, + scratch2, + scratch3); + + bind(&done); +} + + +void MacroAssembler::LoadNumber(Register object, + FPURegister dst, + Register heap_number_map, + Register scratch, + Label* not_number) { + Label is_smi, done; + + UntagAndJumpIfSmi(scratch, object, &is_smi); + JumpIfNotHeapNumber(object, heap_number_map, scratch, not_number); + + ldc1(dst, FieldMemOperand(object, HeapNumber::kValueOffset)); + Branch(&done); + + bind(&is_smi); + mtc1(scratch, dst); + cvt_d_w(dst, dst); + + bind(&done); +} + + +void MacroAssembler::LoadNumberAsInt32Double(Register object, + DoubleRegister double_dst, + Register heap_number_map, + Register scratch1, + Register scratch2, + FPURegister double_scratch, + Label* not_int32) { + ASSERT(!scratch1.is(object) && !scratch2.is(object)); + ASSERT(!scratch1.is(scratch2)); + ASSERT(!heap_number_map.is(object) && + !heap_number_map.is(scratch1) && + !heap_number_map.is(scratch2)); + + Label done, obj_is_not_smi; + + UntagAndJumpIfNotSmi(scratch1, object, &obj_is_not_smi); + mtc1(scratch1, double_scratch); + cvt_d_w(double_dst, double_scratch); + Branch(&done); + + bind(&obj_is_not_smi); + JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32); + + // Load the number. + // Load the double value. + ldc1(double_dst, FieldMemOperand(object, HeapNumber::kValueOffset)); + + Register except_flag = scratch2; + EmitFPUTruncate(kRoundToZero, + scratch1, + double_dst, + at, + double_scratch, + except_flag, + kCheckForInexactConversion); + + // Jump to not_int32 if the operation did not succeed. + Branch(not_int32, ne, except_flag, Operand(zero_reg)); + bind(&done); +} + + +void MacroAssembler::LoadNumberAsInt32(Register object, + Register dst, + Register heap_number_map, + Register scratch1, + Register scratch2, + FPURegister double_scratch0, + FPURegister double_scratch1, + Label* not_int32) { + ASSERT(!dst.is(object)); + ASSERT(!scratch1.is(object) && !scratch2.is(object)); + ASSERT(!scratch1.is(scratch2)); + + Label done, maybe_undefined; + + UntagAndJumpIfSmi(dst, object, &done); + + JumpIfNotHeapNumber(object, heap_number_map, scratch1, &maybe_undefined); + + // Object is a heap number. + // Convert the floating point value to a 32-bit integer. + // Load the double value. + ldc1(double_scratch0, FieldMemOperand(object, HeapNumber::kValueOffset)); + + Register except_flag = scratch2; + EmitFPUTruncate(kRoundToZero, + dst, + double_scratch0, + scratch1, + double_scratch1, + except_flag, + kCheckForInexactConversion); + + // Jump to not_int32 if the operation did not succeed. + Branch(not_int32, ne, except_flag, Operand(zero_reg)); + Branch(&done); + + bind(&maybe_undefined); + LoadRoot(at, Heap::kUndefinedValueRootIndex); + Branch(not_int32, ne, object, Operand(at)); + // |undefined| is truncated to 0. + li(dst, Operand(Smi::FromInt(0))); + // Fall through. + + bind(&done); +} + + void MacroAssembler::EnterFrame(StackFrame::Type type) { addiu(sp, sp, -5 * kPointerSize); li(t8, Operand(Smi::FromInt(type))); @@ -4920,13 +5040,11 @@ void MacroAssembler::AssertName(Register object) { } -void MacroAssembler::AssertRootValue(Register src, - Heap::RootListIndex root_value_index, - BailoutReason reason) { +void MacroAssembler::AssertIsRoot(Register reg, Heap::RootListIndex index) { if (emit_debug_code()) { - ASSERT(!src.is(at)); - LoadRoot(at, root_value_index); - Check(eq, reason, src, Operand(at)); + ASSERT(!reg.is(at)); + LoadRoot(at, index); + Check(eq, kHeapNumberMapRegisterClobbered, reg, Operand(at)); } } @@ -4936,7 +5054,7 @@ void MacroAssembler::JumpIfNotHeapNumber(Register object, Register scratch, Label* on_not_heap_number) { lw(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); - AssertRegisterIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); + AssertIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); Branch(on_not_heap_number, ne, scratch, Operand(heap_number_map)); } diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h index 9605038..26bed68 100644 --- a/src/mips/macro-assembler-mips.h +++ b/src/mips/macro-assembler-mips.h @@ -797,6 +797,54 @@ class MacroAssembler: public Assembler { Register scratch2, Register scratch3); + // Converts the smi or heap number in object to an int32 using the rules + // for ToInt32 as described in ECMAScript 9.5.: the value is truncated + // and brought into the range -2^31 .. +2^31 - 1. + void ConvertNumberToInt32(Register object, + Register dst, + Register heap_number_map, + Register scratch1, + Register scratch2, + Register scratch3, + FPURegister double_scratch, + Label* not_int32); + + // Loads the number from object into dst register. + // If |object| is neither smi nor heap number, |not_number| is jumped to + // with |object| still intact. + void LoadNumber(Register object, + FPURegister dst, + Register heap_number_map, + Register scratch, + Label* not_number); + + // Loads the number from object into double_dst in the double format. + // Control will jump to not_int32 if the value cannot be exactly represented + // by a 32-bit integer. + // Floating point value in the 32-bit integer range that are not exact integer + // won't be loaded. + void LoadNumberAsInt32Double(Register object, + DoubleRegister double_dst, + Register heap_number_map, + Register scratch1, + Register scratch2, + FPURegister double_scratch, + Label* not_int32); + + // Loads the number from object into dst as a 32-bit integer. + // Control will jump to not_int32 if the object cannot be exactly represented + // by a 32-bit integer. + // Floating point value in the 32-bit integer range that are not exact integer + // won't be converted. + void LoadNumberAsInt32(Register object, + Register dst, + Register heap_number_map, + Register scratch1, + Register scratch2, + FPURegister double_scratch0, + FPURegister double_scratch1, + Label* not_int32); + // Enter exit frame. // argc - argument count to be dropped by LeaveExitFrame. // save_doubles - saves FPU registers on stack, currently disabled. @@ -986,16 +1034,13 @@ class MacroAssembler: public Assembler { // Check to see if maybe_number can be stored as a double in // FastDoubleElements. If it can, store it at the index specified by key in - // the FastDoubleElements array elements. Otherwise jump to fail, in which - // case scratch2, scratch3 and scratch4 are unmodified. + // the FastDoubleElements array elements. Otherwise jump to fail. void StoreNumberToDoubleElements(Register value_reg, Register key_reg, - // All regs below here overwritten. Register elements_reg, Register scratch1, Register scratch2, Register scratch3, - Register scratch4, Label* fail, int elements_offset = 0); @@ -1280,7 +1325,6 @@ class MacroAssembler: public Assembler { // Calls Abort(msg) if the condition cc is not satisfied. // Use --debug_code to enable. void Assert(Condition cc, BailoutReason reason, Register rs, Operand rt); - void AssertRegisterIsRoot(Register reg, Heap::RootListIndex index); void AssertFastElements(Register elements); // Like Assert(), but always enabled. @@ -1367,11 +1411,9 @@ class MacroAssembler: public Assembler { // Abort execution if argument is not a name, enabled via --debug-code. void AssertName(Register object); - // Abort execution if argument is not the root value with the given index, + // Abort execution if reg is not the root value with the given index, // enabled via --debug-code. - void AssertRootValue(Register src, - Heap::RootListIndex root_value_index, - BailoutReason reason); + void AssertIsRoot(Register reg, Heap::RootListIndex index); // --------------------------------------------------------------------------- // HeapNumber utilities. diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc index ccbe86a..18353b6 100644 --- a/src/mips/stub-cache-mips.cc +++ b/src/mips/stub-cache-mips.cc @@ -1775,7 +1775,7 @@ Handle CallStubCompiler::CompileArrayPushCall( __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize)); __ StoreNumberToDoubleElements( - t0, v0, elements, a3, t1, a2, t5, + t0, v0, elements, a3, t1, a2, &call_builtin, argc * kDoubleSize); // Save new length.