OLD | NEW |
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 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
665 continue; | 665 continue; |
666 } | 666 } |
667 | 667 |
668 Comment cmnt(masm_, "[ Case comparison"); | 668 Comment cmnt(masm_, "[ Case comparison"); |
669 __ bind(&next_test); | 669 __ bind(&next_test); |
670 next_test.Unuse(); | 670 next_test.Unuse(); |
671 | 671 |
672 // Compile the label expression. | 672 // Compile the label expression. |
673 VisitForValue(clause->label(), kAccumulator); | 673 VisitForValue(clause->label(), kAccumulator); |
674 | 674 |
675 // Perform the comparison as if via '==='. The comparison stub expects | 675 // Perform the comparison as if via '==='. |
676 // the smi vs. smi case to be handled before it is called. | 676 if (ShouldInlineSmiCase(Token::EQ_STRICT)) { |
677 Label slow_case; | 677 Label slow_case; |
678 __ movq(rdx, Operand(rsp, 0)); // Switch value. | 678 __ movq(rdx, Operand(rsp, 0)); // Switch value. |
679 __ JumpIfNotBothSmi(rdx, rax, &slow_case); | 679 __ JumpIfNotBothSmi(rdx, rax, &slow_case); |
680 __ SmiCompare(rdx, rax); | 680 __ SmiCompare(rdx, rax); |
681 __ j(not_equal, &next_test); | 681 __ j(not_equal, &next_test); |
682 __ Drop(1); // Switch value is no longer needed. | 682 __ Drop(1); // Switch value is no longer needed. |
683 __ jmp(clause->body_target()->entry_label()); | 683 __ jmp(clause->body_target()->entry_label()); |
| 684 __ bind(&slow_case); |
| 685 } |
684 | 686 |
685 __ bind(&slow_case); | |
686 CompareStub stub(equal, true); | 687 CompareStub stub(equal, true); |
687 __ CallStub(&stub); | 688 __ CallStub(&stub); |
688 __ testq(rax, rax); | 689 __ testq(rax, rax); |
689 __ j(not_equal, &next_test); | 690 __ j(not_equal, &next_test); |
690 __ Drop(1); // Switch value is no longer needed. | 691 __ Drop(1); // Switch value is no longer needed. |
691 __ jmp(clause->body_target()->entry_label()); | 692 __ jmp(clause->body_target()->entry_label()); |
692 } | 693 } |
693 | 694 |
694 // Discard the test value and jump to the default if present, otherwise to | 695 // Discard the test value and jump to the default if present, otherwise to |
695 // the end of the statement. | 696 // the end of the statement. |
(...skipping 1964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2660 // GenericUnaryOpStub expects the argument to be in the | 2661 // GenericUnaryOpStub expects the argument to be in the |
2661 // accumulator register rax. | 2662 // accumulator register rax. |
2662 VisitForValue(expr->expression(), kAccumulator); | 2663 VisitForValue(expr->expression(), kAccumulator); |
2663 __ CallStub(&stub); | 2664 __ CallStub(&stub); |
2664 Apply(context_, rax); | 2665 Apply(context_, rax); |
2665 break; | 2666 break; |
2666 } | 2667 } |
2667 | 2668 |
2668 case Token::BIT_NOT: { | 2669 case Token::BIT_NOT: { |
2669 Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)"); | 2670 Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)"); |
2670 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); | 2671 // The generic unary operation stub expects the argument to be |
2671 UnaryOverwriteMode overwrite = | 2672 // in the accumulator register rax. |
2672 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; | |
2673 GenericUnaryOpStub stub(Token::BIT_NOT, overwrite); | |
2674 // GenericUnaryOpStub expects the argument to be in the | |
2675 // accumulator register rax. | |
2676 VisitForValue(expr->expression(), kAccumulator); | 2673 VisitForValue(expr->expression(), kAccumulator); |
2677 // Avoid calling the stub for Smis. | 2674 Label done; |
2678 Label smi, done; | 2675 if (ShouldInlineSmiCase(expr->op())) { |
2679 Condition is_smi = masm_->CheckSmi(result_register()); | 2676 Label call_stub; |
2680 __ j(is_smi, &smi); | 2677 __ JumpIfNotSmi(rax, &call_stub); |
2681 // Non-smi: call stub leaving result in accumulator register. | 2678 __ SmiNot(rax, rax); |
| 2679 __ jmp(&done); |
| 2680 __ bind(&call_stub); |
| 2681 } |
| 2682 bool overwrite = expr->expression()->ResultOverwriteAllowed(); |
| 2683 UnaryOverwriteMode mode = |
| 2684 overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; |
| 2685 GenericUnaryOpStub stub(Token::BIT_NOT, mode); |
2682 __ CallStub(&stub); | 2686 __ CallStub(&stub); |
2683 __ jmp(&done); | |
2684 // Perform operation directly on Smis. | |
2685 __ bind(&smi); | |
2686 __ SmiNot(result_register(), result_register()); | |
2687 __ bind(&done); | 2687 __ bind(&done); |
2688 Apply(context_, result_register()); | 2688 Apply(context_, rax); |
2689 break; | 2689 break; |
2690 } | 2690 } |
2691 | 2691 |
2692 default: | 2692 default: |
2693 UNREACHABLE(); | 2693 UNREACHABLE(); |
2694 } | 2694 } |
2695 } | 2695 } |
2696 | 2696 |
2697 | 2697 |
2698 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 2698 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3047 case Token::GTE: | 3047 case Token::GTE: |
3048 cc = greater_equal; | 3048 cc = greater_equal; |
3049 __ pop(rdx); | 3049 __ pop(rdx); |
3050 break; | 3050 break; |
3051 case Token::IN: | 3051 case Token::IN: |
3052 case Token::INSTANCEOF: | 3052 case Token::INSTANCEOF: |
3053 default: | 3053 default: |
3054 UNREACHABLE(); | 3054 UNREACHABLE(); |
3055 } | 3055 } |
3056 | 3056 |
3057 // The comparison stub expects the smi vs. smi case to be handled | 3057 if (ShouldInlineSmiCase(op)) { |
3058 // before it is called. | 3058 Label slow_case; |
3059 Label slow_case; | 3059 __ JumpIfNotBothSmi(rax, rdx, &slow_case); |
3060 __ JumpIfNotBothSmi(rax, rdx, &slow_case); | 3060 __ SmiCompare(rdx, rax); |
3061 __ SmiCompare(rdx, rax); | 3061 Split(cc, if_true, if_false, NULL); |
3062 __ j(cc, if_true); | 3062 __ bind(&slow_case); |
3063 __ jmp(if_false); | 3063 } |
3064 | 3064 |
3065 __ bind(&slow_case); | |
3066 CompareStub stub(cc, strict); | 3065 CompareStub stub(cc, strict); |
3067 __ CallStub(&stub); | 3066 __ CallStub(&stub); |
3068 __ testq(rax, rax); | 3067 __ testq(rax, rax); |
3069 Split(cc, if_true, if_false, fall_through); | 3068 Split(cc, if_true, if_false, fall_through); |
3070 } | 3069 } |
3071 } | 3070 } |
3072 | 3071 |
3073 // Convert the result of the comparison into one expected for this | 3072 // Convert the result of the comparison into one expected for this |
3074 // expression's context. | 3073 // expression's context. |
3075 Apply(context_, if_true, if_false); | 3074 Apply(context_, if_true, if_false); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3161 __ ret(0); | 3160 __ ret(0); |
3162 } | 3161 } |
3163 | 3162 |
3164 | 3163 |
3165 #undef __ | 3164 #undef __ |
3166 | 3165 |
3167 | 3166 |
3168 } } // namespace v8::internal | 3167 } } // namespace v8::internal |
3169 | 3168 |
3170 #endif // V8_TARGET_ARCH_X64 | 3169 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |