OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 ToBooleanStub() { } | 640 ToBooleanStub() { } |
641 | 641 |
642 void Generate(MacroAssembler* masm); | 642 void Generate(MacroAssembler* masm); |
643 | 643 |
644 private: | 644 private: |
645 Major MajorKey() { return ToBoolean; } | 645 Major MajorKey() { return ToBoolean; } |
646 int MinorKey() { return 0; } | 646 int MinorKey() { return 0; } |
647 }; | 647 }; |
648 | 648 |
649 | 649 |
650 // Flag that indicates whether or not the code that handles smi arguments | 650 // Flag that indicates how to generate code for the stub GenericBinaryOpStub. |
651 // should be placed in the stub, inlined, or omitted entirely. | |
652 enum GenericBinaryFlags { | 651 enum GenericBinaryFlags { |
653 SMI_CODE_IN_STUB, | 652 NO_GENERIC_BINARY_FLAGS = 0, |
654 SMI_CODE_INLINED | 653 NO_SMI_CODE_IN_STUB = 1 << 0 // Omit smi code in stub. |
655 }; | 654 }; |
656 | 655 |
657 | 656 |
658 class GenericBinaryOpStub: public CodeStub { | 657 class GenericBinaryOpStub: public CodeStub { |
659 public: | 658 public: |
660 GenericBinaryOpStub(Token::Value op, | 659 GenericBinaryOpStub(Token::Value op, |
661 OverwriteMode mode, | 660 OverwriteMode mode, |
662 GenericBinaryFlags flags) | 661 GenericBinaryFlags flags) |
663 : op_(op), mode_(mode), flags_(flags) { | 662 : op_(op), |
| 663 mode_(mode), |
| 664 flags_(flags), |
| 665 args_in_registers_(false), |
| 666 args_reversed_(false) { |
664 use_sse3_ = CpuFeatures::IsSupported(CpuFeatures::SSE3); | 667 use_sse3_ = CpuFeatures::IsSupported(CpuFeatures::SSE3); |
665 ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); | 668 ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); |
666 } | 669 } |
667 | 670 |
668 void GenerateSmiCode(MacroAssembler* masm, Label* slow); | 671 // Generate code to call the stub with the supplied arguments. This will add |
| 672 // code at the call site to prepare arguments either in registers or on the |
| 673 // stack together with the actual call. |
| 674 void GenerateCall(MacroAssembler* masm, Register left, Register right); |
| 675 void GenerateCall(MacroAssembler* masm, Register left, Smi* right); |
| 676 void GenerateCall(MacroAssembler* masm, Smi* left, Register right); |
669 | 677 |
670 private: | 678 private: |
671 Token::Value op_; | 679 Token::Value op_; |
672 OverwriteMode mode_; | 680 OverwriteMode mode_; |
673 GenericBinaryFlags flags_; | 681 GenericBinaryFlags flags_; |
| 682 bool args_in_registers_; // Arguments passed in registers not on the stack. |
| 683 bool args_reversed_; // Left and right argument are swapped. |
674 bool use_sse3_; | 684 bool use_sse3_; |
675 | 685 |
676 const char* GetName(); | 686 const char* GetName(); |
677 | 687 |
678 #ifdef DEBUG | 688 #ifdef DEBUG |
679 void Print() { | 689 void Print() { |
680 PrintF("GenericBinaryOpStub (op %s), (mode %d, flags %d)\n", | 690 PrintF("GenericBinaryOpStub (op %s), " |
| 691 "(mode %d, flags %d, registers %d, reversed %d)\n", |
681 Token::String(op_), | 692 Token::String(op_), |
682 static_cast<int>(mode_), | 693 static_cast<int>(mode_), |
683 static_cast<int>(flags_)); | 694 static_cast<int>(flags_), |
| 695 static_cast<int>(args_in_registers_), |
| 696 static_cast<int>(args_reversed_)); |
684 } | 697 } |
685 #endif | 698 #endif |
686 | 699 |
687 // Minor key encoding in 16 bits FSOOOOOOOOOOOOMM. | 700 // Minor key encoding in 16 bits FRASOOOOOOOOOOMM. |
688 class ModeBits: public BitField<OverwriteMode, 0, 2> {}; | 701 class ModeBits: public BitField<OverwriteMode, 0, 2> {}; |
689 class OpBits: public BitField<Token::Value, 2, 12> {}; | 702 class OpBits: public BitField<Token::Value, 2, 10> {}; |
690 class SSE3Bits: public BitField<bool, 14, 1> {}; | 703 class SSE3Bits: public BitField<bool, 12, 1> {}; |
| 704 class ArgsInRegistersBits: public BitField<bool, 13, 1> {}; |
| 705 class ArgsReversedBits: public BitField<bool, 14, 1> {}; |
691 class FlagBits: public BitField<GenericBinaryFlags, 15, 1> {}; | 706 class FlagBits: public BitField<GenericBinaryFlags, 15, 1> {}; |
692 | 707 |
693 Major MajorKey() { return GenericBinaryOp; } | 708 Major MajorKey() { return GenericBinaryOp; } |
694 int MinorKey() { | 709 int MinorKey() { |
695 // Encode the parameters in a unique 16 bit value. | 710 // Encode the parameters in a unique 16 bit value. |
696 return OpBits::encode(op_) | 711 return OpBits::encode(op_) |
697 | ModeBits::encode(mode_) | 712 | ModeBits::encode(mode_) |
698 | FlagBits::encode(flags_) | 713 | FlagBits::encode(flags_) |
699 | SSE3Bits::encode(use_sse3_); | 714 | SSE3Bits::encode(use_sse3_) |
| 715 | ArgsInRegistersBits::encode(args_in_registers_) |
| 716 | ArgsReversedBits::encode(args_reversed_); |
700 } | 717 } |
| 718 |
701 void Generate(MacroAssembler* masm); | 719 void Generate(MacroAssembler* masm); |
| 720 void GenerateSmiCode(MacroAssembler* masm, Label* slow); |
| 721 void GenerateLoadArguments(MacroAssembler* masm); |
| 722 void GenerateReturn(MacroAssembler* masm); |
| 723 |
| 724 bool ArgsInRegistersSupported() { |
| 725 return ((op_ == Token::ADD) || (op_ == Token::SUB) |
| 726 || (op_ == Token::MUL) || (op_ == Token::DIV)) |
| 727 && flags_ != NO_SMI_CODE_IN_STUB; |
| 728 } |
| 729 bool IsOperationCommutative() { |
| 730 return (op_ == Token::ADD) || (op_ == Token::MUL); |
| 731 } |
| 732 |
| 733 void SetArgsInRegisters() { args_in_registers_ = true; } |
| 734 void SetArgsReversed() { args_reversed_ = true; } |
| 735 bool HasSmiCodeInStub() { return (flags_ & NO_SMI_CODE_IN_STUB) == 0; } |
| 736 bool HasArgumentsInRegisters() { return args_in_registers_; } |
| 737 bool HasArgumentsReversed() { return args_reversed_; } |
702 }; | 738 }; |
703 | 739 |
704 | 740 |
705 } } // namespace v8::internal | 741 } } // namespace v8::internal |
706 | 742 |
707 #endif // V8_X64_CODEGEN_X64_H_ | 743 #endif // V8_X64_CODEGEN_X64_H_ |
OLD | NEW |