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 "Emu/SysCalls/SysCalls.h"
#include "rpcs3.h" #include "rpcs3.h"
#include <stdint.h> #include <stdint.h>
#include <intrin.h>
#define UNIMPLEMENTED() UNK(__FUNCTION__) #define UNIMPLEMENTED() UNK(__FUNCTION__)
@ -2272,6 +2273,11 @@ private:
} }
void MULHDU(u32 rd, u32 ra, u32 rb, bool rc) 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 RA = CPU.GPR[ra];
const u64 RB = CPU.GPR[rb]; const u64 RB = CPU.GPR[rb];
@ -2292,12 +2298,15 @@ private:
mid += (a0 + a1) * (b0 + b1) - (lo + hi); mid += (a0 + a1) * (b0 + b1) - (lo + hi);
CPU.GPR[rd] = RD._u64[1]; CPU.GPR[rd] = RD._u64[1];
#endif
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]); if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
} }
void MULHWU(u32 rd, u32 ra, u32 rb, bool rc) 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]); if(rc) CPU.UpdateCR0<s32>(CPU.GPR[rd]);
} }
void MFOCRF(u32 a, u32 rd, u32 crm) void MFOCRF(u32 a, u32 rd, u32 crm)
@ -2344,9 +2353,9 @@ private:
} }
void SLW(u32 ra, u32 rs, u32 rb, bool rc) void SLW(u32 ra, u32 rs, u32 rb, bool rc)
{ {
const u32 n = CPU.GPR[rb] & 0x1f; u32 n = CPU.GPR[rb] & 0x1f;
const u32 r = rotl32((u32)CPU.GPR[rs], n); u32 r = rotl32((u32)CPU.GPR[rs], n);
const u32 m = (CPU.GPR[rb] & 0x20) ? 0 : rotate_mask[32][63 - n]; u32 m = (CPU.GPR[rb] & 0x20) ? 0 : rotate_mask[32][63 - n];
CPU.GPR[ra] = r & m; CPU.GPR[ra] = r & m;
@ -2357,18 +2366,18 @@ private:
u32 i; u32 i;
for(i=0; i < 32; 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; 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) void SLD(u32 ra, u32 rs, u32 rb, bool rc)
{ {
const u32 n = CPU.GPR[rb] & 0x3f; u32 n = CPU.GPR[rb] & 0x3f;
const u64 r = rotl64(CPU.GPR[rs], n); u64 r = rotl64(CPU.GPR[rs], n);
const u64 m = (CPU.GPR[rb] & 0x40) ? 0 : rotate_mask[0][63 - n]; u64 m = (CPU.GPR[rb] & 0x40) ? 0 : rotate_mask[0][63 - n];
CPU.GPR[ra] = r & m; CPU.GPR[ra] = r & m;
@ -2435,15 +2444,14 @@ private:
} }
void CNTLZD(u32 ra, u32 rs, bool rc) void CNTLZD(u32 ra, u32 rs, bool rc)
{ {
u32 i = 0; u32 i;
for(i=0; i < 64; i++)
for(u64 mask = 1ULL << 63; i < 64; i++, mask >>= 1)
{ {
if(CPU.GPR[rs] & mask) break; if(CPU.GPR[rs] & (1ULL << (63 - i))) break;
} }
CPU.GPR[ra] = i; 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) 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) 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 RA = CPU.GPR[ra];
const s64 RB = CPU.GPR[rb]; const s64 RB = CPU.GPR[rb];
@ -2479,13 +2491,16 @@ private:
mid += (a0 + a1) * (b0 + b1) - (lo + hi); mid += (a0 + a1) * (b0 + b1) - (lo + hi);
CPU.GPR[rd] = RT._u64[1]; CPU.GPR[rd] = RT._u64[1];
#endif
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]); if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
} }
void MULHW(u32 rd, u32 ra, u32 rb, bool rc) void MULHW(u32 rd, u32 ra, u32 rb, bool rc)
{ {
CPU.GPR[rd] = (s64)(s32)((CPU.GPR[ra] * CPU.GPR[rb]) >> 32); s32 a = CPU.GPR[ra];
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]); 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) void LDARX(u32 rd, u32 ra, u32 rb)
{ {
@ -2889,8 +2904,8 @@ private:
void SRW(u32 ra, u32 rs, u32 rb, bool rc) void SRW(u32 ra, u32 rs, u32 rb, bool rc)
{ {
u32 n = CPU.GPR[rb] & 0x1f; u32 n = CPU.GPR[rb] & 0x1f;
u64 r = rotl32((u32)CPU.GPR[rs], 64 - n); u32 r = rotl32((u32)CPU.GPR[rs], 64 - n);
u64 m = (CPU.GPR[rb] & 0x20) ? 0 : rotate_mask[32 + n][63]; u32 m = (CPU.GPR[rb] & 0x20) ? 0 : rotate_mask[32 + n][63];
CPU.GPR[ra] = r & m; CPU.GPR[ra] = r & m;
if(rc) CPU.UpdateCR0<s32>(CPU.GPR[ra]); 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]; static u32 offset_list[m_vertex_count];
u32 cur_offset = 0; u32 cur_offset = 0;
const u32 data_offset = indexed_draw ? 0 : m_draw_array_first;
for(u32 i=0; i<m_vertex_count; ++i) for(u32 i=0; i<m_vertex_count; ++i)
{ {
offset_list[i] = cur_offset; offset_list[i] = cur_offset;
if(!m_vertex_data[i].IsEnabled() || !m_vertex_data[i].addr) continue; 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(); 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(); m_vao.Create();
@ -1010,7 +1015,7 @@ void GLGSRender::ExecCMD()
if(m_draw_array_count) if(m_draw_array_count)
{ {
//ConLog.Warning("glDrawArrays(%d,%d,%d)", m_draw_mode - 1, m_draw_array_first, 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"); checkForGlError("glDrawArrays");
DisableVertexData(); 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); const u32 addr = GetAddress(args[0] & 0x7fffffff, args[0] >> 31);
CMD_LOG("num=%d, addr=0x%x", index, addr); CMD_LOG("num=%d, addr=0x%x", index, addr);
m_vertex_data[index].addr = addr; m_vertex_data[index].addr = addr;
m_vertex_data[index].data.ClearF();
} }
break; break;