PPU: Corrected SC instruction format to comply with the PowerISA

This commit is contained in:
S Gopal Rajagopal 2014-12-11 19:13:17 +05:30
parent 530c17f4f7
commit 5db254f3a5
8 changed files with 28 additions and 30 deletions

View file

@ -1030,14 +1030,13 @@ private:
Write(fmt::Format("bc [%x:%x:%x:%x:%x], cr%d[%x], 0x%x, %d, %d", bo0, bo1, bo2, bo3, bo4, bi/4, bi%4, bd, aa, lk));
}
void SC(u32 sc_code)
void SC(u32 lev)
{
switch(sc_code)
switch (lev)
{
case 0x1: Write("HyperCall"); break;
case 0x2: Write("sc"); break;
case 0x22: Write("HyperCall LV1"); break;
default: Write(fmt::Format("Unknown sc: 0x%x", sc_code));
case 0x0: Write("sc"); break;
case 0x1: Write("HyperCall LV1"); break;
default: Write(fmt::Format("Unknown sc: 0x%x", lev));
}
}
void B(s32 ll, u32 aa, u32 lk)

View file

@ -162,8 +162,8 @@ namespace PPU_instr
//This field mask is used to identify the CR fields that are to be updated by the mtcrf instruction.
static CodeField<12, 19> CRM;
//
static CodeField<6, 31> SYS;
// This field is used to identify the system call level
static CodeField<20, 26> LEV;
//Immediate field specifying a 16-bit signed two's complement integer that is sign-extended to 64 bits
static CodeFieldSigned<16, 31> D;
@ -238,7 +238,7 @@ namespace PPU_instr
bind_instr(main_list, ADDI, RD, RA, simm16);
bind_instr(main_list, ADDIS, RD, RA, simm16);
bind_instr(main_list, BC, BO, BI, BD, AA, LK);
bind_instr(main_list, SC, SYS);
bind_instr(main_list, SC, LEV);
bind_instr(main_list, B, LI, AA, LK);
bind_instr(main_list, RLWIMI, RA, RS, SH, MB, ME, RC);
bind_instr(main_list, RLWINM, RA, RS, SH, MB, ME, RC);

View file

@ -2164,13 +2164,13 @@ private:
if(lk) CPU.LR = nextLR;
}
}
void SC(u32 sc_code)
void SC(u32 lev)
{
switch(sc_code)
switch (lev)
{
case 0x1: UNK(fmt::Format("HyperCall %d", CPU.GPR[0])); break;
case 0x2: SysCall(); break;
case 0x3:
case 0x0: SysCall(); break;
case 0x1: UNK("HyperCall LV1"); break;
case 0x2:
Emu.GetSFuncManager().StaticExecute(CPU, (u32)CPU.GPR[11]);
if (Ini.HLELogging.GetValue())
{
@ -2178,9 +2178,8 @@ private:
Emu.GetSFuncManager()[CPU.GPR[11]]->name, CPU.GPR[3], CPU.PC);
}
break;
case 0x4: CPU.FastStop(); break;
case 0x22: UNK("HyperCall LV1"); break;
default: UNK(fmt::Format("Unknown sc: 0x%x", sc_code));
case 0x3: CPU.FastStop(); break;
default: UNK(fmt::Format("Unknown sc: 0x%x", lev)); break;
}
}
void B(s32 ll, u32 aa, u32 lk)

View file

@ -1995,20 +1995,20 @@ void Compiler::BC(u32 bo, u32 bi, s32 bd, u32 aa, u32 lk) {
CreateBranch(CheckBranchCondition(bo, bi), target_i32, lk ? true : false);
}
void Compiler::SC(u32 sc_code) {
switch (sc_code) {
case 2:
void Compiler::SC(u32 lev) {
switch (lev) {
case 0:
Call<void>("SysCalls.DoSyscall", SysCalls::DoSyscall, m_state.args[CompileTaskState::Args::State], GetGpr(11));
break;
case 3:
case 2:
Call<void>("StaticFuncManager.StaticExecute", &StaticFuncManager::StaticExecute,
m_ir_builder->getInt64((u64)&Emu.GetSFuncManager()), m_state.args[CompileTaskState::Args::State], GetGpr(11, 32));
break;
case 4:
case 3:
Call<void>("PPUThread.FastStop", &PPUThread::FastStop, m_state.args[CompileTaskState::Args::State]);
break;
default:
CompilationError(fmt::Format("SC %u", sc_code));
CompilationError(fmt::Format("SC %u", lev));
break;
}
}

View file

@ -628,7 +628,7 @@ public:
virtual void ADDI(u32 rd, u32 ra, s32 simm16) = 0;
virtual void ADDIS(u32 rd, u32 ra, s32 simm16) = 0;
virtual void BC(u32 bo, u32 bi, s32 bd, u32 aa, u32 lk) = 0;
virtual void SC(u32 sc_code) = 0;
virtual void SC(u32 lev) = 0;
virtual void B(s32 ll, u32 aa, u32 lk) = 0;
virtual void MCRF(u32 crfd, u32 crfs) = 0;
virtual void BCLR(u32 bo, u32 bi, u32 bh, u32 lk) = 0;

View file

@ -188,7 +188,7 @@ void fix_import(Module* module, u32 func, u32 addr)
*ptr++ = ORI(11, 11, func & 0xffff);
*ptr++ = NOP();
++ptr;
*ptr++ = SC(2);
*ptr++ = SC(0);
*ptr++ = BLR();
*ptr++ = NOP();
*ptr++ = NOP();

View file

@ -85,7 +85,7 @@ void StaticFuncManager::StaticAnalyse(void* ptr, u32 size, u32 base)
LOG_NOTICE(LOADER, "Function '%s' hooked (addr=0x%x)", m_static_funcs_list[j]->name, i * 4 + base);
m_static_funcs_list[j]->found++;
data[i+0] = re32(0x39600000 | j); // li r11, j
data[i+1] = se32(0x44000003); // sc 3
data[i+1] = se32(0x44000042); // sc 2
data[i+2] = se32(0x4e800020); // blr
i += 2; // skip modified code
}

View file

@ -343,17 +343,17 @@ namespace loader
Emu.SetRSXCallback(rsx_callback_data.addr());
rsx_callback_data[0] = ADDI(r11, 0, 0x3ff);
rsx_callback_data[1] = SC(2);
rsx_callback_data[1] = SC(0);
rsx_callback_data[2] = BLR();
auto ppu_thr_exit_data = vm::ptr<u32>::make(Memory.MainMem.AllocAlign(3 * 4));
ppu_thr_exit_data[0] = ADDI(r11, 0, 41);
ppu_thr_exit_data[1] = SC(2);
ppu_thr_exit_data[1] = SC(0);
ppu_thr_exit_data[2] = BLR();
Emu.SetCPUThreadExit(ppu_thr_exit_data.addr());
auto ppu_thr_stop_data = vm::ptr<u32>::make(Memory.MainMem.AllocAlign(2 * 4));
ppu_thr_stop_data[0] = SC(4);
ppu_thr_stop_data[0] = SC(3);
ppu_thr_stop_data[1] = BLR();
Emu.SetCPUThreadStop(ppu_thr_stop_data.addr());
@ -493,7 +493,7 @@ namespace loader
static const stub_data =
{
be_t<u32>::make(MR(11, 2)),
be_t<u32>::make(SC(2)),
be_t<u32>::make(SC(0)),
be_t<u32>::make(BLR())
};