Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1968)

Side by Side Diff: src/mips/code-stubs-mips.cc

Issue 7042031: MIPS: Minor fixes to simulator and builtins-mips. (Closed)
Patch Set: Rebased on r7964, updated for recent commits. Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/mips/builtins-mips.cc ('k') | src/mips/full-codegen-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1454 matching lines...) Expand 10 before | Expand all | Expand 10 after
1465 Label is_smi; 1465 Label is_smi;
1466 Label load_result_from_cache; 1466 Label load_result_from_cache;
1467 if (!object_is_smi) { 1467 if (!object_is_smi) {
1468 __ JumpIfSmi(object, &is_smi); 1468 __ JumpIfSmi(object, &is_smi);
1469 if (CpuFeatures::IsSupported(FPU)) { 1469 if (CpuFeatures::IsSupported(FPU)) {
1470 CpuFeatures::Scope scope(FPU); 1470 CpuFeatures::Scope scope(FPU);
1471 __ CheckMap(object, 1471 __ CheckMap(object,
1472 scratch1, 1472 scratch1,
1473 Heap::kHeapNumberMapRootIndex, 1473 Heap::kHeapNumberMapRootIndex,
1474 not_found, 1474 not_found,
1475 true); 1475 DONT_DO_SMI_CHECK);
1476 1476
1477 STATIC_ASSERT(8 == kDoubleSize); 1477 STATIC_ASSERT(8 == kDoubleSize);
1478 __ Addu(scratch1, 1478 __ Addu(scratch1,
1479 object, 1479 object,
1480 Operand(HeapNumber::kValueOffset - kHeapObjectTag)); 1480 Operand(HeapNumber::kValueOffset - kHeapObjectTag));
1481 __ lw(scratch2, MemOperand(scratch1, kPointerSize)); 1481 __ lw(scratch2, MemOperand(scratch1, kPointerSize));
1482 __ lw(scratch1, MemOperand(scratch1, 0)); 1482 __ lw(scratch1, MemOperand(scratch1, 0));
1483 __ Xor(scratch1, scratch1, Operand(scratch2)); 1483 __ Xor(scratch1, scratch1, Operand(scratch2));
1484 __ And(scratch1, scratch1, Operand(mask)); 1484 __ And(scratch1, scratch1, Operand(mask));
1485 1485
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1729 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) 1729 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
1730 // tagged as a small integer. 1730 // tagged as a small integer.
1731 __ InvokeBuiltin(native, JUMP_FUNCTION); 1731 __ InvokeBuiltin(native, JUMP_FUNCTION);
1732 } 1732 }
1733 1733
1734 1734
1735 // This stub does not handle the inlined cases (Smis, Booleans, undefined). 1735 // This stub does not handle the inlined cases (Smis, Booleans, undefined).
1736 // The stub returns zero for false, and a non-zero value for true. 1736 // The stub returns zero for false, and a non-zero value for true.
1737 void ToBooleanStub::Generate(MacroAssembler* masm) { 1737 void ToBooleanStub::Generate(MacroAssembler* masm) {
1738 // This stub uses FPU instructions. 1738 // This stub uses FPU instructions.
1739 ASSERT(CpuFeatures::IsEnabled(FPU)); 1739 CpuFeatures::Scope scope(FPU);
1740 1740
1741 Label false_result; 1741 Label false_result;
1742 Label not_heap_number; 1742 Label not_heap_number;
1743 Register scratch0 = t5.is(tos_) ? t3 : t5; 1743 Register scratch0 = t5.is(tos_) ? t3 : t5;
1744 1744
1745 // undefined -> false
1746 __ LoadRoot(scratch0, Heap::kUndefinedValueRootIndex);
1747 __ Branch(&false_result, eq, tos_, Operand(scratch0));
1748
1749 // Boolean -> its value
1750 __ LoadRoot(scratch0, Heap::kFalseValueRootIndex);
1751 __ Branch(&false_result, eq, tos_, Operand(scratch0));
1752 __ LoadRoot(scratch0, Heap::kTrueValueRootIndex);
1753 // "tos_" is a register and contains a non-zero value. Hence we implicitly
1754 // return true if the equal condition is satisfied.
1755 __ Ret(eq, tos_, Operand(scratch0));
1756
1757 // Smis: 0 -> false, all other -> true
1758 __ And(scratch0, tos_, tos_);
1759 __ Branch(&false_result, eq, scratch0, Operand(zero_reg));
1760 __ And(scratch0, tos_, Operand(kSmiTagMask));
1761 // "tos_" is a register and contains a non-zero value. Hence we implicitly
1762 // return true if the not equal condition is satisfied.
1763 __ Ret(eq, scratch0, Operand(zero_reg));
1764
1765 // 'null' -> false
1745 __ LoadRoot(scratch0, Heap::kNullValueRootIndex); 1766 __ LoadRoot(scratch0, Heap::kNullValueRootIndex);
1746 __ Branch(&false_result, eq, tos_, Operand(scratch0)); 1767 __ Branch(&false_result, eq, tos_, Operand(scratch0));
1747 1768
1748 // HeapNumber => false if +0, -0, or NaN. 1769 // HeapNumber => false if +0, -0, or NaN.
1749 __ lw(scratch0, FieldMemOperand(tos_, HeapObject::kMapOffset)); 1770 __ lw(scratch0, FieldMemOperand(tos_, HeapObject::kMapOffset));
1750 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 1771 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
1751 __ Branch(&not_heap_number, ne, scratch0, Operand(at)); 1772 __ Branch(&not_heap_number, ne, scratch0, Operand(at));
1752 1773
1753 __ Subu(at, tos_, Operand(kHeapObjectTag)); 1774 __ ldc1(f12, FieldMemOperand(tos_, HeapNumber::kValueOffset));
1754 __ ldc1(f12, MemOperand(at, HeapNumber::kValueOffset));
1755 __ fcmp(f12, 0.0, UEQ); 1775 __ fcmp(f12, 0.0, UEQ);
1756 1776
1757 // "tos_" is a register, and contains a non zero value by default. 1777 // "tos_" is a register, and contains a non zero value by default.
1758 // Hence we only need to overwrite "tos_" with zero to return false for 1778 // Hence we only need to overwrite "tos_" with zero to return false for
1759 // FP_ZERO or FP_NAN cases. Otherwise, by default it returns true. 1779 // FP_ZERO or FP_NAN cases. Otherwise, by default it returns true.
1760 __ movt(tos_, zero_reg); 1780 __ movt(tos_, zero_reg);
1761 __ Ret(); 1781 __ Ret();
1762 1782
1763 __ bind(&not_heap_number); 1783 __ bind(&not_heap_number);
1764 1784
1765 // Check if the value is 'null'.
1766 // 'null' => false.
1767 __ LoadRoot(at, Heap::kNullValueRootIndex);
1768 __ Branch(&false_result, eq, tos_, Operand(at));
1769
1770 // It can be an undetectable object. 1785 // It can be an undetectable object.
1771 // Undetectable => false. 1786 // Undetectable => false.
1772 __ lw(at, FieldMemOperand(tos_, HeapObject::kMapOffset)); 1787 __ lw(at, FieldMemOperand(tos_, HeapObject::kMapOffset));
1773 __ lbu(scratch0, FieldMemOperand(at, Map::kBitFieldOffset)); 1788 __ lbu(scratch0, FieldMemOperand(at, Map::kBitFieldOffset));
1774 __ And(scratch0, scratch0, Operand(1 << Map::kIsUndetectable)); 1789 __ And(scratch0, scratch0, Operand(1 << Map::kIsUndetectable));
1775 __ Branch(&false_result, eq, scratch0, Operand(1 << Map::kIsUndetectable)); 1790 __ Branch(&false_result, eq, scratch0, Operand(1 << Map::kIsUndetectable));
1776 1791
1777 // JavaScript object => true. 1792 // JavaScript object => true.
1778 __ lw(scratch0, FieldMemOperand(tos_, HeapObject::kMapOffset)); 1793 __ lw(scratch0, FieldMemOperand(tos_, HeapObject::kMapOffset));
1779 __ lbu(scratch0, FieldMemOperand(scratch0, Map::kInstanceTypeOffset)); 1794 __ lbu(scratch0, FieldMemOperand(scratch0, Map::kInstanceTypeOffset));
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1937 case Token::BIT_NOT: 1952 case Token::BIT_NOT:
1938 GenerateHeapNumberStubBitNot(masm); 1953 GenerateHeapNumberStubBitNot(masm);
1939 break; 1954 break;
1940 default: 1955 default:
1941 UNREACHABLE(); 1956 UNREACHABLE();
1942 } 1957 }
1943 } 1958 }
1944 1959
1945 1960
1946 void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) { 1961 void TypeRecordingUnaryOpStub::GenerateHeapNumberStubSub(MacroAssembler* masm) {
1947 Label non_smi, slow; 1962 Label non_smi, slow, call_builtin;
1948 GenerateSmiCodeSub(masm, &non_smi, &slow); 1963 GenerateSmiCodeSub(masm, &non_smi, &call_builtin);
1949 __ bind(&non_smi); 1964 __ bind(&non_smi);
1950 GenerateHeapNumberCodeSub(masm, &slow); 1965 GenerateHeapNumberCodeSub(masm, &slow);
1951 __ bind(&slow); 1966 __ bind(&slow);
1952 GenerateTypeTransition(masm); 1967 GenerateTypeTransition(masm);
1968 __ bind(&call_builtin);
1969 GenerateGenericCodeFallback(masm);
1953 } 1970 }
1954 1971
1955 1972
1956 void TypeRecordingUnaryOpStub::GenerateHeapNumberStubBitNot( 1973 void TypeRecordingUnaryOpStub::GenerateHeapNumberStubBitNot(
1957 MacroAssembler* masm) { 1974 MacroAssembler* masm) {
1958 Label non_smi, slow; 1975 Label non_smi, slow;
1959 GenerateSmiCodeBitNot(masm, &non_smi); 1976 GenerateSmiCodeBitNot(masm, &non_smi);
1960 __ bind(&non_smi); 1977 __ bind(&non_smi);
1961 GenerateHeapNumberCodeBitNot(masm, &slow); 1978 GenerateHeapNumberCodeBitNot(masm, &slow);
1962 __ bind(&slow); 1979 __ bind(&slow);
(...skipping 1215 matching lines...) Expand 10 before | Expand all | Expand 10 after
3178 __ mfc1(a2, f4); 3195 __ mfc1(a2, f4);
3179 __ mfc1(a3, f5); 3196 __ mfc1(a3, f5);
3180 __ Branch(&loaded); 3197 __ Branch(&loaded);
3181 3198
3182 __ bind(&input_not_smi); 3199 __ bind(&input_not_smi);
3183 // Check if input is a HeapNumber. 3200 // Check if input is a HeapNumber.
3184 __ CheckMap(a0, 3201 __ CheckMap(a0,
3185 a1, 3202 a1,
3186 Heap::kHeapNumberMapRootIndex, 3203 Heap::kHeapNumberMapRootIndex,
3187 &calculate, 3204 &calculate,
3188 true); 3205 DONT_DO_SMI_CHECK);
3189 // Input is a HeapNumber. Store the 3206 // Input is a HeapNumber. Store the
3190 // low and high words into a2, a3. 3207 // low and high words into a2, a3.
3191 __ lw(a2, FieldMemOperand(a0, HeapNumber::kValueOffset)); 3208 __ lw(a2, FieldMemOperand(a0, HeapNumber::kValueOffset));
3192 __ lw(a3, FieldMemOperand(a0, HeapNumber::kValueOffset + 4)); 3209 __ lw(a3, FieldMemOperand(a0, HeapNumber::kValueOffset + 4));
3193 } else { 3210 } else {
3194 // Input is untagged double in f4. Output goes to f4. 3211 // Input is untagged double in f4. Output goes to f4.
3195 __ mfc1(a2, f4); 3212 __ mfc1(a2, f4);
3196 __ mfc1(a3, f5); 3213 __ mfc1(a3, f5);
3197 } 3214 }
3198 __ bind(&loaded); 3215 __ bind(&loaded);
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after
3757 // caller fp | 3774 // caller fp |
3758 // function slot | entry frame 3775 // function slot | entry frame
3759 // context slot | 3776 // context slot |
3760 // bad fp (0xff...f) | 3777 // bad fp (0xff...f) |
3761 // callee saved registers + ra 3778 // callee saved registers + ra
3762 // 4 args slots 3779 // 4 args slots
3763 // args 3780 // args
3764 3781
3765 #ifdef ENABLE_LOGGING_AND_PROFILING 3782 #ifdef ENABLE_LOGGING_AND_PROFILING
3766 // If this is the outermost JS call, set js_entry_sp value. 3783 // If this is the outermost JS call, set js_entry_sp value.
3784 Label non_outermost_js;
3767 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, 3785 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address,
3768 masm->isolate()); 3786 masm->isolate());
3769 __ li(t1, Operand(ExternalReference(js_entry_sp))); 3787 __ li(t1, Operand(ExternalReference(js_entry_sp)));
3770 __ lw(t2, MemOperand(t1)); 3788 __ lw(t2, MemOperand(t1));
3771 { 3789 __ Branch(&non_outermost_js, ne, t2, Operand(zero_reg));
3772 Label skip; 3790 __ sw(fp, MemOperand(t1));
3773 __ Branch(&skip, ne, t2, Operand(zero_reg)); 3791 __ li(t0, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
3774 __ sw(fp, MemOperand(t1)); 3792 Label cont;
3775 __ bind(&skip); 3793 __ b(&cont);
3776 } 3794 __ nop(); // Branch delay slot nop.
3795 __ bind(&non_outermost_js);
3796 __ li(t0, Operand(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME)));
3797 __ bind(&cont);
3798 __ push(t0);
3777 #endif 3799 #endif
3778 3800
3779 // Call a faked try-block that does the invoke. 3801 // Call a faked try-block that does the invoke.
3780 __ bal(&invoke); // bal exposes branch delay slot. 3802 __ bal(&invoke); // bal exposes branch delay slot.
3781 __ nop(); // Branch delay slot nop. 3803 __ nop(); // Branch delay slot nop.
3782 3804
3783 // Caught exception: Store result (exception) in the pending 3805 // Caught exception: Store result (exception) in the pending
3784 // exception field in the JSEnv and return a failure sentinel. 3806 // exception field in the JSEnv and return a failure sentinel.
3785 // Coming in here the fp will be invalid because the PushTryHandler below 3807 // Coming in here the fp will be invalid because the PushTryHandler below
3786 // sets it to 0 to signal the existence of the JSEntry frame. 3808 // sets it to 0 to signal the existence of the JSEntry frame.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3832 } else { 3854 } else {
3833 ExternalReference entry(Builtins::kJSEntryTrampoline, masm->isolate()); 3855 ExternalReference entry(Builtins::kJSEntryTrampoline, masm->isolate());
3834 __ li(t0, Operand(entry)); 3856 __ li(t0, Operand(entry));
3835 } 3857 }
3836 __ lw(t9, MemOperand(t0)); // Deref address. 3858 __ lw(t9, MemOperand(t0)); // Deref address.
3837 3859
3838 // Call JSEntryTrampoline. 3860 // Call JSEntryTrampoline.
3839 __ addiu(t9, t9, Code::kHeaderSize - kHeapObjectTag); 3861 __ addiu(t9, t9, Code::kHeaderSize - kHeapObjectTag);
3840 __ Call(t9); 3862 __ Call(t9);
3841 3863
3842 // Unlink this frame from the handler chain. When reading the 3864 // Unlink this frame from the handler chain.
3843 // address of the next handler, there is no need to use the address 3865 __ PopTryHandler();
3844 // displacement since the current stack pointer (sp) points directly
3845 // to the stack handler.
3846 __ lw(t1, MemOperand(sp, StackHandlerConstants::kNextOffset));
3847 __ li(t0, Operand(ExternalReference(Isolate::k_handler_address,
3848 masm->isolate())));
3849 __ sw(t1, MemOperand(t0));
3850 3866
3851 // This restores sp to its position before PushTryHandler. 3867 __ bind(&exit); // v0 holds result
3852 __ addiu(sp, sp, StackHandlerConstants::kSize); 3868 #ifdef ENABLE_LOGGING_AND_PROFILING
3869 // Check if the current stack frame is marked as the outermost JS frame.
3870 Label non_outermost_js_2;
3871 __ pop(t1);
3872 __ Branch(&non_outermost_js_2, ne, t1,
3873 Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
3874 __ li(t1, Operand(ExternalReference(js_entry_sp)));
3875 __ sw(zero_reg, MemOperand(t1));
3876 __ bind(&non_outermost_js_2);
3877 #endif
3853 3878
3854 #ifdef ENABLE_LOGGING_AND_PROFILING
3855 // If current FP value is the same as js_entry_sp value, it means that
3856 // the current function is the outermost.
3857 __ li(t1, Operand(ExternalReference(js_entry_sp)));
3858 __ lw(t2, MemOperand(t1));
3859 {
3860 Label skip;
3861 __ Branch(&skip, ne, fp, Operand(t2));
3862 __ sw(zero_reg, MemOperand(t1));
3863 __ bind(&skip);
3864 }
3865 #endif
3866
3867 __ bind(&exit); // v0 holds result.
3868 // Restore the top frame descriptors from the stack. 3879 // Restore the top frame descriptors from the stack.
3869 __ pop(t1); 3880 __ pop(t1);
3870 __ li(t0, Operand(ExternalReference(Isolate::k_c_entry_fp_address, 3881 __ li(t0, Operand(ExternalReference(Isolate::k_c_entry_fp_address,
3871 masm->isolate()))); 3882 masm->isolate())));
3872 __ sw(t1, MemOperand(t0)); 3883 __ sw(t1, MemOperand(t0));
3873 3884
3874 // Reset the stack to the callee saved registers. 3885 // Reset the stack to the callee saved registers.
3875 __ addiu(sp, sp, -EntryFrameConstants::kCallerFPOffset); 3886 __ addiu(sp, sp, -EntryFrameConstants::kCallerFPOffset);
3876 3887
3877 // Restore callee saved registers from the stack. 3888 // Restore callee saved registers from the stack.
(...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after
4839 MacroAssembler* masm, const RuntimeCallHelper& call_helper) { 4850 MacroAssembler* masm, const RuntimeCallHelper& call_helper) {
4840 __ Abort("Unexpected fallthrough to CharCodeAt slow case"); 4851 __ Abort("Unexpected fallthrough to CharCodeAt slow case");
4841 4852
4842 // Index is not a smi. 4853 // Index is not a smi.
4843 __ bind(&index_not_smi_); 4854 __ bind(&index_not_smi_);
4844 // If index is a heap number, try converting it to an integer. 4855 // If index is a heap number, try converting it to an integer.
4845 __ CheckMap(index_, 4856 __ CheckMap(index_,
4846 scratch_, 4857 scratch_,
4847 Heap::kHeapNumberMapRootIndex, 4858 Heap::kHeapNumberMapRootIndex,
4848 index_not_number_, 4859 index_not_number_,
4849 true); 4860 DONT_DO_SMI_CHECK);
4850 call_helper.BeforeCall(masm); 4861 call_helper.BeforeCall(masm);
4851 // Consumed by runtime conversion function: 4862 // Consumed by runtime conversion function:
4852 __ Push(object_, index_, index_); 4863 __ Push(object_, index_, index_);
4853 if (index_flags_ == STRING_INDEX_IS_NUMBER) { 4864 if (index_flags_ == STRING_INDEX_IS_NUMBER) {
4854 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); 4865 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1);
4855 } else { 4866 } else {
4856 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); 4867 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX);
4857 // NumberToSmi discards numbers that are not exact integers. 4868 // NumberToSmi discards numbers that are not exact integers.
4858 __ CallRuntime(Runtime::kNumberToSmi, 1); 4869 __ CallRuntime(Runtime::kNumberToSmi, 1);
4859 } 4870 }
(...skipping 1746 matching lines...) Expand 10 before | Expand all | Expand 10 after
6606 __ mov(result, zero_reg); 6617 __ mov(result, zero_reg);
6607 __ Ret(); 6618 __ Ret();
6608 } 6619 }
6609 6620
6610 6621
6611 #undef __ 6622 #undef __
6612 6623
6613 } } // namespace v8::internal 6624 } } // namespace v8::internal
6614 6625
6615 #endif // V8_TARGET_ARCH_MIPS 6626 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/builtins-mips.cc ('k') | src/mips/full-codegen-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698