1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 02:32:36 +01:00

Improved PPU Interpreter

- Fixed MULHW & MULHWU.
- Improved MULHD & MULHDU.
This commit is contained in:
DH 2013-11-23 04:55:26 +02:00
parent aab69513aa
commit 62c1980cac
3 changed files with 43 additions and 22 deletions

View File

@ -6,6 +6,7 @@
#include "Emu/SysCalls/SysCalls.h"
#include "rpcs3.h"
#include <stdint.h>
#include <intrin.h>
#define UNIMPLEMENTED() UNK(__FUNCTION__)
@ -2272,6 +2273,11 @@ private:
}
void MULHDU(u32 rd, u32 ra, u32 rb, bool rc)
{
#ifdef _M_X64
CPU.GPR[rd] = __umulh(CPU.GPR[ra], CPU.GPR[rb]);
#else
ConLog.Warning("MULHDU");
const u64 RA = CPU.GPR[ra];
const u64 RB = CPU.GPR[rb];
@ -2292,12 +2298,15 @@ private:
mid += (a0 + a1) * (b0 + b1) - (lo + hi);
CPU.GPR[rd] = RD._u64[1];
#endif
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
}
void MULHWU(u32 rd, u32 ra, u32 rb, bool rc)
{
CPU.GPR[rd] = (CPU.GPR[ra] * CPU.GPR[rb]) >> 32;
u32 a = CPU.GPR[ra];
u32 b = CPU.GPR[rb];
CPU.GPR[rd] = ((u64)a * (u64)b) >> 32;
if(rc) CPU.UpdateCR0<s32>(CPU.GPR[rd]);
}
void MFOCRF(u32 a, u32 rd, u32 crm)
@ -2344,9 +2353,9 @@ private:
}
void SLW(u32 ra, u32 rs, u32 rb, bool rc)
{
const u32 n = CPU.GPR[rb] & 0x1f;
const u32 r = rotl32((u32)CPU.GPR[rs], n);
const u32 m = (CPU.GPR[rb] & 0x20) ? 0 : rotate_mask[32][63 - n];
u32 n = CPU.GPR[rb] & 0x1f;
u32 r = rotl32((u32)CPU.GPR[rs], n);
u32 m = (CPU.GPR[rb] & 0x20) ? 0 : rotate_mask[32][63 - n];
CPU.GPR[ra] = r & m;
@ -2357,18 +2366,18 @@ private:
u32 i;
for(i=0; i < 32; i++)
{
if(CPU.GPR[rs] & (0x80000000 >> i)) break;
if(CPU.GPR[rs] & (1ULL << (31 - i))) break;
}
CPU.GPR[ra] = i;
if(rc) CPU.UpdateCR0<s32>(CPU.GPR[ra]);
if(rc) CPU.SetCRBit(CR_LT, false);
}
void SLD(u32 ra, u32 rs, u32 rb, bool rc)
{
const u32 n = CPU.GPR[rb] & 0x3f;
const u64 r = rotl64(CPU.GPR[rs], n);
const u64 m = (CPU.GPR[rb] & 0x40) ? 0 : rotate_mask[0][63 - n];
u32 n = CPU.GPR[rb] & 0x3f;
u64 r = rotl64(CPU.GPR[rs], n);
u64 m = (CPU.GPR[rb] & 0x40) ? 0 : rotate_mask[0][63 - n];
CPU.GPR[ra] = r & m;
@ -2435,15 +2444,14 @@ private:
}
void CNTLZD(u32 ra, u32 rs, bool rc)
{
u32 i = 0;
for(u64 mask = 1ULL << 63; i < 64; i++, mask >>= 1)
u32 i;
for(i=0; i < 64; i++)
{
if(CPU.GPR[rs] & mask) break;
if(CPU.GPR[rs] & (1ULL << (63 - i))) break;
}
CPU.GPR[ra] = i;
if(rc) CPU.UpdateCR0<u64>(CPU.GPR[ra]);
if(rc) CPU.SetCRBit(CR_LT, false);
}
void ANDC(u32 ra, u32 rs, u32 rb, bool rc)
{
@ -2459,6 +2467,10 @@ private:
}
void MULHD(u32 rd, u32 ra, u32 rb, bool rc)
{
#ifdef _M_X64
CPU.GPR[rd] = __mulh(CPU.GPR[ra], CPU.GPR[rb]);
#else
ConLog.Warning("MULHD");
const s64 RA = CPU.GPR[ra];
const s64 RB = CPU.GPR[rb];
@ -2479,13 +2491,16 @@ private:
mid += (a0 + a1) * (b0 + b1) - (lo + hi);
CPU.GPR[rd] = RT._u64[1];
#endif
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
}
void MULHW(u32 rd, u32 ra, u32 rb, bool rc)
{
CPU.GPR[rd] = (s64)(s32)((CPU.GPR[ra] * CPU.GPR[rb]) >> 32);
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
s32 a = CPU.GPR[ra];
s32 b = CPU.GPR[rb];
CPU.GPR[rd] = ((s64)a * (s64)b) >> 32;
if(rc) CPU.UpdateCR0<s32>(CPU.GPR[rd]);
}
void LDARX(u32 rd, u32 ra, u32 rb)
{
@ -2889,8 +2904,8 @@ private:
void SRW(u32 ra, u32 rs, u32 rb, bool rc)
{
u32 n = CPU.GPR[rb] & 0x1f;
u64 r = rotl32((u32)CPU.GPR[rs], 64 - n);
u64 m = (CPU.GPR[rb] & 0x20) ? 0 : rotate_mask[32 + n][63];
u32 r = rotl32((u32)CPU.GPR[rs], 64 - n);
u32 m = (CPU.GPR[rb] & 0x20) ? 0 : rotate_mask[32 + n][63];
CPU.GPR[ra] = r & m;
if(rc) CPU.UpdateCR0<s32>(CPU.GPR[ra]);

View File

@ -124,16 +124,21 @@ void GLGSRender::EnableVertexData(bool indexed_draw)
static u32 offset_list[m_vertex_count];
u32 cur_offset = 0;
const u32 data_offset = indexed_draw ? 0 : m_draw_array_first;
for(u32 i=0; i<m_vertex_count; ++i)
{
offset_list[i] = cur_offset;
if(!m_vertex_data[i].IsEnabled() || !m_vertex_data[i].addr) continue;
cur_offset += m_vertex_data[i].data.GetCount();
const size_t item_size = m_vertex_data[i].GetTypeSize() * m_vertex_data[i].size;
const size_t data_size = m_vertex_data[i].data.GetCount() - data_offset * item_size;
const u32 pos = m_vdata.GetCount();
m_vdata.InsertRoomEnd(m_vertex_data[i].data.GetCount());
memcpy(&m_vdata[pos], &m_vertex_data[i].data[0], m_vertex_data[i].data.GetCount());
cur_offset += data_size;
m_vdata.InsertRoomEnd(data_size);
memcpy(&m_vdata[pos], &m_vertex_data[i].data[data_offset * item_size], data_size);
}
m_vao.Create();
@ -1010,7 +1015,7 @@ void GLGSRender::ExecCMD()
if(m_draw_array_count)
{
//ConLog.Warning("glDrawArrays(%d,%d,%d)", m_draw_mode - 1, m_draw_array_first, m_draw_array_count);
glDrawArrays(m_draw_mode - 1, m_draw_array_first, m_draw_array_count);
glDrawArrays(m_draw_mode - 1, 0, m_draw_array_count);
checkForGlError("glDrawArrays");
DisableVertexData();
}

View File

@ -499,6 +499,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
const u32 addr = GetAddress(args[0] & 0x7fffffff, args[0] >> 31);
CMD_LOG("num=%d, addr=0x%x", index, addr);
m_vertex_data[index].addr = addr;
m_vertex_data[index].data.ClearF();
}
break;