mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 21:32:50 +00:00
ARMv7: CMP_IMM, SUB_IMM, null HLE function
This commit is contained in:
parent
1749b95b57
commit
7172154da7
@ -99,7 +99,7 @@ void ARMv7Interpreter::ADD_IMM(const u32 data, const ARMv7_encoding type)
|
||||
if (set_flags)
|
||||
{
|
||||
bool carry, overflow;
|
||||
u32 res = AddWithCarry(CPU.read_gpr(n), imm32, false, carry, overflow);
|
||||
const u32 res = AddWithCarry(CPU.read_gpr(n), imm32, false, carry, overflow);
|
||||
CPU.write_gpr(d, res);
|
||||
CPU.APSR.N = res >> 31;
|
||||
CPU.APSR.Z = res == 0;
|
||||
@ -504,11 +504,37 @@ void ARMv7Interpreter::CMN_RSR(const u32 data, const ARMv7_encoding type)
|
||||
|
||||
void ARMv7Interpreter::CMP_IMM(const u32 data, const ARMv7_encoding type)
|
||||
{
|
||||
u32 cond = CPU.ITSTATE.advance();
|
||||
u32 n = 0;
|
||||
u32 imm32 = 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case T1:
|
||||
{
|
||||
n = (data & 0x700) >> 8;
|
||||
imm32 = (data & 0xff);
|
||||
break;
|
||||
}
|
||||
case T2:
|
||||
{
|
||||
n = (data & 0xf0000) >> 16;
|
||||
imm32 = ThumbExpandImm((data & 0x4000000) >> 15 | (data & 0x7000) >> 4 | (data & 0xff));
|
||||
break;
|
||||
}
|
||||
case A1: throw __FUNCTION__;
|
||||
default: throw __FUNCTION__;
|
||||
}
|
||||
|
||||
if (ConditionPassed(cond))
|
||||
{
|
||||
bool carry, overflow;
|
||||
const u32 res = AddWithCarry(CPU.read_gpr(n), ~imm32, true, carry, overflow);
|
||||
CPU.APSR.N = res >> 31;
|
||||
CPU.APSR.Z = res == 0;
|
||||
CPU.APSR.C = carry;
|
||||
CPU.APSR.V = overflow;
|
||||
}
|
||||
}
|
||||
|
||||
void ARMv7Interpreter::CMP_REG(const u32 data, const ARMv7_encoding type)
|
||||
@ -1027,7 +1053,7 @@ void ARMv7Interpreter::MOV_REG(const u32 data, const ARMv7_encoding type)
|
||||
|
||||
if (ConditionPassed(cond))
|
||||
{
|
||||
u32 res = CPU.read_gpr(m);
|
||||
const u32 res = CPU.read_gpr(m);
|
||||
CPU.write_gpr(d, res);
|
||||
if (set_flags)
|
||||
{
|
||||
@ -2096,11 +2122,82 @@ void ARMv7Interpreter::STRH_REG(const u32 data, const ARMv7_encoding type)
|
||||
|
||||
void ARMv7Interpreter::SUB_IMM(const u32 data, const ARMv7_encoding type)
|
||||
{
|
||||
bool set_flags = !CPU.ITSTATE;
|
||||
u32 cond = CPU.ITSTATE.advance();
|
||||
u32 d = 0;
|
||||
u32 n = 0;
|
||||
u32 imm32 = 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case T1:
|
||||
{
|
||||
d = (data & 0x7);
|
||||
n = (data & 0x38) >> 3;
|
||||
imm32 = (data & 0x1c) >> 6;
|
||||
break;
|
||||
}
|
||||
case T2:
|
||||
{
|
||||
d = n = (data & 0x700) >> 8;
|
||||
imm32 = (data & 0xff);
|
||||
break;
|
||||
}
|
||||
case T3:
|
||||
{
|
||||
d = (data & 0xf00) >> 8;
|
||||
n = (data & 0xf0000) >> 16;
|
||||
set_flags = (data & 0x100000);
|
||||
imm32 = ThumbExpandImm((data & 0x4000000) >> 15 | (data & 0x7000) >> 4 | (data & 0xff));
|
||||
|
||||
if (d == 15 && set_flags)
|
||||
{
|
||||
throw "CMP (immediate)";
|
||||
}
|
||||
if (n == 13)
|
||||
{
|
||||
throw "SUB (SP minus immediate)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case T4:
|
||||
{
|
||||
d = (data & 0xf00) >> 8;
|
||||
n = (data & 0xf0000) >> 16;
|
||||
set_flags = false;
|
||||
imm32 = (data & 0x4000000) >> 15 | (data & 0x7000) >> 4 | (data & 0xff);
|
||||
|
||||
if (d == 15)
|
||||
{
|
||||
throw "ADR";
|
||||
}
|
||||
if (n == 13)
|
||||
{
|
||||
throw "SUB (SP minus immediate)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case A1: throw __FUNCTION__;
|
||||
default: throw __FUNCTION__;
|
||||
}
|
||||
|
||||
if (ConditionPassed(cond))
|
||||
{
|
||||
if (set_flags)
|
||||
{
|
||||
bool carry, overflow;
|
||||
const u32 res = AddWithCarry(CPU.read_gpr(n), ~imm32, true, carry, overflow);
|
||||
CPU.write_gpr(d, res);
|
||||
CPU.APSR.N = res >> 31;
|
||||
CPU.APSR.Z = res == 0;
|
||||
CPU.APSR.C = carry;
|
||||
CPU.APSR.V = overflow;
|
||||
}
|
||||
else
|
||||
{
|
||||
CPU.write_gpr(d, CPU.read_gpr(n) - imm32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ARMv7Interpreter::SUB_REG(const u32 data, const ARMv7_encoding type)
|
||||
@ -2146,11 +2243,11 @@ void ARMv7Interpreter::SUB_REG(const u32 data, const ARMv7_encoding type)
|
||||
|
||||
if (ConditionPassed(cond))
|
||||
{
|
||||
u32 shifted = Shift(CPU.read_gpr(m), shift_t, shift_n, CPU.APSR.C);
|
||||
const u32 shifted = Shift(CPU.read_gpr(m), shift_t, shift_n, CPU.APSR.C);
|
||||
if (set_flags)
|
||||
{
|
||||
bool carry, overflow;
|
||||
u32 res = AddWithCarry(CPU.read_gpr(n), ~shifted, true, carry, overflow);
|
||||
const u32 res = AddWithCarry(CPU.read_gpr(n), ~shifted, true, carry, overflow);
|
||||
CPU.write_gpr(d, res);
|
||||
CPU.APSR.N = res >> 31;
|
||||
CPU.APSR.Z = res == 0;
|
||||
@ -2177,8 +2274,8 @@ void ARMv7Interpreter::SUB_SPI(const u32 data, const ARMv7_encoding type)
|
||||
{
|
||||
u32 cond = CPU.ITSTATE.advance();
|
||||
u32 d = 13;
|
||||
u32 imm32 = 0;
|
||||
bool set_flags = false;
|
||||
u32 imm32 = 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
@ -2187,6 +2284,26 @@ void ARMv7Interpreter::SUB_SPI(const u32 data, const ARMv7_encoding type)
|
||||
imm32 = (data & 0x7f) << 2;
|
||||
break;
|
||||
}
|
||||
case T2:
|
||||
{
|
||||
d = (data & 0xf00) >> 8;
|
||||
set_flags = (data & 0x100000);
|
||||
imm32 = ThumbExpandImm((data & 0x4000000) >> 15 | (data & 0x7000) >> 4 | (data & 0xff));
|
||||
|
||||
if (d == 15 && set_flags)
|
||||
{
|
||||
throw "CMP (immediate)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case T3:
|
||||
{
|
||||
d = (data & 0xf00) >> 8;
|
||||
set_flags = false;
|
||||
imm32 = (data & 0x4000000) >> 15 | (data & 0x7000) >> 4 | (data & 0xff);
|
||||
break;
|
||||
}
|
||||
case A1: throw __FUNCTION__;
|
||||
default: throw __FUNCTION__;
|
||||
}
|
||||
|
||||
@ -2195,7 +2312,7 @@ void ARMv7Interpreter::SUB_SPI(const u32 data, const ARMv7_encoding type)
|
||||
if (set_flags)
|
||||
{
|
||||
bool carry, overflow;
|
||||
u32 res = AddWithCarry(CPU.SP, ~imm32, true, carry, overflow);
|
||||
const u32 res = AddWithCarry(CPU.SP, ~imm32, true, carry, overflow);
|
||||
CPU.write_gpr(d, res);
|
||||
CPU.APSR.N = res >> 31;
|
||||
CPU.APSR.Z = res == 0;
|
||||
|
@ -262,6 +262,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
u32 ThumbExpandImm(u32 imm12)
|
||||
{
|
||||
bool carry = CPU.APSR.C;
|
||||
return ThumbExpandImm_C(imm12, carry, carry);
|
||||
}
|
||||
|
||||
bool ConditionPassed(u32 cond) const
|
||||
{
|
||||
bool result = false;
|
||||
|
@ -673,6 +673,12 @@ static const ARMv7_opcode_t ARMv7_opcode_table[] =
|
||||
ARMv7_OP4(0xfff0, 0x0fc0, 0xf820, 0x0000, T2, STRH_REG),
|
||||
ARMv7_OP4(0x0e50, 0x0ff0, 0x0000, 0x00b0, A1, STRH_REG),
|
||||
|
||||
ARMv7_OP2(0xff80, 0xb080, T1, SUB_SPI),
|
||||
ARMv7_OP4(0xfbef, 0x8000, 0xf1ad, 0x0000, T2, SUB_SPI),
|
||||
ARMv7_OP4(0xfbff, 0x8000, 0xf2ad, 0x0000, T3, SUB_SPI),
|
||||
ARMv7_OP4(0x0fef, 0x0000, 0x024d, 0x0000, A1, SUB_SPI),
|
||||
ARMv7_OP4(0xffef, 0x8000, 0xebad, 0x0000, T1, SUB_SPR),
|
||||
ARMv7_OP4(0x0fef, 0x0010, 0x004d, 0x0000, A1, SUB_SPR),
|
||||
ARMv7_OP2(0xfe00, 0x1e00, T1, SUB_IMM),
|
||||
ARMv7_OP2(0xf800, 0x3800, T2, SUB_IMM),
|
||||
ARMv7_OP4(0xfbe0, 0x8000, 0xf1a0, 0x0000, T3, SUB_IMM),
|
||||
@ -682,12 +688,6 @@ static const ARMv7_opcode_t ARMv7_opcode_table[] =
|
||||
ARMv7_OP4(0xffe0, 0x8000, 0xeba0, 0x0000, T2, SUB_REG),
|
||||
ARMv7_OP4(0x0fe0, 0x0010, 0x0040, 0x0000, A1, SUB_REG),
|
||||
ARMv7_OP4(0x0fe0, 0x0090, 0x0040, 0x0010, A1, SUB_RSR),
|
||||
ARMv7_OP2(0xff80, 0xb080, T1, SUB_SPI),
|
||||
ARMv7_OP4(0xfbef, 0x8000, 0xf1ad, 0x0000, T2, SUB_SPI),
|
||||
ARMv7_OP4(0xfbff, 0x8000, 0xf2ad, 0x0000, T3, SUB_SPI),
|
||||
ARMv7_OP4(0x0fef, 0x0000, 0x024d, 0x0000, A1, SUB_SPI),
|
||||
ARMv7_OP4(0xffef, 0x8000, 0xebad, 0x0000, T1, SUB_SPR),
|
||||
ARMv7_OP4(0x0fef, 0x0010, 0x004d, 0x0000, A1, SUB_SPR),
|
||||
|
||||
ARMv7_OP2(0xff00, 0xdf00, T1, SVC),
|
||||
ARMv7_OP4(0x0f00, 0x0000, 0x0f00, 0x0000, A1, SVC),
|
||||
|
@ -1,7 +1,28 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "PSVFuncList.h"
|
||||
|
||||
std::vector<psv_func> g_psv_func_list;
|
||||
std::vector<psv_func>& g_psv_func_list = []() -> std::vector<psv_func>&
|
||||
{
|
||||
auto v = new std::vector<psv_func>;
|
||||
|
||||
psv_func f =
|
||||
{
|
||||
0xdeadbeef,
|
||||
"INVALID FUNCTION",
|
||||
new psv_func_detail::func_binder<u32>([]() -> u32
|
||||
{
|
||||
LOG_ERROR(HLE, "Unimplemented function found");
|
||||
Emu.Pause();
|
||||
|
||||
return 0xffffffffu;
|
||||
}),
|
||||
nullptr,
|
||||
};
|
||||
v->push_back(f);
|
||||
|
||||
return *v;
|
||||
}();
|
||||
|
||||
void add_psv_func(psv_func& data)
|
||||
{
|
||||
|
@ -556,10 +556,13 @@ bool ELF32Loader::LoadShdrData(u64 offset)
|
||||
|
||||
if (auto func = get_psv_func_by_nid(nid))
|
||||
{
|
||||
func->module->Notice("Imported function %s (nid=0x%08x, addr=0x%x)", func->name, nid, addr);
|
||||
if (func->module)
|
||||
func->module->Notice("Imported function %s (nid=0x%08x, addr=0x%x)", func->name, nid, addr);
|
||||
else
|
||||
LOG_NOTICE(LOADER, "Imported function %s (nid=0x%08x, addr=0x%x)", func->name, nid, addr);
|
||||
|
||||
// writing Thumb code (temporarily, because it should be ARM)
|
||||
vm::psv::write16(addr + 0, 0xf870); // HACK (special instruction that calls HLE function
|
||||
vm::psv::write16(addr + 0, 0xf870); // HACK (special instruction that calls HLE function)
|
||||
vm::psv::write16(addr + 2, (u16)get_psv_func_index(func));
|
||||
vm::psv::write16(addr + 4, 0x4770); // BX LR
|
||||
vm::psv::write16(addr + 6, 0); // null
|
||||
@ -568,9 +571,8 @@ bool ELF32Loader::LoadShdrData(u64 offset)
|
||||
{
|
||||
LOG_ERROR(LOADER, "Unimplemented function 0x%08x (addr=0x%x)", nid, addr);
|
||||
|
||||
// writing Thumb code (temporarily - it shouldn't be written in this case)
|
||||
vm::psv::write16(addr + 0, 0xf06f); // MVN r0,#0x0
|
||||
vm::psv::write16(addr + 2, 0x0000);
|
||||
vm::psv::write16(addr + 0, 0xf870); // HACK (special instruction that calls HLE function)
|
||||
vm::psv::write16(addr + 2, 0x0000); // (zero index)
|
||||
vm::psv::write16(addr + 4, 0x4770); // BX LR
|
||||
vm::psv::write16(addr + 6, 0); // null
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user