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

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

Issue 11308134: MIPS: ARM: Fast path for integer inputs to EmitVFPTruncate (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased on r13080 Created 8 years 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 | Annotate | Revision Log
« no previous file with comments | « src/mips/code-stubs-mips.h ('k') | src/mips/lithium-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 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 798 matching lines...) Expand 10 before | Expand all | Expand 10 after
809 __ mov(dst1, zero_reg); 809 __ mov(dst1, zero_reg);
810 } 810 }
811 __ bind(&done); 811 __ bind(&done);
812 } 812 }
813 813
814 814
815 void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, 815 void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm,
816 Register object, 816 Register object,
817 Destination destination, 817 Destination destination,
818 DoubleRegister double_dst, 818 DoubleRegister double_dst,
819 DoubleRegister double_scratch,
819 Register dst1, 820 Register dst1,
820 Register dst2, 821 Register dst2,
821 Register heap_number_map, 822 Register heap_number_map,
822 Register scratch1, 823 Register scratch1,
823 Register scratch2, 824 Register scratch2,
824 FPURegister single_scratch, 825 FPURegister single_scratch,
825 Label* not_int32) { 826 Label* not_int32) {
826 ASSERT(!scratch1.is(object) && !scratch2.is(object)); 827 ASSERT(!scratch1.is(object) && !scratch2.is(object));
827 ASSERT(!scratch1.is(scratch2)); 828 ASSERT(!scratch1.is(scratch2));
828 ASSERT(!heap_number_map.is(object) && 829 ASSERT(!heap_number_map.is(object) &&
(...skipping 15 matching lines...) Expand all
844 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32); 845 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32);
845 846
846 // Load the number. 847 // Load the number.
847 if (CpuFeatures::IsSupported(FPU)) { 848 if (CpuFeatures::IsSupported(FPU)) {
848 CpuFeatures::Scope scope(FPU); 849 CpuFeatures::Scope scope(FPU);
849 // Load the double value. 850 // Load the double value.
850 __ ldc1(double_dst, FieldMemOperand(object, HeapNumber::kValueOffset)); 851 __ ldc1(double_dst, FieldMemOperand(object, HeapNumber::kValueOffset));
851 852
852 Register except_flag = scratch2; 853 Register except_flag = scratch2;
853 __ EmitFPUTruncate(kRoundToZero, 854 __ EmitFPUTruncate(kRoundToZero,
854 single_scratch, 855 scratch1,
855 double_dst, 856 double_dst,
856 scratch1, 857 at,
858 double_scratch,
857 except_flag, 859 except_flag,
858 kCheckForInexactConversion); 860 kCheckForInexactConversion);
859 861
860 // Jump to not_int32 if the operation did not succeed. 862 // Jump to not_int32 if the operation did not succeed.
861 __ Branch(not_int32, ne, except_flag, Operand(zero_reg)); 863 __ Branch(not_int32, ne, except_flag, Operand(zero_reg));
862 864
863 if (destination == kCoreRegisters) { 865 if (destination == kCoreRegisters) {
864 __ Move(dst1, dst2, double_dst); 866 __ Move(dst1, dst2, double_dst);
865 } 867 }
866 868
(...skipping 21 matching lines...) Expand all
888 } 890 }
889 891
890 892
891 void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm, 893 void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm,
892 Register object, 894 Register object,
893 Register dst, 895 Register dst,
894 Register heap_number_map, 896 Register heap_number_map,
895 Register scratch1, 897 Register scratch1,
896 Register scratch2, 898 Register scratch2,
897 Register scratch3, 899 Register scratch3,
898 DoubleRegister double_scratch, 900 DoubleRegister double_scratch0,
901 DoubleRegister double_scratch1,
899 Label* not_int32) { 902 Label* not_int32) {
900 ASSERT(!dst.is(object)); 903 ASSERT(!dst.is(object));
901 ASSERT(!scratch1.is(object) && !scratch2.is(object) && !scratch3.is(object)); 904 ASSERT(!scratch1.is(object) && !scratch2.is(object) && !scratch3.is(object));
902 ASSERT(!scratch1.is(scratch2) && 905 ASSERT(!scratch1.is(scratch2) &&
903 !scratch1.is(scratch3) && 906 !scratch1.is(scratch3) &&
904 !scratch2.is(scratch3)); 907 !scratch2.is(scratch3));
905 908
906 Label done, maybe_undefined; 909 Label done, maybe_undefined;
907 910
908 __ UntagAndJumpIfSmi(dst, object, &done); 911 __ UntagAndJumpIfSmi(dst, object, &done);
909 912
910 __ AssertRootValue(heap_number_map, 913 __ AssertRootValue(heap_number_map,
911 Heap::kHeapNumberMapRootIndex, 914 Heap::kHeapNumberMapRootIndex,
912 "HeapNumberMap register clobbered."); 915 "HeapNumberMap register clobbered.");
913 916
914 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, &maybe_undefined); 917 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, &maybe_undefined);
915 918
916 // Object is a heap number. 919 // Object is a heap number.
917 // Convert the floating point value to a 32-bit integer. 920 // Convert the floating point value to a 32-bit integer.
918 if (CpuFeatures::IsSupported(FPU)) { 921 if (CpuFeatures::IsSupported(FPU)) {
919 CpuFeatures::Scope scope(FPU); 922 CpuFeatures::Scope scope(FPU);
920 // Load the double value. 923 // Load the double value.
921 __ ldc1(double_scratch, FieldMemOperand(object, HeapNumber::kValueOffset)); 924 __ ldc1(double_scratch0, FieldMemOperand(object, HeapNumber::kValueOffset));
922 925
923 FPURegister single_scratch = double_scratch.low();
924 Register except_flag = scratch2; 926 Register except_flag = scratch2;
925 __ EmitFPUTruncate(kRoundToZero, 927 __ EmitFPUTruncate(kRoundToZero,
926 single_scratch, 928 dst,
927 double_scratch, 929 double_scratch0,
928 scratch1, 930 scratch1,
931 double_scratch1,
929 except_flag, 932 except_flag,
930 kCheckForInexactConversion); 933 kCheckForInexactConversion);
931 934
932 // Jump to not_int32 if the operation did not succeed. 935 // Jump to not_int32 if the operation did not succeed.
933 __ Branch(not_int32, ne, except_flag, Operand(zero_reg)); 936 __ Branch(not_int32, ne, except_flag, Operand(zero_reg));
934 // Get the result in the destination register.
935 __ mfc1(dst, single_scratch);
936
937 } else { 937 } else {
938 // Load the double value in the destination registers. 938 // Load the double value in the destination registers.
939 __ lw(scratch2, FieldMemOperand(object, HeapNumber::kExponentOffset)); 939 __ lw(scratch2, FieldMemOperand(object, HeapNumber::kExponentOffset));
940 __ lw(scratch1, FieldMemOperand(object, HeapNumber::kMantissaOffset)); 940 __ lw(scratch1, FieldMemOperand(object, HeapNumber::kMantissaOffset));
941 941
942 // Check for 0 and -0. 942 // Check for 0 and -0.
943 __ And(dst, scratch1, Operand(~HeapNumber::kSignMask)); 943 __ And(dst, scratch1, Operand(~HeapNumber::kSignMask));
944 __ Or(dst, scratch2, Operand(dst)); 944 __ Or(dst, scratch2, Operand(dst));
945 __ Branch(&done, eq, dst, Operand(zero_reg)); 945 __ Branch(&done, eq, dst, Operand(zero_reg));
946 946
(...skipping 2001 matching lines...) Expand 10 before | Expand all | Expand 10 after
2948 // and left) are preserved for the runtime call. 2948 // and left) are preserved for the runtime call.
2949 FloatingPointHelper::Destination destination = 2949 FloatingPointHelper::Destination destination =
2950 (CpuFeatures::IsSupported(FPU) && op_ != Token::MOD) 2950 (CpuFeatures::IsSupported(FPU) && op_ != Token::MOD)
2951 ? FloatingPointHelper::kFPURegisters 2951 ? FloatingPointHelper::kFPURegisters
2952 : FloatingPointHelper::kCoreRegisters; 2952 : FloatingPointHelper::kCoreRegisters;
2953 2953
2954 FloatingPointHelper::LoadNumberAsInt32Double(masm, 2954 FloatingPointHelper::LoadNumberAsInt32Double(masm,
2955 right, 2955 right,
2956 destination, 2956 destination,
2957 f14, 2957 f14,
2958 f16,
2958 a2, 2959 a2,
2959 a3, 2960 a3,
2960 heap_number_map, 2961 heap_number_map,
2961 scratch1, 2962 scratch1,
2962 scratch2, 2963 scratch2,
2963 f2, 2964 f2,
2964 &transition); 2965 &transition);
2965 FloatingPointHelper::LoadNumberAsInt32Double(masm, 2966 FloatingPointHelper::LoadNumberAsInt32Double(masm,
2966 left, 2967 left,
2967 destination, 2968 destination,
2968 f12, 2969 f12,
2970 f16,
2969 t0, 2971 t0,
2970 t1, 2972 t1,
2971 heap_number_map, 2973 heap_number_map,
2972 scratch1, 2974 scratch1,
2973 scratch2, 2975 scratch2,
2974 f2, 2976 f2,
2975 &transition); 2977 &transition);
2976 2978
2977 if (destination == FloatingPointHelper::kFPURegisters) { 2979 if (destination == FloatingPointHelper::kFPURegisters) {
2978 CpuFeatures::Scope scope(FPU); 2980 CpuFeatures::Scope scope(FPU);
(...skipping 16 matching lines...) Expand all
2995 } 2997 }
2996 2998
2997 if (op_ != Token::DIV) { 2999 if (op_ != Token::DIV) {
2998 // These operations produce an integer result. 3000 // These operations produce an integer result.
2999 // Try to return a smi if we can. 3001 // Try to return a smi if we can.
3000 // Otherwise return a heap number if allowed, or jump to type 3002 // Otherwise return a heap number if allowed, or jump to type
3001 // transition. 3003 // transition.
3002 3004
3003 Register except_flag = scratch2; 3005 Register except_flag = scratch2;
3004 __ EmitFPUTruncate(kRoundToZero, 3006 __ EmitFPUTruncate(kRoundToZero,
3005 single_scratch, 3007 scratch1,
3006 f10, 3008 f10,
3007 scratch1, 3009 at,
3010 f16,
3008 except_flag); 3011 except_flag);
3009 3012
3010 if (result_type_ <= BinaryOpIC::INT32) { 3013 if (result_type_ <= BinaryOpIC::INT32) {
3011 // If except_flag != 0, result does not fit in a 32-bit integer. 3014 // If except_flag != 0, result does not fit in a 32-bit integer.
3012 __ Branch(&transition, ne, except_flag, Operand(zero_reg)); 3015 __ Branch(&transition, ne, except_flag, Operand(zero_reg));
3013 } 3016 }
3014 3017
3015 // Check if the result fits in a smi. 3018 // Check if the result fits in a smi.
3016 __ mfc1(scratch1, single_scratch);
3017 __ Addu(scratch2, scratch1, Operand(0x40000000)); 3019 __ Addu(scratch2, scratch1, Operand(0x40000000));
3018 // If not try to return a heap number. 3020 // If not try to return a heap number.
3019 __ Branch(&return_heap_number, lt, scratch2, Operand(zero_reg)); 3021 __ Branch(&return_heap_number, lt, scratch2, Operand(zero_reg));
3020 // Check for minus zero. Return heap number for minus zero. 3022 // Check for minus zero. Return heap number for minus zero.
3021 Label not_zero; 3023 Label not_zero;
3022 __ Branch(&not_zero, ne, scratch1, Operand(zero_reg)); 3024 __ Branch(&not_zero, ne, scratch1, Operand(zero_reg));
3023 __ mfc1(scratch2, f11); 3025 __ mfc1(scratch2, f11);
3024 __ And(scratch2, scratch2, HeapNumber::kSignMask); 3026 __ And(scratch2, scratch2, HeapNumber::kSignMask);
3025 __ Branch(&return_heap_number, ne, scratch2, Operand(zero_reg)); 3027 __ Branch(&return_heap_number, ne, scratch2, Operand(zero_reg));
3026 __ bind(&not_zero); 3028 __ bind(&not_zero);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
3101 // registers a0 and a1 (right and left) are preserved for the runtime 3103 // registers a0 and a1 (right and left) are preserved for the runtime
3102 // call. 3104 // call.
3103 FloatingPointHelper::LoadNumberAsInt32(masm, 3105 FloatingPointHelper::LoadNumberAsInt32(masm,
3104 left, 3106 left,
3105 a3, 3107 a3,
3106 heap_number_map, 3108 heap_number_map,
3107 scratch1, 3109 scratch1,
3108 scratch2, 3110 scratch2,
3109 scratch3, 3111 scratch3,
3110 f0, 3112 f0,
3113 f2,
3111 &transition); 3114 &transition);
3112 FloatingPointHelper::LoadNumberAsInt32(masm, 3115 FloatingPointHelper::LoadNumberAsInt32(masm,
3113 right, 3116 right,
3114 a2, 3117 a2,
3115 heap_number_map, 3118 heap_number_map,
3116 scratch1, 3119 scratch1,
3117 scratch2, 3120 scratch2,
3118 scratch3, 3121 scratch3,
3119 f0, 3122 f0,
3123 f2,
3120 &transition); 3124 &transition);
3121 3125
3122 // The ECMA-262 standard specifies that, for shift operations, only the 3126 // The ECMA-262 standard specifies that, for shift operations, only the
3123 // 5 least significant bits of the shift value should be used. 3127 // 5 least significant bits of the shift value should be used.
3124 switch (op_) { 3128 switch (op_) {
3125 case Token::BIT_OR: 3129 case Token::BIT_OR:
3126 __ Or(a2, a3, Operand(a2)); 3130 __ Or(a2, a3, Operand(a2));
3127 break; 3131 break;
3128 case Token::BIT_XOR: 3132 case Token::BIT_XOR:
3129 __ Xor(a2, a3, Operand(a2)); 3133 __ Xor(a2, a3, Operand(a2));
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
3676 __ UntagAndJumpIfSmi(scratch, exponent, &int_exponent); 3680 __ UntagAndJumpIfSmi(scratch, exponent, &int_exponent);
3677 3681
3678 __ ldc1(double_exponent, 3682 __ ldc1(double_exponent,
3679 FieldMemOperand(exponent, HeapNumber::kValueOffset)); 3683 FieldMemOperand(exponent, HeapNumber::kValueOffset));
3680 } 3684 }
3681 3685
3682 if (exponent_type_ != INTEGER) { 3686 if (exponent_type_ != INTEGER) {
3683 Label int_exponent_convert; 3687 Label int_exponent_convert;
3684 // Detect integer exponents stored as double. 3688 // Detect integer exponents stored as double.
3685 __ EmitFPUTruncate(kRoundToMinusInf, 3689 __ EmitFPUTruncate(kRoundToMinusInf,
3686 single_scratch, 3690 scratch,
3687 double_exponent, 3691 double_exponent,
3688 scratch, 3692 at,
3693 double_scratch,
3689 scratch2, 3694 scratch2,
3690 kCheckForInexactConversion); 3695 kCheckForInexactConversion);
3691 // scratch2 == 0 means there was no conversion error. 3696 // scratch2 == 0 means there was no conversion error.
3692 __ Branch(&int_exponent_convert, eq, scratch2, Operand(zero_reg)); 3697 __ Branch(&int_exponent_convert, eq, scratch2, Operand(zero_reg));
3693 3698
3694 if (exponent_type_ == ON_STACK) { 3699 if (exponent_type_ == ON_STACK) {
3695 // Detect square root case. Crankshaft detects constant +/-0.5 at 3700 // Detect square root case. Crankshaft detects constant +/-0.5 at
3696 // compile time and uses DoMathPowHalf instead. We then skip this check 3701 // compile time and uses DoMathPowHalf instead. We then skip this check
3697 // for non-constant cases of +/-0.5 as these hardly occur. 3702 // for non-constant cases of +/-0.5 as these hardly occur.
3698 Label not_plus_half; 3703 Label not_plus_half;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
3736 __ add_d(double_scratch, double_base, kDoubleRegZero); 3741 __ add_d(double_scratch, double_base, kDoubleRegZero);
3737 __ Move(double_result, 1); 3742 __ Move(double_result, 1);
3738 __ sqrt_d(double_scratch, double_scratch); 3743 __ sqrt_d(double_scratch, double_scratch);
3739 __ div_d(double_result, double_result, double_scratch); 3744 __ div_d(double_result, double_result, double_scratch);
3740 __ jmp(&done); 3745 __ jmp(&done);
3741 } 3746 }
3742 3747
3743 __ push(ra); 3748 __ push(ra);
3744 { 3749 {
3745 AllowExternalCallThatCantCauseGC scope(masm); 3750 AllowExternalCallThatCantCauseGC scope(masm);
3746 __ PrepareCallCFunction(0, 2, scratch); 3751 __ PrepareCallCFunction(0, 2, scratch2);
3747 __ SetCallCDoubleArguments(double_base, double_exponent); 3752 __ SetCallCDoubleArguments(double_base, double_exponent);
3748 __ CallCFunction( 3753 __ CallCFunction(
3749 ExternalReference::power_double_double_function(masm->isolate()), 3754 ExternalReference::power_double_double_function(masm->isolate()),
3750 0, 2); 3755 0, 2);
3751 } 3756 }
3752 __ pop(ra); 3757 __ pop(ra);
3753 __ GetCFunctionDoubleResult(double_result); 3758 __ GetCFunctionDoubleResult(double_result);
3754 __ jmp(&done); 3759 __ jmp(&done);
3755 3760
3756 __ bind(&int_exponent_convert); 3761 __ bind(&int_exponent_convert);
3757 __ mfc1(scratch, single_scratch);
3758 } 3762 }
3759 3763
3760 // Calculate power with integer exponent. 3764 // Calculate power with integer exponent.
3761 __ bind(&int_exponent); 3765 __ bind(&int_exponent);
3762 3766
3763 // Get two copies of exponent in the registers scratch and exponent. 3767 // Get two copies of exponent in the registers scratch and exponent.
3764 if (exponent_type_ == INTEGER) { 3768 if (exponent_type_ == INTEGER) {
3765 __ mov(scratch, exponent); 3769 __ mov(scratch, exponent);
3766 } else { 3770 } else {
3767 // Exponent has previously been stored into scratch as untagged integer. 3771 // Exponent has previously been stored into scratch as untagged integer.
(...skipping 4016 matching lines...) Expand 10 before | Expand all | Expand 10 after
7784 __ Pop(ra, t1, a1); 7788 __ Pop(ra, t1, a1);
7785 __ Ret(); 7789 __ Ret();
7786 } 7790 }
7787 7791
7788 7792
7789 #undef __ 7793 #undef __
7790 7794
7791 } } // namespace v8::internal 7795 } } // namespace v8::internal
7792 7796
7793 #endif // V8_TARGET_ARCH_MIPS 7797 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/code-stubs-mips.h ('k') | src/mips/lithium-codegen-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698