interp: Mask moves to vfpu ctrl.

These bits of the registers can't be written.
This commit is contained in:
Unknown W. Brackets 2019-03-30 11:57:11 -07:00
parent 2a5d4e577d
commit af3ed69144
4 changed files with 65 additions and 5 deletions

View File

@ -982,7 +982,15 @@ namespace MIPSComp {
if (imm < 128) {
ir.Write(IROp::FMovFromGPR, vfpuBase + voffset[imm], rt);
} else if ((imm - 128) < VFPU_CTRL_MAX) {
ir.Write(IROp::SetCtrlVFPU, imm - 128, rt);
u32 mask;
if (GetVFPUCtrlMask(imm - 128, &mask)) {
if (mask != 0xFFFFFFFF) {
ir.Write(IROp::AndConst, IRTEMP_0, rt, ir.AddConstant(mask));
ir.Write(IROp::SetCtrlVFPUReg, imm - 128, IRTEMP_0);
} else {
ir.Write(IROp::SetCtrlVFPU, imm - 128, rt);
}
}
if (imm - 128 == VFPU_CTRL_SPREFIX) {
js.prefixSFlag = JitState::PREFIX_UNKNOWN;
@ -1028,7 +1036,16 @@ namespace MIPSComp {
int vs = _VS;
int imm = op & 0xFF;
if (imm >= 128 && imm < 128 + VFPU_CTRL_MAX) {
ir.Write(IROp::SetCtrlVFPUFReg, imm - 128, vfpuBase + voffset[vs]);
u32 mask;
if (GetVFPUCtrlMask(imm - 128, &mask)) {
if (mask != 0xFFFFFFFF) {
ir.Write(IROp::FMovToGPR, IRTEMP_0, vfpuBase + voffset[imm]);
ir.Write(IROp::AndConst, IRTEMP_0, IRTEMP_0, ir.AddConstant(mask));
ir.Write(IROp::SetCtrlVFPUReg, imm - 128, IRTEMP_0);
} else {
ir.Write(IROp::SetCtrlVFPUFReg, imm - 128, vfpuBase + voffset[vs]);
}
}
if (imm - 128 == VFPU_CTRL_SPREFIX) {
js.prefixSFlag = JitState::PREFIX_UNKNOWN;
} else if (imm - 128 == VFPU_CTRL_TPREFIX) {

View File

@ -181,7 +181,7 @@ namespace MIPSInt
{
void Int_VPFX(MIPSOpcode op)
{
int data = op & 0xFFFFF;
int data = op & 0x000FFFFF;
int regnum = (op >> 24) & 3;
if (regnum == VFPU_CTRL_DPREFIX)
data &= 0x00000FFF;
@ -1511,7 +1511,10 @@ namespace MIPSInt
if (imm < 128) {
VI(imm) = R(rt);
} else if (imm < 128 + VFPU_CTRL_MAX) { //mtvc
currentMIPS->vfpuCtrl[imm - 128] = R(rt);
u32 mask;
if (GetVFPUCtrlMask(imm - 128, &mask)) {
currentMIPS->vfpuCtrl[imm - 128] = R(rt) & mask;
}
} else {
//ERROR
_dbg_assert_msg_(CPU,0,"mtv - invalid register");
@ -1538,7 +1541,10 @@ namespace MIPSInt
int vs = _VS;
int imm = op & 0xFF;
if (imm >= 128 && imm < 128 + VFPU_CTRL_MAX) {
currentMIPS->vfpuCtrl[imm - 128] = VI(vs);
u32 mask;
if (GetVFPUCtrlMask(imm - 128, &mask)) {
currentMIPS->vfpuCtrl[imm - 128] = VI(vs) & mask;
}
}
PC += 4;
}

View File

@ -526,6 +526,41 @@ const char *GetMatrixNotation(int reg, MatrixSize size)
return hej[yo];
}
bool GetVFPUCtrlMask(int reg, u32 *mask) {
switch (reg) {
case VFPU_CTRL_SPREFIX:
case VFPU_CTRL_TPREFIX:
*mask = 0x000FFFFF;
return true;
case VFPU_CTRL_DPREFIX:
*mask = 0x00000FFF;
return true;
case VFPU_CTRL_CC:
*mask = 0x0000003F;
return true;
case VFPU_CTRL_INF4:
*mask = 0xFFFFFFFF;
return true;
case VFPU_CTRL_RSV5:
case VFPU_CTRL_RSV6:
case VFPU_CTRL_REV:
// Don't change anything, these regs are read only.
return false;
case VFPU_CTRL_RCX0:
case VFPU_CTRL_RCX1:
case VFPU_CTRL_RCX2:
case VFPU_CTRL_RCX3:
case VFPU_CTRL_RCX4:
case VFPU_CTRL_RCX5:
case VFPU_CTRL_RCX6:
case VFPU_CTRL_RCX7:
*mask = 0x3FFFFFFF;
return true;
default:
return false;
}
}
float Float16ToFloat32(unsigned short l)
{
union float2int {

View File

@ -242,4 +242,6 @@ inline int TransposeMatrixReg(int matrixReg) {
}
int GetVectorOverlap(int reg1, VectorSize size1, int reg2, VectorSize size2);
bool GetVFPUCtrlMask(int reg, u32 *mask);
float Float16ToFloat32(unsigned short l);