OLD | NEW |
---|---|
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
622 }; | 622 }; |
623 | 623 |
624 | 624 |
625 // Flag that indicates how to generate code for the stub GenericBinaryOpStub. | 625 // Flag that indicates how to generate code for the stub GenericBinaryOpStub. |
626 enum GenericBinaryFlags { | 626 enum GenericBinaryFlags { |
627 NO_GENERIC_BINARY_FLAGS = 0, | 627 NO_GENERIC_BINARY_FLAGS = 0, |
628 NO_SMI_CODE_IN_STUB = 1 << 0 // Omit smi code in stub. | 628 NO_SMI_CODE_IN_STUB = 1 << 0 // Omit smi code in stub. |
629 }; | 629 }; |
630 | 630 |
631 | 631 |
632 // The order is important as it is relied upon by ShouldGenerate*Code methods. | |
633 enum BinaryFastCase { | |
634 BINARY_OP_STUB_UNINITIALIZED, | |
635 BINARY_OP_STUB_GENERIC, | |
636 BINARY_OP_STUB_FAST_FP, | |
637 BINARY_OP_STUB_FAST_STRING_ADD, | |
638 BINARY_OP_STUB_FAST_RUNTIME | |
639 }; | |
640 | |
641 | |
632 class GenericBinaryOpStub: public CodeStub { | 642 class GenericBinaryOpStub: public CodeStub { |
633 public: | 643 public: |
634 GenericBinaryOpStub(Token::Value op, | 644 GenericBinaryOpStub(Token::Value op, |
635 OverwriteMode mode, | 645 OverwriteMode mode, |
636 GenericBinaryFlags flags) | 646 GenericBinaryFlags flags) |
637 : op_(op), | 647 : op_(op), |
638 mode_(mode), | 648 mode_(mode), |
639 flags_(flags), | 649 flags_(flags), |
650 fast_case_(BINARY_OP_STUB_UNINITIALIZED), | |
640 args_in_registers_(false), | 651 args_in_registers_(false), |
641 args_reversed_(false), | 652 args_reversed_(false), |
642 name_(NULL) { | 653 name_(NULL) { |
643 use_sse3_ = CpuFeatures::IsSupported(SSE3); | 654 use_sse3_ = CpuFeatures::IsSupported(SSE3); |
644 ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); | 655 ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); |
645 } | 656 } |
646 | 657 |
658 explicit GenericBinaryOpStub(int minor_key) | |
659 : op_(OpBits::decode(minor_key)), | |
660 mode_(ModeBits::decode(minor_key)), | |
661 flags_(FlagBits::decode(minor_key)), | |
662 fast_case_(FastCaseBits::decode(minor_key)), | |
663 args_in_registers_(ArgsInRegistersBits::decode(minor_key)), | |
664 args_reversed_(ArgsReversedBits::decode(minor_key)), | |
665 use_sse3_(SSE3Bits::decode(minor_key)), | |
666 name_(NULL) { | |
667 ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); | |
668 } | |
669 | |
647 // Generate code to call the stub with the supplied arguments. This will add | 670 // Generate code to call the stub with the supplied arguments. This will add |
648 // code at the call site to prepare arguments either in registers or on the | 671 // code at the call site to prepare arguments either in registers or on the |
649 // stack together with the actual call. | 672 // stack together with the actual call. |
650 void GenerateCall(MacroAssembler* masm, Register left, Register right); | 673 void GenerateCall(MacroAssembler* masm, Register left, Register right); |
651 void GenerateCall(MacroAssembler* masm, Register left, Smi* right); | 674 void GenerateCall(MacroAssembler* masm, Register left, Smi* right); |
652 void GenerateCall(MacroAssembler* masm, Smi* left, Register right); | 675 void GenerateCall(MacroAssembler* masm, Smi* left, Register right); |
653 | 676 |
677 void FormatStaticParameters(char* name, int max_length); | |
678 const char* GetFastCaseName(); | |
679 | |
654 private: | 680 private: |
655 Token::Value op_; | 681 Token::Value op_; |
656 OverwriteMode mode_; | 682 OverwriteMode mode_; |
657 GenericBinaryFlags flags_; | 683 GenericBinaryFlags flags_; |
684 BinaryFastCase fast_case_; | |
658 bool args_in_registers_; // Arguments passed in registers not on the stack. | 685 bool args_in_registers_; // Arguments passed in registers not on the stack. |
659 bool args_reversed_; // Left and right argument are swapped. | 686 bool args_reversed_; // Left and right argument are swapped. |
660 bool use_sse3_; | 687 bool use_sse3_; |
661 char* name_; | 688 char* name_; |
662 | 689 |
663 const char* GetName(); | 690 const char* GetName(); |
664 | 691 |
665 #ifdef DEBUG | 692 #ifdef DEBUG |
666 void Print() { | 693 void Print() { |
667 PrintF("GenericBinaryOpStub (op %s), " | 694 PrintF("GenericBinaryOpStub (op %s), " |
668 "(mode %d, flags %d, registers %d, reversed %d)\n", | 695 "(mode %d, flags %d, registers %d, reversed %d)\n", |
669 Token::String(op_), | 696 Token::String(op_), |
670 static_cast<int>(mode_), | 697 static_cast<int>(mode_), |
671 static_cast<int>(flags_), | 698 static_cast<int>(flags_), |
672 static_cast<int>(args_in_registers_), | 699 static_cast<int>(args_in_registers_), |
673 static_cast<int>(args_reversed_)); | 700 static_cast<int>(args_reversed_)); |
674 } | 701 } |
675 #endif | 702 #endif |
676 | 703 |
677 // Minor key encoding in 16 bits FRASOOOOOOOOOOMM. | 704 // Minor key encoding in 16 bits CCCFRASOOOO0OOOMM. |
Mads Ager (chromium)
2010/01/22 12:14:26
I think there is a zero '0' instead of the letter
vladislav.kaznacheev
2010/01/22 14:09:42
Made sure those are letter 'O's
| |
678 class ModeBits: public BitField<OverwriteMode, 0, 2> {}; | 705 class ModeBits: public BitField<OverwriteMode, 0, 2> {}; |
679 class OpBits: public BitField<Token::Value, 2, 10> {}; | 706 class OpBits: public BitField<Token::Value, 2, 7> {}; |
680 class SSE3Bits: public BitField<bool, 12, 1> {}; | 707 class SSE3Bits: public BitField<bool, 9, 1> {}; |
681 class ArgsInRegistersBits: public BitField<bool, 13, 1> {}; | 708 class ArgsInRegistersBits: public BitField<bool, 10, 1> {}; |
682 class ArgsReversedBits: public BitField<bool, 14, 1> {}; | 709 class ArgsReversedBits: public BitField<bool, 11, 1> {}; |
683 class FlagBits: public BitField<GenericBinaryFlags, 15, 1> {}; | 710 class FlagBits: public BitField<GenericBinaryFlags, 12, 1> {}; |
711 class FastCaseBits: public BitField<BinaryFastCase, 13, 3> {}; | |
684 | 712 |
685 Major MajorKey() { return GenericBinaryOp; } | 713 Major MajorKey() { return GenericBinaryOp; } |
686 int MinorKey() { | 714 int MinorKey() { |
687 // Encode the parameters in a unique 16 bit value. | 715 // Encode the parameters in a unique 16 bit value. |
688 return OpBits::encode(op_) | 716 return OpBits::encode(op_) |
689 | ModeBits::encode(mode_) | 717 | ModeBits::encode(mode_) |
690 | FlagBits::encode(flags_) | 718 | FlagBits::encode(flags_) |
719 | FastCaseBits::encode(fast_case_) | |
691 | SSE3Bits::encode(use_sse3_) | 720 | SSE3Bits::encode(use_sse3_) |
692 | ArgsInRegistersBits::encode(args_in_registers_) | 721 | ArgsInRegistersBits::encode(args_in_registers_) |
693 | ArgsReversedBits::encode(args_reversed_); | 722 | ArgsReversedBits::encode(args_reversed_); |
694 } | 723 } |
695 | 724 |
696 void Generate(MacroAssembler* masm); | 725 void Generate(MacroAssembler* masm); |
697 void GenerateSmiCode(MacroAssembler* masm, Label* slow); | 726 void GenerateSmiCode(MacroAssembler* masm, Label* slow); |
727 void GenerateHeapResultAllocation(MacroAssembler* masm, Label* alloc_failure); | |
728 void GenerateRegisterArgumentsPush(MacroAssembler* masm); | |
698 void GenerateLoadArguments(MacroAssembler* masm); | 729 void GenerateLoadArguments(MacroAssembler* masm); |
699 void GenerateReturn(MacroAssembler* masm); | 730 void GenerateReturn(MacroAssembler* masm); |
700 | 731 |
732 // Args in registers are always OK for ADD and SUB. | |
733 // MUL and DIV on SMIs modify the original registers so we need to push args | |
734 // on stack anyway. MUL and DIV on floats are OK. | |
701 bool ArgsInRegistersSupported() { | 735 bool ArgsInRegistersSupported() { |
702 return ((op_ == Token::ADD) || (op_ == Token::SUB) | 736 return ((op_ == Token::ADD) || (op_ == Token::SUB)) || |
703 || (op_ == Token::MUL) || (op_ == Token::DIV)) | 737 (((op_ == Token::MUL) || (op_ == Token::DIV)) && |
704 && flags_ != NO_SMI_CODE_IN_STUB; | 738 (flags_ == NO_SMI_CODE_IN_STUB)); |
705 } | 739 } |
706 bool IsOperationCommutative() { | 740 bool IsOperationCommutative() { |
707 return (op_ == Token::ADD) || (op_ == Token::MUL); | 741 return (op_ == Token::ADD) || (op_ == Token::MUL); |
708 } | 742 } |
709 | 743 |
710 void SetArgsInRegisters() { args_in_registers_ = true; } | 744 void SetArgsInRegisters() { args_in_registers_ = true; } |
711 void SetArgsReversed() { args_reversed_ = true; } | 745 void SetArgsReversed() { args_reversed_ = true; } |
712 bool HasSmiCodeInStub() { return (flags_ & NO_SMI_CODE_IN_STUB) == 0; } | 746 bool HasSmiCodeInStub() { return (flags_ & NO_SMI_CODE_IN_STUB) == 0; } |
713 bool HasArgumentsInRegisters() { return args_in_registers_; } | 747 bool HasArgumentsInRegisters() { return args_in_registers_; } |
714 bool HasArgumentsReversed() { return args_reversed_; } | 748 bool HasArgumentsReversed() { return args_reversed_; } |
749 | |
750 bool ShouldGenerateSmiCode() { | |
751 return HasSmiCodeInStub() && (fast_case_ < BINARY_OP_STUB_FAST_FP); | |
Mads Ager (chromium)
2010/01/22 12:14:26
This is not really related to this method itself,
vladislav.kaznacheev
2010/01/22 14:09:42
This is taken care of in GetFastCase method. It ma
| |
752 } | |
753 | |
754 bool ShouldGenerateFPCode() { | |
755 return fast_case_ <= BINARY_OP_STUB_FAST_FP; | |
756 } | |
757 | |
758 bool ShouldGenerateStringAddCode() { | |
759 return fast_case_ <= BINARY_OP_STUB_FAST_STRING_ADD; | |
760 } | |
761 | |
762 virtual int GetCodeKind() { return Code::BINARY_OP_IC; } | |
763 | |
764 virtual int GetICState(); | |
765 | |
766 static int TransitionMinorKey(int key, BinaryFastCase fast_case) { | |
767 return (key & ~FastCaseBits::mask()) | FastCaseBits::encode(fast_case); | |
768 } | |
769 | |
770 BinaryFastCase GetFastCase(BinaryFastCase target_case); | |
771 void GenerateFastCaseSwitch(MacroAssembler* masm, BinaryFastCase fast_case); | |
772 | |
773 void GenerateBuiltinCallPrologue(MacroAssembler* masm); | |
774 void GenerateBuiltinCallEpilogue(MacroAssembler* masm); | |
775 | |
776 void GenerateBuiltinTailCall(MacroAssembler* masm, | |
777 Builtins::JavaScript id, | |
778 Label* exit_via_builtin); | |
779 | |
780 void GenerateSwitchAndReturn(MacroAssembler* target_fast_case, | |
781 BinaryFastCase target_case); | |
782 | |
783 void GenerateSwitchViaBuiltin(MacroAssembler* masm, | |
784 Builtins::JavaScript id, | |
785 Label* exit_via_builtin, | |
786 BinaryFastCase target_fast_case); | |
787 | |
788 void GenerateSwitchViaStub(MacroAssembler* masm, | |
789 CodeStub& stub, | |
790 BinaryFastCase target_fast_case); | |
715 }; | 791 }; |
716 | 792 |
717 | 793 |
718 // Flag that indicates how to generate code for the stub StringAddStub. | 794 // Flag that indicates how to generate code for the stub StringAddStub. |
719 enum StringAddFlags { | 795 enum StringAddFlags { |
720 NO_STRING_ADD_FLAGS = 0, | 796 NO_STRING_ADD_FLAGS = 0, |
721 NO_STRING_CHECK_IN_STUB = 1 << 0 // Omit string check in stub. | 797 NO_STRING_CHECK_IN_STUB = 1 << 0 // Omit string check in stub. |
722 }; | 798 }; |
723 | 799 |
724 | 800 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
794 Major MajorKey() { return StringCompare; } | 870 Major MajorKey() { return StringCompare; } |
795 int MinorKey() { return 0; } | 871 int MinorKey() { return 0; } |
796 | 872 |
797 void Generate(MacroAssembler* masm); | 873 void Generate(MacroAssembler* masm); |
798 }; | 874 }; |
799 | 875 |
800 | 876 |
801 } } // namespace v8::internal | 877 } } // namespace v8::internal |
802 | 878 |
803 #endif // V8_IA32_CODEGEN_IA32_H_ | 879 #endif // V8_IA32_CODEGEN_IA32_H_ |
OLD | NEW |