From d1656d425a9b73159655ec2666be1e90e31ede88 Mon Sep 17 00:00:00 2001 From: Thomas Lamb Date: Tue, 7 Jul 2026 20:24:13 -0400 Subject: [PATCH] Improve debugger assemble/disassemble compatiblity Update armips for VFPU instruction parsing changes: - Kingcom/armips#255 - Kingcom/armips#256 Remove brackets from VFPU instruction `vpfx*` params Rename VFPU instruction `vuc2i.s` to `vuc2ifs.s` Add brackets to VFPU instruction `vpfxd` saturation operations (i.e. [0:1] & [-1:1]) Rename FPU instructions `c.$OP` to `c.$OP.s` Fix VFPU instruction `vuc2ifs.s` `vd` size in disassembly Replace `CC[imm3]` with `imm3` in VFPU instructions `vcmov*` & `bv*` disassembly --- Core/MIPS/MIPSDisVFPU.cpp | 66 ++++++++++++++++++++++--------------- Core/MIPS/MIPSDisVFPU.h | 4 ++- Core/MIPS/MIPSTables.cpp | 44 ++++++++++++------------- Core/MIPS/MIPSVFPUUtils.cpp | 26 +++++++++++++++ Core/MIPS/MIPSVFPUUtils.h | 4 +++ ext/armips | 2 +- 6 files changed, 95 insertions(+), 51 deletions(-) diff --git a/Core/MIPS/MIPSDisVFPU.cpp b/Core/MIPS/MIPSDisVFPU.cpp index d8ac82c247..d15858325b 100644 --- a/Core/MIPS/MIPSDisVFPU.cpp +++ b/Core/MIPS/MIPSDisVFPU.cpp @@ -153,7 +153,7 @@ namespace MIPSDis void Dis_VPFXST(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) { int data = op & 0xFFFFF; const char *name = MIPSGetName(op); - size_t outpos = snprintf(out, outSize, "%s\t[", name); + size_t outpos = snprintf(out, outSize, "%s\t", name); static const char * const regnam[4] = {"X","Y","Z","W"}; static const char * const constan[8] = {"0","1","2","1/2","3","1/3","1/4","1/6"}; @@ -181,17 +181,14 @@ namespace MIPSDis if (i != 3 && outpos < outSize) outpos += truncate_cpy(out + outpos, outSize - outpos, ","); } - - if (outpos < outSize) - outpos += truncate_cpy(out + outpos, outSize - outpos, "]"); } void Dis_VPFXD(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) { int data = op & 0xFFFFF; const char *name = MIPSGetName(op); - size_t outpos = snprintf(out, outSize, "%s\t[", name); + size_t outpos = snprintf(out, outSize, "%s\t", name); - static const char * const satNames[4] = {"", "0:1", "X", "-1:1"}; + static const char * const satNames[4] = {"", "[0:1]", "X", "[-1:1]"}; for (int i=0; i<4; i++) { int sat = (data>>i*2)&3; @@ -203,9 +200,6 @@ namespace MIPSDis if (i < 4 - 1 && outpos < outSize) outpos += truncate_cpy(out + outpos, outSize - outpos, ","); } - - if (outpos < outSize) - outpos += truncate_cpy(out + outpos, outSize - outpos, "]"); } @@ -373,9 +367,9 @@ namespace MIPSDis return; } if (imm3<6) - snprintf(out, outSize, "%s%s%s\t%s, %s, CC[%i]", name, tf==0?"t":"f", VSuff(op), VN(vd, sz), VN(vs,sz), imm3); - else if (imm3 == 6) - snprintf(out, outSize, "%s%s%s\t%s, %s, CC[...]", name, tf==0?"t":"f", VSuff(op), VN(vd, sz), VN(vs,sz)); + snprintf(out, outSize, "%s%s%s\t%s, %s, %i", name, tf==0?"t":"f", VSuff(op), VN(vd, sz), VN(vs,sz), imm3); + else + snprintf(out, outSize, "%s%s%s\tERROR", name, tf==0?"t":"f", VSuff(op)); } void Dis_Vfad(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) { @@ -490,26 +484,44 @@ namespace MIPSDis snprintf(out, outSize, "%s%s\t%s, %s, %i", name, VSuff(op), VN(vd, sz), VN(vs, sz), imm); } - void Dis_Vs2i(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) { - VectorSize sz = GetVecSize(op); - int vd = _VD; - int vs = _VS; - const char *name = MIPSGetName(op); - snprintf(out, outSize, "%s%s\t%s, %s", name, VSuff(op), VN(vd, sz), VN(vs, sz)); - } - - void Dis_Vi2x(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) { - VectorSize sz = GetVecSize(op); - VectorSize dsz = GetHalfVectorSizeSafe(sz); - if (((op>>16)&3)==0) - dsz = V_Single; - + void Dis_Vx2i(MIPSOpcode op, uint32_t pc, char *out, size_t outSize, VectorSize sz, VectorSize dsz) { int vd = _VD; int vs = _VS; const char *name = MIPSGetName(op); snprintf(out, outSize, "%s%s\t%s, %s", name, VSuff(op), VN(vd, dsz), VN(vs, sz)); } + void Dis_Vc2i(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) { + VectorSize sz = GetVecSize(op); + VectorSize dsz = GetQuadrupleVectorSizeSafe(sz); + Dis_Vx2i(op, pc, out, outSize, sz, dsz); + } + + void Dis_Vs2i(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) { + VectorSize sz = GetVecSize(op); + VectorSize dsz = GetDoubleVectorSizeSafe(sz); + Dis_Vx2i(op, pc, out, outSize, sz, dsz); + } + + void Dis_Vi2x(MIPSOpcode op, uint32_t pc, char *out, size_t outSize, VectorSize sz, VectorSize dsz) { + int vd = _VD; + int vs = _VS; + const char *name = MIPSGetName(op); + snprintf(out, outSize, "%s%s\t%s, %s", name, VSuff(op), VN(vd, dsz), VN(vs, sz)); + } + + void Dis_Vi2c(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) { + VectorSize sz = GetVecSize(op); + VectorSize dsz = GetQuarterVectorSizeSafe(sz); + Dis_Vi2x(op, pc, out, outSize, sz, dsz); + } + + void Dis_Vi2s(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) { + VectorSize sz = GetVecSize(op); + VectorSize dsz = GetHalfVectorSizeSafe(sz); + Dis_Vi2x(op, pc, out, outSize, sz, dsz); + } + void Dis_Vwbn(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) { VectorSize sz = GetVecSize(op); @@ -572,7 +584,7 @@ namespace MIPSDis int imm3 = (op>>18)&7; off += imm + 4; const char *name = MIPSGetName(op); - snprintf(out, outSize, "%s\t->$%08x (CC[%i])", name, off, imm3); + snprintf(out, outSize, "%s\t%i, ->$%08x", name, imm3, off); } } diff --git a/Core/MIPS/MIPSDisVFPU.h b/Core/MIPS/MIPSDisVFPU.h index d03f2ff995..15ce9513b8 100644 --- a/Core/MIPS/MIPSDisVFPU.h +++ b/Core/MIPS/MIPSDisVFPU.h @@ -55,7 +55,9 @@ namespace MIPSDis void Dis_Vflush(MIPSOpcode op, uint32_t pc, char *out, size_t outSize); void Dis_Vbfy(MIPSOpcode op, uint32_t pc, char *out, size_t outSize); void Dis_Vf2i(MIPSOpcode op, uint32_t pc, char *out, size_t outSize); - void Dis_Vi2x(MIPSOpcode op, uint32_t pc, char *out, size_t outSize); + void Dis_Vi2c(MIPSOpcode op, uint32_t pc, char *out, size_t outSize); + void Dis_Vi2s(MIPSOpcode op, uint32_t pc, char *out, size_t outSize); + void Dis_Vc2i(MIPSOpcode op, uint32_t pc, char *out, size_t outSize); void Dis_Vs2i(MIPSOpcode op, uint32_t pc, char *out, size_t outSize); void Dis_Vwbn(MIPSOpcode op, uint32_t pc, char *out, size_t outSize); void Dis_Vf2h(MIPSOpcode op, uint32_t pc, char *out, size_t outSize); diff --git a/Core/MIPS/MIPSTables.cpp b/Core/MIPS/MIPSTables.cpp index 4e3e820c30..8b0e6c5020 100644 --- a/Core/MIPS/MIPSTables.cpp +++ b/Core/MIPS/MIPSTables.cpp @@ -478,22 +478,22 @@ static const MIPSInstruction tableCop1S[64] = // 010001 10000 ..... ..... ..... //40 INVALID_X_8, //48 - 010001 10000 ..... ..... ..... 11xxxx - INSTR("c.f", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG|IS_FPU), - INSTR("c.un", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), - INSTR("c.eq", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), - INSTR("c.ueq", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), - INSTR("c.olt", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), - INSTR("c.ult", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), - INSTR("c.ole", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), - INSTR("c.ule", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), - INSTR("c.sf", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG|IS_FPU), - INSTR("c.ngle",JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), - INSTR("c.seq", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), - INSTR("c.ngl", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), - INSTR("c.lt", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), - INSTR("c.nge", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), - INSTR("c.le", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), - INSTR("c.ngt", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), + INSTR("c.f.s", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG|IS_FPU), + INSTR("c.un.s", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), + INSTR("c.eq.s", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), + INSTR("c.ueq.s", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), + INSTR("c.olt.s", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), + INSTR("c.ult.s", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), + INSTR("c.ole.s", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), + INSTR("c.ule.s", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), + INSTR("c.sf.s", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG|IS_FPU), + INSTR("c.ngle.s",JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), + INSTR("c.seq.s", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), + INSTR("c.ngl.s", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), + INSTR("c.lt.s", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), + INSTR("c.nge.s", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), + INSTR("c.le.s", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), + INSTR("c.ngt.s", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU), }; static const MIPSInstruction tableCop1W[64] = // 010001 10100 ..... ..... ..... xxxxxx @@ -609,15 +609,15 @@ static const MIPSInstruction tableVFPU7[32] = // 110100 00001 xxxxx . ....... . INSTR("vsbz", JITFUNC(Comp_Generic), Dis_Generic, Int_Vsbz, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), INSTR("vlgb", JITFUNC(Comp_Generic), Dis_Generic, Int_Vlgb, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), //24 - INSTR("vuc2i", JITFUNC(Comp_Vx2i), Dis_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), // Seen in BraveStory, initialization 110100 00001110000 000 0001 0000 0000 - INSTR("vc2i", JITFUNC(Comp_Vx2i), Dis_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), + INSTR("vuc2ifs", JITFUNC(Comp_Vx2i), Dis_Vc2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), // Seen in BraveStory, initialization 110100 00001110000 000 0001 0000 0000 + INSTR("vc2i", JITFUNC(Comp_Vx2i), Dis_Vc2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), INSTR("vus2i", JITFUNC(Comp_Vx2i), Dis_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), INSTR("vs2i", JITFUNC(Comp_Vx2i), Dis_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), - INSTR("vi2uc", JITFUNC(Comp_Vi2x), Dis_Vi2x, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), - INSTR("vi2c", JITFUNC(Comp_Vi2x), Dis_Vi2x, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), - INSTR("vi2us", JITFUNC(Comp_Vi2x), Dis_Vi2x, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), - INSTR("vi2s", JITFUNC(Comp_Vi2x), Dis_Vi2x, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), + INSTR("vi2uc", JITFUNC(Comp_Vi2x), Dis_Vi2c, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), + INSTR("vi2c", JITFUNC(Comp_Vi2x), Dis_Vi2c, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), + INSTR("vi2us", JITFUNC(Comp_Vi2x), Dis_Vi2s, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), + INSTR("vi2s", JITFUNC(Comp_Vi2x), Dis_Vi2s, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), }; // 110100 00000 10100 0000000000000000 diff --git a/Core/MIPS/MIPSVFPUUtils.cpp b/Core/MIPS/MIPSVFPUUtils.cpp index a5c31ec515..6da405a15a 100644 --- a/Core/MIPS/MIPSVFPUUtils.cpp +++ b/Core/MIPS/MIPSVFPUUtils.cpp @@ -360,6 +360,19 @@ int GetVectorOverlap(int vec1, VectorSize size1, int vec2, VectorSize size2) { return count; } +VectorSize GetQuarterVectorSizeSafe(VectorSize sz) { + switch (sz) { + case V_Quad: return V_Single; + default: return V_Invalid; + } +} + +VectorSize GetQuarterVectorSize(VectorSize sz) { + VectorSize res = GetQuarterVectorSizeSafe(sz); + _assert_msg_(res != V_Invalid, "%s: Bad vector size", __FUNCTION__); + return res; +} + VectorSize GetHalfVectorSizeSafe(VectorSize sz) { switch (sz) { case V_Pair: return V_Single; @@ -374,6 +387,19 @@ VectorSize GetHalfVectorSize(VectorSize sz) { return res; } +VectorSize GetQuadrupleVectorSizeSafe(VectorSize sz) { + switch (sz) { + case V_Single: return V_Quad; + default: return V_Invalid; + } +} + +VectorSize GetQuadrupleVectorSize(VectorSize sz) { + VectorSize res = GetQuadrupleVectorSizeSafe(sz); + _assert_msg_(res != V_Invalid, "%s: Bad vector size", __FUNCTION__); + return res; +} + VectorSize GetDoubleVectorSizeSafe(VectorSize sz) { switch (sz) { case V_Single: return V_Pair; diff --git a/Core/MIPS/MIPSVFPUUtils.h b/Core/MIPS/MIPSVFPUUtils.h index 08910be9ee..045adef312 100644 --- a/Core/MIPS/MIPSVFPUUtils.h +++ b/Core/MIPS/MIPSVFPUUtils.h @@ -219,8 +219,12 @@ static inline MatrixSize GetMtxSize(MIPSOpcode op) { return (MatrixSize)(a + b + 1); // Safe, there are no other possibilities } +VectorSize GetQuarterVectorSizeSafe(VectorSize sz); +VectorSize GetQuarterVectorSize(VectorSize sz); VectorSize GetHalfVectorSizeSafe(VectorSize sz); VectorSize GetHalfVectorSize(VectorSize sz); +VectorSize GetQuadrupleVectorSizeSafe(VectorSize sz); +VectorSize GetQuadrupleVectorSize(VectorSize sz); VectorSize GetDoubleVectorSizeSafe(VectorSize sz); VectorSize GetDoubleVectorSize(VectorSize sz); VectorSize MatrixVectorSizeSafe(MatrixSize sz); diff --git a/ext/armips b/ext/armips index a8d71f0f27..2d7f351e64 160000 --- a/ext/armips +++ b/ext/armips @@ -1 +1 @@ -Subproject commit a8d71f0f279eb0d30ecf6af51473b66ae0cf8e8d +Subproject commit 2d7f351e640ec260b43943f07a00c57211940378