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

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

Issue 11049025: ARM: Fast path for integer inputs to EmitVFPTruncate (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 8 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « src/arm/code-stubs-arm.h ('k') | src/arm/lithium-arm.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 808 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 __ mov(dst1, Operand::Zero()); 819 __ mov(dst1, Operand::Zero());
820 } 820 }
821 __ bind(&done); 821 __ bind(&done);
822 } 822 }
823 823
824 824
825 void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, 825 void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm,
826 Register object, 826 Register object,
827 Destination destination, 827 Destination destination,
828 DwVfpRegister double_dst, 828 DwVfpRegister double_dst,
829 DwVfpRegister double_scratch,
829 Register dst1, 830 Register dst1,
830 Register dst2, 831 Register dst2,
831 Register heap_number_map, 832 Register heap_number_map,
832 Register scratch1, 833 Register scratch1,
833 Register scratch2, 834 Register scratch2,
834 SwVfpRegister single_scratch, 835 SwVfpRegister single_scratch,
835 Label* not_int32) { 836 Label* not_int32) {
836 ASSERT(!scratch1.is(object) && !scratch2.is(object)); 837 ASSERT(!scratch1.is(object) && !scratch2.is(object));
837 ASSERT(!scratch1.is(scratch2)); 838 ASSERT(!scratch1.is(scratch2));
838 ASSERT(!heap_number_map.is(object) && 839 ASSERT(!heap_number_map.is(object) &&
(...skipping 17 matching lines...) Expand all
856 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32); 857 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32);
857 858
858 // Load the number. 859 // Load the number.
859 if (CpuFeatures::IsSupported(VFP2)) { 860 if (CpuFeatures::IsSupported(VFP2)) {
860 CpuFeatures::Scope scope(VFP2); 861 CpuFeatures::Scope scope(VFP2);
861 // Load the double value. 862 // Load the double value.
862 __ sub(scratch1, object, Operand(kHeapObjectTag)); 863 __ sub(scratch1, object, Operand(kHeapObjectTag));
863 __ vldr(double_dst, scratch1, HeapNumber::kValueOffset); 864 __ vldr(double_dst, scratch1, HeapNumber::kValueOffset);
864 865
865 __ EmitVFPTruncate(kRoundToZero, 866 __ EmitVFPTruncate(kRoundToZero,
866 single_scratch, 867 scratch1,
867 double_dst, 868 double_dst,
868 scratch1,
869 scratch2, 869 scratch2,
870 double_scratch,
870 kCheckForInexactConversion); 871 kCheckForInexactConversion);
871 872
872 // Jump to not_int32 if the operation did not succeed. 873 // Jump to not_int32 if the operation did not succeed.
873 __ b(ne, not_int32); 874 __ b(ne, not_int32);
874 875
875 if (destination == kCoreRegisters) { 876 if (destination == kCoreRegisters) {
876 __ vmov(dst1, dst2, double_dst); 877 __ vmov(dst1, dst2, double_dst);
877 } 878 }
878 879
879 } else { 880 } else {
(...skipping 19 matching lines...) Expand all
899 } 900 }
900 901
901 902
902 void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm, 903 void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm,
903 Register object, 904 Register object,
904 Register dst, 905 Register dst,
905 Register heap_number_map, 906 Register heap_number_map,
906 Register scratch1, 907 Register scratch1,
907 Register scratch2, 908 Register scratch2,
908 Register scratch3, 909 Register scratch3,
909 DwVfpRegister double_scratch, 910 DwVfpRegister double_scratch0,
911 DwVfpRegister double_scratch1,
910 Label* not_int32) { 912 Label* not_int32) {
911 ASSERT(!dst.is(object)); 913 ASSERT(!dst.is(object));
912 ASSERT(!scratch1.is(object) && !scratch2.is(object) && !scratch3.is(object)); 914 ASSERT(!scratch1.is(object) && !scratch2.is(object) && !scratch3.is(object));
913 ASSERT(!scratch1.is(scratch2) && 915 ASSERT(!scratch1.is(scratch2) &&
914 !scratch1.is(scratch3) && 916 !scratch1.is(scratch3) &&
915 !scratch2.is(scratch3)); 917 !scratch2.is(scratch3));
916 918
917 Label done; 919 Label done;
918 920
919 __ UntagAndJumpIfSmi(dst, object, &done); 921 __ UntagAndJumpIfSmi(dst, object, &done);
920 922
921 if (FLAG_debug_code) { 923 if (FLAG_debug_code) {
922 __ AbortIfNotRootValue(heap_number_map, 924 __ AbortIfNotRootValue(heap_number_map,
923 Heap::kHeapNumberMapRootIndex, 925 Heap::kHeapNumberMapRootIndex,
924 "HeapNumberMap register clobbered."); 926 "HeapNumberMap register clobbered.");
925 } 927 }
926 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32); 928 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32);
927 929
928 // Object is a heap number. 930 // Object is a heap number.
929 // Convert the floating point value to a 32-bit integer. 931 // Convert the floating point value to a 32-bit integer.
930 if (CpuFeatures::IsSupported(VFP2)) { 932 if (CpuFeatures::IsSupported(VFP2)) {
931 CpuFeatures::Scope scope(VFP2); 933 CpuFeatures::Scope scope(VFP2);
932 SwVfpRegister single_scratch = double_scratch.low(); 934
933 // Load the double value. 935 // Load the double value.
934 __ sub(scratch1, object, Operand(kHeapObjectTag)); 936 __ sub(scratch1, object, Operand(kHeapObjectTag));
935 __ vldr(double_scratch, scratch1, HeapNumber::kValueOffset); 937 __ vldr(double_scratch0, scratch1, HeapNumber::kValueOffset);
936 938
937 __ EmitVFPTruncate(kRoundToZero, 939 __ EmitVFPTruncate(kRoundToZero,
938 single_scratch, 940 dst,
939 double_scratch, 941 double_scratch0,
940 scratch1, 942 scratch1,
941 scratch2, 943 double_scratch1,
942 kCheckForInexactConversion); 944 kCheckForInexactConversion);
943 945
944 // Jump to not_int32 if the operation did not succeed. 946 // Jump to not_int32 if the operation did not succeed.
945 __ b(ne, not_int32); 947 __ b(ne, not_int32);
946 // Get the result in the destination register.
947 __ vmov(dst, single_scratch);
948
949 } else { 948 } else {
950 // Load the double value in the destination registers. 949 // Load the double value in the destination registers.
951 __ ldr(scratch1, FieldMemOperand(object, HeapNumber::kExponentOffset)); 950 __ ldr(scratch1, FieldMemOperand(object, HeapNumber::kExponentOffset));
952 __ ldr(scratch2, FieldMemOperand(object, HeapNumber::kMantissaOffset)); 951 __ ldr(scratch2, FieldMemOperand(object, HeapNumber::kMantissaOffset));
953 952
954 // Check for 0 and -0. 953 // Check for 0 and -0.
955 __ bic(dst, scratch1, Operand(HeapNumber::kSignMask)); 954 __ bic(dst, scratch1, Operand(HeapNumber::kSignMask));
956 __ orr(dst, scratch2, Operand(dst)); 955 __ orr(dst, scratch2, Operand(dst));
957 __ cmp(dst, Operand::Zero()); 956 __ cmp(dst, Operand::Zero());
958 __ b(eq, &done); 957 __ b(eq, &done);
(...skipping 1884 matching lines...) Expand 10 before | Expand all | Expand 10 after
2843 2842
2844 2843
2845 void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { 2844 void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
2846 ASSERT(operands_type_ == BinaryOpIC::INT32); 2845 ASSERT(operands_type_ == BinaryOpIC::INT32);
2847 2846
2848 Register left = r1; 2847 Register left = r1;
2849 Register right = r0; 2848 Register right = r0;
2850 Register scratch1 = r7; 2849 Register scratch1 = r7;
2851 Register scratch2 = r9; 2850 Register scratch2 = r9;
2852 DwVfpRegister double_scratch = d0; 2851 DwVfpRegister double_scratch = d0;
2853 SwVfpRegister single_scratch = s3;
2854 2852
2855 Register heap_number_result = no_reg; 2853 Register heap_number_result = no_reg;
2856 Register heap_number_map = r6; 2854 Register heap_number_map = r6;
2857 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); 2855 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
2858 2856
2859 Label call_runtime; 2857 Label call_runtime;
2860 // Labels for type transition, used for wrong input or output types. 2858 // Labels for type transition, used for wrong input or output types.
2861 // Both label are currently actually bound to the same position. We use two 2859 // Both label are currently actually bound to the same position. We use two
2862 // different label to differentiate the cause leading to type transition. 2860 // different label to differentiate the cause leading to type transition.
2863 Label transition; 2861 Label transition;
(...skipping 17 matching lines...) Expand all
2881 // and left) are preserved for the runtime call. 2879 // and left) are preserved for the runtime call.
2882 FloatingPointHelper::Destination destination = 2880 FloatingPointHelper::Destination destination =
2883 (CpuFeatures::IsSupported(VFP2) && op_ != Token::MOD) 2881 (CpuFeatures::IsSupported(VFP2) && op_ != Token::MOD)
2884 ? FloatingPointHelper::kVFPRegisters 2882 ? FloatingPointHelper::kVFPRegisters
2885 : FloatingPointHelper::kCoreRegisters; 2883 : FloatingPointHelper::kCoreRegisters;
2886 2884
2887 FloatingPointHelper::LoadNumberAsInt32Double(masm, 2885 FloatingPointHelper::LoadNumberAsInt32Double(masm,
2888 right, 2886 right,
2889 destination, 2887 destination,
2890 d7, 2888 d7,
2889 d8,
2891 r2, 2890 r2,
2892 r3, 2891 r3,
2893 heap_number_map, 2892 heap_number_map,
2894 scratch1, 2893 scratch1,
2895 scratch2, 2894 scratch2,
2896 s0, 2895 s0,
2897 &transition); 2896 &transition);
2898 FloatingPointHelper::LoadNumberAsInt32Double(masm, 2897 FloatingPointHelper::LoadNumberAsInt32Double(masm,
2899 left, 2898 left,
2900 destination, 2899 destination,
2901 d6, 2900 d6,
2901 d8,
2902 r4, 2902 r4,
2903 r5, 2903 r5,
2904 heap_number_map, 2904 heap_number_map,
2905 scratch1, 2905 scratch1,
2906 scratch2, 2906 scratch2,
2907 s0, 2907 s0,
2908 &transition); 2908 &transition);
2909 2909
2910 if (destination == FloatingPointHelper::kVFPRegisters) { 2910 if (destination == FloatingPointHelper::kVFPRegisters) {
2911 CpuFeatures::Scope scope(VFP2); 2911 CpuFeatures::Scope scope(VFP2);
(...skipping 15 matching lines...) Expand all
2927 UNREACHABLE(); 2927 UNREACHABLE();
2928 } 2928 }
2929 2929
2930 if (op_ != Token::DIV) { 2930 if (op_ != Token::DIV) {
2931 // These operations produce an integer result. 2931 // These operations produce an integer result.
2932 // Try to return a smi if we can. 2932 // Try to return a smi if we can.
2933 // Otherwise return a heap number if allowed, or jump to type 2933 // Otherwise return a heap number if allowed, or jump to type
2934 // transition. 2934 // transition.
2935 2935
2936 __ EmitVFPTruncate(kRoundToZero, 2936 __ EmitVFPTruncate(kRoundToZero,
2937 single_scratch, 2937 scratch1,
2938 d5, 2938 d5,
2939 scratch1, 2939 scratch2,
2940 scratch2); 2940 d8);
2941 2941
2942 if (result_type_ <= BinaryOpIC::INT32) { 2942 if (result_type_ <= BinaryOpIC::INT32) {
2943 // If the ne condition is set, result does 2943 // If the ne condition is set, result does
2944 // not fit in a 32-bit integer. 2944 // not fit in a 32-bit integer.
2945 __ b(ne, &transition); 2945 __ b(ne, &transition);
2946 } 2946 }
2947 2947
2948 // Check if the result fits in a smi. 2948 // Check if the result fits in a smi.
2949 __ vmov(scratch1, single_scratch);
2950 __ add(scratch2, scratch1, Operand(0x40000000), SetCC); 2949 __ add(scratch2, scratch1, Operand(0x40000000), SetCC);
2951 // If not try to return a heap number. 2950 // If not try to return a heap number.
2952 __ b(mi, &return_heap_number); 2951 __ b(mi, &return_heap_number);
2953 // Check for minus zero. Return heap number for minus zero. 2952 // Check for minus zero. Return heap number for minus zero.
2954 Label not_zero; 2953 Label not_zero;
2955 __ cmp(scratch1, Operand::Zero()); 2954 __ cmp(scratch1, Operand::Zero());
2956 __ b(ne, &not_zero); 2955 __ b(ne, &not_zero);
2957 __ vmov(scratch2, d5.high()); 2956 __ vmov(scratch2, d5.high());
2958 __ tst(scratch2, Operand(HeapNumber::kSignMask)); 2957 __ tst(scratch2, Operand(HeapNumber::kSignMask));
2959 __ b(ne, &return_heap_number); 2958 __ b(ne, &return_heap_number);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
3034 // registers r0 and r1 (right and left) are preserved for the runtime 3033 // registers r0 and r1 (right and left) are preserved for the runtime
3035 // call. 3034 // call.
3036 FloatingPointHelper::LoadNumberAsInt32(masm, 3035 FloatingPointHelper::LoadNumberAsInt32(masm,
3037 left, 3036 left,
3038 r3, 3037 r3,
3039 heap_number_map, 3038 heap_number_map,
3040 scratch1, 3039 scratch1,
3041 scratch2, 3040 scratch2,
3042 scratch3, 3041 scratch3,
3043 d0, 3042 d0,
3043 d1,
3044 &transition); 3044 &transition);
3045 FloatingPointHelper::LoadNumberAsInt32(masm, 3045 FloatingPointHelper::LoadNumberAsInt32(masm,
3046 right, 3046 right,
3047 r2, 3047 r2,
3048 heap_number_map, 3048 heap_number_map,
3049 scratch1, 3049 scratch1,
3050 scratch2, 3050 scratch2,
3051 scratch3, 3051 scratch3,
3052 d0, 3052 d0,
3053 d1,
3053 &transition); 3054 &transition);
3054 3055
3055 // The ECMA-262 standard specifies that, for shift operations, only the 3056 // The ECMA-262 standard specifies that, for shift operations, only the
3056 // 5 least significant bits of the shift value should be used. 3057 // 5 least significant bits of the shift value should be used.
3057 switch (op_) { 3058 switch (op_) {
3058 case Token::BIT_OR: 3059 case Token::BIT_OR:
3059 __ orr(r2, r3, Operand(r2)); 3060 __ orr(r2, r3, Operand(r2));
3060 break; 3061 break;
3061 case Token::BIT_XOR: 3062 case Token::BIT_XOR:
3062 __ eor(r2, r3, Operand(r2)); 3063 __ eor(r2, r3, Operand(r2));
(...skipping 4568 matching lines...) Expand 10 before | Expand all | Expand 10 after
7631 7632
7632 __ Pop(lr, r5, r1); 7633 __ Pop(lr, r5, r1);
7633 __ Ret(); 7634 __ Ret();
7634 } 7635 }
7635 7636
7636 #undef __ 7637 #undef __
7637 7638
7638 } } // namespace v8::internal 7639 } } // namespace v8::internal
7639 7640
7640 #endif // V8_TARGET_ARCH_ARM 7641 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.h ('k') | src/arm/lithium-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698