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

Side by Side Diff: src/ia32/codegen-ia32.cc

Issue 3388005: Make the CompareStub and the UnaryOpStub accept smi inputs.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: x64 and ARM port Created 10 years, 3 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
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 2628 matching lines...) Expand 10 before | Expand all | Expand 10 after
2639 case less_equal: return below_equal; 2639 case less_equal: return below_equal;
2640 case greater: return above; 2640 case greater: return above;
2641 case greater_equal: return above_equal; 2641 case greater_equal: return above_equal;
2642 default: UNREACHABLE(); 2642 default: UNREACHABLE();
2643 } 2643 }
2644 UNREACHABLE(); 2644 UNREACHABLE();
2645 return equal; 2645 return equal;
2646 } 2646 }
2647 2647
2648 2648
2649 static CompareFlags ComputeCompareFlags(NaNInformation nan_info,
2650 bool inline_number_compare) {
2651 CompareFlags flags = NO_SMI_COMPARE_IN_STUB;
2652 if (nan_info == kCantBothBeNaN) {
2653 flags = static_cast<CompareFlags>(flags | CANT_BOTH_BE_NAN);
2654 }
2655 if (inline_number_compare) {
2656 flags = static_cast<CompareFlags>(flags | NO_NUMBER_COMPARE_IN_STUB);
2657 }
2658 return flags;
2659 }
2660
2661
2649 void CodeGenerator::Comparison(AstNode* node, 2662 void CodeGenerator::Comparison(AstNode* node,
2650 Condition cc, 2663 Condition cc,
2651 bool strict, 2664 bool strict,
2652 ControlDestination* dest) { 2665 ControlDestination* dest) {
2653 // Strict only makes sense for equality comparisons. 2666 // Strict only makes sense for equality comparisons.
2654 ASSERT(!strict || cc == equal); 2667 ASSERT(!strict || cc == equal);
2655 2668
2656 Result left_side; 2669 Result left_side;
2657 Result right_side; 2670 Result right_side;
2658 // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order. 2671 // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order.
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
2766 } 2779 }
2767 // Call the compare stub if the left side is not a flat ascii string. 2780 // Call the compare stub if the left side is not a flat ascii string.
2768 __ and_(temp.reg(), 2781 __ and_(temp.reg(),
2769 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask); 2782 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask);
2770 __ cmp(temp.reg(), kStringTag | kSeqStringTag | kAsciiStringTag); 2783 __ cmp(temp.reg(), kStringTag | kSeqStringTag | kAsciiStringTag);
2771 temp.Unuse(); 2784 temp.Unuse();
2772 is_string.Branch(equal, &left_side); 2785 is_string.Branch(equal, &left_side);
2773 2786
2774 // Setup and call the compare stub. 2787 // Setup and call the compare stub.
2775 is_not_string.Bind(&left_side); 2788 is_not_string.Bind(&left_side);
2776 CompareStub stub(cc, strict, kCantBothBeNaN); 2789 CompareFlags flags =
2790 static_cast<CompareFlags>(CANT_BOTH_BE_NAN | NO_SMI_COMPARE_IN_STUB);
2791 CompareStub stub(cc, strict, flags);
2777 Result result = frame_->CallStub(&stub, &left_side, &right_side); 2792 Result result = frame_->CallStub(&stub, &left_side, &right_side);
2778 result.ToRegister(); 2793 result.ToRegister();
2779 __ cmp(result.reg(), 0); 2794 __ cmp(result.reg(), 0);
2780 result.Unuse(); 2795 result.Unuse();
2781 dest->true_target()->Branch(cc); 2796 dest->true_target()->Branch(cc);
2782 dest->false_target()->Jump(); 2797 dest->false_target()->Jump();
2783 2798
2784 is_string.Bind(&left_side); 2799 is_string.Bind(&left_side);
2785 // left_side is a sequential ASCII string. 2800 // left_side is a sequential ASCII string.
2786 left_side = Result(left_reg); 2801 left_side = Result(left_reg);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2860 dest->true_target()->Branch(equal); 2875 dest->true_target()->Branch(equal);
2861 } 2876 }
2862 2877
2863 // Inlined number comparison: 2878 // Inlined number comparison:
2864 if (inline_number_compare) { 2879 if (inline_number_compare) {
2865 GenerateInlineNumberComparison(&left_side, &right_side, cc, dest); 2880 GenerateInlineNumberComparison(&left_side, &right_side, cc, dest);
2866 } 2881 }
2867 2882
2868 // End of in-line compare, call out to the compare stub. Don't include 2883 // End of in-line compare, call out to the compare stub. Don't include
2869 // number comparison in the stub if it was inlined. 2884 // number comparison in the stub if it was inlined.
2870 CompareStub stub(cc, strict, nan_info, !inline_number_compare); 2885 CompareFlags flags = ComputeCompareFlags(nan_info, inline_number_compare);
2886 CompareStub stub(cc, strict, flags);
2871 Result answer = frame_->CallStub(&stub, &left_side, &right_side); 2887 Result answer = frame_->CallStub(&stub, &left_side, &right_side);
2872 __ test(answer.reg(), Operand(answer.reg())); 2888 __ test(answer.reg(), Operand(answer.reg()));
2873 answer.Unuse(); 2889 answer.Unuse();
2874 dest->Split(cc); 2890 dest->Split(cc);
2875 } else { 2891 } else {
2876 // Here we split control flow to the stub call and inlined cases 2892 // Here we split control flow to the stub call and inlined cases
2877 // before finally splitting it to the control destination. We use 2893 // before finally splitting it to the control destination. We use
2878 // a jump target and branching to duplicate the virtual frame at 2894 // a jump target and branching to duplicate the virtual frame at
2879 // the first split. We manually handle the off-frame references 2895 // the first split. We manually handle the off-frame references
2880 // by reconstituting them on the non-fall-through path. 2896 // by reconstituting them on the non-fall-through path.
(...skipping 12 matching lines...) Expand all
2893 dest->true_target()->Branch(equal); 2909 dest->true_target()->Branch(equal);
2894 } 2910 }
2895 2911
2896 // Inlined number comparison: 2912 // Inlined number comparison:
2897 if (inline_number_compare) { 2913 if (inline_number_compare) {
2898 GenerateInlineNumberComparison(&left_side, &right_side, cc, dest); 2914 GenerateInlineNumberComparison(&left_side, &right_side, cc, dest);
2899 } 2915 }
2900 2916
2901 // End of in-line compare, call out to the compare stub. Don't include 2917 // End of in-line compare, call out to the compare stub. Don't include
2902 // number comparison in the stub if it was inlined. 2918 // number comparison in the stub if it was inlined.
2903 CompareStub stub(cc, strict, nan_info, !inline_number_compare); 2919 CompareFlags flags =
2920 ComputeCompareFlags(nan_info, inline_number_compare);
2921 CompareStub stub(cc, strict, flags);
2904 Result answer = frame_->CallStub(&stub, &left_side, &right_side); 2922 Result answer = frame_->CallStub(&stub, &left_side, &right_side);
2905 __ test(answer.reg(), Operand(answer.reg())); 2923 __ test(answer.reg(), Operand(answer.reg()));
2906 answer.Unuse(); 2924 answer.Unuse();
2907 if (is_smi.is_linked()) { 2925 if (is_smi.is_linked()) {
2908 dest->true_target()->Branch(cc); 2926 dest->true_target()->Branch(cc);
2909 dest->false_target()->Jump(); 2927 dest->false_target()->Jump();
2910 } else { 2928 } else {
2911 dest->Split(cc); 2929 dest->Split(cc);
2912 } 2930 }
2913 } 2931 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2987 // Only the case where the left side could possibly be a non-smi is left. 3005 // Only the case where the left side could possibly be a non-smi is left.
2988 JumpTarget is_smi; 3006 JumpTarget is_smi;
2989 if (cc == equal) { 3007 if (cc == equal) {
2990 // We can do the equality comparison before the smi check. 3008 // We can do the equality comparison before the smi check.
2991 __ cmp(Operand(left_reg), Immediate(right_side->handle())); 3009 __ cmp(Operand(left_reg), Immediate(right_side->handle()));
2992 dest->true_target()->Branch(equal); 3010 dest->true_target()->Branch(equal);
2993 __ test(left_reg, Immediate(kSmiTagMask)); 3011 __ test(left_reg, Immediate(kSmiTagMask));
2994 dest->false_target()->Branch(zero); 3012 dest->false_target()->Branch(zero);
2995 } else { 3013 } else {
2996 // Do the smi check, then the comparison. 3014 // Do the smi check, then the comparison.
2997 JumpTarget is_not_smi;
2998 __ test(left_reg, Immediate(kSmiTagMask)); 3015 __ test(left_reg, Immediate(kSmiTagMask));
2999 is_smi.Branch(zero, left_side, right_side); 3016 is_smi.Branch(zero, left_side, right_side);
3000 } 3017 }
3001 3018
3002 // Jump or fall through to here if we are comparing a non-smi to a 3019 // Jump or fall through to here if we are comparing a non-smi to a
3003 // constant smi. If the non-smi is a heap number and this is not 3020 // constant smi. If the non-smi is a heap number and this is not
3004 // a loop condition, inline the floating point code. 3021 // a loop condition, inline the floating point code.
3005 if (!is_loop_condition && CpuFeatures::IsSupported(SSE2)) { 3022 if (!is_loop_condition && CpuFeatures::IsSupported(SSE2)) {
3006 // Right side is a constant smi and left side has been checked 3023 // Right side is a constant smi and left side has been checked
3007 // not to be a smi. 3024 // not to be a smi.
(...skipping 16 matching lines...) Expand all
3024 __ ucomisd(xmm1, xmm0); 3041 __ ucomisd(xmm1, xmm0);
3025 // Jump to builtin for NaN. 3042 // Jump to builtin for NaN.
3026 not_number.Branch(parity_even, left_side); 3043 not_number.Branch(parity_even, left_side);
3027 left_side->Unuse(); 3044 left_side->Unuse();
3028 dest->true_target()->Branch(DoubleCondition(cc)); 3045 dest->true_target()->Branch(DoubleCondition(cc));
3029 dest->false_target()->Jump(); 3046 dest->false_target()->Jump();
3030 not_number.Bind(left_side); 3047 not_number.Bind(left_side);
3031 } 3048 }
3032 3049
3033 // Setup and call the compare stub. 3050 // Setup and call the compare stub.
3034 CompareStub stub(cc, strict, kCantBothBeNaN); 3051 CompareFlags flags =
3052 static_cast<CompareFlags>(CANT_BOTH_BE_NAN | NO_SMI_CODE_IN_STUB);
3053 CompareStub stub(cc, strict, flags);
3035 Result result = frame_->CallStub(&stub, left_side, right_side); 3054 Result result = frame_->CallStub(&stub, left_side, right_side);
3036 result.ToRegister(); 3055 result.ToRegister();
3037 __ test(result.reg(), Operand(result.reg())); 3056 __ test(result.reg(), Operand(result.reg()));
3038 result.Unuse(); 3057 result.Unuse();
3039 if (cc == equal) { 3058 if (cc == equal) {
3040 dest->Split(cc); 3059 dest->Split(cc);
3041 } else { 3060 } else {
3042 dest->true_target()->Branch(cc); 3061 dest->true_target()->Branch(cc);
3043 dest->false_target()->Jump(); 3062 dest->false_target()->Jump();
3044 3063
(...skipping 5094 matching lines...) Expand 10 before | Expand all | Expand 10 after
8139 case Token::NOT: 8158 case Token::NOT:
8140 case Token::DELETE: 8159 case Token::DELETE:
8141 case Token::TYPEOF: 8160 case Token::TYPEOF:
8142 UNREACHABLE(); // handled above 8161 UNREACHABLE(); // handled above
8143 break; 8162 break;
8144 8163
8145 case Token::SUB: { 8164 case Token::SUB: {
8146 GenericUnaryOpStub stub( 8165 GenericUnaryOpStub stub(
8147 Token::SUB, 8166 Token::SUB,
8148 overwrite, 8167 overwrite,
8168 NO_UNARY_FLAGS,
8149 no_negative_zero ? kIgnoreNegativeZero : kStrictNegativeZero); 8169 no_negative_zero ? kIgnoreNegativeZero : kStrictNegativeZero);
8150 Result operand = frame_->Pop(); 8170 Result operand = frame_->Pop();
8151 Result answer = frame_->CallStub(&stub, &operand); 8171 Result answer = frame_->CallStub(&stub, &operand);
8152 answer.set_type_info(TypeInfo::Number()); 8172 answer.set_type_info(TypeInfo::Number());
8153 frame_->Push(&answer); 8173 frame_->Push(&answer);
8154 break; 8174 break;
8155 } 8175 }
8156 case Token::BIT_NOT: { 8176 case Token::BIT_NOT: {
8157 // Smi check. 8177 // Smi check.
8158 JumpTarget smi_label; 8178 JumpTarget smi_label;
8159 JumpTarget continue_label; 8179 JumpTarget continue_label;
8160 Result operand = frame_->Pop(); 8180 Result operand = frame_->Pop();
8161 TypeInfo operand_info = operand.type_info(); 8181 TypeInfo operand_info = operand.type_info();
8162 operand.ToRegister(); 8182 operand.ToRegister();
8163 if (operand_info.IsSmi()) { 8183 if (operand_info.IsSmi()) {
8164 if (FLAG_debug_code) __ AbortIfNotSmi(operand.reg()); 8184 if (FLAG_debug_code) __ AbortIfNotSmi(operand.reg());
8165 frame_->Spill(operand.reg()); 8185 frame_->Spill(operand.reg());
8166 // Set smi tag bit. It will be reset by the not operation. 8186 // Set smi tag bit. It will be reset by the not operation.
8167 __ lea(operand.reg(), Operand(operand.reg(), kSmiTagMask)); 8187 __ lea(operand.reg(), Operand(operand.reg(), kSmiTagMask));
8168 __ not_(operand.reg()); 8188 __ not_(operand.reg());
8169 Result answer = operand; 8189 Result answer = operand;
8170 answer.set_type_info(TypeInfo::Smi()); 8190 answer.set_type_info(TypeInfo::Smi());
8171 frame_->Push(&answer); 8191 frame_->Push(&answer);
8172 } else { 8192 } else {
8173 __ test(operand.reg(), Immediate(kSmiTagMask)); 8193 __ test(operand.reg(), Immediate(kSmiTagMask));
8174 smi_label.Branch(zero, &operand, taken); 8194 smi_label.Branch(zero, &operand, taken);
8175 8195
8176 GenericUnaryOpStub stub(Token::BIT_NOT, overwrite); 8196 GenericUnaryOpStub stub(Token::BIT_NOT,
8197 overwrite,
8198 NO_UNARY_SMI_CODE_IN_STUB);
8177 Result answer = frame_->CallStub(&stub, &operand); 8199 Result answer = frame_->CallStub(&stub, &operand);
8178 continue_label.Jump(&answer); 8200 continue_label.Jump(&answer);
8179 8201
8180 smi_label.Bind(&answer); 8202 smi_label.Bind(&answer);
8181 answer.ToRegister(); 8203 answer.ToRegister();
8182 frame_->Spill(answer.reg()); 8204 frame_->Spill(answer.reg());
8183 // Set smi tag bit. It will be reset by the not operation. 8205 // Set smi tag bit. It will be reset by the not operation.
8184 __ lea(answer.reg(), Operand(answer.reg(), kSmiTagMask)); 8206 __ lea(answer.reg(), Operand(answer.reg(), kSmiTagMask));
8185 __ not_(answer.reg()); 8207 __ not_(answer.reg());
8186 8208
(...skipping 1846 matching lines...) Expand 10 before | Expand all | Expand 10 after
10033 masm.GetCode(&desc); 10055 masm.GetCode(&desc);
10034 // Call the function from C++. 10056 // Call the function from C++.
10035 return FUNCTION_CAST<MemCopyFunction>(buffer); 10057 return FUNCTION_CAST<MemCopyFunction>(buffer);
10036 } 10058 }
10037 10059
10038 #undef __ 10060 #undef __
10039 10061
10040 } } // namespace v8::internal 10062 } } // namespace v8::internal
10041 10063
10042 #endif // V8_TARGET_ARCH_IA32 10064 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698