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 CodeFieldSignedOffset<6, 29, 2> LI(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, HACK, uimm26);
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, RLWINM, RA, RS, SH, 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(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)
{
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(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)
{
u32 a = (u32)CPU.GPR[ra];
@ -2780,14 +2780,6 @@ private:
const u8 eb = (addr & 0xf) >> 2;
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)
{
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(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)
{
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]);
}
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)
{
const s64 RA = CPU.GPR[ra];
@ -2832,6 +2824,14 @@ private:
}
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)
{
const s64 RA = CPU.GPR[ra];
@ -3432,9 +3432,7 @@ private:
{
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);
if (cache_line)
memset(cache_line, 0, 128);
memset(vm::get_ptr<u8>(vm::cast(addr) & ~127), 0, 128);
}
void LWZ(u32 rd, u32 ra, s32 d)
{
@ -3618,7 +3616,6 @@ private:
}
void LDU(u32 rd, u32 ra, s32 ds)
{
//if(ra == 0 || rt == ra) return;
const u64 addr = CPU.GPR[ra] + ds;
CPU.GPR[rd] = vm::read64(vm::cast(addr));
CPU.GPR[ra] = addr;
@ -3684,7 +3681,6 @@ private:
}
void STDU(u32 rs, u32 ra, s32 ds)
{
//if(ra == 0 || rs == ra) return;
const u64 addr = CPU.GPR[ra] + ds;
vm::write64(vm::cast(addr), CPU.GPR[rs]);
CPU.GPR[ra] = addr;

View file

@ -22,10 +22,11 @@ union ppu_opcode_t
struct
{
u32 : 6; // 26..31
u32 vsh : 4; // 22..25
u32 : 1; // 21
u32 : 6; // 26..31
u32 vsh : 4; // 22..25
u32 oe : 1; // 21
u32 spr : 10; // 11..20
u32 : 11;
};
struct
@ -40,7 +41,9 @@ union ppu_opcode_t
struct
{
u32 : 6; // 26..31
u32 lk : 1; // 31
u32 aa : 1; // 30
u32 : 4; // 26..29
u32 : 5; // 21..25
u32 rb : 5; // 16..20
u32 ra : 5; // 11..15
@ -51,7 +54,8 @@ union ppu_opcode_t
struct
{
u32 uimm16 : 16; // 16..31
u32 : 5; // 11..15
u32 : 4; // 12..15
u32 l11 : 1; // 11
u32 rs : 5; // 6..10
u32 : 6;
};
@ -65,10 +69,32 @@ union ppu_opcode_t
struct
{
u32 : 18; // 14..31
u32 crfs : 3; // 11..13
u32 : 2; // 9..10
u32 crfd : 3; // 6..8
s32 ll : 26; // 6..31
s32 : 6;
};
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;
};
@ -82,6 +108,32 @@ union ppu_opcode_t
u32 bo : 5; // 6..10
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);
@ -406,8 +458,7 @@ namespace ppu_interpreter
void LVRXL(PPUThread& CPU, ppu_opcode_t op);
void DSS(PPUThread& CPU, ppu_opcode_t op);
void SRAWI(PPUThread& CPU, ppu_opcode_t op);
void SRADI1(PPUThread& CPU, ppu_opcode_t op);
void SRADI2(PPUThread& CPU, ppu_opcode_t op);
void SRADI(PPUThread& CPU, ppu_opcode_t op);
void EIEIO(PPUThread& CPU, ppu_opcode_t op);
void STVLXL(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 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 SRADI1(u32 ra, u32 rs, u32 sh, bool rc) { func = ppu_interpreter::SRADI1; }
virtual void SRADI2(u32 ra, u32 rs, u32 sh, bool rc) { func = ppu_interpreter::SRADI2; }
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::SRADI; }
virtual void EIEIO() { func = ppu_interpreter::EIEIO; }
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; }

View file

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