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 | 7 |
8 #include "src/base/logging.h" | 8 #include "src/base/logging.h" |
9 #include "src/base/macros.h" | 9 #include "src/base/macros.h" |
10 #include "src/globals.h" | 10 #include "src/globals.h" |
(...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
892 | 892 |
893 // Break 0xfffff, reserved for redirected real time call. | 893 // Break 0xfffff, reserved for redirected real time call. |
894 const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6; | 894 const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6; |
895 // A nop instruction. (Encoding of sll 0 0 0). | 895 // A nop instruction. (Encoding of sll 0 0 0). |
896 const Instr nopInstr = 0; | 896 const Instr nopInstr = 0; |
897 | 897 |
898 static constexpr uint64_t OpcodeToBitNumber(Opcode opcode) { | 898 static constexpr uint64_t OpcodeToBitNumber(Opcode opcode) { |
899 return 1ULL << (static_cast<uint32_t>(opcode) >> kOpcodeShift); | 899 return 1ULL << (static_cast<uint32_t>(opcode) >> kOpcodeShift); |
900 } | 900 } |
901 | 901 |
902 | 902 class InstructionBase { |
903 class Instruction { | |
904 public: | 903 public: |
905 enum { | 904 enum { |
906 kInstrSize = 4, | 905 kInstrSize = 4, |
907 kInstrSizeLog2 = 2, | 906 kInstrSizeLog2 = 2, |
908 // On MIPS PC cannot actually be directly accessed. We behave as if PC was | 907 // On MIPS PC cannot actually be directly accessed. We behave as if PC was |
909 // always the value of the current instruction being executed. | 908 // always the value of the current instruction being executed. |
910 kPCReadOffset = 0 | 909 kPCReadOffset = 0 |
911 }; | 910 }; |
912 | 911 |
912 // Instruction type. | |
913 enum Type { kRegisterType, kImmediateType, kJumpType, kUnsupported = -1 }; | |
914 | |
913 // Get the raw instruction bits. | 915 // Get the raw instruction bits. |
914 inline Instr InstructionBits() const { | 916 inline Instr InstructionBits() const { |
915 return *reinterpret_cast<const Instr*>(this); | 917 return *reinterpret_cast<const Instr*>(this); |
916 } | 918 } |
917 | 919 |
918 // Set the raw instruction bits to value. | 920 // Set the raw instruction bits to value. |
919 inline void SetInstructionBits(Instr value) { | 921 inline void SetInstructionBits(Instr value) { |
920 *reinterpret_cast<Instr*>(this) = value; | 922 *reinterpret_cast<Instr*>(this) = value; |
921 } | 923 } |
922 | 924 |
923 // Read one particular bit out of the instruction bits. | 925 // Read one particular bit out of the instruction bits. |
924 inline int Bit(int nr) const { | 926 inline int Bit(int nr) const { |
925 return (InstructionBits() >> nr) & 1; | 927 return (InstructionBits() >> nr) & 1; |
926 } | 928 } |
927 | 929 |
928 // Read a bit field out of the instruction bits. | 930 // Read a bit field out of the instruction bits. |
929 inline int Bits(int hi, int lo) const { | 931 inline int Bits(int hi, int lo) const { |
930 return (InstructionBits() >> lo) & ((2U << (hi - lo)) - 1); | 932 return (InstructionBits() >> lo) & ((2U << (hi - lo)) - 1); |
931 } | 933 } |
932 | 934 |
933 // Instruction type. | |
934 enum Type { | |
935 kRegisterType, | |
936 kImmediateType, | |
937 kJumpType, | |
938 kUnsupported = -1 | |
939 }; | |
940 | |
941 enum TypeChecks { NORMAL, EXTRA }; | 935 enum TypeChecks { NORMAL, EXTRA }; |
942 | 936 |
943 static constexpr uint64_t kOpcodeImmediateTypeMask = | 937 static constexpr uint64_t kOpcodeImmediateTypeMask = |
944 OpcodeToBitNumber(REGIMM) | OpcodeToBitNumber(BEQ) | | 938 OpcodeToBitNumber(REGIMM) | OpcodeToBitNumber(BEQ) | |
945 OpcodeToBitNumber(BNE) | OpcodeToBitNumber(BLEZ) | | 939 OpcodeToBitNumber(BNE) | OpcodeToBitNumber(BLEZ) | |
946 OpcodeToBitNumber(BGTZ) | OpcodeToBitNumber(ADDI) | | 940 OpcodeToBitNumber(BGTZ) | OpcodeToBitNumber(ADDI) | |
947 OpcodeToBitNumber(DADDI) | OpcodeToBitNumber(ADDIU) | | 941 OpcodeToBitNumber(DADDI) | OpcodeToBitNumber(ADDIU) | |
948 OpcodeToBitNumber(DADDIU) | OpcodeToBitNumber(SLTI) | | 942 OpcodeToBitNumber(DADDIU) | OpcodeToBitNumber(SLTI) | |
949 OpcodeToBitNumber(SLTIU) | OpcodeToBitNumber(ANDI) | | 943 OpcodeToBitNumber(SLTIU) | OpcodeToBitNumber(ANDI) | |
950 OpcodeToBitNumber(ORI) | OpcodeToBitNumber(XORI) | | 944 OpcodeToBitNumber(ORI) | OpcodeToBitNumber(XORI) | |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
989 FunctionFieldToBitNumber(AND) | FunctionFieldToBitNumber(OR) | | 983 FunctionFieldToBitNumber(AND) | FunctionFieldToBitNumber(OR) | |
990 FunctionFieldToBitNumber(XOR) | FunctionFieldToBitNumber(NOR) | | 984 FunctionFieldToBitNumber(XOR) | FunctionFieldToBitNumber(NOR) | |
991 FunctionFieldToBitNumber(SLT) | FunctionFieldToBitNumber(SLTU) | | 985 FunctionFieldToBitNumber(SLT) | FunctionFieldToBitNumber(SLTU) | |
992 FunctionFieldToBitNumber(TGE) | FunctionFieldToBitNumber(TGEU) | | 986 FunctionFieldToBitNumber(TGE) | FunctionFieldToBitNumber(TGEU) | |
993 FunctionFieldToBitNumber(TLT) | FunctionFieldToBitNumber(TLTU) | | 987 FunctionFieldToBitNumber(TLT) | FunctionFieldToBitNumber(TLTU) | |
994 FunctionFieldToBitNumber(TEQ) | FunctionFieldToBitNumber(TNE) | | 988 FunctionFieldToBitNumber(TEQ) | FunctionFieldToBitNumber(TNE) | |
995 FunctionFieldToBitNumber(MOVZ) | FunctionFieldToBitNumber(MOVN) | | 989 FunctionFieldToBitNumber(MOVZ) | FunctionFieldToBitNumber(MOVN) | |
996 FunctionFieldToBitNumber(MOVCI) | FunctionFieldToBitNumber(SELEQZ_S) | | 990 FunctionFieldToBitNumber(MOVCI) | FunctionFieldToBitNumber(SELEQZ_S) | |
997 FunctionFieldToBitNumber(SELNEZ_S) | FunctionFieldToBitNumber(SYNC); | 991 FunctionFieldToBitNumber(SELNEZ_S) | FunctionFieldToBitNumber(SYNC); |
998 | 992 |
999 // Get the encoding type of the instruction. | |
1000 inline Type InstructionType(TypeChecks checks = NORMAL) const; | |
1001 | |
1002 | 993 |
1003 // Accessors for the different named fields used in the MIPS encoding. | 994 // Accessors for the different named fields used in the MIPS encoding. |
1004 inline Opcode OpcodeValue() const { | 995 inline Opcode OpcodeValue() const { |
1005 return static_cast<Opcode>( | 996 return static_cast<Opcode>( |
1006 Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift)); | 997 Bits(kOpcodeShift + kOpcodeBits - 1, kOpcodeShift)); |
1007 } | 998 } |
1008 | 999 |
1009 inline int RsValue() const { | 1000 inline int FunctionFieldRaw() const { |
1010 DCHECK(InstructionType() == kRegisterType || | 1001 return InstructionBits() & kFunctionFieldMask; |
1011 InstructionType() == kImmediateType); | |
1012 return Bits(kRsShift + kRsBits - 1, kRsShift); | |
1013 } | |
1014 | |
1015 inline int RtValue() const { | |
1016 DCHECK(InstructionType() == kRegisterType || | |
1017 InstructionType() == kImmediateType); | |
1018 return Bits(kRtShift + kRtBits - 1, kRtShift); | |
1019 } | |
1020 | |
1021 inline int RdValue() const { | |
1022 DCHECK(InstructionType() == kRegisterType); | |
1023 return Bits(kRdShift + kRdBits - 1, kRdShift); | |
1024 } | |
1025 | |
1026 inline int SaValue() const { | |
1027 DCHECK(InstructionType() == kRegisterType); | |
1028 return Bits(kSaShift + kSaBits - 1, kSaShift); | |
1029 } | |
1030 | |
1031 inline int LsaSaValue() const { | |
1032 DCHECK(InstructionType() == kRegisterType); | |
1033 return Bits(kSaShift + kLsaSaBits - 1, kSaShift); | |
1034 } | |
1035 | |
1036 inline int FunctionValue() const { | |
1037 DCHECK(InstructionType() == kRegisterType || | |
1038 InstructionType() == kImmediateType); | |
1039 return Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift); | |
1040 } | |
1041 | |
1042 inline int FdValue() const { | |
1043 return Bits(kFdShift + kFdBits - 1, kFdShift); | |
1044 } | |
1045 | |
1046 inline int FsValue() const { | |
1047 return Bits(kFsShift + kFsBits - 1, kFsShift); | |
1048 } | |
1049 | |
1050 inline int FtValue() const { | |
1051 return Bits(kFtShift + kFtBits - 1, kFtShift); | |
1052 } | |
1053 | |
1054 inline int FrValue() const { | |
1055 return Bits(kFrShift + kFrBits -1, kFrShift); | |
1056 } | |
1057 | |
1058 inline int Bp2Value() const { | |
1059 DCHECK(InstructionType() == kRegisterType); | |
1060 return Bits(kBp2Shift + kBp2Bits - 1, kBp2Shift); | |
1061 } | |
1062 | |
1063 inline int Bp3Value() const { | |
1064 DCHECK(InstructionType() == kRegisterType); | |
1065 return Bits(kBp3Shift + kBp3Bits - 1, kBp3Shift); | |
1066 } | |
1067 | |
1068 // Float Compare condition code instruction bits. | |
1069 inline int FCccValue() const { | |
1070 return Bits(kFCccShift + kFCccBits - 1, kFCccShift); | |
1071 } | |
1072 | |
1073 // Float Branch condition code instruction bits. | |
1074 inline int FBccValue() const { | |
1075 return Bits(kFBccShift + kFBccBits - 1, kFBccShift); | |
1076 } | |
1077 | |
1078 // Float Branch true/false instruction bit. | |
1079 inline int FBtrueValue() const { | |
1080 return Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift); | |
1081 } | 1002 } |
1082 | 1003 |
1083 // Return the fields at their original place in the instruction encoding. | 1004 // Return the fields at their original place in the instruction encoding. |
1084 inline Opcode OpcodeFieldRaw() const { | 1005 inline Opcode OpcodeFieldRaw() const { |
1085 return static_cast<Opcode>(InstructionBits() & kOpcodeMask); | 1006 return static_cast<Opcode>(InstructionBits() & kOpcodeMask); |
1086 } | 1007 } |
1087 | 1008 |
1009 // Safe to call within InstructionType(). | |
1010 inline int RsFieldRawNoAssert() const { | |
1011 return InstructionBits() & kRsFieldMask; | |
1012 } | |
1013 | |
1014 inline int SaFieldRaw() const { return InstructionBits() & kSaFieldMask; } | |
1015 | |
1016 // Get the encoding type of the instruction. | |
1017 inline Type InstructionType(TypeChecks checks = NORMAL) const; | |
1018 | |
1019 protected: | |
1020 InstructionBase() {} | |
1021 }; | |
1022 | |
1023 template <class T> | |
1024 class InstructionGetters : public T { | |
1025 public: | |
1026 inline int RsValue() const { | |
1027 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || | |
1028 this->InstructionType() == InstructionBase::kImmediateType); | |
1029 return this->Bits(kRsShift + kRsBits - 1, kRsShift); | |
1030 } | |
1031 | |
1032 inline int RtValue() const { | |
1033 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || | |
1034 this->InstructionType() == InstructionBase::kImmediateType); | |
1035 return this->Bits(kRtShift + kRtBits - 1, kRtShift); | |
1036 } | |
1037 | |
1038 inline int RdValue() const { | |
1039 DCHECK(this->InstructionType() == InstructionBase::kRegisterType); | |
1040 return this->Bits(kRdShift + kRdBits - 1, kRdShift); | |
1041 } | |
1042 | |
1043 inline int SaValue() const { | |
1044 DCHECK(this->InstructionType() == InstructionBase::kRegisterType); | |
1045 return this->Bits(kSaShift + kSaBits - 1, kSaShift); | |
1046 } | |
1047 | |
1048 inline int LsaSaValue() const { | |
1049 DCHECK(this->InstructionType() == InstructionBase::kRegisterType); | |
1050 return this->Bits(kSaShift + kLsaSaBits - 1, kSaShift); | |
1051 } | |
1052 | |
1053 inline int FunctionValue() const { | |
1054 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || | |
1055 this->InstructionType() == InstructionBase::kImmediateType); | |
1056 return this->Bits(kFunctionShift + kFunctionBits - 1, kFunctionShift); | |
1057 } | |
1058 | |
1059 inline int FdValue() const { | |
1060 return this->Bits(kFdShift + kFdBits - 1, kFdShift); | |
1061 } | |
1062 | |
1063 inline int FsValue() const { | |
1064 return this->Bits(kFsShift + kFsBits - 1, kFsShift); | |
1065 } | |
1066 | |
1067 inline int FtValue() const { | |
1068 return this->Bits(kFtShift + kFtBits - 1, kFtShift); | |
1069 } | |
1070 | |
1071 inline int FrValue() const { | |
1072 return this->Bits(kFrShift + kFrBits - 1, kFrShift); | |
1073 } | |
1074 | |
1075 inline int Bp2Value() const { | |
1076 DCHECK(this->InstructionType() == InstructionBase::kRegisterType); | |
1077 return this->Bits(kBp2Shift + kBp2Bits - 1, kBp2Shift); | |
1078 } | |
1079 | |
1080 inline int Bp3Value() const { | |
1081 DCHECK(this->InstructionType() == InstructionBase::kRegisterType); | |
1082 return this->Bits(kBp3Shift + kBp3Bits - 1, kBp3Shift); | |
1083 } | |
1084 | |
1085 // Float Compare condition code instruction bits. | |
1086 inline int FCccValue() const { | |
1087 return this->Bits(kFCccShift + kFCccBits - 1, kFCccShift); | |
1088 } | |
1089 | |
1090 // Float Branch condition code instruction bits. | |
1091 inline int FBccValue() const { | |
1092 return this->Bits(kFBccShift + kFBccBits - 1, kFBccShift); | |
1093 } | |
1094 | |
1095 // Float Branch true/false instruction bit. | |
1096 inline int FBtrueValue() const { | |
1097 return this->Bits(kFBtrueShift + kFBtrueBits - 1, kFBtrueShift); | |
1098 } | |
1099 | |
1100 // Return the fields at their original place in the instruction encoding. | |
1101 inline Opcode OpcodeFieldRaw() const { | |
1102 return static_cast<Opcode>(this->InstructionBits() & kOpcodeMask); | |
1103 } | |
1104 | |
1088 inline int RsFieldRaw() const { | 1105 inline int RsFieldRaw() const { |
1089 DCHECK(InstructionType() == kRegisterType || | 1106 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || |
1090 InstructionType() == kImmediateType); | 1107 this->InstructionType() == InstructionBase::kImmediateType); |
1091 return InstructionBits() & kRsFieldMask; | 1108 return this->InstructionBits() & kRsFieldMask; |
1092 } | 1109 } |
1093 | 1110 |
1094 // Same as above function, but safe to call within InstructionType(). | 1111 // Same as above function, but safe to call within InstructionType(). |
1095 inline int RsFieldRawNoAssert() const { | 1112 inline int RsFieldRawNoAssert() const { |
1096 return InstructionBits() & kRsFieldMask; | 1113 return this->InstructionBits() & kRsFieldMask; |
1097 } | 1114 } |
1098 | 1115 |
1099 inline int RtFieldRaw() const { | 1116 inline int RtFieldRaw() const { |
1100 DCHECK(InstructionType() == kRegisterType || | 1117 DCHECK(this->InstructionType() == InstructionBase::kRegisterType || |
1101 InstructionType() == kImmediateType); | 1118 this->InstructionType() == InstructionBase::kImmediateType); |
1102 return InstructionBits() & kRtFieldMask; | 1119 return this->InstructionBits() & kRtFieldMask; |
1103 } | 1120 } |
1104 | 1121 |
1105 inline int RdFieldRaw() const { | 1122 inline int RdFieldRaw() const { |
1106 DCHECK(InstructionType() == kRegisterType); | 1123 DCHECK(this->InstructionType() == InstructionBase::kRegisterType); |
1107 return InstructionBits() & kRdFieldMask; | 1124 return this->InstructionBits() & kRdFieldMask; |
1108 } | 1125 } |
1109 | 1126 |
1110 inline int SaFieldRaw() const { | 1127 inline int SaFieldRaw() const { |
1111 return InstructionBits() & kSaFieldMask; | 1128 return this->InstructionBits() & kSaFieldMask; |
1112 } | 1129 } |
1113 | 1130 |
1114 inline int FunctionFieldRaw() const { | 1131 inline int FunctionFieldRaw() const { |
1115 return InstructionBits() & kFunctionFieldMask; | 1132 return this->InstructionBits() & kFunctionFieldMask; |
1116 } | 1133 } |
1117 | 1134 |
1118 // Get the secondary field according to the opcode. | 1135 // Get the secondary field according to the opcode. |
1119 inline int SecondaryValue() const { | 1136 inline int SecondaryValue() const { |
1120 Opcode op = OpcodeFieldRaw(); | 1137 Opcode op = this->OpcodeFieldRaw(); |
1121 switch (op) { | 1138 switch (op) { |
1122 case SPECIAL: | 1139 case SPECIAL: |
1123 case SPECIAL2: | 1140 case SPECIAL2: |
1124 return FunctionValue(); | 1141 return FunctionValue(); |
1125 case COP1: | 1142 case COP1: |
1126 return RsValue(); | 1143 return RsValue(); |
1127 case REGIMM: | 1144 case REGIMM: |
1128 return RtValue(); | 1145 return RtValue(); |
1129 default: | 1146 default: |
1130 return NULLSF; | 1147 return NULLSF; |
1131 } | 1148 } |
1132 } | 1149 } |
1133 | 1150 |
1134 inline int32_t ImmValue(int bits) const { | 1151 inline int32_t ImmValue(int bits) const { |
1135 DCHECK(InstructionType() == kImmediateType); | 1152 DCHECK(this->InstructionType() == InstructionBase::kImmediateType); |
1136 return Bits(bits - 1, 0); | 1153 return this->Bits(bits - 1, 0); |
1137 } | 1154 } |
1138 | 1155 |
1139 inline int32_t Imm16Value() const { | 1156 inline int32_t Imm16Value() const { |
1140 DCHECK(InstructionType() == kImmediateType); | 1157 DCHECK(this->InstructionType() == InstructionBase::kImmediateType); |
1141 return Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift); | 1158 return this->Bits(kImm16Shift + kImm16Bits - 1, kImm16Shift); |
1142 } | 1159 } |
1143 | 1160 |
1144 inline int32_t Imm18Value() const { | 1161 inline int32_t Imm18Value() const { |
1145 DCHECK(InstructionType() == kImmediateType); | 1162 DCHECK(this->InstructionType() == InstructionBase::kImmediateType); |
1146 return Bits(kImm18Shift + kImm18Bits - 1, kImm18Shift); | 1163 return this->Bits(kImm18Shift + kImm18Bits - 1, kImm18Shift); |
1147 } | 1164 } |
1148 | 1165 |
1149 inline int32_t Imm19Value() const { | 1166 inline int32_t Imm19Value() const { |
1150 DCHECK(InstructionType() == kImmediateType); | 1167 DCHECK(this->InstructionType() == InstructionBase::kImmediateType); |
1151 return Bits(kImm19Shift + kImm19Bits - 1, kImm19Shift); | 1168 return this->Bits(kImm19Shift + kImm19Bits - 1, kImm19Shift); |
1152 } | 1169 } |
1153 | 1170 |
1154 inline int32_t Imm21Value() const { | 1171 inline int32_t Imm21Value() const { |
1155 DCHECK(InstructionType() == kImmediateType); | 1172 DCHECK(this->InstructionType() == InstructionBase::kImmediateType); |
1156 return Bits(kImm21Shift + kImm21Bits - 1, kImm21Shift); | 1173 return this->Bits(kImm21Shift + kImm21Bits - 1, kImm21Shift); |
1157 } | 1174 } |
1158 | 1175 |
1159 inline int32_t Imm26Value() const { | 1176 inline int32_t Imm26Value() const { |
1160 DCHECK((InstructionType() == kJumpType) || | 1177 DCHECK((this->InstructionType() == InstructionBase::kJumpType) || |
1161 (InstructionType() == kImmediateType)); | 1178 (this->InstructionType() == InstructionBase::kImmediateType)); |
1162 return Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift); | 1179 return this->Bits(kImm26Shift + kImm26Bits - 1, kImm26Shift); |
1163 } | 1180 } |
1164 | 1181 |
1165 static bool IsForbiddenAfterBranchInstr(Instr instr); | 1182 static bool IsForbiddenAfterBranchInstr(Instr instr); |
1166 | 1183 |
1167 // Say if the instruction should not be used in a branch delay slot or | 1184 // Say if the instruction should not be used in a branch delay slot or |
1168 // immediately after a compact branch. | 1185 // immediately after a compact branch. |
1169 inline bool IsForbiddenAfterBranch() const { | 1186 inline bool IsForbiddenAfterBranch() const { |
1170 return IsForbiddenAfterBranchInstr(InstructionBits()); | 1187 return IsForbiddenAfterBranchInstr(this->InstructionBits()); |
1188 } | |
1189 | |
1190 inline bool IsForbiddenInBranchDelay() const { | |
1191 return IsForbiddenAfterBranch(); | |
1171 } | 1192 } |
1172 | 1193 |
1173 // Say if the instruction 'links'. e.g. jal, bal. | 1194 // Say if the instruction 'links'. e.g. jal, bal. |
1174 bool IsLinkingInstruction() const; | 1195 bool IsLinkingInstruction() const; |
1175 // Say if the instruction is a break or a trap. | 1196 // Say if the instruction is a break or a trap. |
1176 bool IsTrap() const; | 1197 bool IsTrap() const; |
1198 }; | |
1177 | 1199 |
1200 class Instruction : public InstructionGetters<InstructionBase> { | |
1201 public: | |
1178 // Instructions are read of out a code stream. The only way to get a | 1202 // Instructions are read of out a code stream. The only way to get a |
1179 // reference to an instruction is to convert a pointer. There is no way | 1203 // reference to an instruction is to convert a pointer. There is no way |
1180 // to allocate or create instances of class Instruction. | 1204 // to allocate or create instances of class Instruction. |
1181 // Use the At(pc) function to create references to Instruction. | 1205 // Use the At(pc) function to create references to Instruction. |
1182 static Instruction* At(byte* pc) { | 1206 static Instruction* At(byte* pc) { |
1183 return reinterpret_cast<Instruction*>(pc); | 1207 return reinterpret_cast<Instruction*>(pc); |
1184 } | 1208 } |
1185 | 1209 |
1186 private: | 1210 private: |
1187 // We need to prevent the creation of instances of class Instruction. | 1211 // We need to prevent the creation of instances of class Instruction. |
1188 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction); | 1212 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction); |
1189 }; | 1213 }; |
1190 | 1214 |
1191 | 1215 |
1192 // ----------------------------------------------------------------------------- | 1216 // ----------------------------------------------------------------------------- |
1193 // MIPS assembly various constants. | 1217 // MIPS assembly various constants. |
1194 | 1218 |
1195 // C/C++ argument slots size. | 1219 // C/C++ argument slots size. |
1196 const int kCArgSlotCount = 0; | 1220 const int kCArgSlotCount = 0; |
1197 | 1221 |
1198 // TODO(plind): below should be based on kPointerSize | 1222 // TODO(plind): below should be based on kPointerSize |
1199 // TODO(plind): find all usages and remove the needless instructions for n64. | 1223 // TODO(plind): find all usages and remove the needless instructions for n64. |
1200 const int kCArgsSlotsSize = kCArgSlotCount * Instruction::kInstrSize * 2; | 1224 const int kCArgsSlotsSize = kCArgSlotCount * Instruction::kInstrSize * 2; |
1201 | 1225 |
1202 const int kInvalidStackOffset = -1; | 1226 const int kInvalidStackOffset = -1; |
1203 const int kBranchReturnOffset = 2 * Instruction::kInstrSize; | 1227 const int kBranchReturnOffset = 2 * Instruction::kInstrSize; |
1204 | 1228 |
1205 | 1229 InstructionBase::Type InstructionBase::InstructionType( |
1206 Instruction::Type Instruction::InstructionType(TypeChecks checks) const { | 1230 TypeChecks checks) const { |
1207 if (checks == EXTRA) { | 1231 if (checks == EXTRA) { |
1208 if (OpcodeToBitNumber(OpcodeFieldRaw()) & kOpcodeImmediateTypeMask) { | 1232 if (OpcodeToBitNumber(OpcodeFieldRaw()) & kOpcodeImmediateTypeMask) { |
1209 return kImmediateType; | 1233 return kImmediateType; |
1210 } | 1234 } |
1211 } | 1235 } |
1212 switch (OpcodeFieldRaw()) { | 1236 switch (OpcodeFieldRaw()) { |
1213 case SPECIAL: | 1237 case SPECIAL: |
1214 if (checks == EXTRA) { | 1238 if (checks == EXTRA) { |
1215 if (FunctionFieldToBitNumber(FunctionFieldRaw()) & | 1239 if (FunctionFieldToBitNumber(FunctionFieldRaw()) & |
1216 kFunctionFieldRegisterTypeMask) { | 1240 kFunctionFieldRegisterTypeMask) { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1299 | 1323 |
1300 default: | 1324 default: |
1301 if (checks == NORMAL) { | 1325 if (checks == NORMAL) { |
1302 return kImmediateType; | 1326 return kImmediateType; |
1303 } else { | 1327 } else { |
1304 return kUnsupported; | 1328 return kUnsupported; |
1305 } | 1329 } |
1306 } | 1330 } |
1307 return kUnsupported; | 1331 return kUnsupported; |
1308 } | 1332 } |
1309 | |
1310 #undef OpcodeToBitNumber | 1333 #undef OpcodeToBitNumber |
1311 #undef FunctionFieldToBitNumber | 1334 #undef FunctionFieldToBitNumber |
1335 | |
Ilija.Pavlovic1
2016/09/29 10:13:39
Why this code is transferred here from constants-m
balazs.kilvady
2016/09/29 10:57:41
Because of the template stuff. Template implementa
Ilija.Pavlovic1
2016/09/29 13:15:33
Acknowledged.
| |
1336 // ----------------------------------------------------------------------------- | |
1337 // Instructions. | |
1338 | |
1339 template <class P> | |
1340 bool InstructionGetters<P>::IsLinkingInstruction() const { | |
1341 switch (OpcodeFieldRaw()) { | |
1342 case JAL: | |
1343 return true; | |
1344 case POP76: | |
1345 if (RsFieldRawNoAssert() == JIALC) | |
1346 return true; // JIALC | |
1347 else | |
1348 return false; // BNEZC | |
1349 case REGIMM: | |
1350 switch (RtFieldRaw()) { | |
1351 case BGEZAL: | |
1352 case BLTZAL: | |
1353 return true; | |
1354 default: | |
1355 return false; | |
1356 } | |
1357 case SPECIAL: | |
1358 switch (FunctionFieldRaw()) { | |
1359 case JALR: | |
1360 return true; | |
1361 default: | |
1362 return false; | |
1363 } | |
1364 default: | |
1365 return false; | |
1366 } | |
1367 } | |
1368 | |
1369 template <class P> | |
1370 bool InstructionGetters<P>::IsTrap() const { | |
1371 if (OpcodeFieldRaw() != SPECIAL) { | |
1372 return false; | |
1373 } else { | |
1374 switch (FunctionFieldRaw()) { | |
1375 case BREAK: | |
1376 case TGE: | |
1377 case TGEU: | |
1378 case TLT: | |
1379 case TLTU: | |
1380 case TEQ: | |
1381 case TNE: | |
1382 return true; | |
1383 default: | |
1384 return false; | |
1385 } | |
1386 } | |
1387 } | |
1388 | |
1389 // static | |
1390 template <class T> | |
1391 bool InstructionGetters<T>::IsForbiddenAfterBranchInstr(Instr instr) { | |
1392 Opcode opcode = static_cast<Opcode>(instr & kOpcodeMask); | |
1393 switch (opcode) { | |
1394 case J: | |
1395 case JAL: | |
1396 case BEQ: | |
1397 case BNE: | |
1398 case BLEZ: // POP06 bgeuc/bleuc, blezalc, bgezalc | |
1399 case BGTZ: // POP07 bltuc/bgtuc, bgtzalc, bltzalc | |
1400 case BEQL: | |
1401 case BNEL: | |
1402 case BLEZL: // POP26 bgezc, blezc, bgec/blec | |
1403 case BGTZL: // POP27 bgtzc, bltzc, bltc/bgtc | |
1404 case BC: | |
1405 case BALC: | |
1406 case POP10: // beqzalc, bovc, beqc | |
1407 case POP30: // bnezalc, bnvc, bnec | |
1408 case POP66: // beqzc, jic | |
1409 case POP76: // bnezc, jialc | |
1410 return true; | |
1411 case REGIMM: | |
1412 switch (instr & kRtFieldMask) { | |
1413 case BLTZ: | |
1414 case BGEZ: | |
1415 case BLTZAL: | |
1416 case BGEZAL: | |
1417 return true; | |
1418 default: | |
1419 return false; | |
1420 } | |
1421 break; | |
1422 case SPECIAL: | |
1423 switch (instr & kFunctionFieldMask) { | |
1424 case JR: | |
1425 case JALR: | |
1426 return true; | |
1427 default: | |
1428 return false; | |
1429 } | |
1430 break; | |
1431 case COP1: | |
1432 switch (instr & kRsFieldMask) { | |
1433 case BC1: | |
1434 case BC1EQZ: | |
1435 case BC1NEZ: | |
1436 return true; | |
1437 break; | |
1438 default: | |
1439 return false; | |
1440 } | |
1441 break; | |
1442 default: | |
1443 return false; | |
1444 } | |
1445 } | |
1312 } // namespace internal | 1446 } // namespace internal |
1313 } // namespace v8 | 1447 } // namespace v8 |
1314 | 1448 |
1315 #endif // #ifndef V8_MIPS_CONSTANTS_H_ | 1449 #endif // #ifndef V8_MIPS_CONSTANTS_H_ |
OLD | NEW |