mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-29 22:20:48 +00:00
-Partial Implementation of Floating-Point Status and Control Register (FPSCR)
This commit is contained in:
parent
3c762750a0
commit
1192d20295
@ -428,7 +428,7 @@ private:
|
|||||||
{
|
{
|
||||||
DisAsm("sumb", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]);
|
DisAsm("sumb", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]);
|
||||||
}
|
}
|
||||||
void HGT(u32 rt, u32 ra, u32 rb)
|
void HGT(u32 rt, s32 ra, s32 rb)
|
||||||
{
|
{
|
||||||
DisAsm("hgt", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]);
|
DisAsm("hgt", spu_reg_name[rt], spu_reg_name[ra], spu_reg_name[rb]);
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ private:
|
|||||||
void MFSPR(u32 rt, u32 sa)
|
void MFSPR(u32 rt, u32 sa)
|
||||||
{
|
{
|
||||||
//If register is a dummy register (register labeled 0x0)
|
//If register is a dummy register (register labeled 0x0)
|
||||||
if(sa == 0)
|
if(sa == 0x0)
|
||||||
{
|
{
|
||||||
CPU.GPR[rt]._u128.hi = 0x0;
|
CPU.GPR[rt]._u128.hi = 0x0;
|
||||||
CPU.GPR[rt]._u128.lo = 0x0;
|
CPU.GPR[rt]._u128.lo = 0x0;
|
||||||
@ -260,7 +260,11 @@ private:
|
|||||||
}
|
}
|
||||||
void MTSPR(u32 rt, u32 sa)
|
void MTSPR(u32 rt, u32 sa)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
if(sa != 0)
|
||||||
|
{
|
||||||
|
CPU.SPR[sa]._u128.hi = CPU.GPR[rt]._u128.hi;
|
||||||
|
CPU.SPR[sa]._u128.lo = CPU.GPR[rt]._u128.lo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void WRCH(u32 ra, u32 rt)
|
void WRCH(u32 ra, u32 rt)
|
||||||
{
|
{
|
||||||
@ -307,7 +311,7 @@ private:
|
|||||||
void IRET(u32 ra)
|
void IRET(u32 ra)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
// SetBranch(SRR0);
|
//SetBranch(SRR0);
|
||||||
}
|
}
|
||||||
void BISLED(u32 rt, u32 ra)
|
void BISLED(u32 rt, u32 ra)
|
||||||
{
|
{
|
||||||
@ -628,9 +632,13 @@ private:
|
|||||||
CPU.GPR[rt]._u16[w*2 + 1] = CPU.GPR[rb]._u8[w*4] + CPU.GPR[rb]._u8[w*4 + 1] + CPU.GPR[rb]._u8[w*4 + 2] + CPU.GPR[rb]._u8[w*4 + 3];
|
CPU.GPR[rt]._u16[w*2 + 1] = CPU.GPR[rb]._u8[w*4] + CPU.GPR[rb]._u8[w*4 + 1] + CPU.GPR[rb]._u8[w*4 + 2] + CPU.GPR[rb]._u8[w*4 + 3];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void HGT(u32 rt, u32 ra, u32 rb)
|
//HGT uses signed values. HLGT uses unsigned values
|
||||||
|
void HGT(u32 rt, s32 ra, s32 rb)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
if(CPU.GPR[ra]._i32[0] > CPU.GPR[rb]._i32[0])
|
||||||
|
{
|
||||||
|
CPU.Stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void CLZ(u32 rt, u32 ra)
|
void CLZ(u32 rt, u32 ra)
|
||||||
{
|
{
|
||||||
@ -757,7 +765,10 @@ private:
|
|||||||
}
|
}
|
||||||
void HLGT(u32 rt, u32 ra, u32 rb)
|
void HLGT(u32 rt, u32 ra, u32 rb)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED();
|
if(CPU.GPR[ra]._u32[0] > CPU.GPR[rb]._u32[0])
|
||||||
|
{
|
||||||
|
CPU.Stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void DFMA(u32 rt, u32 ra, u32 rb)
|
void DFMA(u32 rt, u32 ra, u32 rb)
|
||||||
{
|
{
|
||||||
@ -824,8 +835,13 @@ private:
|
|||||||
for (int w = 0; w < 4; w++)
|
for (int w = 0; w < 4; w++)
|
||||||
CPU.GPR[rt]._u32[w] += CPU.GPR[ra]._u16[w*2] * CPU.GPR[rb]._u16[w*2];
|
CPU.GPR[rt]._u32[w] += CPU.GPR[ra]._u16[w*2] * CPU.GPR[rb]._u16[w*2];
|
||||||
}
|
}
|
||||||
|
//Forced bits to 0, hence the shift:
|
||||||
|
|
||||||
void FSCRRD(u32 rt)
|
void FSCRRD(u32 rt)
|
||||||
{
|
{
|
||||||
|
/*CPU.GPR[rt]._u128.lo =
|
||||||
|
CPU.FPSCR.Exception0 << 20 &
|
||||||
|
CPU.FPSCR.*/
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
}
|
}
|
||||||
void FESD(u32 rt, u32 ra)
|
void FESD(u32 rt, u32 ra)
|
||||||
|
@ -323,7 +323,7 @@ public:
|
|||||||
virtual void EQV(u32 rt, u32 ra, u32 rb) = 0;
|
virtual void EQV(u32 rt, u32 ra, u32 rb) = 0;
|
||||||
virtual void CGTB(u32 rt, u32 ra, u32 rb) = 0;
|
virtual void CGTB(u32 rt, u32 ra, u32 rb) = 0;
|
||||||
virtual void SUMB(u32 rt, u32 ra, u32 rb) = 0;
|
virtual void SUMB(u32 rt, u32 ra, u32 rb) = 0;
|
||||||
virtual void HGT(u32 rt, u32 ra, u32 rb) = 0;
|
virtual void HGT(u32 rt, s32 ra, s32 rb) = 0;
|
||||||
virtual void CLZ(u32 rt, u32 ra) = 0;
|
virtual void CLZ(u32 rt, u32 ra) = 0;
|
||||||
virtual void XSWD(u32 rt, u32 ra) = 0;
|
virtual void XSWD(u32 rt, u32 ra) = 0;
|
||||||
virtual void XSHW(u32 rt, u32 ra) = 0;
|
virtual void XSHW(u32 rt, u32 ra) = 0;
|
||||||
|
@ -117,6 +117,89 @@ enum
|
|||||||
SPU_STATUS_SINGLE_STEP = 0x10,
|
SPU_STATUS_SINGLE_STEP = 0x10,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Floating point status and control register. Unsure if this is one of the GPRs or SPRs
|
||||||
|
//Is 128 bits, but bits 0-19, 24-28, 32-49, 56-60, 64-81, 88-92, 96-115, 120-124 are unused
|
||||||
|
class FPSCR
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
u64 low;
|
||||||
|
u64 hi;
|
||||||
|
|
||||||
|
FPSCR() {}
|
||||||
|
|
||||||
|
wxString ToString() const
|
||||||
|
{
|
||||||
|
return "FPSCR writer not yet implemented"; //wxString::Format("%08x%08x%08x%08x", _u32[3], _u32[2], _u32[1], _u32[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset()
|
||||||
|
{
|
||||||
|
memset(this, 0, sizeof(*this));
|
||||||
|
}
|
||||||
|
//slice -> 0 - 1 (4 slices total, only two have rounding)
|
||||||
|
//0 -> round even
|
||||||
|
//1 -> round towards zero (truncate)
|
||||||
|
//2 -> round towards positive inf
|
||||||
|
//3 -> round towards neg inf
|
||||||
|
void setSliceRounding(u8 slice, u8 roundTo)
|
||||||
|
{
|
||||||
|
u64 mask = roundTo;
|
||||||
|
switch(slice)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
mask = mask << 20;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
mask = mask << 22;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//rounding is located in the low end of the FPSCR
|
||||||
|
this->low = this->low & mask;
|
||||||
|
}
|
||||||
|
//Slice 0 or 1
|
||||||
|
u8 checkSliceRounding(u8 slice)
|
||||||
|
{
|
||||||
|
switch(slice)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return this->low >> 20 & 0x3;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
return this->low >> 22 & 0x3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Single Precision Exception Flags (all 3 slices)
|
||||||
|
//slice -> slice number (0-3)
|
||||||
|
//exception: 1 -> Overflow 2 -> Underflow 4-> Diff (could be IE^3 non compliant)
|
||||||
|
void setSinglePrecisionExceptionFlags(u8 slice, u8 exception)
|
||||||
|
{
|
||||||
|
u64 mask = exception;
|
||||||
|
switch(slice)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
mask = mask << 29;
|
||||||
|
this->low = this->low & mask;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
mask = mask << 61;
|
||||||
|
this->low = this->low & mask;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
mask = mask << 29;
|
||||||
|
this->hi = this->hi & mask;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
mask = mask << 61;
|
||||||
|
this->hi = this->hi & mask;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
union SPU_GPR_hdr
|
union SPU_GPR_hdr
|
||||||
{
|
{
|
||||||
u128 _u128;
|
u128 _u128;
|
||||||
@ -169,6 +252,7 @@ class SPUThread : public PPCThread
|
|||||||
public:
|
public:
|
||||||
SPU_GPR_hdr GPR[128]; //General-Purpose Register
|
SPU_GPR_hdr GPR[128]; //General-Purpose Register
|
||||||
SPU_SPR_hdr SPR[128]; //Special-Purpose Registers
|
SPU_SPR_hdr SPR[128]; //Special-Purpose Registers
|
||||||
|
FPSCR FPSCR;
|
||||||
|
|
||||||
template<size_t _max_count>
|
template<size_t _max_count>
|
||||||
class Channel
|
class Channel
|
||||||
|
Loading…
x
Reference in New Issue
Block a user