Basic load

This commit is contained in:
Nekotekina 2015-03-17 23:03:24 +03:00
parent 573f112b37
commit 620e937473
5 changed files with 2472 additions and 428 deletions

View file

@ -115,8 +115,6 @@ namespace PPU_instr
*/ */
static CodeField<30> AA; static CodeField<30> AA;
static CodeFieldSignedOffset<6, 29, 2> LI(FIELD_BRANCH);
// //
static CodeFieldSignedOffset<6, 29, 2> LL(FIELD_BRANCH); static CodeFieldSignedOffset<6, 29, 2> LL(FIELD_BRANCH);
/* /*
@ -245,7 +243,7 @@ namespace PPU_instr
bind_instr(main_list, BC, BO, BI, BD, AA, LK); bind_instr(main_list, BC, BO, BI, BD, AA, LK);
bind_instr(main_list, HACK, uimm26); bind_instr(main_list, HACK, uimm26);
bind_instr(main_list, SC, LEV); bind_instr(main_list, SC, LEV);
bind_instr(main_list, B, LI, AA, LK); bind_instr(main_list, B, LL, AA, LK);
bind_instr(main_list, RLWIMI, RA, RS, SH, MB, ME, RC); bind_instr(main_list, RLWIMI, RA, RS, SH, MB, ME, RC);
bind_instr(main_list, RLWINM, RA, RS, SH, MB, ME, RC); bind_instr(main_list, RLWINM, RA, RS, SH, MB, ME, RC);
bind_instr(main_list, RLWNM, RA, RS, RB, MB, ME, RC); bind_instr(main_list, RLWNM, RA, RS, RB, MB, ME, RC);

File diff suppressed because it is too large Load diff

View file

@ -2445,6 +2445,11 @@ private:
if(oe) CPU.SetOV((~RA>>63 == RB>>63) && (~RA>>63 != CPU.GPR[rd]>>63)); if(oe) CPU.SetOV((~RA>>63 == RB>>63) && (~RA>>63 != CPU.GPR[rd]>>63));
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]); if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
} }
void MULHDU(u32 rd, u32 ra, u32 rb, bool rc)
{
CPU.GPR[rd] = __umulh(CPU.GPR[ra], CPU.GPR[rb]);
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
}
void ADDC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) void ADDC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc)
{ {
const u64 RA = CPU.GPR[ra]; const u64 RA = CPU.GPR[ra];
@ -2454,11 +2459,6 @@ private:
if(oe) CPU.SetOV((RA>>63 == RB>>63) && (RA>>63 != CPU.GPR[rd]>>63)); if(oe) CPU.SetOV((RA>>63 == RB>>63) && (RA>>63 != CPU.GPR[rd]>>63));
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]); if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
} }
void MULHDU(u32 rd, u32 ra, u32 rb, bool rc)
{
CPU.GPR[rd] = __umulh(CPU.GPR[ra], CPU.GPR[rb]);
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)
{ {
u32 a = (u32)CPU.GPR[ra]; u32 a = (u32)CPU.GPR[ra];
@ -2780,14 +2780,6 @@ private:
const u8 eb = (addr & 0xf) >> 2; const u8 eb = (addr & 0xf) >> 2;
vm::write32(vm::cast(addr), CPU.VPR[vs]._u32[3 - eb]); vm::write32(vm::cast(addr), CPU.VPR[vs]._u32[3 - eb]);
} }
void ADDZE(u32 rd, u32 ra, u32 oe, bool rc)
{
const u64 RA = CPU.GPR[ra];
CPU.GPR[rd] = RA + CPU.XER.CA;
CPU.XER.CA = CPU.IsCarry(RA, CPU.XER.CA);
if(oe) CPU.SetOV((RA>>63 == 0) && (RA>>63 != CPU.GPR[rd]>>63));
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
}
void SUBFZE(u32 rd, u32 ra, u32 oe, bool rc) void SUBFZE(u32 rd, u32 ra, u32 oe, bool rc)
{ {
const u64 RA = CPU.GPR[ra]; const u64 RA = CPU.GPR[ra];
@ -2796,6 +2788,14 @@ private:
if(oe) CPU.SetOV((~RA>>63 == 0) && (~RA>>63 != CPU.GPR[rd]>>63)); if(oe) CPU.SetOV((~RA>>63 == 0) && (~RA>>63 != CPU.GPR[rd]>>63));
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]); if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
} }
void ADDZE(u32 rd, u32 ra, u32 oe, bool rc)
{
const u64 RA = CPU.GPR[ra];
CPU.GPR[rd] = RA + CPU.XER.CA;
CPU.XER.CA = CPU.IsCarry(RA, CPU.XER.CA);
if(oe) CPU.SetOV((RA>>63 == 0) && (RA>>63 != CPU.GPR[rd]>>63));
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
}
void STDCX_(u32 rs, u32 ra, u32 rb) void STDCX_(u32 rs, u32 ra, u32 rb)
{ {
const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb];
@ -2812,14 +2812,6 @@ private:
{ {
vm::write128((u64)((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL), CPU.VPR[vs]); vm::write128((u64)((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL), CPU.VPR[vs]);
} }
void SUBFME(u32 rd, u32 ra, u32 oe, bool rc)
{
const u64 RA = CPU.GPR[ra];
CPU.GPR[rd] = ~RA + CPU.XER.CA + ~0ULL;
CPU.XER.CA = CPU.IsCarry(~RA, CPU.XER.CA, ~0ULL);
if(oe) CPU.SetOV((~RA>>63 == 1) && (~RA>>63 != CPU.GPR[rd]>>63));
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
}
void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc)
{ {
const s64 RA = CPU.GPR[ra]; const s64 RA = CPU.GPR[ra];
@ -2832,6 +2824,14 @@ private:
} }
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]); if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
} }
void SUBFME(u32 rd, u32 ra, u32 oe, bool rc)
{
const u64 RA = CPU.GPR[ra];
CPU.GPR[rd] = ~RA + CPU.XER.CA + ~0ULL;
CPU.XER.CA = CPU.IsCarry(~RA, CPU.XER.CA, ~0ULL);
if(oe) CPU.SetOV((~RA>>63 == 1) && (~RA>>63 != CPU.GPR[rd]>>63));
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[rd]);
}
void ADDME(u32 rd, u32 ra, u32 oe, bool rc) void ADDME(u32 rd, u32 ra, u32 oe, bool rc)
{ {
const s64 RA = CPU.GPR[ra]; const s64 RA = CPU.GPR[ra];
@ -3432,9 +3432,7 @@ private:
{ {
const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb];
auto const cache_line = vm::get_ptr<u8>(vm::cast(addr) & ~127); memset(vm::get_ptr<u8>(vm::cast(addr) & ~127), 0, 128);
if (cache_line)
memset(cache_line, 0, 128);
} }
void LWZ(u32 rd, u32 ra, s32 d) void LWZ(u32 rd, u32 ra, s32 d)
{ {
@ -3618,7 +3616,6 @@ private:
} }
void LDU(u32 rd, u32 ra, s32 ds) void LDU(u32 rd, u32 ra, s32 ds)
{ {
//if(ra == 0 || rt == ra) return;
const u64 addr = CPU.GPR[ra] + ds; const u64 addr = CPU.GPR[ra] + ds;
CPU.GPR[rd] = vm::read64(vm::cast(addr)); CPU.GPR[rd] = vm::read64(vm::cast(addr));
CPU.GPR[ra] = addr; CPU.GPR[ra] = addr;
@ -3684,7 +3681,6 @@ private:
} }
void STDU(u32 rs, u32 ra, s32 ds) void STDU(u32 rs, u32 ra, s32 ds)
{ {
//if(ra == 0 || rs == ra) return;
const u64 addr = CPU.GPR[ra] + ds; const u64 addr = CPU.GPR[ra] + ds;
vm::write64(vm::cast(addr), CPU.GPR[rs]); vm::write64(vm::cast(addr), CPU.GPR[rs]);
CPU.GPR[ra] = addr; CPU.GPR[ra] = addr;

View file

@ -22,10 +22,11 @@ union ppu_opcode_t
struct struct
{ {
u32 : 6; // 26..31 u32 : 6; // 26..31
u32 vsh : 4; // 22..25 u32 vsh : 4; // 22..25
u32 : 1; // 21 u32 oe : 1; // 21
u32 spr : 10; // 11..20 u32 spr : 10; // 11..20
u32 : 11;
}; };
struct struct
@ -40,7 +41,9 @@ union ppu_opcode_t
struct struct
{ {
u32 : 6; // 26..31 u32 lk : 1; // 31
u32 aa : 1; // 30
u32 : 4; // 26..29
u32 : 5; // 21..25 u32 : 5; // 21..25
u32 rb : 5; // 16..20 u32 rb : 5; // 16..20
u32 ra : 5; // 11..15 u32 ra : 5; // 11..15
@ -51,7 +54,8 @@ union ppu_opcode_t
struct struct
{ {
u32 uimm16 : 16; // 16..31 u32 uimm16 : 16; // 16..31
u32 : 5; // 11..15 u32 : 4; // 12..15
u32 l11 : 1; // 11
u32 rs : 5; // 6..10 u32 rs : 5; // 6..10
u32 : 6; u32 : 6;
}; };
@ -65,10 +69,32 @@ union ppu_opcode_t
struct struct
{ {
u32 : 18; // 14..31 s32 ll : 26; // 6..31
u32 crfs : 3; // 11..13 s32 : 6;
u32 : 2; // 9..10 };
u32 crfd : 3; // 6..8
struct
{
u32 : 5; // 27..31
u32 lev : 7; // 20..26
u32 i : 4; // 16..19
u32 : 2; // 14..15
u32 crfs : 3; // 11..13
u32 l10 : 1; // 10
u32 : 1; // 9
u32 crfd : 3; // 6..8
u32 : 6;
};
struct
{
u32 : 1; // 31
u32 : 1; // 30
u32 : 4; // 26..29
u32 : 5; // 21..25
u32 crbb : 5; // 16..20
u32 crba : 5; // 11..15
u32 crbd : 5; // 6..10
u32 : 6; u32 : 6;
}; };
@ -82,6 +108,32 @@ union ppu_opcode_t
u32 bo : 5; // 6..10 u32 bo : 5; // 6..10
u32 : 6; u32 : 6;
}; };
struct
{
u32 : 6; // 26..31
u32 frc : 5; // 21..25
u32 frb : 5; // 16..20
u32 fra : 5; // 11..15
u32 frd : 5; // 6..10
u32 : 6;
};
struct
{
u32 : 12; // 20..31
u32 crm : 8; // 12..19
u32 : 1; // 11
u32 frs : 5; // 6..10
u32 : 6;
};
struct
{
u32 : 17; // 15..31
u32 flm : 8; // 7..14
u32 : 7;
};
}; };
using ppu_inter_func_t = void(*)(PPUThread& CPU, ppu_opcode_t opcode); using ppu_inter_func_t = void(*)(PPUThread& CPU, ppu_opcode_t opcode);
@ -406,8 +458,7 @@ namespace ppu_interpreter
void LVRXL(PPUThread& CPU, ppu_opcode_t op); void LVRXL(PPUThread& CPU, ppu_opcode_t op);
void DSS(PPUThread& CPU, ppu_opcode_t op); void DSS(PPUThread& CPU, ppu_opcode_t op);
void SRAWI(PPUThread& CPU, ppu_opcode_t op); void SRAWI(PPUThread& CPU, ppu_opcode_t op);
void SRADI1(PPUThread& CPU, ppu_opcode_t op); void SRADI(PPUThread& CPU, ppu_opcode_t op);
void SRADI2(PPUThread& CPU, ppu_opcode_t op);
void EIEIO(PPUThread& CPU, ppu_opcode_t op); void EIEIO(PPUThread& CPU, ppu_opcode_t op);
void STVLXL(PPUThread& CPU, ppu_opcode_t op); void STVLXL(PPUThread& CPU, ppu_opcode_t op);
void STHBRX(PPUThread& CPU, ppu_opcode_t op); void STHBRX(PPUThread& CPU, ppu_opcode_t op);
@ -816,8 +867,8 @@ public:
virtual void LVRXL(u32 vd, u32 ra, u32 rb) { func = ppu_interpreter::LVRXL; } virtual void LVRXL(u32 vd, u32 ra, u32 rb) { func = ppu_interpreter::LVRXL; }
virtual void DSS(u32 strm, u32 a) { func = ppu_interpreter::DSS; } virtual void DSS(u32 strm, u32 a) { func = ppu_interpreter::DSS; }
virtual void SRAWI(u32 ra, u32 rs, u32 sh, bool rc) { func = ppu_interpreter::SRAWI; } virtual void SRAWI(u32 ra, u32 rs, u32 sh, bool rc) { func = ppu_interpreter::SRAWI; }
virtual void SRADI1(u32 ra, u32 rs, u32 sh, bool rc) { func = ppu_interpreter::SRADI1; } virtual void SRADI1(u32 ra, u32 rs, u32 sh, bool rc) { func = ppu_interpreter::SRADI; }
virtual void SRADI2(u32 ra, u32 rs, u32 sh, bool rc) { func = ppu_interpreter::SRADI2; } virtual void SRADI2(u32 ra, u32 rs, u32 sh, bool rc) { func = ppu_interpreter::SRADI; }
virtual void EIEIO() { func = ppu_interpreter::EIEIO; } virtual void EIEIO() { func = ppu_interpreter::EIEIO; }
virtual void STVLXL(u32 vs, u32 ra, u32 rb) { func = ppu_interpreter::STVLXL; } virtual void STVLXL(u32 vs, u32 ra, u32 rb) { func = ppu_interpreter::STVLXL; }
virtual void STHBRX(u32 rs, u32 ra, u32 rb) { func = ppu_interpreter::STHBRX; } virtual void STHBRX(u32 rs, u32 ra, u32 rb) { func = ppu_interpreter::STHBRX; }

View file

@ -24,8 +24,6 @@ u64 rotate_mask[64][64];
const ppu_inter_func_t g_ppu_inter_func_list[] = const ppu_inter_func_t g_ppu_inter_func_list[] =
{ {
nullptr,
ppu_interpreter::NULL_OP, ppu_interpreter::NULL_OP,
ppu_interpreter::NOP, ppu_interpreter::NOP,
@ -344,8 +342,7 @@ const ppu_inter_func_t g_ppu_inter_func_list[] =
ppu_interpreter::LVRXL, ppu_interpreter::LVRXL,
ppu_interpreter::DSS, ppu_interpreter::DSS,
ppu_interpreter::SRAWI, ppu_interpreter::SRAWI,
ppu_interpreter::SRADI1, ppu_interpreter::SRADI,
ppu_interpreter::SRADI2,
ppu_interpreter::EIEIO, ppu_interpreter::EIEIO,
ppu_interpreter::STVLXL, ppu_interpreter::STVLXL,
ppu_interpreter::STHBRX, ppu_interpreter::STHBRX,
@ -471,7 +468,7 @@ void fill_ppu_exec_map(u32 addr, u32 size)
for (u32 pos = addr; pos < addr + size; pos += 4) for (u32 pos = addr; pos < addr + size; pos += 4)
{ {
inter->func = nullptr; inter->func = ppu_interpreter::NULL_OP;
// decode PPU opcode // decode PPU opcode
dec.Decode(vm::read32(pos)); dec.Decode(vm::read32(pos));
@ -479,18 +476,14 @@ void fill_ppu_exec_map(u32 addr, u32 size)
u32 index = 0; u32 index = 0;
// find function index // find function index
for (const auto& func : g_ppu_inter_func_list) for (; index < sizeof(g_ppu_inter_func_list) / sizeof(ppu_inter_func_t); index++)
{ {
if (inter->func == func) if (inter->func == g_ppu_inter_func_list[index])
{ {
index = &func - g_ppu_inter_func_list;
break; break;
} }
} }
// zero function is nullptr, it shouldn't happen
assert(index);
// write index in memory // write index in memory
*(u32*)((u8*)g_ppu_exec_map + pos) = index; *(u32*)((u8*)g_ppu_exec_map + pos) = index;
} }
@ -700,6 +693,8 @@ void PPUThread::FastStop()
void PPUThread::Task() void PPUThread::Task()
{ {
SetHostRoundingMode(FPSCR_RN_NEAR);
if (custom_task) if (custom_task)
{ {
return custom_task(*this); return custom_task(*this);
@ -712,10 +707,8 @@ void PPUThread::Task()
while (true) while (true)
{ {
//if (Emu.IsStopped()) // get interpreter function
//{ const auto func = g_ppu_inter_func_list[*(u32*)((u8*)g_ppu_exec_map + PC)];
// return;
//}
if (m_events) if (m_events)
{ {
@ -730,11 +723,8 @@ void PPUThread::Task()
// read opcode // read opcode
const ppu_opcode_t opcode = { vm::read32(PC) }; const ppu_opcode_t opcode = { vm::read32(PC) };
// read interpreter function index
const u32 index = *(u32*)((u8*)g_ppu_exec_map + PC);
// call interpreter function // call interpreter function
g_ppu_inter_func_list[index](*this, opcode); func(*this, opcode);
// next instruction // next instruction
//PC += 4; //PC += 4;