#ifndef __OPCODE_CLASS__H__ #define __OPCODE_CLASS__H__ //typedef struct { // DWORD VirtualAddress; // // union { // unsigned long Hex; // unsigned char Ascii[4]; // // struct { // unsigned offset : 16; // unsigned rt : 5; // unsigned rs : 5; // unsigned op : 6; // }; // // struct { // unsigned immediate : 16; // unsigned : 5; // unsigned base : 5; // unsigned : 6; // }; // // struct { // unsigned target : 26; // unsigned : 6; // }; // // struct { // unsigned funct : 6; // unsigned sa : 5; // unsigned rd : 5; // unsigned : 5; // unsigned : 5; // unsigned : 6; // }; // // struct { // unsigned : 6; // unsigned fd : 5; // unsigned fs : 5; // unsigned ft : 5; // unsigned fmt : 5; // unsigned : 6; // }; // }; //} OPCODE; #include "OpCode Analysis Class.h" enum StepType { StepNormal, StepDelaySlot, StepJump, //Recompiler Flags DoDelaySlot, InsideDelaySlot, DelaySlotDone, BranchCompiled }; //enum R4300iOpCodes //{ // R4300i_SPECIAL = 0, R4300i_REGIMM = 1, R4300i_J = 2, R4300i_JAL = 3, // R4300i_BEQ = 4, R4300i_BNE = 5, R4300i_BLEZ = 6, R4300i_BGTZ = 7, // R4300i_ADDI = 8, R4300i_ADDIU = 9, R4300i_SLTI = 10, R4300i_SLTIU = 11, // R4300i_ANDI = 12, R4300i_ORI = 13, R4300i_XORI = 14, R4300i_LUI = 15, // R4300i_CP0 = 16, R4300i_CP1 = 17, R4300i_BEQL = 20, R4300i_BNEL = 21, // R4300i_BLEZL = 22, R4300i_BGTZL = 23, R4300i_DADDI = 24, R4300i_DADDIU = 25, // R4300i_LDL = 26, R4300i_LDR = 27, R4300i_LB = 32, R4300i_LH = 33, // R4300i_LWL = 34, R4300i_LW = 35, R4300i_LBU = 36, R4300i_LHU = 37, // R4300i_LWR = 38, R4300i_LWU = 39, R4300i_SB = 40, R4300i_SH = 41, // R4300i_SWL = 42, R4300i_SW = 43, R4300i_SDL = 44, R4300i_SDR = 45, // R4300i_SWR = 46, R4300i_CACHE = 47, R4300i_LL = 48, R4300i_LWC1 = 49, // R4300i_LDC1 = 53, R4300i_LD = 55, R4300i_SC = 56, R4300i_SWC1 = 57, // R4300i_SDC1 = 61, R4300i_SDC2 = 62, R4300i_SD = 63 //}; // //enum R4300iSpecialOpCodes //{ // R4300i_SPECIAL_SLL = 0, R4300i_SPECIAL_SRL = 2, R4300i_SPECIAL_SRA = 3, // R4300i_SPECIAL_SLLV = 4, R4300i_SPECIAL_SRLV = 6, R4300i_SPECIAL_SRAV = 7, // R4300i_SPECIAL_JR = 8, R4300i_SPECIAL_JALR = 9, R4300i_SPECIAL_SYSCALL = 12, // R4300i_SPECIAL_BREAK = 13, R4300i_SPECIAL_SYNC = 15, R4300i_SPECIAL_MFHI = 16, // R4300i_SPECIAL_MTHI = 17, R4300i_SPECIAL_MFLO = 18, R4300i_SPECIAL_MTLO = 19, // R4300i_SPECIAL_DSLLV = 20, R4300i_SPECIAL_DSRLV = 22, R4300i_SPECIAL_DSRAV = 23, // R4300i_SPECIAL_MULT = 24, R4300i_SPECIAL_MULTU = 25, R4300i_SPECIAL_DIV = 26, // R4300i_SPECIAL_DIVU = 27, R4300i_SPECIAL_DMULT = 28, R4300i_SPECIAL_DMULTU = 29, // R4300i_SPECIAL_DDIV = 30, R4300i_SPECIAL_DDIVU = 31, R4300i_SPECIAL_ADD = 32, // R4300i_SPECIAL_ADDU = 33, R4300i_SPECIAL_SUB = 34, R4300i_SPECIAL_SUBU = 35, // R4300i_SPECIAL_AND = 36, R4300i_SPECIAL_OR = 37, R4300i_SPECIAL_XOR = 38, // R4300i_SPECIAL_NOR = 39, R4300i_SPECIAL_SLT = 42, R4300i_SPECIAL_SLTU = 43, // R4300i_SPECIAL_DADD = 44, R4300i_SPECIAL_DADDU = 45, R4300i_SPECIAL_DSUB = 46, // R4300i_SPECIAL_DSUBU = 47, R4300i_SPECIAL_TGE = 48, R4300i_SPECIAL_TGEU = 49, // R4300i_SPECIAL_TLT = 50, R4300i_SPECIAL_TLTU = 51, R4300i_SPECIAL_TEQ = 52, // R4300i_SPECIAL_TNE = 54, R4300i_SPECIAL_DSLL = 56, R4300i_SPECIAL_DSRL = 58, // R4300i_SPECIAL_DSRA = 59, R4300i_SPECIAL_DSLL32 = 60, R4300i_SPECIAL_DSRL32 = 62, // R4300i_SPECIAL_DSRA32 = 63 //}; // //enum R4300iRegImmOpCodes //{ // R4300i_REGIMM_BLTZ = 0, R4300i_REGIMM_BGEZ = 1, R4300i_REGIMM_BLTZL = 2, // R4300i_REGIMM_BGEZL = 3, R4300i_REGIMM_TGEI = 8, R4300i_REGIMM_TGEIU = 9, // R4300i_REGIMM_TLTI = 10, R4300i_REGIMM_TLTIU = 11, R4300i_REGIMM_TEQI = 12, // R4300i_REGIMM_TNEI = 14, R4300i_REGIMM_BLTZAL = 16, R4300i_REGIMM_BGEZAL = 17, // R4300i_REGIMM_BLTZALL = 18, R4300i_REGIMM_BGEZALL = 19, //}; // //enum R4300iCOP0OpCodes //{ // R4300i_COP0_MF = 0, R4300i_COP0_MT = 4 //}; // //enum R4300iCOP0C0OpCodes //{ // R4300i_COP0_CO_TLBR = 1, R4300i_COP0_CO_TLBWI = 2, R4300i_COP0_CO_TLBWR = 6, // R4300i_COP0_CO_TLBP = 8, R4300i_COP0_CO_ERET = 24, //}; // //enum R4300iCOP1OpCodes //{ // R4300i_COP1_MF = 0, R4300i_COP1_DMF = 1, R4300i_COP1_CF = 2, R4300i_COP1_MT = 4, // R4300i_COP1_DMT = 5, R4300i_COP1_CT = 6, R4300i_COP1_BC = 8, R4300i_COP1_S = 16, // R4300i_COP1_D = 17, R4300i_COP1_W = 20, R4300i_COP1_L = 21, //}; // //enum R4300iCOP1BcOpCodes //{ // R4300i_COP1_BC_BCF = 0, R4300i_COP1_BC_BCT = 1, R4300i_COP1_BC_BCFL = 2, // R4300i_COP1_BC_BCTL = 3, //}; // //enum R4300iCOP1FuntOpCodes //{ // R4300i_COP1_FUNCT_ADD = 0, R4300i_COP1_FUNCT_SUB = 1, R4300i_COP1_FUNCT_MUL = 2, // R4300i_COP1_FUNCT_DIV = 3, R4300i_COP1_FUNCT_SQRT = 4, R4300i_COP1_FUNCT_ABS = 5, // R4300i_COP1_FUNCT_MOV = 6, R4300i_COP1_FUNCT_NEG = 7, R4300i_COP1_FUNCT_ROUND_L = 8, // R4300i_COP1_FUNCT_TRUNC_L = 9, R4300i_COP1_FUNCT_CEIL_L = 10,R4300i_COP1_FUNCT_FLOOR_L = 11, // R4300i_COP1_FUNCT_ROUND_W = 12,R4300i_COP1_FUNCT_TRUNC_W = 13,R4300i_COP1_FUNCT_CEIL_W = 14, // R4300i_COP1_FUNCT_FLOOR_W = 15,R4300i_COP1_FUNCT_CVT_S = 32,R4300i_COP1_FUNCT_CVT_D = 33, // R4300i_COP1_FUNCT_CVT_W = 36,R4300i_COP1_FUNCT_CVT_L = 37,R4300i_COP1_FUNCT_C_F = 48, // R4300i_COP1_FUNCT_C_UN = 49,R4300i_COP1_FUNCT_C_EQ = 50,R4300i_COP1_FUNCT_C_UEQ = 51, // R4300i_COP1_FUNCT_C_OLT = 52,R4300i_COP1_FUNCT_C_ULT = 53,R4300i_COP1_FUNCT_C_OLE = 54, // R4300i_COP1_FUNCT_C_ULE = 55,R4300i_COP1_FUNCT_C_SF = 56,R4300i_COP1_FUNCT_C_NGLE = 57, // R4300i_COP1_FUNCT_C_SEQ = 58,R4300i_COP1_FUNCT_C_NGL = 59,R4300i_COP1_FUNCT_C_LT = 60, // R4300i_COP1_FUNCT_C_NGE = 61,R4300i_COP1_FUNCT_C_LE = 62,R4300i_COP1_FUNCT_C_NGT = 63, //}; #define FPR_Type(Reg) (Reg) == R4300i_COP1_S ? "S" : (Reg) == R4300i_COP1_D ? "D" :\ (Reg) == R4300i_COP1_W ? "W" : "L" enum { OpCode_Size = 4}; enum PERM_LOOP { PermLoop_None, PermLoop_Jump, PermLoop_Delay }; class CRecompilerOps; class COpcode : public COpcodeAnalysis { friend CRecompilerOps; //Can manipulate how the opcode moves CMipsMemory * const _MMU; CRegisters * const _Reg; DWORD const m_OpLen; //Length of the current opcode (MIPS will always be 4) bool const m_FixedOpcodeCount; //Is the opcode count fixed or is it variable float const m_OpcodeCount; //how many cycles is the fixed opcode count StepType m_NextStep; //How to go to the next opcode, is a jump or the next opcode ? DWORD m_JumpLocation; //If the opcode is going to jump it will jump to this address public: //Constructor/deconstructor COpcode ( CMipsMemory * MMU, DWORD VirtualAddress ); //Geting/changing details about the opcode stored bool Next ( void ); //move to the next opcode, if it is a jump returns true inline DWORD PC ( void ) { return m_opcode.VirtualAddress; } //current VAddr StepType NextStep ( void ) { return m_NextStep; } void SetJump ( DWORD Target, bool Delay ); bool SetPC ( DWORD VirtualAddress ); //Info about the opcode DWORD DelaySize ( void ) { return m_OpLen; } //How big is the delay slot opcode float CycleCount ( void ); inline bool InDelaySlot ( void ) const { return m_NextStep != StepNormal; } //Contains the break down of the opcode OPCODE m_opcode; //Flags bool m_FlagSet; //A Flag was set bool m_ExectionJumped; //Was the last next moved to a new location from a jump PERM_LOOP m_InPermLoop; //Jumped to same address with delay slot not effecting the operation //Flags used in LWL/SWL/etc .. instructions static QWORD const LDL_MASK[8], LDR_MASK[8], SDL_MASK[8], SDR_MASK[8]; static DWORD const LWL_MASK[4], LWR_MASK[4], SWL_MASK[4], SWR_MASK[4]; static int const WL_SHIFT[4], WR_SHIFT[4], DL_SHIFT[8], DR_SHIFT[8]; }; #endif