OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_MIPS_CONSTANTS_H_ | 5 #ifndef V8_MIPS_CONSTANTS_H_ |
6 #define V8_MIPS_CONSTANTS_H_ | 6 #define V8_MIPS_CONSTANTS_H_ |
7 #include "src/globals.h" | 7 #include "src/globals.h" |
8 // UNIMPLEMENTED_ macro for MIPS. | 8 // UNIMPLEMENTED_ macro for MIPS. |
9 #ifdef DEBUG | 9 #ifdef DEBUG |
10 #define UNIMPLEMENTED_MIPS() \ | 10 #define UNIMPLEMENTED_MIPS() \ |
(...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
859 | 859 |
860 // Break 0xfffff, reserved for redirected real time call. | 860 // Break 0xfffff, reserved for redirected real time call. |
861 const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6; | 861 const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6; |
862 // A nop instruction. (Encoding of sll 0 0 0). | 862 // A nop instruction. (Encoding of sll 0 0 0). |
863 const Instr nopInstr = 0; | 863 const Instr nopInstr = 0; |
864 | 864 |
865 static constexpr uint64_t OpcodeToBitNumber(Opcode opcode) { | 865 static constexpr uint64_t OpcodeToBitNumber(Opcode opcode) { |
866 return 1ULL << (static_cast<uint32_t>(opcode) >> kOpcodeShift); | 866 return 1ULL << (static_cast<uint32_t>(opcode) >> kOpcodeShift); |
867 } | 867 } |
868 | 868 |
869 | 869 class InstructionBase { |
870 class Instruction { | |
871 public: | 870 public: |
872 enum { | 871 enum { |
873 kInstrSize = 4, | 872 kInstrSize = 4, |
874 kInstrSizeLog2 = 2, | 873 kInstrSizeLog2 = 2, |
875 // On MIPS PC cannot actually be directly accessed. We behave as if PC was | 874 // On MIPS PC cannot actually be directly accessed. We behave as if PC was |
876 // always the value of the current instruction being executed. | 875 // always the value of the current instruction being executed. |
877 kPCReadOffset = 0 | 876 kPCReadOffset = 0 |
878 }; | 877 }; |
879 | 878 |
| 879 // Instruction type. |
| 880 enum Type { kRegisterType, kImmediateType, kJumpType, kUnsupported = -1 }; |
| 881 |
880 // Get the raw instruction bits. | 882 // Get the raw instruction bits. |
881 inline Instr InstructionBits() const { | 883 inline Instr InstructionBits() const { |
882 return *reinterpret_cast<const Instr*>(this); | 884 return *reinterpret_cast<const Instr*>(this); |
883 } | 885 } |
884 | 886 |
885 // Set the raw instruction bits to value. | 887 // Set the raw instruction bits to value. |
886 inline void SetInstructionBits(Instr value) { | 888 inline void SetInstructionBits(Instr value) { |
887 *reinterpret_cast<Instr*>(this) = value; | 889 *reinterpret_cast<Instr*>(this) = value; |
888 } | 890 } |
889 | 891 |
890 // Read one particular bit out of the instruction bits. | 892 // Read one particular bit out of the instruction bits. |
891 inline int Bit(int nr) const { | 893 inline int Bit(int nr) const { |
892 return (InstructionBits() >> nr) & 1; | 894 return (InstructionBits() >> nr) & 1; |
893 } | 895 } |
894 | 896 |
895 // Read a bit field out of the instruction bits. | 897 // Read a bit field out of the instruction bits. |
896 inline int Bits(int hi, int lo) const { | 898 inline int Bits(int hi, int lo) const { |
897 return (InstructionBits() >> lo) & ((2U << (hi - lo)) - 1); | 899 return (InstructionBits() >> lo) & ((2U << (hi - lo)) - 1); |
898 } | 900 } |
899 | |
900 // Instruction type. | |
901 enum Type { | |
902 kRegisterType, | |
903 kImmediateType, | |
904 kJumpType, | |
905 kUnsupported = -1 | |
906 }; | |
907 | |
908 enum TypeChecks { NORMAL, EXTRA }; | 901 enum TypeChecks { NORMAL, EXTRA }; |
909 | 902 |
910 | 903 |
911 static constexpr uint64_t kOpcodeImmediateTypeMask = | 904 static constexpr uint64_t kOpcodeImmediateTypeMask = |
912 OpcodeToBitNumber(REGIMM) | OpcodeToBitNumber(BEQ) | | 905 OpcodeToBitNumber(REGIMM) | OpcodeToBitNumber(BEQ) | |
913 OpcodeToBitNumber(BNE) | OpcodeToBitNumber(BLEZ) | | 906 OpcodeToBitNumber(BNE) | OpcodeToBitNumber(BLEZ) | |
914 OpcodeToBitNumber(BGTZ) | OpcodeToBitNumber(ADDI) | | 907 OpcodeToBitNumber(BGTZ) | OpcodeToBitNumber(ADDI) | |
915 OpcodeToBitNumber(DADDI) | OpcodeToBitNumber(ADDIU) | | 908 OpcodeToBitNumber(DADDI) | OpcodeToBitNumber(ADDIU) | |
916 OpcodeToBitNumber(SLTI) | OpcodeToBitNumber(SLTIU) | | 909 OpcodeToBitNumber(SLTI) | OpcodeToBitNumber(SLTIU) | |
917 OpcodeToBitNumber(ANDI) | OpcodeToBitNumber(ORI) | | 910 OpcodeToBitNumber(ANDI) | OpcodeToBitNumber(ORI) | |
(...skipping 26 matching lines...) Expand all Loading... |
944 FunctionFieldToBitNumber(AND) | FunctionFieldToBitNumber(OR) | | 937 FunctionFieldToBitNumber(AND) | FunctionFieldToBitNumber(OR) | |
945 FunctionFieldToBitNumber(XOR) | FunctionFieldToBitNumber(NOR) | | 938 FunctionFieldToBitNumber(XOR) | FunctionFieldToBitNumber(NOR) | |
946 FunctionFieldToBitNumber(SLT) | FunctionFieldToBitNumber(SLTU) | | 939 FunctionFieldToBitNumber(SLT) | FunctionFieldToBitNumber(SLTU) | |
947 FunctionFieldToBitNumber(TGE) | FunctionFieldToBitNumber(TGEU) | | 940 FunctionFieldToBitNumber(TGE) | FunctionFieldToBitNumber(TGEU) | |
948 FunctionFieldToBitNumber(TLT) | FunctionFieldToBitNumber(TLTU) | | 941 FunctionFieldToBitNumber(TLT) | FunctionFieldToBitNumber(TLTU) | |
949 FunctionFieldToBitNumber(TEQ) | FunctionFieldToBitNumber(TNE) | | 942 FunctionFieldToBitNumber(TEQ) | FunctionFieldToBitNumber(TNE) | |
950 FunctionFieldToBitNumber(MOVZ) | FunctionFieldToBitNumber(MOVN) | | 943 FunctionFieldToBitNumber(MOVZ) | FunctionFieldToBitNumber(MOVN) | |
951 FunctionFieldToBitNumber(MOVCI) | FunctionFieldToBitNumber(SELEQZ_S) | | 944 FunctionFieldToBitNumber(MOVCI) | FunctionFieldToBitNumber(SELEQZ_S) | |
952 FunctionFieldToBitNumber(SELNEZ_S) | FunctionFieldToBitNumber(SYNC); | 945 FunctionFieldToBitNumber(SELNEZ_S) | FunctionFieldToBitNumber(SYNC); |
953 | 946 |
954 // Get the encoding type of the instruction. | |
955 inline Type InstructionType(TypeChecks checks = NORMAL) const; | |
956 | |
957 // Accessors for the different named fields used in the MIPS encoding. | 947 // Accessors for the different named fields used in the MIPS encoding. |
958 inline Opcode OpcodeValue() const { | 948 inline Opcode OpcodeValue() const { |
959 return static_cast<Opcode>( | 949 return static_cast<Opcode>( |
960 Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift)); | 950 Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift)); |
961 } | 951 } |
962 | 952 |
963 inline int RsValue() const { | 953 inline int FunctionFieldRaw() const { |
964 DCHECK(InstructionType() == kRegisterType || | 954 return InstructionBits() & kFunctionFieldMask; |
965 InstructionType() == kImmediateType); | |
966 return Bits(kRsShift + kRsBits - 1, kRsShift); | |
967 } | |
968 | |
969 inline int RtValue() const { | |
970 DCHECK(InstructionType() == kRegisterType || | |
971 InstructionType() == kImmediateType); | |
972 return Bits(kRtShift + kRtBits - 1, kRtShift); | |
973 } | |
974 | |
975 inline int RdValue() const { | |
976 DCHECK(InstructionType() == kRegisterType); | |
977 return Bits(kRdShift + kRdBits - 1, kRdShift); | |
978 } | |
979 | |
980 inline int SaValue() const { | |
981 DCHECK(InstructionType() == kRegisterType); | |
982 return Bits(kSaShift + kSaBits - 1, kSaShift); | |
983 } | |
984 | |
985 inline int LsaSaValue() const { | |
986 DCHECK(InstructionType() == kRegisterType); | |
987 return Bits(kSaShift + kLsaSaBits - 1, kSaShift); | |
988 } | |
989 | |
990 inline int FunctionValue() const { | |
991 DCHECK(InstructionType() == kRegisterType || | |
992 InstructionType() == kImmediateType); | |
993 return Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift); | |
994 } | |
995 | |
996 inline int FdValue() const { | |
997 return Bits(kFdShift + kFdBits - 1, kFdShift); | |
998 } | |
999 | |
1000 inline int FsValue() const { | |
1001 return Bits(kFsShift + kFsBits - 1, kFsShift); | |
1002 } | |
1003 | |
1004 inline int FtValue() const { | |
1005 return Bits(kFtShift + kFtBits - 1, kFtShift); | |
1006 } | |
1007 | |
1008 inline int FrValue() const { | |
1009 return Bits(kFrShift + kFrBits -1, kFrShift); | |
1010 } | |
1011 | |
1012 inline int Bp2Value() const { | |
1013 DCHECK(InstructionType() == kRegisterType); | |
1014 return Bits(kBp2Shift + kBp2Bits - 1, kBp2Shift); | |
1015 } | |
1016 | |
1017 // Float Compare condition code instruction bits. | |
1018 inline int FCccValue() const { | |
1019 return Bits(kFCccShift + kFCccBits - 1, kFCccShift); | |
1020 } | |
1021 | |
1022 // Float Branch condition code instruction bits. | |
1023 inline int FBccValue() const { | |
1024 return Bits(kFBccShift + kFBccBits - 1, kFBccShift); | |
1025 } | |
1026 | |
1027 // Float Branch true/false instruction bit. | |
1028 inline int FBtrueValue() const { | |
1029 return Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift); | |
1030 } | 955 } |
1031 | 956 |
1032 // Return the fields at their original place in the instruction encoding. | 957 // Return the fields at their original place in the instruction encoding. |
1033 inline Opcode OpcodeFieldRaw() const { | 958 inline Opcode OpcodeFieldRaw() const { |
1034 return static_cast<Opcode>(InstructionBits() & kOpcodeMask); | 959 return static_cast<Opcode>(InstructionBits() & kOpcodeMask); |
1035 } | 960 } |
1036 | 961 |
1037 inline int RsFieldRaw() const { | 962 // Safe to call within InstructionType(). |
1038 DCHECK(InstructionType() == kRegisterType || | |
1039 InstructionType() == kImmediateType); | |
1040 return InstructionBits() & kRsFieldMask; | |
1041 } | |
1042 | |
1043 // Same as above function, but safe to call within InstructionType(). | |
1044 inline int RsFieldRawNoAssert() const { | 963 inline int RsFieldRawNoAssert() const { |
1045 return InstructionBits() & kRsFieldMask; | 964 return InstructionBits() & kRsFieldMask; |
1046 } | 965 } |
1047 | 966 |
| 967 inline int SaFieldRaw() const { return InstructionBits() & kSaFieldMask; } |
| 968 |
| 969 // Get the encoding type of the instruction. |
| 970 inline Type InstructionType(TypeChecks checks = NORMAL) const; |
| 971 |
| 972 protected: |
| 973 InstructionBase() {} |
| 974 }; |
| 975 |
| 976 template <class T> |
| 977 class InstructionGetters : public T { |
| 978 public: |
| 979 inline int RsValue() const { |
| 980 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || |
| 981 this->InstructionType() == InstructionBase::kImmediateType); |
| 982 return InstructionBase::Bits(kRsShift + kRsBits - 1, kRsShift); |
| 983 } |
| 984 |
| 985 inline int RtValue() const { |
| 986 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || |
| 987 this->InstructionType() == InstructionBase::kImmediateType); |
| 988 return this->Bits(kRtShift + kRtBits - 1, kRtShift); |
| 989 } |
| 990 |
| 991 inline int RdValue() const { |
| 992 DCHECK(this->InstructionType() == InstructionBase::kRegisterType); |
| 993 return this->Bits(kRdShift + kRdBits - 1, kRdShift); |
| 994 } |
| 995 |
| 996 inline int SaValue() const { |
| 997 DCHECK(this->InstructionType() == InstructionBase::kRegisterType); |
| 998 return this->Bits(kSaShift + kSaBits - 1, kSaShift); |
| 999 } |
| 1000 |
| 1001 inline int LsaSaValue() const { |
| 1002 DCHECK(this->InstructionType() == InstructionBase::kRegisterType); |
| 1003 return this->Bits(kSaShift + kLsaSaBits - 1, kSaShift); |
| 1004 } |
| 1005 |
| 1006 inline int FunctionValue() const { |
| 1007 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || |
| 1008 this->InstructionType() == InstructionBase::kImmediateType); |
| 1009 return this->Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift); |
| 1010 } |
| 1011 |
| 1012 inline int FdValue() const { |
| 1013 return this->Bits(kFdShift + kFdBits - 1, kFdShift); |
| 1014 } |
| 1015 |
| 1016 inline int FsValue() const { |
| 1017 return this->Bits(kFsShift + kFsBits - 1, kFsShift); |
| 1018 } |
| 1019 |
| 1020 inline int FtValue() const { |
| 1021 return this->Bits(kFtShift + kFtBits - 1, kFtShift); |
| 1022 } |
| 1023 |
| 1024 inline int FrValue() const { |
| 1025 return this->Bits(kFrShift + kFrBits - 1, kFrShift); |
| 1026 } |
| 1027 |
| 1028 inline int Bp2Value() const { |
| 1029 DCHECK(this->InstructionType() == InstructionBase::kRegisterType); |
| 1030 return this->Bits(kBp2Shift + kBp2Bits - 1, kBp2Shift); |
| 1031 } |
| 1032 |
| 1033 // Float Compare condition code instruction bits. |
| 1034 inline int FCccValue() const { |
| 1035 return this->Bits(kFCccShift + kFCccBits - 1, kFCccShift); |
| 1036 } |
| 1037 |
| 1038 // Float Branch condition code instruction bits. |
| 1039 inline int FBccValue() const { |
| 1040 return this->Bits(kFBccShift + kFBccBits - 1, kFBccShift); |
| 1041 } |
| 1042 |
| 1043 // Float Branch true/false instruction bit. |
| 1044 inline int FBtrueValue() const { |
| 1045 return this->Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift); |
| 1046 } |
| 1047 |
| 1048 // Return the fields at their original place in the instruction encoding. |
| 1049 inline Opcode OpcodeFieldRaw() const { |
| 1050 return static_cast<Opcode>(this->InstructionBits() & kOpcodeMask); |
| 1051 } |
| 1052 |
| 1053 inline int RsFieldRaw() const { |
| 1054 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || |
| 1055 this->InstructionType() == InstructionBase::kImmediateType); |
| 1056 return this->InstructionBits() & kRsFieldMask; |
| 1057 } |
| 1058 |
1048 inline int RtFieldRaw() const { | 1059 inline int RtFieldRaw() const { |
1049 DCHECK(InstructionType() == kRegisterType || | 1060 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || |
1050 InstructionType() == kImmediateType); | 1061 this->InstructionType() == InstructionBase::kImmediateType); |
1051 return InstructionBits() & kRtFieldMask; | 1062 return this->InstructionBits() & kRtFieldMask; |
1052 } | 1063 } |
1053 | 1064 |
1054 inline int RdFieldRaw() const { | 1065 inline int RdFieldRaw() const { |
1055 DCHECK(InstructionType() == kRegisterType); | 1066 DCHECK(this->InstructionType() == InstructionBase::kRegisterType); |
1056 return InstructionBits() & kRdFieldMask; | 1067 return this->InstructionBits() & kRdFieldMask; |
1057 } | 1068 } |
1058 | 1069 |
1059 inline int SaFieldRaw() const { | 1070 inline int SaFieldRaw() const { |
1060 return InstructionBits() & kSaFieldMask; | 1071 return this->InstructionBits() & kSaFieldMask; |
1061 } | 1072 } |
1062 | 1073 |
1063 inline int FunctionFieldRaw() const { | 1074 inline int FunctionFieldRaw() const { |
1064 return InstructionBits() & kFunctionFieldMask; | 1075 return this->InstructionBits() & kFunctionFieldMask; |
1065 } | 1076 } |
1066 | 1077 |
1067 // Get the secondary field according to the opcode. | 1078 // Get the secondary field according to the opcode. |
1068 inline int SecondaryValue() const { | 1079 inline int SecondaryValue() const { |
1069 Opcode op = OpcodeFieldRaw(); | 1080 Opcode op = this->OpcodeFieldRaw(); |
1070 switch (op) { | 1081 switch (op) { |
1071 case SPECIAL: | 1082 case SPECIAL: |
1072 case SPECIAL2: | 1083 case SPECIAL2: |
1073 return FunctionValue(); | 1084 return FunctionValue(); |
1074 case COP1: | 1085 case COP1: |
1075 return RsValue(); | 1086 return RsValue(); |
1076 case REGIMM: | 1087 case REGIMM: |
1077 return RtValue(); | 1088 return RtValue(); |
1078 default: | 1089 default: |
1079 return NULLSF; | 1090 return NULLSF; |
1080 } | 1091 } |
1081 } | 1092 } |
1082 | 1093 |
1083 inline int32_t ImmValue(int bits) const { | 1094 inline int32_t ImmValue(int bits) const { |
1084 DCHECK(InstructionType() == kImmediateType); | 1095 DCHECK(this->InstructionType() == InstructionBase::kImmediateType); |
1085 return Bits(bits - 1, 0); | 1096 return this->Bits(bits - 1, 0); |
1086 } | 1097 } |
1087 | 1098 |
1088 inline int32_t Imm16Value() const { | 1099 inline int32_t Imm16Value() const { |
1089 DCHECK(InstructionType() == kImmediateType); | 1100 DCHECK(this->InstructionType() == InstructionBase::kImmediateType); |
1090 return Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift); | 1101 return this->Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift); |
1091 } | 1102 } |
1092 | 1103 |
1093 inline int32_t Imm18Value() const { | 1104 inline int32_t Imm18Value() const { |
1094 DCHECK(InstructionType() == kImmediateType); | 1105 DCHECK(this->InstructionType() == InstructionBase::kImmediateType); |
1095 return Bits(kImm18Shift + kImm18Bits - 1, kImm18Shift); | 1106 return this->Bits(kImm18Shift + kImm18Bits - 1, kImm18Shift); |
1096 } | 1107 } |
1097 | 1108 |
1098 inline int32_t Imm19Value() const { | 1109 inline int32_t Imm19Value() const { |
1099 DCHECK(InstructionType() == kImmediateType); | 1110 DCHECK(this->InstructionType() == InstructionBase::kImmediateType); |
1100 return Bits(kImm19Shift + kImm19Bits - 1, kImm19Shift); | 1111 return this->Bits(kImm19Shift + kImm19Bits - 1, kImm19Shift); |
1101 } | 1112 } |
1102 | 1113 |
1103 inline int32_t Imm21Value() const { | 1114 inline int32_t Imm21Value() const { |
1104 DCHECK(InstructionType() == kImmediateType); | 1115 DCHECK(this->InstructionType() == InstructionBase::kImmediateType); |
1105 return Bits(kImm21Shift + kImm21Bits - 1, kImm21Shift); | 1116 return this->Bits(kImm21Shift + kImm21Bits - 1, kImm21Shift); |
1106 } | 1117 } |
1107 | 1118 |
1108 inline int32_t Imm26Value() const { | 1119 inline int32_t Imm26Value() const { |
1109 DCHECK((InstructionType() == kJumpType) || | 1120 DCHECK((this->InstructionType() == InstructionBase::kJumpType) || |
1110 (InstructionType() == kImmediateType)); | 1121 (this->InstructionType() == InstructionBase::kImmediateType)); |
1111 return Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift); | 1122 return this->Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift); |
1112 } | 1123 } |
1113 | 1124 |
1114 static bool IsForbiddenAfterBranchInstr(Instr instr); | 1125 static bool IsForbiddenAfterBranchInstr(Instr instr); |
1115 | 1126 |
1116 // Say if the instruction should not be used in a branch delay slot or | 1127 // Say if the instruction should not be used in a branch delay slot or |
1117 // immediately after a compact branch. | 1128 // immediately after a compact branch. |
1118 inline bool IsForbiddenAfterBranch() const { | 1129 inline bool IsForbiddenAfterBranch() const { |
1119 return IsForbiddenAfterBranchInstr(InstructionBits()); | 1130 return IsForbiddenAfterBranchInstr(this->InstructionBits()); |
1120 } | 1131 } |
1121 | 1132 |
1122 inline bool IsForbiddenInBranchDelay() const { | 1133 inline bool IsForbiddenInBranchDelay() const { |
1123 return IsForbiddenAfterBranch(); | 1134 return IsForbiddenAfterBranch(); |
1124 } | 1135 } |
1125 | 1136 |
1126 // Say if the instruction 'links'. e.g. jal, bal. | 1137 // Say if the instruction 'links'. e.g. jal, bal. |
1127 bool IsLinkingInstruction() const; | 1138 bool IsLinkingInstruction() const; |
1128 // Say if the instruction is a break or a trap. | 1139 // Say if the instruction is a break or a trap. |
1129 bool IsTrap() const; | 1140 bool IsTrap() const; |
| 1141 }; |
1130 | 1142 |
1131 // Instructions are read of out a code stream. The only way to get a | 1143 class Instruction : public InstructionGetters<InstructionBase> { |
1132 // reference to an instruction is to convert a pointer. There is no way | 1144 public: |
1133 // to allocate or create instances of class Instruction. | |
1134 // Use the At(pc) function to create references to Instruction. | |
1135 static Instruction* At(byte* pc) { | 1145 static Instruction* At(byte* pc) { |
1136 return reinterpret_cast<Instruction*>(pc); | 1146 return reinterpret_cast<Instruction*>(pc); |
1137 } | 1147 } |
1138 | 1148 |
1139 private: | 1149 private: |
1140 // We need to prevent the creation of instances of class Instruction. | |
1141 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction); | 1150 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction); |
1142 }; | 1151 }; |
1143 | 1152 |
1144 | 1153 |
1145 // ----------------------------------------------------------------------------- | 1154 // ----------------------------------------------------------------------------- |
1146 // MIPS assembly various constants. | 1155 // MIPS assembly various constants. |
1147 | 1156 |
1148 // C/C++ argument slots size. | 1157 // C/C++ argument slots size. |
1149 const int kCArgSlotCount = 4; | 1158 const int kCArgSlotCount = 4; |
1150 const int kCArgsSlotsSize = kCArgSlotCount * Instruction::kInstrSize; | 1159 const int kCArgsSlotsSize = kCArgSlotCount * Instruction::kInstrSize; |
1151 const int kInvalidStackOffset = -1; | 1160 const int kInvalidStackOffset = -1; |
1152 // JS argument slots size. | 1161 // JS argument slots size. |
1153 const int kJSArgsSlotsSize = 0 * Instruction::kInstrSize; | 1162 const int kJSArgsSlotsSize = 0 * Instruction::kInstrSize; |
1154 // Assembly builtins argument slots size. | 1163 // Assembly builtins argument slots size. |
1155 const int kBArgsSlotsSize = 0 * Instruction::kInstrSize; | 1164 const int kBArgsSlotsSize = 0 * Instruction::kInstrSize; |
1156 | 1165 |
1157 const int kBranchReturnOffset = 2 * Instruction::kInstrSize; | 1166 const int kBranchReturnOffset = 2 * Instruction::kInstrSize; |
1158 | 1167 |
1159 | 1168 InstructionBase::Type InstructionBase::InstructionType( |
1160 Instruction::Type Instruction::InstructionType(TypeChecks checks) const { | 1169 TypeChecks checks) const { |
1161 if (checks == EXTRA) { | 1170 if (checks == EXTRA) { |
1162 if (OpcodeToBitNumber(OpcodeFieldRaw()) & kOpcodeImmediateTypeMask) { | 1171 if (OpcodeToBitNumber(OpcodeFieldRaw()) & kOpcodeImmediateTypeMask) { |
1163 return kImmediateType; | 1172 return kImmediateType; |
1164 } | 1173 } |
1165 } | 1174 } |
1166 switch (OpcodeFieldRaw()) { | 1175 switch (OpcodeFieldRaw()) { |
1167 case SPECIAL: | 1176 case SPECIAL: |
1168 if (checks == EXTRA) { | 1177 if (checks == EXTRA) { |
1169 if (FunctionFieldToBitNumber(FunctionFieldRaw()) & | 1178 if (FunctionFieldToBitNumber(FunctionFieldRaw()) & |
1170 kFunctionFieldRegisterTypeMask) { | 1179 kFunctionFieldRegisterTypeMask) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1233 if (checks == NORMAL) { | 1242 if (checks == NORMAL) { |
1234 return kImmediateType; | 1243 return kImmediateType; |
1235 } else { | 1244 } else { |
1236 return kUnsupported; | 1245 return kUnsupported; |
1237 } | 1246 } |
1238 } | 1247 } |
1239 } | 1248 } |
1240 | 1249 |
1241 #undef OpcodeToBitNumber | 1250 #undef OpcodeToBitNumber |
1242 #undef FunctionFieldToBitNumber | 1251 #undef FunctionFieldToBitNumber |
| 1252 |
| 1253 // ----------------------------------------------------------------------------- |
| 1254 // Instructions. |
| 1255 |
| 1256 template <class P> |
| 1257 bool InstructionGetters<P>::IsLinkingInstruction() const { |
| 1258 uint32_t op = this->OpcodeFieldRaw(); |
| 1259 switch (op) { |
| 1260 case JAL: |
| 1261 return true; |
| 1262 case POP76: |
| 1263 if (this->RsFieldRawNoAssert() == JIALC) |
| 1264 return true; // JIALC |
| 1265 else |
| 1266 return false; // BNEZC |
| 1267 case REGIMM: |
| 1268 switch (this->RtFieldRaw()) { |
| 1269 case BGEZAL: |
| 1270 case BLTZAL: |
| 1271 return true; |
| 1272 default: |
| 1273 return false; |
| 1274 } |
| 1275 case SPECIAL: |
| 1276 switch (this->FunctionFieldRaw()) { |
| 1277 case JALR: |
| 1278 return true; |
| 1279 default: |
| 1280 return false; |
| 1281 } |
| 1282 default: |
| 1283 return false; |
| 1284 } |
| 1285 } |
| 1286 |
| 1287 template <class P> |
| 1288 bool InstructionGetters<P>::IsTrap() const { |
| 1289 if (this->OpcodeFieldRaw() != SPECIAL) { |
| 1290 return false; |
| 1291 } else { |
| 1292 switch (this->FunctionFieldRaw()) { |
| 1293 case BREAK: |
| 1294 case TGE: |
| 1295 case TGEU: |
| 1296 case TLT: |
| 1297 case TLTU: |
| 1298 case TEQ: |
| 1299 case TNE: |
| 1300 return true; |
| 1301 default: |
| 1302 return false; |
| 1303 } |
| 1304 } |
| 1305 } |
| 1306 |
| 1307 // static |
| 1308 template <class T> |
| 1309 bool InstructionGetters<T>::IsForbiddenAfterBranchInstr(Instr instr) { |
| 1310 Opcode opcode = static_cast<Opcode>(instr & kOpcodeMask); |
| 1311 switch (opcode) { |
| 1312 case J: |
| 1313 case JAL: |
| 1314 case BEQ: |
| 1315 case BNE: |
| 1316 case BLEZ: // POP06 bgeuc/bleuc, blezalc, bgezalc |
| 1317 case BGTZ: // POP07 bltuc/bgtuc, bgtzalc, bltzalc |
| 1318 case BEQL: |
| 1319 case BNEL: |
| 1320 case BLEZL: // POP26 bgezc, blezc, bgec/blec |
| 1321 case BGTZL: // POP27 bgtzc, bltzc, bltc/bgtc |
| 1322 case BC: |
| 1323 case BALC: |
| 1324 case POP10: // beqzalc, bovc, beqc |
| 1325 case POP30: // bnezalc, bnvc, bnec |
| 1326 case POP66: // beqzc, jic |
| 1327 case POP76: // bnezc, jialc |
| 1328 return true; |
| 1329 case REGIMM: |
| 1330 switch (instr & kRtFieldMask) { |
| 1331 case BLTZ: |
| 1332 case BGEZ: |
| 1333 case BLTZAL: |
| 1334 case BGEZAL: |
| 1335 return true; |
| 1336 default: |
| 1337 return false; |
| 1338 } |
| 1339 break; |
| 1340 case SPECIAL: |
| 1341 switch (instr & kFunctionFieldMask) { |
| 1342 case JR: |
| 1343 case JALR: |
| 1344 return true; |
| 1345 default: |
| 1346 return false; |
| 1347 } |
| 1348 break; |
| 1349 case COP1: |
| 1350 switch (instr & kRsFieldMask) { |
| 1351 case BC1: |
| 1352 case BC1EQZ: |
| 1353 case BC1NEZ: |
| 1354 return true; |
| 1355 break; |
| 1356 default: |
| 1357 return false; |
| 1358 } |
| 1359 break; |
| 1360 default: |
| 1361 return false; |
| 1362 } |
| 1363 } |
1243 } // namespace internal | 1364 } // namespace internal |
1244 } // namespace v8 | 1365 } // namespace v8 |
1245 | 1366 |
1246 #endif // #ifndef V8_MIPS_CONSTANTS_H_ | 1367 #endif // #ifndef V8_MIPS_CONSTANTS_H_ |
OLD | NEW |