Index: src/mips/constants-mips.h |
diff --git a/src/mips/constants-mips.h b/src/mips/constants-mips.h |
index 37ac2336bfd184542e5ad5712bdaa5541878921e..fcbda801919ed2ced32babf0b1e47a590f8ca0ed 100644 |
--- a/src/mips/constants-mips.h |
+++ b/src/mips/constants-mips.h |
@@ -820,6 +820,7 @@ const Instr rtCallRedirInstr = SPECIAL | BREAK | call_rt_redirected << 6; |
// A nop instruction. (Encoding of sll 0 0 0). |
const Instr nopInstr = 0; |
+ |
class Instruction { |
public: |
enum { |
@@ -858,9 +859,57 @@ class Instruction { |
kUnsupported = -1 |
}; |
- // Get the encoding type of the instruction. |
- Type InstructionType() const; |
+ enum TypeChecks { NORMAL, EXTRA }; |
+ |
+ |
+#define OpcodeToBitNumber(opcode) \ |
+ (1ULL << (static_cast<uint32_t>(opcode) >> kOpcodeShift)) |
+ |
+ static const uint64_t kOpcodeImmediateTypeMask = |
+ OpcodeToBitNumber(REGIMM) | OpcodeToBitNumber(BEQ) | |
+ OpcodeToBitNumber(BNE) | OpcodeToBitNumber(BLEZ) | |
+ OpcodeToBitNumber(BGTZ) | OpcodeToBitNumber(ADDI) | |
+ OpcodeToBitNumber(DADDI) | OpcodeToBitNumber(ADDIU) | |
+ OpcodeToBitNumber(SLTI) | OpcodeToBitNumber(SLTIU) | |
+ OpcodeToBitNumber(ANDI) | OpcodeToBitNumber(ORI) | |
+ OpcodeToBitNumber(XORI) | OpcodeToBitNumber(LUI) | |
+ OpcodeToBitNumber(BEQL) | OpcodeToBitNumber(BNEL) | |
+ OpcodeToBitNumber(BLEZL) | OpcodeToBitNumber(BGTZL) | |
+ OpcodeToBitNumber(POP66) | OpcodeToBitNumber(POP76) | |
+ OpcodeToBitNumber(LB) | OpcodeToBitNumber(LH) | OpcodeToBitNumber(LWL) | |
+ OpcodeToBitNumber(LW) | OpcodeToBitNumber(LBU) | OpcodeToBitNumber(LHU) | |
+ OpcodeToBitNumber(LWR) | OpcodeToBitNumber(SB) | OpcodeToBitNumber(SH) | |
+ OpcodeToBitNumber(SWL) | OpcodeToBitNumber(SW) | OpcodeToBitNumber(SWR) | |
+ OpcodeToBitNumber(LWC1) | OpcodeToBitNumber(LDC1) | |
+ OpcodeToBitNumber(SWC1) | OpcodeToBitNumber(SDC1) | |
+ OpcodeToBitNumber(PCREL) | OpcodeToBitNumber(BC) | |
+ OpcodeToBitNumber(BALC); |
+ |
+#define FunctionFieldToBitNumber(function) (1ULL << function) |
+ |
+ static const uint64_t kFunctionFieldRegisterTypeMask = |
+ FunctionFieldToBitNumber(JR) | FunctionFieldToBitNumber(JALR) | |
+ FunctionFieldToBitNumber(BREAK) | FunctionFieldToBitNumber(SLL) | |
+ FunctionFieldToBitNumber(SRL) | FunctionFieldToBitNumber(SRA) | |
+ FunctionFieldToBitNumber(SLLV) | FunctionFieldToBitNumber(SRLV) | |
+ FunctionFieldToBitNumber(SRAV) | FunctionFieldToBitNumber(MFHI) | |
+ FunctionFieldToBitNumber(MFLO) | FunctionFieldToBitNumber(MULT) | |
+ FunctionFieldToBitNumber(MULTU) | FunctionFieldToBitNumber(DIV) | |
+ FunctionFieldToBitNumber(DIVU) | FunctionFieldToBitNumber(ADD) | |
+ FunctionFieldToBitNumber(ADDU) | FunctionFieldToBitNumber(SUB) | |
+ FunctionFieldToBitNumber(SUBU) | FunctionFieldToBitNumber(AND) | |
+ FunctionFieldToBitNumber(OR) | FunctionFieldToBitNumber(XOR) | |
+ FunctionFieldToBitNumber(NOR) | FunctionFieldToBitNumber(SLT) | |
+ FunctionFieldToBitNumber(SLTU) | FunctionFieldToBitNumber(TGE) | |
+ FunctionFieldToBitNumber(TGEU) | FunctionFieldToBitNumber(TLT) | |
+ FunctionFieldToBitNumber(TLTU) | FunctionFieldToBitNumber(TEQ) | |
+ FunctionFieldToBitNumber(TNE) | FunctionFieldToBitNumber(MOVZ) | |
+ FunctionFieldToBitNumber(MOVN) | FunctionFieldToBitNumber(MOVCI) | |
+ FunctionFieldToBitNumber(SELEQZ_S) | FunctionFieldToBitNumber(SELNEZ_S); |
+ |
+ // Get the encoding type of the instruction. |
+ inline Type InstructionType(TypeChecks checks = NORMAL) const; |
// Accessors for the different named fields used in the MIPS encoding. |
inline Opcode OpcodeValue() const { |
@@ -1044,6 +1093,91 @@ const int kBArgsSlotsSize = 0 * Instruction::kInstrSize; |
const int kBranchReturnOffset = 2 * Instruction::kInstrSize; |
+ |
+Instruction::Type Instruction::InstructionType(TypeChecks checks) const { |
+ if (checks == EXTRA) { |
+ if (OpcodeToBitNumber(OpcodeFieldRaw()) & kOpcodeImmediateTypeMask) { |
+ return kImmediateType; |
+ } |
+ } |
+ switch (OpcodeFieldRaw()) { |
+ case SPECIAL: |
+ if (checks == EXTRA) { |
+ if (FunctionFieldToBitNumber(FunctionFieldRaw()) & |
+ kFunctionFieldRegisterTypeMask) { |
+ return kRegisterType; |
+ } else { |
+ return kUnsupported; |
+ } |
+ } else { |
+ return kRegisterType; |
+ } |
+ break; |
+ case SPECIAL2: |
+ switch (FunctionFieldRaw()) { |
+ case MUL: |
+ case CLZ: |
+ return kRegisterType; |
+ default: |
+ return kUnsupported; |
+ } |
+ break; |
+ case SPECIAL3: |
+ switch (FunctionFieldRaw()) { |
+ case INS: |
+ case EXT: |
+ return kRegisterType; |
+ case BSHFL: { |
+ int sa = SaFieldRaw() >> kSaShift; |
+ switch (sa) { |
+ case BITSWAP: |
+ return kRegisterType; |
+ case WSBH: |
+ case SEB: |
+ case SEH: |
+ return kUnsupported; |
+ } |
+ sa >>= kBp2Bits; |
+ switch (sa) { |
+ case ALIGN: |
+ return kRegisterType; |
+ default: |
+ return kUnsupported; |
+ } |
+ } |
+ default: |
+ return kUnsupported; |
+ } |
+ break; |
+ case COP1: // Coprocessor instructions. |
+ switch (RsFieldRawNoAssert()) { |
+ case BC1: // Branch on coprocessor condition. |
+ case BC1EQZ: |
+ case BC1NEZ: |
+ return kImmediateType; |
+ default: |
+ return kRegisterType; |
+ } |
+ break; |
+ case COP1X: |
+ return kRegisterType; |
+ |
+ // 26 bits immediate type instructions. e.g.: j imm26. |
+ case J: |
+ case JAL: |
+ return kJumpType; |
+ |
+ default: |
+ if (checks == NORMAL) { |
+ return kImmediateType; |
+ } else { |
+ return kUnsupported; |
+ } |
+ } |
+} |
+ |
+#undef OpcodeToBitNumber |
+#undef FunctionFieldToBitNumber |
} } // namespace v8::internal |
#endif // #ifndef V8_MIPS_CONSTANTS_H_ |