Chromium Code Reviews| 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 |