| OLD | NEW |
| 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 2737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2748 __ bind(&done); | 2748 __ bind(&done); |
| 2749 } | 2749 } |
| 2750 | 2750 |
| 2751 | 2751 |
| 2752 void FloatingPointHelper::CheckFloatOperandsAreInt32(MacroAssembler* masm, | 2752 void FloatingPointHelper::CheckFloatOperandsAreInt32(MacroAssembler* masm, |
| 2753 Label* non_int32) { | 2753 Label* non_int32) { |
| 2754 return; | 2754 return; |
| 2755 } | 2755 } |
| 2756 | 2756 |
| 2757 | 2757 |
| 2758 void GenericUnaryOpStub::Generate(MacroAssembler* masm) { | |
| 2759 Label slow, done, undo; | |
| 2760 | |
| 2761 if (op_ == Token::SUB) { | |
| 2762 if (include_smi_code_) { | |
| 2763 // Check whether the value is a smi. | |
| 2764 NearLabel try_float; | |
| 2765 __ test(eax, Immediate(kSmiTagMask)); | |
| 2766 __ j(not_zero, &try_float, not_taken); | |
| 2767 | |
| 2768 if (negative_zero_ == kStrictNegativeZero) { | |
| 2769 // Go slow case if the value of the expression is zero | |
| 2770 // to make sure that we switch between 0 and -0. | |
| 2771 __ test(eax, Operand(eax)); | |
| 2772 __ j(zero, &slow, not_taken); | |
| 2773 } | |
| 2774 | |
| 2775 // The value of the expression is a smi that is not zero. Try | |
| 2776 // optimistic subtraction '0 - value'. | |
| 2777 __ mov(edx, Operand(eax)); | |
| 2778 __ Set(eax, Immediate(0)); | |
| 2779 __ sub(eax, Operand(edx)); | |
| 2780 __ j(overflow, &undo, not_taken); | |
| 2781 __ StubReturn(1); | |
| 2782 | |
| 2783 // Try floating point case. | |
| 2784 __ bind(&try_float); | |
| 2785 } else if (FLAG_debug_code) { | |
| 2786 __ AbortIfSmi(eax); | |
| 2787 } | |
| 2788 | |
| 2789 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); | |
| 2790 __ cmp(edx, masm->isolate()->factory()->heap_number_map()); | |
| 2791 __ j(not_equal, &slow); | |
| 2792 if (overwrite_ == UNARY_OVERWRITE) { | |
| 2793 __ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset)); | |
| 2794 __ xor_(edx, HeapNumber::kSignMask); // Flip sign. | |
| 2795 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), edx); | |
| 2796 } else { | |
| 2797 __ mov(edx, Operand(eax)); | |
| 2798 // edx: operand | |
| 2799 __ AllocateHeapNumber(eax, ebx, ecx, &undo); | |
| 2800 // eax: allocated 'empty' number | |
| 2801 __ mov(ecx, FieldOperand(edx, HeapNumber::kExponentOffset)); | |
| 2802 __ xor_(ecx, HeapNumber::kSignMask); // Flip sign. | |
| 2803 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ecx); | |
| 2804 __ mov(ecx, FieldOperand(edx, HeapNumber::kMantissaOffset)); | |
| 2805 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx); | |
| 2806 } | |
| 2807 } else if (op_ == Token::BIT_NOT) { | |
| 2808 if (include_smi_code_) { | |
| 2809 Label non_smi; | |
| 2810 __ test(eax, Immediate(kSmiTagMask)); | |
| 2811 __ j(not_zero, &non_smi); | |
| 2812 __ not_(eax); | |
| 2813 __ and_(eax, ~kSmiTagMask); // Remove inverted smi-tag. | |
| 2814 __ ret(0); | |
| 2815 __ bind(&non_smi); | |
| 2816 } else if (FLAG_debug_code) { | |
| 2817 __ AbortIfSmi(eax); | |
| 2818 } | |
| 2819 | |
| 2820 // Check if the operand is a heap number. | |
| 2821 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); | |
| 2822 __ cmp(edx, masm->isolate()->factory()->heap_number_map()); | |
| 2823 __ j(not_equal, &slow, not_taken); | |
| 2824 | |
| 2825 // Convert the heap number in eax to an untagged integer in ecx. | |
| 2826 IntegerConvert(masm, | |
| 2827 eax, | |
| 2828 TypeInfo::Unknown(), | |
| 2829 CpuFeatures::IsSupported(SSE3), | |
| 2830 &slow); | |
| 2831 | |
| 2832 // Do the bitwise operation and check if the result fits in a smi. | |
| 2833 NearLabel try_float; | |
| 2834 __ not_(ecx); | |
| 2835 __ cmp(ecx, 0xc0000000); | |
| 2836 __ j(sign, &try_float, not_taken); | |
| 2837 | |
| 2838 // Tag the result as a smi and we're done. | |
| 2839 STATIC_ASSERT(kSmiTagSize == 1); | |
| 2840 __ lea(eax, Operand(ecx, times_2, kSmiTag)); | |
| 2841 __ jmp(&done); | |
| 2842 | |
| 2843 // Try to store the result in a heap number. | |
| 2844 __ bind(&try_float); | |
| 2845 if (overwrite_ == UNARY_NO_OVERWRITE) { | |
| 2846 // Allocate a fresh heap number, but don't overwrite eax until | |
| 2847 // we're sure we can do it without going through the slow case | |
| 2848 // that needs the value in eax. | |
| 2849 __ AllocateHeapNumber(ebx, edx, edi, &slow); | |
| 2850 __ mov(eax, Operand(ebx)); | |
| 2851 } | |
| 2852 if (CpuFeatures::IsSupported(SSE2)) { | |
| 2853 CpuFeatures::Scope use_sse2(SSE2); | |
| 2854 __ cvtsi2sd(xmm0, Operand(ecx)); | |
| 2855 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); | |
| 2856 } else { | |
| 2857 __ push(ecx); | |
| 2858 __ fild_s(Operand(esp, 0)); | |
| 2859 __ pop(ecx); | |
| 2860 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); | |
| 2861 } | |
| 2862 } else { | |
| 2863 UNIMPLEMENTED(); | |
| 2864 } | |
| 2865 | |
| 2866 // Return from the stub. | |
| 2867 __ bind(&done); | |
| 2868 __ StubReturn(1); | |
| 2869 | |
| 2870 // Restore eax and go slow case. | |
| 2871 __ bind(&undo); | |
| 2872 __ mov(eax, Operand(edx)); | |
| 2873 | |
| 2874 // Handle the slow case by jumping to the JavaScript builtin. | |
| 2875 __ bind(&slow); | |
| 2876 __ pop(ecx); // pop return address. | |
| 2877 __ push(eax); | |
| 2878 __ push(ecx); // push return address | |
| 2879 switch (op_) { | |
| 2880 case Token::SUB: | |
| 2881 __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_FUNCTION); | |
| 2882 break; | |
| 2883 case Token::BIT_NOT: | |
| 2884 __ InvokeBuiltin(Builtins::BIT_NOT, JUMP_FUNCTION); | |
| 2885 break; | |
| 2886 default: | |
| 2887 UNREACHABLE(); | |
| 2888 } | |
| 2889 } | |
| 2890 | |
| 2891 | |
| 2892 void MathPowStub::Generate(MacroAssembler* masm) { | 2758 void MathPowStub::Generate(MacroAssembler* masm) { |
| 2893 // Registers are used as follows: | 2759 // Registers are used as follows: |
| 2894 // edx = base | 2760 // edx = base |
| 2895 // eax = exponent | 2761 // eax = exponent |
| 2896 // ecx = temporary, result | 2762 // ecx = temporary, result |
| 2897 | 2763 |
| 2898 CpuFeatures::Scope use_sse2(SSE2); | 2764 CpuFeatures::Scope use_sse2(SSE2); |
| 2899 Label allocate_return, call_runtime; | 2765 Label allocate_return, call_runtime; |
| 2900 | 2766 |
| 2901 // Load input parameters. | 2767 // Load input parameters. |
| (...skipping 3090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5992 // Do a tail call to the rewritten stub. | 5858 // Do a tail call to the rewritten stub. |
| 5993 __ jmp(Operand(edi)); | 5859 __ jmp(Operand(edi)); |
| 5994 } | 5860 } |
| 5995 | 5861 |
| 5996 | 5862 |
| 5997 #undef __ | 5863 #undef __ |
| 5998 | 5864 |
| 5999 } } // namespace v8::internal | 5865 } } // namespace v8::internal |
| 6000 | 5866 |
| 6001 #endif // V8_TARGET_ARCH_IA32 | 5867 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |