mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-31 20:41:45 +01: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]);
|
||||
}
|
||||
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]);
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ private:
|
||||
void MFSPR(u32 rt, u32 sa)
|
||||
{
|
||||
//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.lo = 0x0;
|
||||
@ -260,7 +260,11 @@ private:
|
||||
}
|
||||
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)
|
||||
{
|
||||
@ -307,7 +311,7 @@ private:
|
||||
void IRET(u32 ra)
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
// SetBranch(SRR0);
|
||||
//SetBranch(SRR0);
|
||||
}
|
||||
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];
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
@ -757,7 +765,10 @@ private:
|
||||
}
|
||||
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)
|
||||
{
|
||||
@ -824,8 +835,13 @@ private:
|
||||
for (int w = 0; w < 4; w++)
|
||||
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)
|
||||
{
|
||||
/*CPU.GPR[rt]._u128.lo =
|
||||
CPU.FPSCR.Exception0 << 20 &
|
||||
CPU.FPSCR.*/
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
void FESD(u32 rt, u32 ra)
|
||||
|
@ -323,7 +323,7 @@ public:
|
||||
virtual void EQV(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 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 XSWD(u32 rt, u32 ra) = 0;
|
||||
virtual void XSHW(u32 rt, u32 ra) = 0;
|
||||
|
@ -117,6 +117,89 @@ enum
|
||||
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
|
||||
{
|
||||
u128 _u128;
|
||||
@ -169,6 +252,7 @@ class SPUThread : public PPCThread
|
||||
public:
|
||||
SPU_GPR_hdr GPR[128]; //General-Purpose Register
|
||||
SPU_SPR_hdr SPR[128]; //Special-Purpose Registers
|
||||
FPSCR FPSCR;
|
||||
|
||||
template<size_t _max_count>
|
||||
class Channel
|
||||
|
Loading…
x
Reference in New Issue
Block a user