private static string decodeMoveControlToFromCoprocessorOperation(string opcode, uint operation) { GP_REGISTER rt = (GP_REGISTER)((operation >> 16) & 0x1F); byte rd = (byte)((operation >> 11) & 0x1F); return(opcode + " " + getGRPRegName(rt) + ", $v" + rd); }
private static string decodeBranchOperation(string opcode, uint operation, uint address) { GP_REGISTER src = (GP_REGISTER)((operation >> 21) & 0x1F); short imm = (short)((operation & 0xFFFF) << 2); uint current_offset = (uint)((address + 4) + imm); return(opcode + " " + getGRPRegName(src) + ", 0x" + (current_offset).ToString("X8")); }
private static string decodeSpecialShiftOperation(string opcode, uint operation) { GP_REGISTER dest = (GP_REGISTER)((operation >> 11) & 0x1F); GP_REGISTER src = (GP_REGISTER)((operation >> 16) & 0x1F); int imm = (int)((operation >> 6) & 0x1F); return(opcode + " " + getGRPRegName(dest) + ", " + getGRPRegName(src) + ", " + imm); }
private static string decodeBranchEqualsOperation(string opcode, uint operation, uint address) { GP_REGISTER src1 = (GP_REGISTER)((operation >> 21) & 0x1F); GP_REGISTER src2 = (GP_REGISTER)((operation >> 16) & 0x1F); short imm = (short)((operation & 0xFFFF) << 2); //Console.WriteLine("("+address.ToString("X8")+")immediate = " + imm); uint current_offset = (uint)((address + 4) + imm); return(opcode + " " + getGRPRegName(src1) + ", " + getGRPRegName(src2) + ", 0x" + current_offset.ToString("X8")); }
private static string getGRPRegName(GP_REGISTER reg) { if (usingRegNames) { return(reg.ToString()); } else { return("r" + ((byte)reg).ToString()); } }
private static string decodeThreeRegisterOperation(string opcode, uint operation, bool swapRT_RS) { GP_REGISTER dest = (GP_REGISTER)((operation >> 11) & 0x1F); GP_REGISTER src1 = (GP_REGISTER)((operation >> 21) & 0x1F); GP_REGISTER src2 = (GP_REGISTER)((operation >> 16) & 0x1F); if (!swapRT_RS) { return(opcode + " " + getGRPRegName(dest) + ", " + getGRPRegName(src1) + ", " + getGRPRegName(src2)); } else { return(opcode + " " + getGRPRegName(dest) + ", " + getGRPRegName(src2) + ", " + getGRPRegName(src1)); } }
private static string decodeTwoRegistersWithImmediateOperation(string opcode, uint operation) { GP_REGISTER dest = (GP_REGISTER)((operation >> 16) & 0x1F); GP_REGISTER src = (GP_REGISTER)((operation >> 21) & 0x1F); short imm = (short)(operation & 0xFFFF); if (imm < 0) { return(opcode + " " + getGRPRegName(dest) + ", " + getGRPRegName(src) + ", -0x" + (-imm).ToString("X4")); } else { return(opcode + " " + getGRPRegName(dest) + ", " + getGRPRegName(src) + ", 0x" + imm.ToString("X4")); } }
private static string decodeNormalMIPSLoadStore(string opcode, uint operation) { GP_REGISTER dest = (GP_REGISTER)((operation >> 16) & 0x1F); GP_REGISTER base_ = (GP_REGISTER)((operation >> 21) & 0x1F); short imm = (short)(operation & 0xFFFF); if (imm < 0) { opcode += " " + getGRPRegName(dest) + ", -0x" + (-imm).ToString("X4") + "(" + getGRPRegName(base_) + ")"; } else { opcode += " " + getGRPRegName(dest) + ", 0x" + imm.ToString("X4") + "(" + getGRPRegName(base_) + ")"; } return(opcode); }
private static string decodeCOP0Operation(uint operation) { string str = "Unimplemented (COP0 operation)"; byte mt = (byte)((operation >> 21) & 0x1F); GP_REGISTER rt = (GP_REGISTER)((operation >> 16) & 0x1F); CP0_REGISTER rd = (CP0_REGISTER)((operation >> 11) & 0x1F); switch (mt) { case 0x00: // MFC0 str = "mfc0 " + getGRPRegName(rt) + ", " + getCP0RegName(rd); break; case 0x04: // MTC0 str = "mtc0 " + getGRPRegName(rt) + ", " + getCP0RegName(rd); break; } return(str); }
public static string decodeOPERATION(uint operation, uint address, OPTIONS options) { if (operation == 0x00000000) { return("nop"); } usingRegNames = options.HasFlag(OPTIONS.USE_GP_NAMES); usingLongForm = options.HasFlag(OPTIONS.USE_LONG_FORM); usingArmipsCP0Names = options.HasFlag(OPTIONS.USE_ARMIPS_CP0_NAMES); RSP_OPCODE opcode = (RSP_OPCODE)((operation >> 26) & 0x3F); string str = "Unimplemented (opcode: " + Convert.ToString((int)opcode, 2) + "b)"; switch (opcode) { case RSP_OPCODE.J: case RSP_OPCODE.JAL: str = opcode.ToString().ToLower() + " 0x0" + ((operation & 0x03FFFFFF) << 2).ToString("X7"); break; case RSP_OPCODE.BEQ: case RSP_OPCODE.BNE: str = decodeBranchEqualsOperation(opcode.ToString().ToLower(), operation, address); break; case RSP_OPCODE.BLEZ: case RSP_OPCODE.BGTZ: str = decodeBranchOperation(opcode.ToString().ToLower(), operation, address); break; case RSP_OPCODE.ADDI: case RSP_OPCODE.ADDIU: case RSP_OPCODE.SLTI: case RSP_OPCODE.SLTIU: case RSP_OPCODE.ANDI: case RSP_OPCODE.ORI: case RSP_OPCODE.XORI: str = decodeTwoRegistersWithImmediateOperation(opcode.ToString().ToLower(), operation); break; case RSP_OPCODE.LUI: str = decodeOneRegisterWithImmediateOperation(opcode.ToString().ToLower(), operation); break; case RSP_OPCODE.COP0: str = decodeCOP0Operation(operation); break; case RSP_OPCODE.COP2: { //str = "Vector operation!"; str = decodeCOP2Operation(operation); } break; case RSP_OPCODE.LB: case RSP_OPCODE.LH: case RSP_OPCODE.LW: case RSP_OPCODE.LBU: case RSP_OPCODE.LHU: case RSP_OPCODE.LWU: case RSP_OPCODE.SB: case RSP_OPCODE.SH: case RSP_OPCODE.SW: str = decodeNormalMIPSLoadStore(opcode.ToString().ToLower(), operation); break; case RSP_OPCODE.LWC2: { str = decodeLoadStoreOperation(operation, "l"); } break; case RSP_OPCODE.SWC2: { str = decodeLoadStoreOperation(operation, "s"); } break; case RSP_OPCODE.REGIMM: { byte subop = (byte)((operation >> 16) & 0x1F); switch (subop) { case 0x00: // BLTZ operation str = decodeBranchOperation("bltz", operation, address); break; case 0x01: // BGEZ operation str = decodeBranchOperation("bgez", operation, address); break; case 0x10: // BLTZAL operation str = decodeBranchOperation("bltzal", operation, address); break; case 0x11: // BGEZAL operation str = decodeBranchOperation("bgezal", operation, address); break; } } break; case RSP_OPCODE.SPECIAL: { byte subop = (byte)(operation & 0x3F); switch (subop) { case 0x00: // SLL operation str = decodeSpecialShiftOperation("sll", operation); break; case 0x02: // SRL operation str = decodeSpecialShiftOperation("srl", operation); break; case 0x03: // SRA operation str = decodeSpecialShiftOperation("sra", operation); break; case 0x04: // SLLV operation str = decodeThreeRegisterOperation("sllv", operation, true); break; case 0x06: // SRLV operation str = decodeThreeRegisterOperation("srlv", operation, true); break; case 0x07: // SRAV operation str = decodeThreeRegisterOperation("srav", operation, true); break; case 0x08: // JR operation str = "jr " + getGRPRegName(((GP_REGISTER)((operation >> 21) & 0x1F))); break; case 0x09: // JALR operation { GP_REGISTER return_reg = (GP_REGISTER)((operation >> 11) & 0x1F); if (return_reg == GP_REGISTER.ra) { str = "jalr " + getGRPRegName(((GP_REGISTER)((operation >> 21) & 0x1F))); } else { str = "jalr " + getGRPRegName(return_reg) + ", " + getGRPRegName(((GP_REGISTER)((operation >> 21) & 0x1F))); } } break; case 0x0D: // BREAK operation str = "break " + ((operation >> 6) & 0xFFFFF); break; case 0x20: // ADD operation str = decodeThreeRegisterOperation("add", operation, false); break; case 0x21: // ADDU operation str = decodeThreeRegisterOperation("addu", operation, false); break; case 0x22: // SUB operation str = decodeThreeRegisterOperation("sub", operation, false); break; case 0x23: // SUBU operation str = decodeThreeRegisterOperation("subu", operation, false); break; case 0x24: // AND operation str = decodeThreeRegisterOperation("and", operation, false); break; case 0x25: // OR operation str = decodeThreeRegisterOperation("or", operation, false); break; case 0x26: // XOR operation str = decodeThreeRegisterOperation("xor", operation, false); break; case 0x27: // NOR operation str = decodeThreeRegisterOperation("nor", operation, false); break; case 0x2A: // SLT operation str = decodeThreeRegisterOperation("slt", operation, false); break; case 0x2B: // SLTU operation str = decodeThreeRegisterOperation("sltu", operation, false); break; default: str = "Unimplemented (special: " + Convert.ToString(subop, 2) + "b)"; break; } } break; } return(str); }
private static string decodeOneRegisterWithImmediateOperation(string opcode, uint operation) { GP_REGISTER dest = (GP_REGISTER)((operation >> 16) & 0x1F); return(opcode + " " + getGRPRegName(dest) + ", 0x" + (operation & 0xFFFF).ToString("X4")); }