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
This commit is contained in:
Thomas Lamb
2026-07-07 20:24:13 -04:00
parent 04aeef1180
commit d1656d425a
6 changed files with 95 additions and 51 deletions
+39 -27
View File
@@ -153,7 +153,7 @@ namespace MIPSDis
void Dis_VPFXST(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) { void Dis_VPFXST(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
int data = op & 0xFFFFF; int data = op & 0xFFFFF;
const char *name = MIPSGetName(op); 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 regnam[4] = {"X","Y","Z","W"};
static const char * const constan[8] = {"0","1","2","1/2","3","1/3","1/4","1/6"}; 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) if (i != 3 && outpos < outSize)
outpos += truncate_cpy(out + outpos, outSize - outpos, ","); 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) { void Dis_VPFXD(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
int data = op & 0xFFFFF; int data = op & 0xFFFFF;
const char *name = MIPSGetName(op); 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++) for (int i=0; i<4; i++)
{ {
int sat = (data>>i*2)&3; int sat = (data>>i*2)&3;
@@ -203,9 +200,6 @@ namespace MIPSDis
if (i < 4 - 1 && outpos < outSize) if (i < 4 - 1 && outpos < outSize)
outpos += truncate_cpy(out + outpos, outSize - outpos, ","); outpos += truncate_cpy(out + outpos, outSize - outpos, ",");
} }
if (outpos < outSize)
outpos += truncate_cpy(out + outpos, outSize - outpos, "]");
} }
@@ -373,9 +367,9 @@ namespace MIPSDis
return; return;
} }
if (imm3<6) 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); 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 if (imm3 == 6) else
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\tERROR", name, tf==0?"t":"f", VSuff(op));
} }
void Dis_Vfad(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) { 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); 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) { void Dis_Vx2i(MIPSOpcode op, uint32_t pc, char *out, size_t outSize, VectorSize sz, VectorSize dsz) {
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;
int vd = _VD; int vd = _VD;
int vs = _VS; int vs = _VS;
const char *name = MIPSGetName(op); const char *name = MIPSGetName(op);
snprintf(out, outSize, "%s%s\t%s, %s", name, VSuff(op), VN(vd, dsz), VN(vs, sz)); 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) { void Dis_Vwbn(MIPSOpcode op, uint32_t pc, char *out, size_t outSize) {
VectorSize sz = GetVecSize(op); VectorSize sz = GetVecSize(op);
@@ -572,7 +584,7 @@ namespace MIPSDis
int imm3 = (op>>18)&7; int imm3 = (op>>18)&7;
off += imm + 4; off += imm + 4;
const char *name = MIPSGetName(op); 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);
} }
} }
+3 -1
View File
@@ -55,7 +55,9 @@ namespace MIPSDis
void Dis_Vflush(MIPSOpcode op, uint32_t pc, char *out, size_t outSize); 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_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_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_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_Vwbn(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
void Dis_Vf2h(MIPSOpcode op, uint32_t pc, char *out, size_t outSize); void Dis_Vf2h(MIPSOpcode op, uint32_t pc, char *out, size_t outSize);
+22 -22
View File
@@ -478,22 +478,22 @@ static const MIPSInstruction tableCop1S[64] = // 010001 10000 ..... ..... .....
//40 //40
INVALID_X_8, INVALID_X_8,
//48 - 010001 10000 ..... ..... ..... 11xxxx //48 - 010001 10000 ..... ..... ..... 11xxxx
INSTR("c.f", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG|IS_FPU), INSTR("c.f.s", 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.un.s", 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.eq.s", 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.ueq.s", 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.olt.s", 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.ult.s", 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.ole.s", 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.ule.s", 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.sf.s", 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.ngle.s",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.seq.s", 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.ngl.s", 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.lt.s", 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.nge.s", 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.le.s", 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.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 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("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), INSTR("vlgb", JITFUNC(Comp_Generic), Dis_Generic, Int_Vlgb, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
//24 //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("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_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), 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("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("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("vi2uc", JITFUNC(Comp_Vi2x), Dis_Vi2c, 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("vi2c", JITFUNC(Comp_Vi2x), Dis_Vi2c, 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("vi2us", JITFUNC(Comp_Vi2x), Dis_Vi2s, 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("vi2s", JITFUNC(Comp_Vi2x), Dis_Vi2s, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),
}; };
// 110100 00000 10100 0000000000000000 // 110100 00000 10100 0000000000000000
+26
View File
@@ -360,6 +360,19 @@ int GetVectorOverlap(int vec1, VectorSize size1, int vec2, VectorSize size2) {
return count; 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) { VectorSize GetHalfVectorSizeSafe(VectorSize sz) {
switch (sz) { switch (sz) {
case V_Pair: return V_Single; case V_Pair: return V_Single;
@@ -374,6 +387,19 @@ VectorSize GetHalfVectorSize(VectorSize sz) {
return res; 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) { VectorSize GetDoubleVectorSizeSafe(VectorSize sz) {
switch (sz) { switch (sz) {
case V_Single: return V_Pair; case V_Single: return V_Pair;
+4
View File
@@ -219,8 +219,12 @@ static inline MatrixSize GetMtxSize(MIPSOpcode op) {
return (MatrixSize)(a + b + 1); // Safe, there are no other possibilities return (MatrixSize)(a + b + 1); // Safe, there are no other possibilities
} }
VectorSize GetQuarterVectorSizeSafe(VectorSize sz);
VectorSize GetQuarterVectorSize(VectorSize sz);
VectorSize GetHalfVectorSizeSafe(VectorSize sz); VectorSize GetHalfVectorSizeSafe(VectorSize sz);
VectorSize GetHalfVectorSize(VectorSize sz); VectorSize GetHalfVectorSize(VectorSize sz);
VectorSize GetQuadrupleVectorSizeSafe(VectorSize sz);
VectorSize GetQuadrupleVectorSize(VectorSize sz);
VectorSize GetDoubleVectorSizeSafe(VectorSize sz); VectorSize GetDoubleVectorSizeSafe(VectorSize sz);
VectorSize GetDoubleVectorSize(VectorSize sz); VectorSize GetDoubleVectorSize(VectorSize sz);
VectorSize MatrixVectorSizeSafe(MatrixSize sz); VectorSize MatrixVectorSizeSafe(MatrixSize sz);