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

Side by Side Diff: src/arm/codegen-arm.h

Issue 3195022: Move code stubs from codegen*.* files to code-stub*.* files. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' 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
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/arm/codegen-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 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 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 friend class JumpTarget; 605 friend class JumpTarget;
606 friend class Reference; 606 friend class Reference;
607 friend class FastCodeGenerator; 607 friend class FastCodeGenerator;
608 friend class FullCodeGenerator; 608 friend class FullCodeGenerator;
609 friend class FullCodeGenSyntaxChecker; 609 friend class FullCodeGenSyntaxChecker;
610 610
611 DISALLOW_COPY_AND_ASSIGN(CodeGenerator); 611 DISALLOW_COPY_AND_ASSIGN(CodeGenerator);
612 }; 612 };
613 613
614 614
615 // Compute a transcendental math function natively, or call the
616 // TranscendentalCache runtime function.
617 class TranscendentalCacheStub: public CodeStub {
618 public:
619 explicit TranscendentalCacheStub(TranscendentalCache::Type type)
620 : type_(type) {}
621 void Generate(MacroAssembler* masm);
622 private:
623 TranscendentalCache::Type type_;
624 Major MajorKey() { return TranscendentalCache; }
625 int MinorKey() { return type_; }
626 Runtime::FunctionId RuntimeFunction();
627 };
628
629
630 class ToBooleanStub: public CodeStub {
631 public:
632 explicit ToBooleanStub(Register tos) : tos_(tos) { }
633
634 void Generate(MacroAssembler* masm);
635
636 private:
637 Register tos_;
638 Major MajorKey() { return ToBoolean; }
639 int MinorKey() { return tos_.code(); }
640 };
641
642
643 class GenericBinaryOpStub : public CodeStub {
644 public:
645 GenericBinaryOpStub(Token::Value op,
646 OverwriteMode mode,
647 Register lhs,
648 Register rhs,
649 int constant_rhs = CodeGenerator::kUnknownIntValue)
650 : op_(op),
651 mode_(mode),
652 lhs_(lhs),
653 rhs_(rhs),
654 constant_rhs_(constant_rhs),
655 specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op, constant_rhs)),
656 runtime_operands_type_(BinaryOpIC::DEFAULT),
657 name_(NULL) { }
658
659 GenericBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info)
660 : op_(OpBits::decode(key)),
661 mode_(ModeBits::decode(key)),
662 lhs_(LhsRegister(RegisterBits::decode(key))),
663 rhs_(RhsRegister(RegisterBits::decode(key))),
664 constant_rhs_(KnownBitsForMinorKey(KnownIntBits::decode(key))),
665 specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op_, constant_rhs_)),
666 runtime_operands_type_(type_info),
667 name_(NULL) { }
668
669 private:
670 Token::Value op_;
671 OverwriteMode mode_;
672 Register lhs_;
673 Register rhs_;
674 int constant_rhs_;
675 bool specialized_on_rhs_;
676 BinaryOpIC::TypeInfo runtime_operands_type_;
677 char* name_;
678
679 static const int kMaxKnownRhs = 0x40000000;
680 static const int kKnownRhsKeyBits = 6;
681
682 // Minor key encoding in 17 bits.
683 class ModeBits: public BitField<OverwriteMode, 0, 2> {};
684 class OpBits: public BitField<Token::Value, 2, 6> {};
685 class TypeInfoBits: public BitField<int, 8, 2> {};
686 class RegisterBits: public BitField<bool, 10, 1> {};
687 class KnownIntBits: public BitField<int, 11, kKnownRhsKeyBits> {};
688
689 Major MajorKey() { return GenericBinaryOp; }
690 int MinorKey() {
691 ASSERT((lhs_.is(r0) && rhs_.is(r1)) ||
692 (lhs_.is(r1) && rhs_.is(r0)));
693 // Encode the parameters in a unique 18 bit value.
694 return OpBits::encode(op_)
695 | ModeBits::encode(mode_)
696 | KnownIntBits::encode(MinorKeyForKnownInt())
697 | TypeInfoBits::encode(runtime_operands_type_)
698 | RegisterBits::encode(lhs_.is(r0));
699 }
700
701 void Generate(MacroAssembler* masm);
702 void HandleNonSmiBitwiseOp(MacroAssembler* masm,
703 Register lhs,
704 Register rhs);
705 void HandleBinaryOpSlowCases(MacroAssembler* masm,
706 Label* not_smi,
707 Register lhs,
708 Register rhs,
709 const Builtins::JavaScript& builtin);
710 void GenerateTypeTransition(MacroAssembler* masm);
711
712 static bool RhsIsOneWeWantToOptimizeFor(Token::Value op, int constant_rhs) {
713 if (constant_rhs == CodeGenerator::kUnknownIntValue) return false;
714 if (op == Token::DIV) return constant_rhs >= 2 && constant_rhs <= 3;
715 if (op == Token::MOD) {
716 if (constant_rhs <= 1) return false;
717 if (constant_rhs <= 10) return true;
718 if (constant_rhs <= kMaxKnownRhs && IsPowerOf2(constant_rhs)) return true;
719 return false;
720 }
721 return false;
722 }
723
724 int MinorKeyForKnownInt() {
725 if (!specialized_on_rhs_) return 0;
726 if (constant_rhs_ <= 10) return constant_rhs_ + 1;
727 ASSERT(IsPowerOf2(constant_rhs_));
728 int key = 12;
729 int d = constant_rhs_;
730 while ((d & 1) == 0) {
731 key++;
732 d >>= 1;
733 }
734 ASSERT(key >= 0 && key < (1 << kKnownRhsKeyBits));
735 return key;
736 }
737
738 int KnownBitsForMinorKey(int key) {
739 if (!key) return 0;
740 if (key <= 11) return key - 1;
741 int d = 1;
742 while (key != 12) {
743 key--;
744 d <<= 1;
745 }
746 return d;
747 }
748
749 Register LhsRegister(bool lhs_is_r0) {
750 return lhs_is_r0 ? r0 : r1;
751 }
752
753 Register RhsRegister(bool lhs_is_r0) {
754 return lhs_is_r0 ? r1 : r0;
755 }
756
757 bool ShouldGenerateSmiCode() {
758 return ((op_ != Token::DIV && op_ != Token::MOD) || specialized_on_rhs_) &&
759 runtime_operands_type_ != BinaryOpIC::HEAP_NUMBERS &&
760 runtime_operands_type_ != BinaryOpIC::STRINGS;
761 }
762
763 bool ShouldGenerateFPCode() {
764 return runtime_operands_type_ != BinaryOpIC::STRINGS;
765 }
766
767 virtual int GetCodeKind() { return Code::BINARY_OP_IC; }
768
769 virtual InlineCacheState GetICState() {
770 return BinaryOpIC::ToState(runtime_operands_type_);
771 }
772
773 const char* GetName();
774
775 #ifdef DEBUG
776 void Print() {
777 if (!specialized_on_rhs_) {
778 PrintF("GenericBinaryOpStub (%s)\n", Token::String(op_));
779 } else {
780 PrintF("GenericBinaryOpStub (%s by %d)\n",
781 Token::String(op_),
782 constant_rhs_);
783 }
784 }
785 #endif
786 };
787
788
789 class StringHelper : public AllStatic {
790 public:
791 // Generate code for copying characters using a simple loop. This should only
792 // be used in places where the number of characters is small and the
793 // additional setup and checking in GenerateCopyCharactersLong adds too much
794 // overhead. Copying of overlapping regions is not supported.
795 // Dest register ends at the position after the last character written.
796 static void GenerateCopyCharacters(MacroAssembler* masm,
797 Register dest,
798 Register src,
799 Register count,
800 Register scratch,
801 bool ascii);
802
803 // Generate code for copying a large number of characters. This function
804 // is allowed to spend extra time setting up conditions to make copying
805 // faster. Copying of overlapping regions is not supported.
806 // Dest register ends at the position after the last character written.
807 static void GenerateCopyCharactersLong(MacroAssembler* masm,
808 Register dest,
809 Register src,
810 Register count,
811 Register scratch1,
812 Register scratch2,
813 Register scratch3,
814 Register scratch4,
815 Register scratch5,
816 int flags);
817
818
819 // Probe the symbol table for a two character string. If the string is
820 // not found by probing a jump to the label not_found is performed. This jump
821 // does not guarantee that the string is not in the symbol table. If the
822 // string is found the code falls through with the string in register r0.
823 // Contents of both c1 and c2 registers are modified. At the exit c1 is
824 // guaranteed to contain halfword with low and high bytes equal to
825 // initial contents of c1 and c2 respectively.
826 static void GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
827 Register c1,
828 Register c2,
829 Register scratch1,
830 Register scratch2,
831 Register scratch3,
832 Register scratch4,
833 Register scratch5,
834 Label* not_found);
835
836 // Generate string hash.
837 static void GenerateHashInit(MacroAssembler* masm,
838 Register hash,
839 Register character);
840
841 static void GenerateHashAddCharacter(MacroAssembler* masm,
842 Register hash,
843 Register character);
844
845 static void GenerateHashGetHash(MacroAssembler* masm,
846 Register hash);
847
848 private:
849 DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper);
850 };
851
852
853 // Flag that indicates how to generate code for the stub StringAddStub.
854 enum StringAddFlags {
855 NO_STRING_ADD_FLAGS = 0,
856 NO_STRING_CHECK_IN_STUB = 1 << 0 // Omit string check in stub.
857 };
858
859
860 class StringAddStub: public CodeStub {
861 public:
862 explicit StringAddStub(StringAddFlags flags) {
863 string_check_ = ((flags & NO_STRING_CHECK_IN_STUB) == 0);
864 }
865
866 private:
867 Major MajorKey() { return StringAdd; }
868 int MinorKey() { return string_check_ ? 0 : 1; }
869
870 void Generate(MacroAssembler* masm);
871
872 // Should the stub check whether arguments are strings?
873 bool string_check_;
874 };
875
876
877 class SubStringStub: public CodeStub {
878 public:
879 SubStringStub() {}
880
881 private:
882 Major MajorKey() { return SubString; }
883 int MinorKey() { return 0; }
884
885 void Generate(MacroAssembler* masm);
886 };
887
888
889
890 class StringCompareStub: public CodeStub {
891 public:
892 StringCompareStub() { }
893
894 // Compare two flat ASCII strings and returns result in r0.
895 // Does not use the stack.
896 static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
897 Register left,
898 Register right,
899 Register scratch1,
900 Register scratch2,
901 Register scratch3,
902 Register scratch4);
903
904 private:
905 Major MajorKey() { return StringCompare; }
906 int MinorKey() { return 0; }
907
908 void Generate(MacroAssembler* masm);
909 };
910
911
912 // This stub can do a fast mod operation without using fp.
913 // It is tail called from the GenericBinaryOpStub and it always
914 // returns an answer. It never causes GC so it doesn't need a real frame.
915 //
916 // The inputs are always positive Smis. This is never called
917 // where the denominator is a power of 2. We handle that separately.
918 //
919 // If we consider the denominator as an odd number multiplied by a power of 2,
920 // then:
921 // * The exponent (power of 2) is in the shift_distance register.
922 // * The odd number is in the odd_number register. It is always in the range
923 // of 3 to 25.
924 // * The bits from the numerator that are to be copied to the answer (there are
925 // shift_distance of them) are in the mask_bits register.
926 // * The other bits of the numerator have been shifted down and are in the lhs
927 // register.
928 class IntegerModStub : public CodeStub {
929 public:
930 IntegerModStub(Register result,
931 Register shift_distance,
932 Register odd_number,
933 Register mask_bits,
934 Register lhs,
935 Register scratch)
936 : result_(result),
937 shift_distance_(shift_distance),
938 odd_number_(odd_number),
939 mask_bits_(mask_bits),
940 lhs_(lhs),
941 scratch_(scratch) {
942 // We don't code these in the minor key, so they should always be the same.
943 // We don't really want to fix that since this stub is rather large and we
944 // don't want many copies of it.
945 ASSERT(shift_distance_.is(r9));
946 ASSERT(odd_number_.is(r4));
947 ASSERT(mask_bits_.is(r3));
948 ASSERT(scratch_.is(r5));
949 }
950
951 private:
952 Register result_;
953 Register shift_distance_;
954 Register odd_number_;
955 Register mask_bits_;
956 Register lhs_;
957 Register scratch_;
958
959 // Minor key encoding in 16 bits.
960 class ResultRegisterBits: public BitField<int, 0, 4> {};
961 class LhsRegisterBits: public BitField<int, 4, 4> {};
962
963 Major MajorKey() { return IntegerMod; }
964 int MinorKey() {
965 // Encode the parameters in a unique 16 bit value.
966 return ResultRegisterBits::encode(result_.code())
967 | LhsRegisterBits::encode(lhs_.code());
968 }
969
970 void Generate(MacroAssembler* masm);
971
972 const char* GetName() { return "IntegerModStub"; }
973
974 // Utility functions.
975 void DigitSum(MacroAssembler* masm,
976 Register lhs,
977 int mask,
978 int shift,
979 Label* entry);
980 void DigitSum(MacroAssembler* masm,
981 Register lhs,
982 Register scratch,
983 int mask,
984 int shift1,
985 int shift2,
986 Label* entry);
987 void ModGetInRangeBySubtraction(MacroAssembler* masm,
988 Register lhs,
989 int shift,
990 int rhs);
991 void ModReduce(MacroAssembler* masm,
992 Register lhs,
993 int max,
994 int denominator);
995 void ModAnswer(MacroAssembler* masm,
996 Register result,
997 Register shift_distance,
998 Register mask_bits,
999 Register sum_of_digits);
1000
1001
1002 #ifdef DEBUG
1003 void Print() { PrintF("IntegerModStub\n"); }
1004 #endif
1005 };
1006
1007
1008 // This stub can convert a signed int32 to a heap number (double). It does
1009 // not work for int32s that are in Smi range! No GC occurs during this stub
1010 // so you don't have to set up the frame.
1011 class WriteInt32ToHeapNumberStub : public CodeStub {
1012 public:
1013 WriteInt32ToHeapNumberStub(Register the_int,
1014 Register the_heap_number,
1015 Register scratch)
1016 : the_int_(the_int),
1017 the_heap_number_(the_heap_number),
1018 scratch_(scratch) { }
1019
1020 private:
1021 Register the_int_;
1022 Register the_heap_number_;
1023 Register scratch_;
1024
1025 // Minor key encoding in 16 bits.
1026 class IntRegisterBits: public BitField<int, 0, 4> {};
1027 class HeapNumberRegisterBits: public BitField<int, 4, 4> {};
1028 class ScratchRegisterBits: public BitField<int, 8, 4> {};
1029
1030 Major MajorKey() { return WriteInt32ToHeapNumber; }
1031 int MinorKey() {
1032 // Encode the parameters in a unique 16 bit value.
1033 return IntRegisterBits::encode(the_int_.code())
1034 | HeapNumberRegisterBits::encode(the_heap_number_.code())
1035 | ScratchRegisterBits::encode(scratch_.code());
1036 }
1037
1038 void Generate(MacroAssembler* masm);
1039
1040 const char* GetName() { return "WriteInt32ToHeapNumberStub"; }
1041
1042 #ifdef DEBUG
1043 void Print() { PrintF("WriteInt32ToHeapNumberStub\n"); }
1044 #endif
1045 };
1046
1047
1048 class NumberToStringStub: public CodeStub {
1049 public:
1050 NumberToStringStub() { }
1051
1052 // Generate code to do a lookup in the number string cache. If the number in
1053 // the register object is found in the cache the generated code falls through
1054 // with the result in the result register. The object and the result register
1055 // can be the same. If the number is not found in the cache the code jumps to
1056 // the label not_found with only the content of register object unchanged.
1057 static void GenerateLookupNumberStringCache(MacroAssembler* masm,
1058 Register object,
1059 Register result,
1060 Register scratch1,
1061 Register scratch2,
1062 Register scratch3,
1063 bool object_is_smi,
1064 Label* not_found);
1065
1066 private:
1067 Major MajorKey() { return NumberToString; }
1068 int MinorKey() { return 0; }
1069
1070 void Generate(MacroAssembler* masm);
1071
1072 const char* GetName() { return "NumberToStringStub"; }
1073
1074 #ifdef DEBUG
1075 void Print() {
1076 PrintF("NumberToStringStub\n");
1077 }
1078 #endif
1079 };
1080
1081
1082 class RecordWriteStub : public CodeStub {
1083 public:
1084 RecordWriteStub(Register object, Register offset, Register scratch)
1085 : object_(object), offset_(offset), scratch_(scratch) { }
1086
1087 void Generate(MacroAssembler* masm);
1088
1089 private:
1090 Register object_;
1091 Register offset_;
1092 Register scratch_;
1093
1094 #ifdef DEBUG
1095 void Print() {
1096 PrintF("RecordWriteStub (object reg %d), (offset reg %d),"
1097 " (scratch reg %d)\n",
1098 object_.code(), offset_.code(), scratch_.code());
1099 }
1100 #endif
1101
1102 // Minor key encoding in 12 bits. 4 bits for each of the three
1103 // registers (object, offset and scratch) OOOOAAAASSSS.
1104 class ScratchBits: public BitField<uint32_t, 0, 4> {};
1105 class OffsetBits: public BitField<uint32_t, 4, 4> {};
1106 class ObjectBits: public BitField<uint32_t, 8, 4> {};
1107
1108 Major MajorKey() { return RecordWrite; }
1109
1110 int MinorKey() {
1111 // Encode the registers.
1112 return ObjectBits::encode(object_.code()) |
1113 OffsetBits::encode(offset_.code()) |
1114 ScratchBits::encode(scratch_.code());
1115 }
1116 };
1117
1118
1119 } } // namespace v8::internal 615 } } // namespace v8::internal
1120 616
1121 #endif // V8_ARM_CODEGEN_ARM_H_ 617 #endif // V8_ARM_CODEGEN_ARM_H_
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/arm/codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698