OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 2382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2393 BinaryOpStub_GenerateSmiCode( | 2393 BinaryOpStub_GenerateSmiCode( |
2394 masm, &call_runtime, &call_runtime, op_, ALLOW_HEAPNUMBER_RESULTS, | 2394 masm, &call_runtime, &call_runtime, op_, ALLOW_HEAPNUMBER_RESULTS, |
2395 mode_); | 2395 mode_); |
2396 } | 2396 } |
2397 | 2397 |
2398 // Code falls through if the result is not returned as either a smi or heap | 2398 // Code falls through if the result is not returned as either a smi or heap |
2399 // number. | 2399 // number. |
2400 GenerateTypeTransition(masm); | 2400 GenerateTypeTransition(masm); |
2401 | 2401 |
2402 __ bind(&call_runtime); | 2402 __ bind(&call_runtime); |
2403 GenerateRegisterArgsPush(masm); | 2403 { |
2404 GenerateCallRuntime(masm); | 2404 FrameScope scope(masm, StackFrame::INTERNAL); |
| 2405 GenerateRegisterArgsPush(masm); |
| 2406 GenerateCallRuntime(masm); |
| 2407 } |
| 2408 __ Ret(); |
2405 } | 2409 } |
2406 | 2410 |
2407 | 2411 |
2408 void BinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) { | 2412 void BinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) { |
2409 Label call_runtime; | 2413 Label call_runtime; |
2410 ASSERT(left_type_ == BinaryOpIC::STRING && right_type_ == BinaryOpIC::STRING); | 2414 ASSERT(left_type_ == BinaryOpIC::STRING && right_type_ == BinaryOpIC::STRING); |
2411 ASSERT(op_ == Token::ADD); | 2415 ASSERT(op_ == Token::ADD); |
2412 // If both arguments are strings, call the string add stub. | 2416 // If both arguments are strings, call the string add stub. |
2413 // Otherwise, do a transition. | 2417 // Otherwise, do a transition. |
2414 | 2418 |
2415 // Registers containing left and right operands respectively. | 2419 // Registers containing left and right operands respectively. |
2416 Register left = a1; | 2420 Register left = a1; |
2417 Register right = a0; | 2421 Register right = a0; |
2418 | 2422 |
2419 // Test if left operand is a string. | 2423 // Test if left operand is a string. |
2420 __ JumpIfSmi(left, &call_runtime); | 2424 __ JumpIfSmi(left, &call_runtime); |
2421 __ GetObjectType(left, a2, a2); | 2425 __ GetObjectType(left, a2, a2); |
2422 __ Branch(&call_runtime, ge, a2, Operand(FIRST_NONSTRING_TYPE)); | 2426 __ Branch(&call_runtime, ge, a2, Operand(FIRST_NONSTRING_TYPE)); |
2423 | 2427 |
2424 // Test if right operand is a string. | 2428 // Test if right operand is a string. |
2425 __ JumpIfSmi(right, &call_runtime); | 2429 __ JumpIfSmi(right, &call_runtime); |
2426 __ GetObjectType(right, a2, a2); | 2430 __ GetObjectType(right, a2, a2); |
2427 __ Branch(&call_runtime, ge, a2, Operand(FIRST_NONSTRING_TYPE)); | 2431 __ Branch(&call_runtime, ge, a2, Operand(FIRST_NONSTRING_TYPE)); |
2428 | 2432 |
2429 StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB); | 2433 StringAddStub string_add_stub((StringAddFlags) |
| 2434 (ERECT_FRAME | NO_STRING_CHECK_IN_STUB)); |
2430 GenerateRegisterArgsPush(masm); | 2435 GenerateRegisterArgsPush(masm); |
2431 __ TailCallStub(&string_add_stub); | 2436 __ TailCallStub(&string_add_stub); |
2432 | 2437 |
2433 __ bind(&call_runtime); | 2438 __ bind(&call_runtime); |
2434 GenerateTypeTransition(masm); | 2439 GenerateTypeTransition(masm); |
2435 } | 2440 } |
2436 | 2441 |
2437 | 2442 |
2438 void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { | 2443 void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { |
2439 ASSERT(Max(left_type_, right_type_) == BinaryOpIC::INT32); | 2444 ASSERT(Max(left_type_, right_type_) == BinaryOpIC::INT32); |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2739 // We never expect DIV to yield an integer result, so we always generate | 2744 // We never expect DIV to yield an integer result, so we always generate |
2740 // type transition code for DIV operations expecting an integer result: the | 2745 // type transition code for DIV operations expecting an integer result: the |
2741 // code will fall through to this type transition. | 2746 // code will fall through to this type transition. |
2742 if (transition.is_linked() || | 2747 if (transition.is_linked() || |
2743 ((op_ == Token::DIV) && (result_type_ <= BinaryOpIC::INT32))) { | 2748 ((op_ == Token::DIV) && (result_type_ <= BinaryOpIC::INT32))) { |
2744 __ bind(&transition); | 2749 __ bind(&transition); |
2745 GenerateTypeTransition(masm); | 2750 GenerateTypeTransition(masm); |
2746 } | 2751 } |
2747 | 2752 |
2748 __ bind(&call_runtime); | 2753 __ bind(&call_runtime); |
2749 GenerateRegisterArgsPush(masm); | 2754 { |
2750 GenerateCallRuntime(masm); | 2755 FrameScope scope(masm, StackFrame::INTERNAL); |
| 2756 GenerateRegisterArgsPush(masm); |
| 2757 GenerateCallRuntime(masm); |
| 2758 } |
| 2759 __ Ret(); |
2751 } | 2760 } |
2752 | 2761 |
2753 | 2762 |
2754 void BinaryOpStub::GenerateOddballStub(MacroAssembler* masm) { | 2763 void BinaryOpStub::GenerateOddballStub(MacroAssembler* masm) { |
2755 Label call_runtime; | 2764 Label call_runtime; |
2756 | 2765 |
2757 if (op_ == Token::ADD) { | 2766 if (op_ == Token::ADD) { |
2758 // Handle string addition here, because it is the only operation | 2767 // Handle string addition here, because it is the only operation |
2759 // that does not do a ToNumber conversion on the operands. | 2768 // that does not do a ToNumber conversion on the operands. |
2760 GenerateAddStrings(masm); | 2769 GenerateAddStrings(masm); |
(...skipping 26 matching lines...) Expand all Loading... |
2787 void BinaryOpStub::GenerateNumberStub(MacroAssembler* masm) { | 2796 void BinaryOpStub::GenerateNumberStub(MacroAssembler* masm) { |
2788 Label call_runtime, transition; | 2797 Label call_runtime, transition; |
2789 BinaryOpStub_GenerateFPOperation( | 2798 BinaryOpStub_GenerateFPOperation( |
2790 masm, left_type_, right_type_, false, | 2799 masm, left_type_, right_type_, false, |
2791 &transition, &call_runtime, &transition, op_, mode_); | 2800 &transition, &call_runtime, &transition, op_, mode_); |
2792 | 2801 |
2793 __ bind(&transition); | 2802 __ bind(&transition); |
2794 GenerateTypeTransition(masm); | 2803 GenerateTypeTransition(masm); |
2795 | 2804 |
2796 __ bind(&call_runtime); | 2805 __ bind(&call_runtime); |
2797 GenerateRegisterArgsPush(masm); | 2806 { |
2798 GenerateCallRuntime(masm); | 2807 FrameScope scope(masm, StackFrame::INTERNAL); |
| 2808 GenerateRegisterArgsPush(masm); |
| 2809 GenerateCallRuntime(masm); |
| 2810 } |
| 2811 __ Ret(); |
2799 } | 2812 } |
2800 | 2813 |
2801 | 2814 |
2802 void BinaryOpStub::GenerateGeneric(MacroAssembler* masm) { | 2815 void BinaryOpStub::GenerateGeneric(MacroAssembler* masm) { |
2803 Label call_runtime, call_string_add_or_runtime, transition; | 2816 Label call_runtime, call_string_add_or_runtime, transition; |
2804 | 2817 |
2805 BinaryOpStub_GenerateSmiCode( | 2818 BinaryOpStub_GenerateSmiCode( |
2806 masm, &call_runtime, &call_runtime, op_, ALLOW_HEAPNUMBER_RESULTS, mode_); | 2819 masm, &call_runtime, &call_runtime, op_, ALLOW_HEAPNUMBER_RESULTS, mode_); |
2807 | 2820 |
2808 BinaryOpStub_GenerateFPOperation( | 2821 BinaryOpStub_GenerateFPOperation( |
2809 masm, left_type_, right_type_, false, | 2822 masm, left_type_, right_type_, false, |
2810 &call_string_add_or_runtime, &call_runtime, &transition, op_, mode_); | 2823 &call_string_add_or_runtime, &call_runtime, &transition, op_, mode_); |
2811 | 2824 |
2812 __ bind(&transition); | 2825 __ bind(&transition); |
2813 GenerateTypeTransition(masm); | 2826 GenerateTypeTransition(masm); |
2814 | 2827 |
2815 __ bind(&call_string_add_or_runtime); | 2828 __ bind(&call_string_add_or_runtime); |
2816 if (op_ == Token::ADD) { | 2829 if (op_ == Token::ADD) { |
2817 GenerateAddStrings(masm); | 2830 GenerateAddStrings(masm); |
2818 } | 2831 } |
2819 | 2832 |
2820 __ bind(&call_runtime); | 2833 __ bind(&call_runtime); |
2821 GenerateRegisterArgsPush(masm); | 2834 { |
2822 GenerateCallRuntime(masm); | 2835 FrameScope scope(masm, StackFrame::INTERNAL); |
| 2836 GenerateRegisterArgsPush(masm); |
| 2837 GenerateCallRuntime(masm); |
| 2838 } |
| 2839 __ Ret(); |
2823 } | 2840 } |
2824 | 2841 |
2825 | 2842 |
2826 void BinaryOpStub::GenerateAddStrings(MacroAssembler* masm) { | 2843 void BinaryOpStub::GenerateAddStrings(MacroAssembler* masm) { |
2827 ASSERT(op_ == Token::ADD); | 2844 ASSERT(op_ == Token::ADD); |
2828 Label left_not_string, call_runtime; | 2845 Label left_not_string, call_runtime; |
2829 | 2846 |
2830 Register left = a1; | 2847 Register left = a1; |
2831 Register right = a0; | 2848 Register right = a0; |
2832 | 2849 |
2833 // Check if left argument is a string. | 2850 // Check if left argument is a string. |
2834 __ JumpIfSmi(left, &left_not_string); | 2851 __ JumpIfSmi(left, &left_not_string); |
2835 __ GetObjectType(left, a2, a2); | 2852 __ GetObjectType(left, a2, a2); |
2836 __ Branch(&left_not_string, ge, a2, Operand(FIRST_NONSTRING_TYPE)); | 2853 __ Branch(&left_not_string, ge, a2, Operand(FIRST_NONSTRING_TYPE)); |
2837 | 2854 |
2838 StringAddStub string_add_left_stub(NO_STRING_CHECK_LEFT_IN_STUB); | 2855 StringAddStub string_add_left_stub((StringAddFlags) |
| 2856 (ERECT_FRAME | NO_STRING_CHECK_LEFT_IN_STUB)); |
2839 GenerateRegisterArgsPush(masm); | 2857 GenerateRegisterArgsPush(masm); |
2840 __ TailCallStub(&string_add_left_stub); | 2858 __ TailCallStub(&string_add_left_stub); |
2841 | 2859 |
2842 // Left operand is not a string, test right. | 2860 // Left operand is not a string, test right. |
2843 __ bind(&left_not_string); | 2861 __ bind(&left_not_string); |
2844 __ JumpIfSmi(right, &call_runtime); | 2862 __ JumpIfSmi(right, &call_runtime); |
2845 __ GetObjectType(right, a2, a2); | 2863 __ GetObjectType(right, a2, a2); |
2846 __ Branch(&call_runtime, ge, a2, Operand(FIRST_NONSTRING_TYPE)); | 2864 __ Branch(&call_runtime, ge, a2, Operand(FIRST_NONSTRING_TYPE)); |
2847 | 2865 |
2848 StringAddStub string_add_right_stub(NO_STRING_CHECK_RIGHT_IN_STUB); | 2866 StringAddStub string_add_right_stub((StringAddFlags) |
| 2867 (ERECT_FRAME | NO_STRING_CHECK_RIGHT_IN_STUB)); |
2849 GenerateRegisterArgsPush(masm); | 2868 GenerateRegisterArgsPush(masm); |
2850 __ TailCallStub(&string_add_right_stub); | 2869 __ TailCallStub(&string_add_right_stub); |
2851 | 2870 |
2852 // At least one argument is not a string. | 2871 // At least one argument is not a string. |
2853 __ bind(&call_runtime); | 2872 __ bind(&call_runtime); |
2854 } | 2873 } |
2855 | 2874 |
2856 | 2875 |
2857 void BinaryOpStub_GenerateHeapResultAllocation(MacroAssembler* masm, | 2876 void BinaryOpStub_GenerateHeapResultAllocation(MacroAssembler* masm, |
2858 Register result, | 2877 Register result, |
(...skipping 3315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6174 | 6193 |
6175 // Stack on entry: | 6194 // Stack on entry: |
6176 // sp[0]: second argument (right). | 6195 // sp[0]: second argument (right). |
6177 // sp[4]: first argument (left). | 6196 // sp[4]: first argument (left). |
6178 | 6197 |
6179 // Load the two arguments. | 6198 // Load the two arguments. |
6180 __ lw(a0, MemOperand(sp, 1 * kPointerSize)); // First argument. | 6199 __ lw(a0, MemOperand(sp, 1 * kPointerSize)); // First argument. |
6181 __ lw(a1, MemOperand(sp, 0 * kPointerSize)); // Second argument. | 6200 __ lw(a1, MemOperand(sp, 0 * kPointerSize)); // Second argument. |
6182 | 6201 |
6183 // Make sure that both arguments are strings if not known in advance. | 6202 // Make sure that both arguments are strings if not known in advance. |
6184 if (flags_ == NO_STRING_ADD_FLAGS) { | 6203 if ((flags_ & NO_STRING_ADD_FLAGS) != 0) { |
6185 __ JumpIfEitherSmi(a0, a1, &call_runtime); | 6204 __ JumpIfEitherSmi(a0, a1, &call_runtime); |
6186 // Load instance types. | 6205 // Load instance types. |
6187 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset)); | 6206 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset)); |
6188 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset)); | 6207 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset)); |
6189 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset)); | 6208 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset)); |
6190 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset)); | 6209 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset)); |
6191 STATIC_ASSERT(kStringTag == 0); | 6210 STATIC_ASSERT(kStringTag == 0); |
6192 // If either is not a string, go to runtime. | 6211 // If either is not a string, go to runtime. |
6193 __ Or(t4, t0, Operand(t1)); | 6212 __ Or(t4, t0, Operand(t1)); |
6194 __ And(t4, t4, Operand(kIsNotStringMask)); | 6213 __ And(t4, t4, Operand(kIsNotStringMask)); |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6463 // t2: first character of result. | 6482 // t2: first character of result. |
6464 StringHelper::GenerateCopyCharacters(masm, t2, t3, a2, t0, false); | 6483 StringHelper::GenerateCopyCharacters(masm, t2, t3, a2, t0, false); |
6465 // t2: next character of result. | 6484 // t2: next character of result. |
6466 StringHelper::GenerateCopyCharacters(masm, t2, a1, a3, t0, false); | 6485 StringHelper::GenerateCopyCharacters(masm, t2, a1, a3, t0, false); |
6467 | 6486 |
6468 __ IncrementCounter(counters->string_add_native(), 1, a2, a3); | 6487 __ IncrementCounter(counters->string_add_native(), 1, a2, a3); |
6469 __ DropAndRet(2); | 6488 __ DropAndRet(2); |
6470 | 6489 |
6471 // Just jump to runtime to add the two strings. | 6490 // Just jump to runtime to add the two strings. |
6472 __ bind(&call_runtime); | 6491 __ bind(&call_runtime); |
6473 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 6492 if ((flags_ & ERECT_FRAME) != 0) { |
| 6493 GenerateRegisterArgsPop(masm); |
| 6494 // Build a frame. |
| 6495 { |
| 6496 FrameScope scope(masm, StackFrame::INTERNAL); |
| 6497 GenerateRegisterArgsPush(masm); |
| 6498 __ CallRuntime(Runtime::kStringAdd, 2); |
| 6499 } |
| 6500 __ Ret(); |
| 6501 } else { |
| 6502 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
| 6503 } |
6474 | 6504 |
6475 if (call_builtin.is_linked()) { | 6505 if (call_builtin.is_linked()) { |
6476 __ bind(&call_builtin); | 6506 __ bind(&call_builtin); |
6477 __ InvokeBuiltin(builtin_id, JUMP_FUNCTION); | 6507 if ((flags_ & ERECT_FRAME) != 0) { |
| 6508 GenerateRegisterArgsPop(masm); |
| 6509 // Build a frame. |
| 6510 { |
| 6511 FrameScope scope(masm, StackFrame::INTERNAL); |
| 6512 GenerateRegisterArgsPush(masm); |
| 6513 __ InvokeBuiltin(builtin_id, CALL_FUNCTION); |
| 6514 } |
| 6515 __ Ret(); |
| 6516 } else { |
| 6517 __ InvokeBuiltin(builtin_id, JUMP_FUNCTION); |
| 6518 } |
6478 } | 6519 } |
6479 } | 6520 } |
6480 | 6521 |
6481 | 6522 |
| 6523 void StringAddStub::GenerateRegisterArgsPush(MacroAssembler* masm) { |
| 6524 __ push(a0); |
| 6525 __ push(a1); |
| 6526 } |
| 6527 |
| 6528 |
| 6529 void StringAddStub::GenerateRegisterArgsPop(MacroAssembler* masm) { |
| 6530 __ pop(a1); |
| 6531 __ pop(a0); |
| 6532 } |
| 6533 |
| 6534 |
6482 void StringAddStub::GenerateConvertArgument(MacroAssembler* masm, | 6535 void StringAddStub::GenerateConvertArgument(MacroAssembler* masm, |
6483 int stack_offset, | 6536 int stack_offset, |
6484 Register arg, | 6537 Register arg, |
6485 Register scratch1, | 6538 Register scratch1, |
6486 Register scratch2, | 6539 Register scratch2, |
6487 Register scratch3, | 6540 Register scratch3, |
6488 Register scratch4, | 6541 Register scratch4, |
6489 Label* slow) { | 6542 Label* slow) { |
6490 // First check if the argument is already a string. | 6543 // First check if the argument is already a string. |
6491 Label not_string, done; | 6544 Label not_string, done; |
(...skipping 1303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7795 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); | 7848 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); |
7796 } | 7849 } |
7797 } | 7850 } |
7798 | 7851 |
7799 | 7852 |
7800 #undef __ | 7853 #undef __ |
7801 | 7854 |
7802 } } // namespace v8::internal | 7855 } } // namespace v8::internal |
7803 | 7856 |
7804 #endif // V8_TARGET_ARCH_MIPS | 7857 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |