From 282317c46e1548b33235fe680d850ec3fd5192ca Mon Sep 17 00:00:00 2001 From: Ty Date: Mon, 3 Feb 2025 16:52:27 -0500 Subject: [PATCH] Debugger: Add opcodes and fixes to the assembler (#12267) --- pcsx2/DebugTools/DisASM.h | 1 + pcsx2/DebugTools/DisR5900asm.cpp | 22 +- pcsx2/DebugTools/MipsAssembler.cpp | 443 +++++++++++------------ pcsx2/DebugTools/MipsAssembler.h | 1 - pcsx2/DebugTools/MipsAssemblerTables.cpp | 271 +++++++++++++- pcsx2/DebugTools/MipsAssemblerTables.h | 11 + 6 files changed, 510 insertions(+), 239 deletions(-) diff --git a/pcsx2/DebugTools/DisASM.h b/pcsx2/DebugTools/DisASM.h index 6f43969e1c6ca..4943dc1be5423 100644 --- a/pcsx2/DebugTools/DisASM.h +++ b/pcsx2/DebugTools/DisASM.h @@ -25,6 +25,7 @@ #define DECODE_C0BC ((disasmOpcode >> 16) & 0x03) #define DECODE_C1BC ((disasmOpcode >> 16) & 0x03) #define DECODE_C2BC ((disasmOpcode >> 16) & 0x03) +#define DECODE_ILOCK (disasmOpcode & 1) //IOP diff --git a/pcsx2/DebugTools/DisR5900asm.cpp b/pcsx2/DebugTools/DisR5900asm.cpp index 43c13fd9f4675..0e516cc78cafc 100644 --- a/pcsx2/DebugTools/DisR5900asm.cpp +++ b/pcsx2/DebugTools/DisR5900asm.cpp @@ -1073,11 +1073,11 @@ void MTSAH( std::string& output ) { _sap("mtsah\t%s, 0x%04X") GPR_REG[DECODE_R //***************************SPECIAL 2 CPU OPCODES******************* const char* pmfhl_sub[] = {"lw", "uw", "slw", "lh", "sh", "??", "??", "??"}; -void MADD( std::string& output ) { _sap("madd\t%s, %s %s") GPR_REG[DECODE_RD],GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); } -void MADDU( std::string& output ) { _sap("maddu\t%s, %s %s") GPR_REG[DECODE_RD],GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]);} +void MADD( std::string& output ) { _sap("madd\t%s, %s, %s") GPR_REG[DECODE_RD],GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); } +void MADDU( std::string& output ) { _sap("maddu\t%s, %s, %s") GPR_REG[DECODE_RD],GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]);} void PLZCW( std::string& output ) { _sap("plzcw\t%s, %s") GPR_REG[DECODE_RD], GPR_REG[DECODE_RS]); } -void MADD1( std::string& output ) { _sap("madd1\t%s, %s %s") GPR_REG[DECODE_RD],GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); } -void MADDU1( std::string& output ) { _sap("maddu1\t%s, %s %s") GPR_REG[DECODE_RD],GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); } +void MADD1( std::string& output ) { _sap("madd1\t%s, %s, %s") GPR_REG[DECODE_RD],GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); } +void MADDU1( std::string& output ) { _sap("maddu1\t%s, %s, %s") GPR_REG[DECODE_RD],GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); } void MFHI1( std::string& output ) { _sap("mfhi1\t%s") GPR_REG[DECODE_RD]); } void MTHI1( std::string& output ) { _sap("mthi1\t%s") GPR_REG[DECODE_RS]); } void MFLO1( std::string& output ) { _sap("mflo1\t%s") GPR_REG[DECODE_RD]); } @@ -1125,11 +1125,11 @@ void PEXT5( std::string& output ) { _sap( "pext5\t%s, %s") GPR_REG[DECODE_R void PPAC5( std::string& output ) { _sap( "ppac5\t%s, %s") GPR_REG[DECODE_RD], GPR_REG[DECODE_RT]); } //**********END OF MMI0 OPCODES********************************* //**********MMI1 OPCODES************************************** -void PABSW( std::string& output ){ _sap( "pabsw%s, %s") GPR_REG[DECODE_RD], GPR_REG[DECODE_RT]); } +void PABSW( std::string& output ){ _sap( "pabsw\t%s, %s") GPR_REG[DECODE_RD], GPR_REG[DECODE_RT]); } void PCEQW( std::string& output ){ _sap( "pceqw\t%s, %s, %s") GPR_REG[DECODE_RD], GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); } void PMINW( std::string& output ){ _sap( "pminw\t%s, %s, %s") GPR_REG[DECODE_RD], GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); } void PADSBH( std::string& output ){ _sap( "padsbh\t%s, %s, %s") GPR_REG[DECODE_RD], GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); } -void PABSH( std::string& output ){ _sap( "pabsh%s, %s") GPR_REG[DECODE_RD], GPR_REG[DECODE_RT]); } +void PABSH( std::string& output ){ _sap( "pabsh\t%s, %s") GPR_REG[DECODE_RD], GPR_REG[DECODE_RT]); } void PCEQH( std::string& output ){ _sap( "pceqh\t%s, %s, %s") GPR_REG[DECODE_RD], GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); } void PMINH( std::string& output ){ _sap( "pminh\t%s, %s, %s") GPR_REG[DECODE_RD], GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); } void PCEQB( std::string& output ){ _sap( "pceqb\t%s, %s, %s") GPR_REG[DECODE_RD], GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); } @@ -1148,7 +1148,7 @@ void QFSRV( std::string& output ) { _sap( "qfsrv\t%s, %s, %s") GPR_REG[DECODE_ void PMADDW( std::string& output ){ _sap( "pmaddw\t%s, %s, %s") GPR_REG[DECODE_RD], GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); } void PSLLVW( std::string& output ){ _sap( "psllvw\t%s, %s, %s") GPR_REG[DECODE_RD], GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); } void PSRLVW( std::string& output ){ _sap( "psrlvw\t%s, %s, %s") GPR_REG[DECODE_RD], GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); } -void PMSUBW( std::string& output ){ _sap( "msubw\t%s, %s, %s") GPR_REG[DECODE_RD], GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); } +void PMSUBW( std::string& output ){ _sap( "pmsubw\t%s, %s, %s") GPR_REG[DECODE_RD], GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); } void PMFHI( std::string& output ){ _sap( "pmfhi\t%s") GPR_REG[DECODE_RD]); } void PMFLO( std::string& output ){ _sap( "pmflo\t%s") GPR_REG[DECODE_RD]); } void PINTH( std::string& output ){ _sap( "pinth\t%s, %s, %s") GPR_REG[DECODE_RD], GPR_REG[DECODE_RS], GPR_REG[DECODE_RT]); } @@ -1247,10 +1247,10 @@ void CVT_S( std::string& output ){ _sap("cvt.s.w\t%s, %s") COP1_REG_FP[DECODE //**************************************************************************** //** COP2 - (VU0) ** //**************************************************************************** -void P_QMFC2( std::string& output ){ _sap("qmfc2\t%s, %s") GPR_REG[DECODE_RT], COP2_REG_FP[DECODE_FS]); } -void P_CFC2( std::string& output ){ _sap("cfc2\t%s, %s") GPR_REG[DECODE_RT], COP2_REG_CTL[DECODE_FS]); } -void P_QMTC2( std::string& output ){ _sap("qmtc2\t%s, %s") GPR_REG[DECODE_RT], COP2_REG_FP[DECODE_FS]); } -void P_CTC2( std::string& output ){ _sap("ctc2\t%s, %s") GPR_REG[DECODE_RT], COP2_REG_CTL[DECODE_FS]); } +void P_QMFC2( std::string& output ){ _sap("qmfc2%s\t%s, %s") DECODE_ILOCK ? ".i" : "", GPR_REG[DECODE_RT], COP2_REG_FP[DECODE_FS]); } +void P_CFC2( std::string& output ){ _sap("cfc2%s\t%s, %s") DECODE_ILOCK ? ".i" : "", GPR_REG[DECODE_RT], COP2_REG_CTL[DECODE_FS]); } +void P_QMTC2( std::string& output ){ _sap("qmtc2%s\t%s, %s") DECODE_ILOCK ? ".i" : "", GPR_REG[DECODE_RT], COP2_REG_FP[DECODE_FS]); } +void P_CTC2( std::string& output ){ _sap("ctc2%s\t%s, %s") DECODE_ILOCK ? ".i" : "", GPR_REG[DECODE_RT], COP2_REG_CTL[DECODE_FS]); } void P_BC2F( std::string& output ){ output += "bc2f\t"; offset_decode(output); } void P_BC2T( std::string& output ){ output += "bc2t\t"; offset_decode(output); } void P_BC2FL( std::string& output ){ output += "bc2fl\t"; offset_decode(output); } diff --git a/pcsx2/DebugTools/MipsAssembler.cpp b/pcsx2/DebugTools/MipsAssembler.cpp index b6286538bfad0..caa9bf5cfae2f 100644 --- a/pcsx2/DebugTools/MipsAssembler.cpp +++ b/pcsx2/DebugTools/MipsAssembler.cpp @@ -3,7 +3,10 @@ #include "MipsAssembler.h" -#include +#include +#include +#include +#include // just an empty class, so that it's not necessary to remove all the calls manually // will make it easier to update if there are changes later on @@ -24,133 +27,176 @@ class Logger }; +constexpr auto MipsRegisters = std::to_array({ + { "r0", 0}, { "zero", 0}, { "$0", 0 }, { "$zero", 0 }, + { "at", 1}, { "r1", 1}, { "$1", 1 }, { "$at", 1 }, + { "v0", 2}, { "r2", 2}, { "$v0", 2 }, + { "v1", 3}, { "r3", 3}, { "$v1", 3 }, + { "a0", 4}, { "r4", 4}, { "$a0", 4 }, + { "a1", 5}, { "r5", 5}, { "$a1", 5 }, + { "a2", 6}, { "r6", 6}, { "$a2", 6 }, + { "a3", 7}, { "r7", 7}, { "$a3", 7 }, + { "t0", 8}, { "r8", 8}, { "$t0", 8 }, + { "t1", 9}, { "r9", 9}, { "$t1", 9 }, + { "t2", 10}, { "r10", 10}, { "$t2", 10 }, + { "t3", 11}, { "r11", 11}, { "$t3", 11 }, + { "t4", 12}, { "r12", 12}, { "$t4", 12 }, + { "t5", 13}, { "r13", 13}, { "$t5", 13 }, + { "t6", 14}, { "r14", 14}, { "$t6", 14 }, + { "t7", 15}, { "r15", 15}, { "$t7", 15 }, + { "s0", 16}, { "r16", 16}, { "$s0", 16 }, + { "s1", 17}, { "r17", 17}, { "$s1", 17 }, + { "s2", 18}, { "r18", 18}, { "$s2", 18 }, + { "s3", 19}, { "r19", 19}, { "$s3", 19 }, + { "s4", 20}, { "r20", 20}, { "$s4", 20 }, + { "s5", 21}, { "r21", 21}, { "$s5", 21 }, + { "s6", 22}, { "r22", 22}, { "$s6", 22 }, + { "s7", 23}, { "r23", 23}, { "$s7", 23 }, + { "t8", 24}, { "r24", 24}, { "$t8", 24 }, + { "t9", 25}, { "r25", 25}, { "$t9", 25 }, + { "k0", 26}, { "r26", 26}, { "$k0", 26 }, + { "k1", 27}, { "r27", 27}, { "$k1", 27 }, + { "gp", 28}, { "r28", 28}, { "$gp", 28 }, + { "sp", 29}, { "r29", 29}, { "$sp", 29 }, + { "fp", 30}, { "r30", 30}, { "$fp", 30 }, + { "ra", 31}, { "r31", 31}, { "$ra", 31 } +}); + +constexpr auto MipsFloatRegisters = std::to_array({ + { "f0", 0, }, { "$f0", 0 }, + { "f1", 1, }, { "$f1", 1 }, + { "f2", 2, }, { "$f2", 2 }, + { "f3", 3, }, { "$f3", 3 }, + { "f4", 4, }, { "$f4", 4 }, + { "f5", 5, }, { "$f5", 5 }, + { "f6", 6, }, { "$f6", 6 }, + { "f7", 7, }, { "$f7", 7 }, + { "f8", 8, }, { "$f8", 8 }, + { "f9", 9, }, { "$f9", 9 }, + { "f00", 0,}, { "$f00", 0 }, + { "f01", 1,}, { "$f01", 1 }, + { "f02", 2,}, { "$f02", 2 }, + { "f03", 3,}, { "$f03", 3 }, + { "f04", 4,}, { "$f04", 4 }, + { "f05", 5,}, { "$f05", 5 }, + { "f06", 6,}, { "$f06", 6 }, + { "f07", 7,}, { "$f07", 7 }, + { "f08", 8,}, { "$f08", 8 }, + { "f09", 9,}, { "$f09", 9 }, + { "f10", 10 }, { "$f10", 10 }, + { "f11", 11 }, { "$f11", 11 }, + { "f12", 12 }, { "$f12", 12 }, + { "f13", 13 }, { "$f13", 13 }, + { "f14", 14 }, { "$f14", 14 }, + { "f15", 15 }, { "$f15", 15 }, + { "f16", 16 }, { "$f16", 16 }, + { "f17", 17 }, { "$f17", 17 }, + { "f18", 18 }, { "$f18", 18 }, + { "f19", 19 }, { "$f19", 19 }, + { "f20", 20 }, { "$f20", 20 }, + { "f21", 21 }, { "$f21", 21 }, + { "f22", 22 }, { "$f22", 22 }, + { "f23", 23 }, { "$f23", 23 }, + { "f24", 24 }, { "$f24", 24 }, + { "f25", 25 }, { "$f25", 25 }, + { "f26", 26 }, { "$f26", 26 }, + { "f27", 27 }, { "$f27", 27 }, + { "f28", 28 }, { "$f28", 28 }, + { "f29", 29 }, { "$f29", 29 }, + { "f30", 30 }, { "$f30", 30 }, + { "f31", 31 }, { "$f31", 31 } +}); + +constexpr auto MipsPs2Cop2FpRegisters = std::to_array({ + { "vf0", 0 }, { "$vf0", 0 }, + { "vf1", 1 }, { "$vf1", 1 }, + { "vf2", 2 }, { "$vf2", 2 }, + { "vf3", 3 }, { "$vf3", 3 }, + { "vf4", 4 }, { "$vf4", 4 }, + { "vf5", 5 }, { "$vf5", 5 }, + { "vf6", 6 }, { "$vf6", 6 }, + { "vf7", 7 }, { "$vf7", 7 }, + { "vf8", 8 }, { "$vf8", 8 }, + { "vf9", 9 }, { "$vf9", 9 }, + { "vf00", 0 }, { "$vf00", 0 }, + { "vf01", 1 }, { "$vf01", 1 }, + { "vf02", 2 }, { "$vf02", 2 }, + { "vf03", 3 }, { "$vf03", 3 }, + { "vf04", 4 }, { "$vf04", 4 }, + { "vf05", 5 }, { "$vf05", 5 }, + { "vf06", 6 }, { "$vf06", 6 }, + { "vf07", 7 }, { "$vf07", 7 }, + { "vf08", 8 }, { "$vf08", 8 }, + { "vf09", 9 }, { "$vf09", 9 }, + { "vf10", 10 }, { "$vf10", 10 }, + { "vf11", 11 }, { "$vf11", 11 }, + { "vf12", 12 }, { "$vf12", 12 }, + { "vf13", 13 }, { "$vf13", 13 }, + { "vf14", 14 }, { "$vf14", 14 }, + { "vf15", 15 }, { "$vf15", 15 }, + { "vf16", 16 }, { "$vf16", 16 }, + { "vf17", 17 }, { "$vf17", 17 }, + { "vf18", 18 }, { "$vf18", 18 }, + { "vf19", 19 }, { "$vf19", 19 }, + { "vf20", 20 }, { "$vf20", 20 }, + { "vf21", 21 }, { "$vf21", 21 }, + { "vf22", 22 }, { "$vf22", 22 }, + { "vf23", 23 }, { "$vf23", 23 }, + { "vf24", 24 }, { "$vf24", 24 }, + { "vf25", 25 }, { "$vf25", 25 }, + { "vf26", 26 }, { "$vf26", 26 }, + { "vf27", 27 }, { "$vf27", 27 }, + { "vf28", 28 }, { "$vf28", 28 }, + { "vf29", 29 }, { "$vf29", 29 }, + { "vf30", 30 }, { "$vf30", 30 }, + { "vf31", 31 }, { "$vf31", 31 } +}); + +constexpr auto MipsPs2Cop2IRegisters = std::to_array({ + { "vi0", 0 }, { "$vi0", 0 }, + { "vi1", 1 }, { "$vi1", 1 }, + { "vi2", 2 }, { "$vi2", 2 }, + { "vi3", 3 }, { "$vi3", 3 }, + { "vi4", 4 }, { "$vi4", 4 }, + { "vi5", 5 }, { "$vi5", 5 }, + { "vi6", 6 }, { "$vi6", 6 }, + { "vi7", 7 }, { "$vi7", 7 }, + { "vi8", 8 }, { "$vi8", 8 }, + { "vi9", 9 }, { "$vi9", 9 }, + { "vi00", 0 }, { "$vi00", 0 }, + { "vi01", 1 }, { "$vi01", 1 }, + { "vi02", 2 }, { "$vi02", 2 }, + { "vi03", 3 }, { "$vi03", 3 }, + { "vi04", 4 }, { "$vi04", 4 }, + { "vi05", 5 }, { "$vi05", 5 }, + { "vi06", 6 }, { "$vi06", 6 }, + { "vi07", 7 }, { "$vi07", 7 }, + { "vi08", 8 }, { "$vi08", 8 }, + { "vi09", 9 }, { "$vi09", 9 }, + { "vi10", 10 }, { "$vi10", 10 }, + { "vi11", 11 }, { "$vi11", 11 }, + { "vi12", 12 }, { "$vi12", 12 }, + { "vi13", 13 }, { "$vi13", 13 }, + { "vi14", 14 }, { "$vi14", 14 }, + { "vi15", 15 }, { "$vi15", 15 } +}); + +bool charEquals(char a, char b) +{ + return std::tolower(a) == std::tolower(b); +} -const tMipsRegister MipsRegister[] = { - { "r0", 0, 2 }, { "zero", 0, 4}, { "$0", 0, 2 }, { "$zero", 0, 5 }, - { "at", 1, 2 }, { "r1", 1, 2 }, { "$1", 1, 2 }, { "$at", 1, 3 }, - { "v0", 2, 2 }, { "r2", 2, 2 }, { "$v0", 2, 3 }, - { "v1", 3, 2 }, { "r3", 3, 2 }, { "$v1", 3, 3 }, - { "a0", 4, 2 }, { "r4", 4, 2 }, { "$a0", 4, 3 }, - { "a1", 5, 2 }, { "r5", 5, 2 }, { "$a1", 5, 3 }, - { "a2", 6, 2 }, { "r6", 6, 2 }, { "$a2", 6, 3 }, - { "a3", 7, 2 }, { "r7", 7, 2 }, { "$a3", 7, 3 }, - { "t0", 8, 2 }, { "r8", 8, 2 }, { "$t0", 8, 3 }, - { "t1", 9, 2 }, { "r9", 9, 2 }, { "$t1", 9, 3 }, - { "t2", 10, 2 }, { "r10", 10, 3 }, { "$t2", 10, 3 }, - { "t3", 11, 2 }, { "r11", 11, 3 }, { "$t3", 11, 3 }, - { "t4", 12, 2 }, { "r12", 12, 3 }, { "$t4", 12, 3 }, - { "t5", 13, 2 }, { "r13", 13, 3 }, { "$t5", 13, 3 }, - { "t6", 14, 2 }, { "r14", 14, 3 }, { "$t6", 14, 3 }, - { "t7", 15, 2 }, { "r15", 15, 3 }, { "$t7", 15, 3 }, - { "s0", 16, 2 }, { "r16", 16, 3 }, { "$s0", 16, 3 }, - { "s1", 17, 2 }, { "r17", 17, 3 }, { "$s1", 17, 3 }, - { "s2", 18, 2 }, { "r18", 18, 3 }, { "$s2", 18, 3 }, - { "s3", 19, 2 }, { "r19", 19, 3 }, { "$s3", 19, 3 }, - { "s4", 20, 2 }, { "r20", 20, 3 }, { "$s4", 20, 3 }, - { "s5", 21, 2 }, { "r21", 21, 3 }, { "$s5", 21, 3 }, - { "s6", 22, 2 }, { "r22", 22, 3 }, { "$s6", 22, 3 }, - { "s7", 23, 2 }, { "r23", 23, 3 }, { "$s7", 23, 3 }, - { "t8", 24, 2 }, { "r24", 24, 3 }, { "$t8", 24, 3 }, - { "t9", 25, 2 }, { "r25", 25, 3 }, { "$t9", 25, 3 }, - { "k0", 26, 2 }, { "r26", 26, 3 }, { "$k0", 26, 3 }, - { "k1", 27, 2 }, { "r27", 27, 3 }, { "$k1", 27, 3 }, - { "gp", 28, 2 }, { "r28", 28, 3 }, { "$gp", 28, 3 }, - { "sp", 29, 2 }, { "r29", 29, 3 }, { "$sp", 29, 3 }, - { "fp", 30, 2 }, { "r30", 30, 3 }, { "$fp", 30, 3 }, - { "ra", 31, 2 }, { "r31", 31, 3 }, { "$ra", 31, 3 }, - { NULL, -1, 0} -}; - - -const tMipsRegister MipsFloatRegister[] = { - { "f0", 0, 2}, { "$f0", 0, 3 }, - { "f1", 1, 2}, { "$f1", 1, 3 }, - { "f2", 2, 2}, { "$f2", 2, 3 }, - { "f3", 3, 2}, { "$f3", 3, 3 }, - { "f4", 4, 2}, { "$f4", 4, 3 }, - { "f5", 5, 2}, { "$f5", 5, 3 }, - { "f6", 6, 2}, { "$f6", 6, 3 }, - { "f7", 7, 2}, { "$f7", 7, 3 }, - { "f8", 8, 2}, { "$f8", 8, 3 }, - { "f9", 9, 2}, { "$f9", 9, 3 }, - { "f00", 0, 3}, { "$f00", 0, 4 }, - { "f01", 1, 3}, { "$f01", 1, 4 }, - { "f02", 2, 3}, { "$f02", 2, 4 }, - { "f03", 3, 3}, { "$f03", 3, 4 }, - { "f04", 4, 3}, { "$f04", 4, 4 }, - { "f05", 5, 3}, { "$f05", 5, 4 }, - { "f06", 6, 3}, { "$f06", 6, 4 }, - { "f07", 7, 3}, { "$f07", 7, 4 }, - { "f08", 8, 3}, { "$f08", 8, 4 }, - { "f09", 9, 3}, { "$f09", 9, 4 }, - { "f10", 10, 3}, { "$f10", 10, 4 }, - { "f11", 11, 3}, { "$f11", 11, 4 }, - { "f12", 12, 3}, { "$f12", 12, 4 }, - { "f13", 13, 3}, { "$f13", 13, 4 }, - { "f14", 14, 3}, { "$f14", 14, 4 }, - { "f15", 15, 3}, { "$f15", 15, 4 }, - { "f16", 16, 3}, { "$f16", 16, 4 }, - { "f17", 17, 3}, { "$f17", 17, 4 }, - { "f18", 18, 3}, { "$f18", 18, 4 }, - { "f19", 19, 3}, { "$f19", 19, 4 }, - { "f20", 20, 3}, { "$f20", 20, 4 }, - { "f21", 21, 3}, { "$f21", 21, 4 }, - { "f22", 22, 3}, { "$f22", 22, 4 }, - { "f23", 23, 3}, { "$f23", 23, 4 }, - { "f24", 24, 3}, { "$f24", 24, 4 }, - { "f25", 25, 3}, { "$f25", 25, 4 }, - { "f26", 26, 3}, { "$f26", 26, 4 }, - { "f27", 27, 3}, { "$f27", 27, 4 }, - { "f28", 28, 3}, { "$f28", 28, 4 }, - { "f29", 29, 3}, { "$f29", 29, 4 }, - { "f30", 30, 3}, { "$f30", 30, 4 }, - { "f31", 31, 3}, { "$f31", 31, 4 } -}; +bool strEquals(std::string_view lhs, std::string_view rhs) +{ + const size_t compare_to = std::min(lhs.size(), rhs.size()); + return std::ranges::equal(lhs.begin(), lhs.begin() + compare_to, rhs.begin(), rhs.begin() + compare_to, charEquals); +} -const tMipsRegister MipsPs2Cop2FpRegister[] = { - { "vf0", 0, 3}, { "$vf0", 0, 4 }, - { "vf1", 1, 3}, { "$vf1", 1, 4 }, - { "vf2", 2, 3}, { "$vf2", 2, 4 }, - { "vf3", 3, 3}, { "$vf3", 3, 4 }, - { "vf4", 4, 3}, { "$vf4", 4, 4 }, - { "vf5", 5, 3}, { "$vf5", 5, 4 }, - { "vf6", 6, 3}, { "$vf6", 6, 4 }, - { "vf7", 7, 3}, { "$vf7", 7, 4 }, - { "vf8", 8, 3}, { "$vf8", 8, 4 }, - { "vf9", 9, 3}, { "$vf9", 9, 4 }, - { "vf00", 0, 4}, { "$vf00", 0, 5 }, - { "vf01", 1, 4}, { "$vf01", 1, 5 }, - { "vf02", 2, 4}, { "$vf02", 2, 5 }, - { "vf03", 3, 4}, { "$vf03", 3, 5 }, - { "vf04", 4, 4}, { "$vf04", 4, 5 }, - { "vf05", 5, 4}, { "$vf05", 5, 5 }, - { "vf06", 6, 4}, { "$vf06", 6, 5 }, - { "vf07", 7, 4}, { "$vf07", 7, 5 }, - { "vf08", 8, 4}, { "$vf08", 8, 5 }, - { "vf09", 9, 4}, { "$vf09", 9, 5 }, - { "vf10", 10, 4}, { "$vf10", 10, 5 }, - { "vf11", 11, 4}, { "$vf11", 11, 5 }, - { "vf12", 12, 4}, { "$vf12", 12, 5 }, - { "vf13", 13, 4}, { "$vf13", 13, 5 }, - { "vf14", 14, 4}, { "$vf14", 14, 5 }, - { "vf15", 15, 4}, { "$vf15", 15, 5 }, - { "vf16", 16, 4}, { "$vf16", 16, 5 }, - { "vf17", 17, 4}, { "$vf17", 17, 5 }, - { "vf18", 18, 4}, { "$vf18", 18, 5 }, - { "vf19", 19, 4}, { "$vf19", 19, 5 }, - { "vf20", 20, 4}, { "$vf20", 20, 5 }, - { "vf21", 21, 4}, { "$vf21", 21, 5 }, - { "vf22", 22, 4}, { "$vf22", 22, 5 }, - { "vf23", 23, 4}, { "$vf23", 23, 5 }, - { "vf24", 24, 4}, { "$vf24", 24, 5 }, - { "vf25", 25, 4}, { "$vf25", 25, 5 }, - { "vf26", 26, 4}, { "$vf26", 26, 5 }, - { "vf27", 27, 4}, { "$vf27", 27, 5 }, - { "vf28", 28, 4}, { "$vf28", 28, 5 }, - { "vf29", 29, 4}, { "$vf29", 29, 5 }, - { "vf30", 30, 4}, { "$vf30", 30, 5 }, - { "vf31", 31, 4}, { "$vf31", 31, 5 } -}; +bool isValidRegisterTrail(std::string_view source, size_t idx) +{ + return source.size() <= idx || source[idx] == ',' || source[idx] == '\n' || source[idx] == 0 + || source[idx] == ')' || source[idx] == '(' || source[idx] == '-'; +} void SplitLine(const char* Line, char* Name, char* Arguments) { @@ -200,102 +246,29 @@ bool MipsAssembleOpcode(const char* line, DebugInterface* cpu, u32 address, u32& return true; } - -bool MipsGetRegister(const char* source, int& RetLen, MipsRegisterInfo& Result) +template +bool MipsGetRegister(const char* source, int& RetLen, MipsRegisterInfo& Result, const std::array& RegisterList) { - for (int z = 0; MipsRegister[z].name != NULL; z++) - { - int len = MipsRegister[z].len; - if (strncmp(MipsRegister[z].name,source,len) == 0) // okay so far + for (const auto& reg : RegisterList) { + if(strEquals(reg.name, source) && isValidRegisterTrail(source, strlen(reg.name))) { - if (source[len] == ',' || source[len] == '\n' || source[len] == 0 - || source[len] == ')' || source[len] == '(' || source[len] == '-') // one of these has to come after a register - { - memcpy(Result.name,source,len); - Result.name[len] = 0; - Result.num = MipsRegister[z].num; - RetLen = len; - return true; - } + std::strncpy(Result.name, source, strlen(reg.name)); + Result.num = reg.num; + RetLen = static_cast(strlen(reg.name)); // grrr... should be unsigned!! + return true; } } return false; } -int MipsGetRegister(const char* source, int& RetLen) +template +int MipsGetRegister(const char* source, int& RetLen, const std::array& RegisterList) { - for (int z = 0; MipsRegister[z].name != NULL; z++) - { - int len = MipsRegister[z].len; - if (strncmp(MipsRegister[z].name,source,len) == 0) // okay so far + for (const auto& reg : RegisterList) { + if(strEquals(reg.name, source) && isValidRegisterTrail(source, strlen(reg.name))) { - if (source[len] == ',' || source[len] == '\n' || source[len] == 0 - || source[len] == ')' || source[len] == '(' || source[len] == '-') // one of these has to come after a register - { - RetLen = len; - return MipsRegister[z].num; - } - } - } - return -1; -} - - -bool MipsGetFloatRegister(const char* source, int& RetLen, MipsRegisterInfo& Result) -{ - for (int z = 0; MipsFloatRegister[z].name != NULL; z++) - { - int len = MipsFloatRegister[z].len; - if (strncmp(MipsFloatRegister[z].name,source,len) == 0) // okay so far - { - if (source[len] == ',' || source[len] == '\n' || source[len] == 0 - || source[len] == ')' || source[len] == '(' || source[len] == '-') // one of these has to come after a register - { - memcpy(Result.name,source,len); - Result.name[len] = 0; - Result.num = MipsFloatRegister[z].num; - RetLen = len; - return true; - } - } - } - return false; -} - -bool MipsGetPs2VectorRegister(const char* source, int& RetLen, MipsRegisterInfo& Result) -{ - for (int z = 0; MipsPs2Cop2FpRegister[z].name != NULL; z++) - { - int len = MipsPs2Cop2FpRegister[z].len; - if (strncmp(MipsPs2Cop2FpRegister[z].name,source,len) == 0) // okay so far - { - if (source[len] == ',' || source[len] == '\n' || source[len] == 0 - || source[len] == ')' || source[len] == '(' || source[len] == '-') // one of these has to come after a register - { - memcpy(Result.name,source,len); - Result.name[len] = 0; - Result.num = MipsPs2Cop2FpRegister[z].num; - RetLen = len; - return true; - } - } - } - return false; -} - -int MipsGetFloatRegister(const char* source, int& RetLen) -{ - for (int z = 0; MipsFloatRegister[z].name != NULL; z++) - { - int len = MipsFloatRegister[z].len; - if (strncmp(MipsFloatRegister[z].name,source,len) == 0) // okay so far - { - if (source[len] == ',' || source[len] == '\n' || source[len] == 0 - || source[len] == ')' || source[len] == '(' || source[len] == '-') // one of these has to come after a register - { - RetLen = len; - return MipsFloatRegister[z].num; - } + RetLen = static_cast(strlen(reg.name)); // grrr... should be unsigned!! + return reg.num; } } return -1; @@ -308,7 +281,7 @@ bool MipsCheckImmediate(const char* Source, DebugInterface* cpu, int& dest, int& int BufferPos = 0; int l; - if (MipsGetRegister(Source,l) != -1) // error + if (MipsGetRegister(Source,l, MipsRegisters) != -1) // error { return false; } @@ -341,7 +314,7 @@ bool MipsCheckImmediate(const char* Source, DebugInterface* cpu, int& dest, int& if (*Source == '(') // could be part of the opcode { - if (MipsGetRegister(Source+1,l) != -1) // end + if (MipsGetRegister(Source+1,l, MipsRegisters) != -1) // end { Buffer[BufferPos] = 0; break; @@ -488,32 +461,32 @@ bool CMipsInstruction::LoadEncoding(const tMipsOpcode& SourceOpcode, const char* switch (*SourceEncoding) { case 'T': // float reg - if (!MipsGetFloatRegister(Line,RetLen,registers.frt)) return false; + if (!MipsGetRegister(Line,RetLen,registers.frt, MipsFloatRegisters)) return false; Line += RetLen; SourceEncoding++; break; case 'D': // float reg - if (!MipsGetFloatRegister(Line,RetLen,registers.frd)) return false; + if (!MipsGetRegister(Line,RetLen,registers.frd, MipsFloatRegisters)) return false; Line += RetLen; SourceEncoding++; break; case 'S': // float reg - if (!MipsGetFloatRegister(Line,RetLen,registers.frs)) return false; + if (!MipsGetRegister(Line,RetLen,registers.frs, MipsFloatRegisters)) return false; Line += RetLen; SourceEncoding++; break; case 't': - if (!MipsGetRegister(Line,RetLen,registers.grt)) return false; + if (!MipsGetRegister(Line,RetLen,registers.grt, MipsRegisters)) return false; Line += RetLen; SourceEncoding++; break; case 'd': - if (!MipsGetRegister(Line,RetLen,registers.grd)) return false; + if (!MipsGetRegister(Line,RetLen,registers.grd, MipsRegisters)) return false; Line += RetLen; SourceEncoding++; break; case 's': - if (!MipsGetRegister(Line,RetLen,registers.grs)) return false; + if (!MipsGetRegister(Line,RetLen,registers.grs, MipsRegisters)) return false; Line += RetLen; SourceEncoding++; break; @@ -521,17 +494,35 @@ bool CMipsInstruction::LoadEncoding(const tMipsOpcode& SourceOpcode, const char* switch (*(SourceEncoding+1)) { case 's': - if (!MipsGetPs2VectorRegister(Line,RetLen,registers.ps2vrs)) return false; + if (!MipsGetRegister(Line,RetLen,registers.ps2vrs, MipsPs2Cop2FpRegisters)) return false; Line += RetLen; break; case 't': - if (!MipsGetPs2VectorRegister(Line,RetLen,registers.ps2vrt)) return false; + if (!MipsGetRegister(Line,RetLen,registers.ps2vrt, MipsPs2Cop2FpRegisters)) return false; Line += RetLen; break; case 'd': - if (!MipsGetPs2VectorRegister(Line,RetLen,registers.ps2vrd)) return false; + if (!MipsGetRegister(Line,RetLen,registers.ps2vrd, MipsPs2Cop2FpRegisters)) return false; Line += RetLen; break; + case 'i': + switch(*(SourceEncoding+2)) + { + case 's': + if (!MipsGetRegister(Line,RetLen,registers.ps2vrs, MipsPs2Cop2IRegisters)) return false; + Line += RetLen; + break; + case 't': + if (!MipsGetRegister(Line,RetLen,registers.ps2vrt, MipsPs2Cop2IRegisters)) return false; + Line += RetLen; + break; + case 'd': + if (!MipsGetRegister(Line,RetLen,registers.ps2vrd, MipsPs2Cop2IRegisters)) return false; + Line += RetLen; + break; + } + SourceEncoding += 1; + break; default: return false; } @@ -562,7 +553,7 @@ bool CMipsInstruction::LoadEncoding(const tMipsOpcode& SourceOpcode, const char* SourceEncoding++; break; case 'r': // forced register - if (MipsGetRegister(Line,RetLen) != *(SourceEncoding+1)) return false; + if (MipsGetRegister(Line,RetLen, MipsRegisters) != *(SourceEncoding+1)) return false; Line += RetLen; SourceEncoding += 2; break; @@ -685,7 +676,7 @@ void CMipsInstruction::encodeNormal() if (registers.frd.num != -1) encoding |= MIPS_FD(registers.frd.num); // float dest reg if (registers.ps2vrt.num != -1) encoding |= (registers.ps2vrt.num << 16); // ps2 vector target reg - if (registers.ps2vrs.num != -1) encoding |= (registers.ps2vrs.num << 21); // ps2 vector source reg + if (registers.ps2vrs.num != -1) encoding |= (registers.ps2vrs.num << 11); // ps2 vector source reg if (registers.ps2vrd.num != -1) encoding |= (registers.ps2vrd.num << 6); // ps2 vector dest reg switch (immediateType) diff --git a/pcsx2/DebugTools/MipsAssembler.h b/pcsx2/DebugTools/MipsAssembler.h index fb1d566512ba0..de0b0c249e690 100644 --- a/pcsx2/DebugTools/MipsAssembler.h +++ b/pcsx2/DebugTools/MipsAssembler.h @@ -13,7 +13,6 @@ enum MipsArchType { MARCH_PSX = 0, MARCH_N64, MARCH_PS2, MARCH_PSP, MARCH_INVALI typedef struct { const char* name; short num; - short len; } tMipsRegister; typedef struct { diff --git a/pcsx2/DebugTools/MipsAssemblerTables.cpp b/pcsx2/DebugTools/MipsAssemblerTables.cpp index 70ee103847cc5..db3a8c0e26eff 100644 --- a/pcsx2/DebugTools/MipsAssemblerTables.cpp +++ b/pcsx2/DebugTools/MipsAssemblerTables.cpp @@ -304,6 +304,275 @@ const tMipsOpcode MipsOpcodes[] = { { "mtsab", "s,i", MIPS_REGIMM(0x18), MA_PS2, 0 }, { "mtsah", "s,i", MIPS_REGIMM(0x19), MA_PS2, 0 }, +// 31---------26------------------------------------------5--------0 +// |= MMI| | function| +// ------6----------------------------------------------------6----- +// |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo +// 000 | MADD | MADDU | --- | --- | PLZCW | --- | --- | --- | 00-07 +// 001 | MMI0 | MMI2 | --- | --- | --- | --- | --- | --- | 08-0F +// 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | --- | --- | --- | --- | 10-17 +// 011 | MULT1 | MULTU1| DIV1 | DIVU1 | --- | --- | --- | --- | 18-1F +// 100 | MADD1 | MADDU1| --- | --- | --- | --- | --- | --- | 20..27 +// 101 | MMI1 | MMI3 | --- | --- | --- | --- | --- | --- | 28..2F +// 110 | PMFHL | PMTHL | --- | --- | PSLLH | --- | --- | PSRAH | 30..37 +// 111 | --- | --- | --- | --- | PSLLW | --- | PSRLW | PSRAW | 38..3F +// hi |-------|-------|-------|-------|-------|-------|-------|-------| + { "madd", "d,s,t", MIPS_MMI(0x00), MA_PS2, 0 }, + { "madd", "s,t", MIPS_MMI(0x00), MA_PS2, MO_RSD }, + { "maddu", "d,s,t", MIPS_MMI(0x01), MA_PS2, 0 }, + { "maddu", "s,t", MIPS_MMI(0x01), MA_PS2, MO_RSD }, + { "plzcw", "d,s", MIPS_MMI(0x04), MA_PS2, 0 }, + { "mfhi1", "d", MIPS_MMI(0x10), MA_PS2, 0 }, + { "mthi1", "s", MIPS_MMI(0x11), MA_PS2, 0 }, + { "mflo1", "d", MIPS_MMI(0x12), MA_PS2, 0 }, + { "mtlo1", "s", MIPS_MMI(0x13), MA_PS2, 0 }, + { "mult1", "d,s,t", MIPS_MMI(0x18), MA_PS2, 0 }, + { "mult1", "s,t", MIPS_MMI(0x18), MA_PS2, MO_RSD }, + { "multu1", "d,s,t", MIPS_MMI(0x19), MA_PS2, 0 }, + { "multu1", "s,t", MIPS_MMI(0x19), MA_PS2, MO_RSD }, + { "div1", "s,t", MIPS_MMI(0x1A), MA_PS2, 0 }, + { "divu1", "s,t", MIPS_MMI(0x1B), MA_PS2, 0 }, + { "madd1", "d,s,t", MIPS_MMI(0x20), MA_PS2, 0 }, + { "madd1", "s,t", MIPS_MMI(0x20), MA_PS2, MO_RSD }, + { "maddu1", "d,s,t", MIPS_MMI(0x21), MA_PS2, 0 }, + { "maddu1", "s,t", MIPS_MMI(0x21), MA_PS2, MO_RSD }, + { "pmfhl", "d", MIPS_PMFHL(0), MA_PS2, 0 }, + { "pmfhl.lw", "d", MIPS_PMFHL(0), MA_PS2, 0 }, + { "pmfhl.uw", "d", MIPS_PMFHL(1), MA_PS2, 0 }, + { "pmfhl.slw", "d", MIPS_PMFHL(2), MA_PS2, 0 }, + { "pmfhl.lh", "d", MIPS_PMFHL(3), MA_PS2, 0 }, + { "pmfhl.sh", "d", MIPS_PMFHL(4), MA_PS2, 0 }, + { "pmthl.lw", "s", MIPS_PMTHL(0), MA_PS2, 0 }, + { "pmthl", "s", MIPS_PMTHL(0), MA_PS2, 0 }, + { "psllh", "d,t,a", MIPS_MMI(0x34), MA_PS2, 0 }, + { "psrah", "d,t,a", MIPS_MMI(0x37), MA_PS2, 0 }, + { "psllw", "d,t,a", MIPS_MMI(0x3C), MA_PS2, 0 }, + { "psrlw", "d,t,a", MIPS_MMI(0x3E), MA_PS2, 0 }, + { "psraw", "d,t,a", MIPS_MMI(0x3F), MA_PS2, 0 }, + +// 31---------26--------------------------------10--------6-5-------0 +// |= MMI| | function | MMI0 | +// -----6--------------------------------------------5---------6----- +// |---00---|---01---|---10---|---11---| lo +// 000 | PADDW | PSUBW | PCGTW | PMAXW | 00..03 +// 001 | PADDH | PSUBH | PCGTH | PMAXH | 04..07 +// 010 | PADDB | PSUBB | PCGTB | ---- | 08..0B +// 011 | ---- | ---- | ---- | ---- | 0C..0F +// 100 | PADDSW | PSUBSW | PEXTLW | PPACW | 10..13 +// 101 | PADDSH | PSUBSH | PEXTLH | PPACH | 14..17 +// 110 | PADDSB | PSUBSB | PEXTLB | PPACB | 18..1B +// 111 | ---- | --- | PEXT5 | PPAC5 | 1C..1F +// hi |--------|--------|--------|--------| + { "paddw", "d,s,t", MIPS_MMI0(0x00), MA_PS2, 0 }, + { "paddw", "s,t", MIPS_MMI0(0x00), MA_PS2, MO_RSD }, + { "psubw", "d,s,t", MIPS_MMI0(0x01), MA_PS2, 0 }, + { "psubw", "s,t", MIPS_MMI0(0x01), MA_PS2, MO_RSD }, + { "pcgtw", "d,s,t", MIPS_MMI0(0x02), MA_PS2, 0 }, + { "pcgtw", "s,t", MIPS_MMI0(0x02), MA_PS2, MO_RSD }, + { "pmaxw", "d,s,t", MIPS_MMI0(0x03), MA_PS2, 0 }, + { "pmaxw", "s,t", MIPS_MMI0(0x03), MA_PS2, MO_RSD }, + { "paddh", "d,s,t", MIPS_MMI0(0x04), MA_PS2, 0 }, + { "paddh", "s,t", MIPS_MMI0(0x04), MA_PS2, MO_RSD }, + { "psubh", "d,s,t", MIPS_MMI0(0x05), MA_PS2, 0 }, + { "psubh", "s,t", MIPS_MMI0(0x05), MA_PS2, MO_RSD }, + { "pcgth", "d,s,t", MIPS_MMI0(0x06), MA_PS2, 0 }, + { "pcgth", "s,t", MIPS_MMI0(0x06), MA_PS2, MO_RSD }, + { "pmaxh", "d,s,t", MIPS_MMI0(0x07), MA_PS2, 0 }, + { "pmaxh", "s,t", MIPS_MMI0(0x07), MA_PS2, MO_RSD }, + { "paddb", "d,s,t", MIPS_MMI0(0x08), MA_PS2, 0 }, + { "paddb", "s,t", MIPS_MMI0(0x08), MA_PS2, MO_RSD }, + { "psubb", "d,s,t", MIPS_MMI0(0x09), MA_PS2, 0 }, + { "psubb", "s,t", MIPS_MMI0(0x09), MA_PS2, MO_RSD }, + { "pcgtb", "d,s,t", MIPS_MMI0(0x0A), MA_PS2, 0 }, + { "pcgtb", "s,t", MIPS_MMI0(0x0A), MA_PS2, MO_RSD }, + { "paddsw", "d,s,t", MIPS_MMI0(0x10), MA_PS2, 0 }, + { "paddsw", "s,t", MIPS_MMI0(0x10), MA_PS2, MO_RSD }, + { "psubsw", "d,s,t", MIPS_MMI0(0x11), MA_PS2, 0 }, + { "psubsw", "s,t", MIPS_MMI0(0x11), MA_PS2, MO_RSD }, + { "pextlw", "d,s,t", MIPS_MMI0(0x12), MA_PS2, 0 }, + { "pextlw", "s,t", MIPS_MMI0(0x12), MA_PS2, MO_RSD }, + { "ppacw", "d,s,t", MIPS_MMI0(0x13), MA_PS2, 0 }, + { "ppacw", "s,t", MIPS_MMI0(0x13), MA_PS2, MO_RSD }, + { "paddsh", "d,s,t", MIPS_MMI0(0x14), MA_PS2, 0 }, + { "paddsh", "s,t", MIPS_MMI0(0x14), MA_PS2, MO_RSD }, + { "psubsh", "d,s,t", MIPS_MMI0(0x15), MA_PS2, 0 }, + { "psubsh", "s,t", MIPS_MMI0(0x15), MA_PS2, MO_RSD }, + { "pextlh", "d,s,t", MIPS_MMI0(0x16), MA_PS2, 0 }, + { "pextlh", "s,t", MIPS_MMI0(0x16), MA_PS2, MO_RSD }, + { "ppach", "d,s,t", MIPS_MMI0(0x17), MA_PS2, 0 }, + { "ppach", "s,t", MIPS_MMI0(0x17), MA_PS2, MO_RSD }, + { "paddsb", "d,s,t", MIPS_MMI0(0x18), MA_PS2, 0 }, + { "paddsb", "s,t", MIPS_MMI0(0x18), MA_PS2, MO_RSD }, + { "psubsb", "d,s,t", MIPS_MMI0(0x19), MA_PS2, 0 }, + { "psubsb", "s,t", MIPS_MMI0(0x19), MA_PS2, MO_RSD }, + { "pextlb", "d,s,t", MIPS_MMI0(0x1A), MA_PS2, 0 }, + { "pextlb", "s,t", MIPS_MMI0(0x1A), MA_PS2, MO_RSD }, + { "ppacb", "d,s,t", MIPS_MMI0(0x1B), MA_PS2, 0 }, + { "ppacb", "s,t", MIPS_MMI0(0x1B), MA_PS2, MO_RSD }, + { "pext5", "d,t", MIPS_MMI0(0x1E), MA_PS2, 0 }, + { "ppac5", "d,t", MIPS_MMI0(0x1F), MA_PS2, 0 }, + +// 31---------26--------------------------------10--------6-5-------0 +// |= MMI| | function | MMI1 | +// -----6--------------------------------------------5---------6----- +// |---00---|---01---|---10---|---11---| lo +// 000 | ---- | PABSW | PCEQW | PMINW | 00..03 +// 001 | PADSBH | PABSH | PCEQH | PMINH | 04..07 +// 010 | ---- | ---- | PCEQB | ---- | 08..0B +// 011 | ---- | ---- | ---- | ---- | 0C..0F +// 100 | PADDUW | PSUBUW | PEXTUW | PPACW | 10..13 +// 101 | PADDUH | PSUBUH | PEXTUH | PPACH | 14..17 +// 110 | PADDUB | PSUBUB | PEXTUB | QFSRV | 18..1B +// 111 | ---- | --- | ---- | ---- | 1C..1F +// hi |--------|--------|--------|--------| + { "pabsw", "d,t", MIPS_MMI1(0x01), MA_PS2, 0 }, + { "pceqw", "d,s,t", MIPS_MMI1(0x02), MA_PS2, 0 }, + { "pceqw", "s,t", MIPS_MMI1(0x02), MA_PS2, MO_RSD }, + { "pminw", "d,s,t", MIPS_MMI1(0x03), MA_PS2, 0 }, + { "pminw", "s,t", MIPS_MMI1(0x03), MA_PS2, MO_RSD }, + { "padsbh", "d,s,t", MIPS_MMI1(0x04), MA_PS2, 0 }, + { "padsbh", "s,t", MIPS_MMI1(0x04), MA_PS2, MO_RSD }, + { "pabsh", "d,t", MIPS_MMI1(0x05), MA_PS2, 0 }, + { "pceqh", "d,s,t", MIPS_MMI1(0x06), MA_PS2, 0 }, + { "pceqh", "s,t", MIPS_MMI1(0x06), MA_PS2, MO_RSD }, + { "pminh", "d,s,t", MIPS_MMI1(0x07), MA_PS2, 0 }, + { "pminh", "s,t", MIPS_MMI1(0x07), MA_PS2, MO_RSD }, + { "pceqb", "d,s,t", MIPS_MMI1(0x0A), MA_PS2, 0 }, + { "pceqb", "s,t", MIPS_MMI1(0x0A), MA_PS2, MO_RSD }, + { "padduw", "d,s,t", MIPS_MMI1(0x10), MA_PS2, 0 }, + { "padduw", "s,t", MIPS_MMI1(0x10), MA_PS2, MO_RSD }, + { "psubuw", "d,s,t", MIPS_MMI1(0x11), MA_PS2, 0 }, + { "psubuw", "s,t", MIPS_MMI1(0x11), MA_PS2, MO_RSD }, + { "pextuw", "d,s,t", MIPS_MMI1(0x12), MA_PS2, 0 }, + { "pextuw", "s,t", MIPS_MMI1(0x12), MA_PS2, MO_RSD }, + { "ppacw", "d,s,t", MIPS_MMI1(0x13), MA_PS2, 0 }, + { "ppacw", "s,t", MIPS_MMI1(0x13), MA_PS2, MO_RSD }, + { "padduh", "d,s,t", MIPS_MMI1(0x14), MA_PS2, 0 }, + { "padduh", "s,t", MIPS_MMI1(0x14), MA_PS2, MO_RSD }, + { "psubuh", "d,s,t", MIPS_MMI1(0x15), MA_PS2, 0 }, + { "psubuh", "s,t", MIPS_MMI1(0x15), MA_PS2, MO_RSD }, + { "pextuh", "d,s,t", MIPS_MMI1(0x16), MA_PS2, 0 }, + { "pextuh", "s,t", MIPS_MMI1(0x16), MA_PS2, MO_RSD }, + { "ppach", "d,s,t", MIPS_MMI1(0x17), MA_PS2, 0 }, + { "ppach", "s,t", MIPS_MMI1(0x17), MA_PS2, MO_RSD }, + { "paddub", "d,s,t", MIPS_MMI1(0x18), MA_PS2, 0 }, + { "paddub", "s,t", MIPS_MMI1(0x18), MA_PS2, MO_RSD }, + { "psubub", "d,s,t", MIPS_MMI1(0x19), MA_PS2, 0 }, + { "psubub", "s,t", MIPS_MMI1(0x19), MA_PS2, MO_RSD }, + { "pextub", "d,s,t", MIPS_MMI1(0x1A), MA_PS2, 0 }, + { "pextub", "s,t", MIPS_MMI1(0x1A), MA_PS2, MO_RSD }, + { "qfsrv", "d,s,t", MIPS_MMI1(0x1B), MA_PS2, 0 }, + { "qfsrv", "s,t", MIPS_MMI1(0x1B), MA_PS2, MO_RSD }, + +// 31---------26--------------------------------10--------6-5-------0 +// |= MMI| | function | MMI2 | +// -----6--------------------------------------------5---------6----- +// |---00---|---01---|---10---|---11---| lo +// 000 | PMADDW | ---- | PSLLVW | PSRLVW | 00..03 +// 001 | PMSUBW | ---- | ---- | ---- | 04..07 +// 010 | PMFHI | PMFLO | PINTH | ---- | 08..0B +// 011 | PMULTW | PDIVW | PCPYLD | ---- | 0C..0F +// 100 | PMADDH | PHMADH | PAND | PXOR | 10..13 +// 101 | PMSUBH | PHMSBH | ---- | ---- | 14..17 +// 110 | ---- | ---- | PEXEH | PREVH | 18..1B +// 111 | PMULTH | PDIVBW | PEXEW | PROT3W | 1C..1F +// hi |--------|--------|--------|--------| + { "pmaddw", "d,s,t", MIPS_MMI2(0x00), MA_PS2, 0 }, + { "pmaddw", "s,t", MIPS_MMI2(0x00), MA_PS2, MO_RSD }, + { "psllvw", "d,s,t", MIPS_MMI2(0x02), MA_PS2, 0 }, + { "psllvw", "s,t", MIPS_MMI2(0x02), MA_PS2, MO_RSD }, + { "psrlvw", "d,s,t", MIPS_MMI2(0x03), MA_PS2, 0 }, + { "psrlvw", "s,t", MIPS_MMI2(0x03), MA_PS2, MO_RSD }, + { "pmsubw", "d,s,t", MIPS_MMI2(0x04), MA_PS2, 0 }, + { "pmsubw", "s,t", MIPS_MMI2(0x04), MA_PS2, MO_RSD }, + { "pmfhi", "d", MIPS_MMI2(0x08), MA_PS2, 0 }, + { "pmflo", "d", MIPS_MMI2(0x09), MA_PS2, 0 }, + { "pinth", "d,s,t", MIPS_MMI2(0x0A), MA_PS2, 0 }, + { "pinth", "s,t", MIPS_MMI2(0x0A), MA_PS2, MO_RSD }, + { "pmultw", "d,s,t", MIPS_MMI2(0x0C), MA_PS2, 0 }, + { "pmultw", "s,t", MIPS_MMI2(0x0C), MA_PS2, MO_RSD }, + { "pdivw", "s,t", MIPS_MMI2(0x0D), MA_PS2, 0 }, + { "pcpyld", "d,s,t", MIPS_MMI2(0x0E), MA_PS2, 0 }, + { "pcpyld", "s,t", MIPS_MMI2(0x0E), MA_PS2, MO_RSD }, + { "pmaddh", "d,s,t", MIPS_MMI2(0x10), MA_PS2, 0 }, + { "pmaddh", "s,t", MIPS_MMI2(0x10), MA_PS2, MO_RSD }, + { "phmadh", "d,s,t", MIPS_MMI2(0x11), MA_PS2, 0 }, + { "phmadh", "s,t", MIPS_MMI2(0x11), MA_PS2, MO_RSD }, + { "pand", "d,s,t", MIPS_MMI2(0x12), MA_PS2, 0 }, + { "pand", "s,t", MIPS_MMI2(0x12), MA_PS2, MO_RSD }, + { "pxor", "d,s,t", MIPS_MMI2(0x13), MA_PS2, 0 }, + { "pxor", "s,t", MIPS_MMI2(0x13), MA_PS2, MO_RSD }, + { "pmsubh", "d,s,t", MIPS_MMI2(0x14), MA_PS2, 0 }, + { "pmsubh", "s,t", MIPS_MMI2(0x14), MA_PS2, MO_RSD }, + { "phmsbh", "d,s,t", MIPS_MMI2(0x15), MA_PS2, 0 }, + { "phmsbh", "s,t", MIPS_MMI2(0x15), MA_PS2, MO_RSD }, + { "pexeh", "d,t", MIPS_MMI2(0x1A), MA_PS2, 0 }, + { "prevh", "d,t", MIPS_MMI2(0x1B), MA_PS2, 0 }, + { "pmulth", "d,s,t", MIPS_MMI2(0x1C), MA_PS2, 0 }, + { "pmulth", "s,t", MIPS_MMI2(0x1C), MA_PS2, MO_RSD }, + { "pdivbw", "s,t", MIPS_MMI2(0x1D), MA_PS2, 0 }, + { "pexew", "d,t", MIPS_MMI2(0x1E), MA_PS2, 0 }, + { "prot3w", "d,t", MIPS_MMI2(0x1F), MA_PS2, 0 }, + +// 31---------26--------------------------------10--------6-5-------0 +// |= MMI| | function | MMI3 | +// -----6--------------------------------------------5---------6----- +// |---00---|---01---|---10---|---11---| lo +// 000 | PMADDUW| ---- | ---- | PSRAVW | 00..03 +// 001 | ---- | ---- | ---- | ---- | 04..07 +// 010 | PMTHI | PMTLO | PINTEH | ---- | 08..0B +// 011 | PMULTUW| PDIVUW | PCPYUD | ---- | 0C..0F +// 100 | ---- | ---- | POR | PNOR | 10..13 +// 101 | ---- | ---- | ---- | ---- | 14..17 +// 110 | ---- | ---- | PEXCH | PCPYH | 18..1B +// 111 | ---- | ---- | PEXCW | ---- | 1C..1F +// hi |--------|--------|--------|--------| + { "pmadduw","d,s,t", MIPS_MMI3(0x00), MA_PS2, 0 }, + { "pmadduw","s,t", MIPS_MMI3(0x00), MA_PS2, MO_RSD }, + { "psravw", "d,s,t", MIPS_MMI3(0x03), MA_PS2, 0 }, + { "psravw", "s,t", MIPS_MMI3(0x03), MA_PS2, MO_RSD }, + { "pmthi", "s", MIPS_MMI3(0x08), MA_PS2, 0 }, + { "pmtlo", "s", MIPS_MMI3(0x09), MA_PS2, 0 }, + { "pinteh", "d,s,t", MIPS_MMI3(0x0A), MA_PS2, 0 }, + { "pinteh", "s,t", MIPS_MMI3(0x0A), MA_PS2, MO_RSD }, + { "pmultuw","d,s,t", MIPS_MMI3(0x0C), MA_PS2, 0 }, + { "pmultuw","s,t", MIPS_MMI3(0x0C), MA_PS2, MO_RSD }, + { "pdivuw", "s,t", MIPS_MMI3(0x0D), MA_PS2, 0 }, + { "pcpyud", "d,s,t", MIPS_MMI3(0x0E), MA_PS2, 0 }, + { "pcpyud", "s,t", MIPS_MMI3(0x0E), MA_PS2, MO_RSD }, + { "por", "d,s,t", MIPS_MMI3(0x12), MA_PS2, 0 }, + { "por", "s,t", MIPS_MMI3(0x12), MA_PS2, MO_RSD }, + { "pnor", "d,s,t", MIPS_MMI3(0x13), MA_PS2, 0 }, + { "pnor", "s,t", MIPS_MMI3(0x13), MA_PS2, MO_RSD }, + { "pexch", "d,t", MIPS_MMI3(0x1A), MA_PS2, 0 }, + { "pcpyh", "d,s,t", MIPS_MMI3(0x1B), MA_PS2, 0 }, + { "pcpyh", "s,t", MIPS_MMI3(0x1B), MA_PS2, MO_RSD }, + { "pexcw", "d,t", MIPS_MMI3(0x1E), MA_PS2, 0 }, + +// COP2 (VU0 Macro Mode) +// Incomplete, only field type 11 supported (top bit of opcode is unset) +// 31-------26---------21----------------------------------------1-0 +// |= COP2| opcode | |I| +// -----6---------5-----------------------------------------------1- +// |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo +// 00 | --- | QMFC2 | CFC2 | --- | --- | QMTC2 | CTC2 | --- | 00..07 +// 01 | --- | --- | --- | --- | --- | --- | --- | --- | 08..0F +// 10 | --- | --- | --- | --- | --- | --- | --- | --- | 10..17 +// 11 | --- | --- | --- | --- | --- | --- | --- | --- | 18..1F +// hi |-------|-------|-------|-------|-------|-------|-------|-------| + { "qmfc2", "t,Vs", MIPS_COP2_NI(0x01), MA_PS2, 0 }, + { "qmfc2.ni", "t,Vs", MIPS_COP2_NI(0x01), MA_PS2, 0 }, + { "qmfc2.i", "t,Vs", MIPS_COP2_I(0x01), MA_PS2, 0 }, + { "cfc2", "t,Vis",MIPS_COP2_NI(0x02), MA_PS2, 0 }, + { "cfc2.ni", "t,Vis",MIPS_COP2_NI(0x02), MA_PS2, 0 }, + { "cfc2.i", "t,Vis",MIPS_COP2_I(0x02), MA_PS2, 0 }, + { "qmtc2", "t,Vs", MIPS_COP2_NI(0x05), MA_PS2, 0 }, + { "qmtc2.ni", "t,Vs", MIPS_COP2_NI(0x05), MA_PS2, 0 }, + { "qmtc2.i", "t,Vs", MIPS_COP2_I(0x05), MA_PS2, 0 }, + { "ctc2", "t,Vis",MIPS_COP2_NI(0x06), MA_PS2, 0 }, + { "ctc2.ni", "t,Vis",MIPS_COP2_NI(0x06), MA_PS2, 0 }, + { "ctc2.i", "t,Vis",MIPS_COP2_I(0x06), MA_PS2, 0 }, + // 31-------26------21---------------------------------------------0 // |= COP1| rs | | // -----6-------5--------------------------------------------------- @@ -317,7 +586,7 @@ const tMipsOpcode MipsOpcodes[] = { { "cfc1", "t,S", MIPS_COP1(0x02), MA_MIPS2, 0 }, { "mtc1", "t,S", MIPS_COP1(0x04), MA_MIPS2, 0 }, { "ctc1", "t,S", MIPS_COP1(0x06), MA_MIPS2, 0 }, - + // 31---------21-------16------------------------------------------0 // |= COP1BC| rt | | // ------11---------5----------------------------------------------- diff --git a/pcsx2/DebugTools/MipsAssemblerTables.h b/pcsx2/DebugTools/MipsAssemblerTables.h index bb69ea6dbabac..429e7f736661a 100644 --- a/pcsx2/DebugTools/MipsAssemblerTables.h +++ b/pcsx2/DebugTools/MipsAssemblerTables.h @@ -54,12 +54,23 @@ #define MIPS_COP1BC(VALUE) (MIPS_COP1(8) | MIPS_RT(VALUE)) #define MIPS_COP1S(VALUE) (MIPS_COP1(16) | MIPS_FUNC(VALUE)) #define MIPS_COP1W(VALUE) (MIPS_COP1(20) | MIPS_FUNC(VALUE)) +#define MIPS_MMI(VALUE) (MIPS_OP(28) | MIPS_FUNC(VALUE)) +#define MIPS_MMI0(VALUE) (MIPS_MMI(8) | MIPS_SECFUNC(VALUE)) +#define MIPS_MMI1(VALUE) (MIPS_MMI(40) | MIPS_SECFUNC(VALUE)) +#define MIPS_MMI2(VALUE) (MIPS_MMI(9) | MIPS_SECFUNC(VALUE)) +#define MIPS_MMI3(VALUE) (MIPS_MMI(41) | MIPS_SECFUNC(VALUE)) + +#define MIPS_COP2_NI(VALUE) (MIPS_OP(18) | MIPS_RS(VALUE) | 0) +#define MIPS_COP2_I(VALUE) (MIPS_OP(18) | MIPS_RS(VALUE) | 1) #define MIPS_VFPUSIZE(VALUE) ( (((VALUE) & 1) << 7) | (((VALUE) & 2) << 14) ) #define MIPS_VFPU0(VALUE) (MIPS_OP(0x18) | BITFIELD(23,3,(VALUE))) #define MIPS_ALLEGREX0(VALUE) (MIPS_SPECIAL(32) | MIPS_SECFUNC(VALUE)) +#define MIPS_PMFHL(VALUE) (MIPS_MMI(0x30) | MIPS_SECFUNC(VALUE)) +#define MIPS_PMTHL(VALUE) (MIPS_MMI(0x31) | MIPS_SECFUNC(VALUE)) + struct MipsArchDefinition { const char* name;