Merge pull request #975 from Nekotekina/master

ARMv7 changes
This commit is contained in:
Raul Tambre 2015-01-23 16:55:13 +02:00
commit f2e2786959
35 changed files with 4871 additions and 1994 deletions

View File

@ -96,9 +96,9 @@ size_t fmt::detail::get_fmt_len(const char* fmt, size_t len)
fmt += 2;
len -= 2;
if (fmt[1] == '1')
if (fmt[0] == '1')
{
assert(len >= 3 && fmt[2] - '0' < 7);
assert(len >= 3 && fmt[1] - '0' < 7);
res++;
fmt++;
len--;

View File

@ -198,7 +198,7 @@ namespace fmt
{
return to_hex(arg, get_fmt_precision(fmt, len));
}
else if (fmt[len - 1] == 'd')
else if (fmt[len - 1] == 'd' || fmt[len - 1] == 'u')
{
return to_udec(arg);
}
@ -220,7 +220,7 @@ namespace fmt
{
return to_hex(arg, get_fmt_precision(fmt, len));
}
else if (fmt[len - 1] == 'd')
else if (fmt[len - 1] == 'd' || fmt[len - 1] == 'u')
{
return to_udec(arg);
}
@ -242,7 +242,7 @@ namespace fmt
{
return to_hex(arg, get_fmt_precision(fmt, len));
}
else if (fmt[len - 1] == 'd')
else if (fmt[len - 1] == 'd' || fmt[len - 1] == 'u')
{
return to_udec(arg);
}
@ -264,7 +264,7 @@ namespace fmt
{
return to_hex(arg, get_fmt_precision(fmt, len));
}
else if (fmt[len - 1] == 'd')
else if (fmt[len - 1] == 'd' || fmt[len - 1] == 'u')
{
return to_udec(arg);
}
@ -418,7 +418,7 @@ namespace fmt
{
return to_hex(arg, get_fmt_precision(fmt, len));
}
else if (fmt[len - 1] == 'd')
else if (fmt[len - 1] == 'd' || fmt[len - 1] == 'u')
{
return arg ? "1" : "0";
}
@ -435,24 +435,6 @@ namespace fmt
}
};
template<>
struct get_fmt<char*>
{
static std::string text(const char* fmt, size_t len, char* arg)
{
if (fmt[len - 1] == 's')
{
return arg;
}
else
{
throw "Invalid formatting (char*): " + std::string(fmt, len);
}
return{};
}
};
template<>
struct get_fmt<const char*>
{
@ -471,60 +453,6 @@ namespace fmt
}
};
//template<size_t size>
//struct get_fmt<char[size], false>
//{
// static std::string text(const char* fmt, size_t len, const char(&arg)[size])
// {
// if (fmt[len - 1] == 's')
// {
// return std::string(arg, size);
// }
// else
// {
// throw "Invalid formatting (char[size]): " + std::string(fmt, len);
// }
// return{};
// }
//};
//template<size_t size>
//struct get_fmt<const char[size], false>
//{
// static std::string text(const char* fmt, size_t len, const char(&arg)[size])
// {
// if (fmt[len - 1] == 's')
// {
// return std::string(arg, size);
// }
// else
// {
// throw "Invalid formatting (const char[size]): " + std::string(fmt, len);
// }
// return{};
// }
//};
template<>
struct get_fmt<std::string>
{
static std::string text(const char* fmt, size_t len, const std::string& arg)
{
if (fmt[len - 1] == 's')
{
return arg;
}
else
{
throw "Invalid formatting (std::string): " + std::string(fmt, len);
}
return{};
}
};
std::string format(const char* fmt, size_t len); // terminator
template<typename T, typename... Args>
@ -549,6 +477,17 @@ namespace fmt
}
};
template<>
struct unveil<char*, false>
{
typedef const char* result_type;
__forceinline static result_type get_value(const char* arg)
{
return arg;
}
};
template<size_t N>
struct unveil<const char[N], false>
{
@ -563,11 +502,11 @@ namespace fmt
template<>
struct unveil<std::string, false>
{
typedef const std::string& result_type;
typedef const char* result_type;
__forceinline static result_type get_value(const std::string& arg)
{
return arg;
return arg.c_str();
}
};
@ -613,8 +552,9 @@ namespace fmt
float (%x, %f)
double (%x, %f)
bool (%x, %d, %s)
char*, const char*, std::string (%s)
char* (%s)
std::string forced to .c_str() (fmt::unveil)
be_t<> of any appropriate type in this list (fmt::unveil)
enum of any appropriate type in this list (fmt::unveil)

View File

@ -0,0 +1,18 @@
#pragma once
#include "Emu/Memory/Memory.h"
#include "Emu/ARMv7/PSVFuncList.h"
namespace vm
{
template<typename AT, typename RT, typename... T>
__forceinline RT _ptr_base<RT(*)(T...), 1, AT>::operator()(ARMv7Context& context, T... args) const
{
return psv_func_detail::func_caller<RT, T...>::call(context, vm::cast(this->addr()), args...);
}
}
template<typename RT, typename... T>
__forceinline RT cb_call(ARMv7Context& context, u32 addr, T... args)
{
return psv_func_detail::func_caller<RT, T...>::call(context, addr, args...);
}

View File

@ -0,0 +1,276 @@
#pragma once
class ARMv7Thread;
enum ARMv7InstructionSet
{
ARM,
Thumb,
Jazelle,
ThumbEE
};
struct ARMv7Context
{
ARMv7Thread& thread;
ARMv7Context(ARMv7Thread& thread) : thread(thread) {}
void write_pc(u32 value);
u32 read_pc();
void put_stack_arg(u32 shift, u32 value);
u32 get_stack_arg(u32 pos);
void fast_call(u32 addr);
union
{
u32 GPR[15];
struct
{
u32 pad[13];
union
{
u32 SP;
struct { u16 SP_main, SP_process; };
};
u32 LR;
};
};
union
{
struct
{
u32 N : 1; //Negative condition code flag
u32 Z : 1; //Zero condition code flag
u32 C : 1; //Carry condition code flag
u32 V : 1; //Overflow condition code flag
u32 Q : 1; //Set to 1 if an SSAT or USAT instruction changes (saturates) the input value for the signed or unsigned range of the result
u32 dummy : 27;
};
u32 APSR;
} APSR;
union
{
struct
{
u32 dummy : 24;
u32 exception : 8;
};
u32 IPSR;
} IPSR;
ARMv7InstructionSet ISET;
union
{
struct
{
u8 cond : 3;
u8 state : 5;
};
u8 IT;
u32 advance()
{
const u32 res = (state & 0xf) ? (cond << 1 | state >> 4) : 0xe /* true */;
state <<= 1;
if ((state & 0xf) == 0) // if no d
{
IT = 0; // clear ITSTATE
}
return res;
}
operator bool() const
{
return (state & 0xf) != 0;
}
} ITSTATE;
u32 R_ADDR;
u64 R_DATA;
void write_gpr(u32 n, u32 value)
{
assert(n < 16);
if (n < 15)
{
GPR[n] = value;
}
else
{
write_pc(value & ~1);
}
}
u32 read_gpr(u32 n)
{
assert(n < 16);
if (n < 15)
{
return GPR[n];
}
return read_pc();
}
// function for processing va_args in printf-like functions
u32 get_next_gpr_arg(u32& g_count, u32& f_count, u32& v_count)
{
assert(!f_count && !v_count); // not supported
if (g_count < 4)
{
return GPR[g_count++];
}
else
{
return get_stack_arg(g_count++);
}
}
};
template<typename T, bool is_enum = std::is_enum<T>::value>
struct cast_armv7_gpr
{
static_assert(is_enum, "Invalid type for cast_armv7_gpr");
typedef typename std::underlying_type<T>::type underlying_type;
__forceinline static u32 to_gpr(const T& value)
{
return cast_armv7_gpr<underlying_type>::to_gpr(static_cast<underlying_type>(value));
}
__forceinline static T from_gpr(const u32 reg)
{
return static_cast<T>(cast_armv7_gpr<underlying_type>::from_gpr(reg));
}
};
template<>
struct cast_armv7_gpr<u8, false>
{
__forceinline static u32 to_gpr(const u8& value)
{
return value;
}
__forceinline static u8 from_gpr(const u32 reg)
{
return static_cast<u8>(reg);
}
};
template<>
struct cast_armv7_gpr<u16, false>
{
__forceinline static u32 to_gpr(const u16& value)
{
return value;
}
__forceinline static u16 from_gpr(const u32 reg)
{
return static_cast<u16>(reg);
}
};
template<>
struct cast_armv7_gpr<u32, false>
{
__forceinline static u32 to_gpr(const u32& value)
{
return value;
}
__forceinline static u32 from_gpr(const u32 reg)
{
return reg;
}
};
template<>
struct cast_armv7_gpr<s8, false>
{
__forceinline static u32 to_gpr(const s8& value)
{
return value;
}
__forceinline static s8 from_gpr(const u32 reg)
{
return static_cast<s8>(reg);
}
};
template<>
struct cast_armv7_gpr<s16, false>
{
__forceinline static u32 to_gpr(const s16& value)
{
return value;
}
__forceinline static s16 from_gpr(const u32 reg)
{
return static_cast<s16>(reg);
}
};
template<>
struct cast_armv7_gpr<s32, false>
{
__forceinline static u32 to_gpr(const s32& value)
{
return value;
}
__forceinline static s32 from_gpr(const u32 reg)
{
return static_cast<s32>(reg);
}
};
template<>
struct cast_armv7_gpr<bool, false>
{
__forceinline static u32 to_gpr(const bool& value)
{
return value;
}
__forceinline static bool from_gpr(const u32 reg)
{
return reinterpret_cast<const bool&>(reg);
}
};
template<typename T>
__forceinline u32 cast_to_armv7_gpr(const T& value)
{
return cast_armv7_gpr<T>::to_gpr(value);
}
template<typename T>
__forceinline T cast_from_armv7_gpr(const u32 reg)
{
return cast_armv7_gpr<T>::from_gpr(reg);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,48 +1,18 @@
#pragma once
#include "Emu/CPU/CPUDecoder.h"
#include "ARMv7Thread.h"
#include "ARMv7Interpreter.h"
#include "ARMv7Opcodes.h"
#include "Utilities/Log.h"
struct ARMv7Context;
class ARMv7Decoder : public CPUDecoder
{
ARMv7Thread& m_thr;
ARMv7Context& m_ctx;
public:
ARMv7Decoder(ARMv7Thread& thr) : m_thr(thr)
ARMv7Decoder(ARMv7Context& context) : m_ctx(context)
{
}
virtual u8 DecodeMemory(const u32 address)
{
m_thr.update_code(address & ~1);
virtual u32 DecodeMemory(const u32 address);
};
// LOG_NOTICE(GENERAL, "code0 = 0x%04x, code1 = 0x%04x, data = 0x%08x", m_thr.code.code0, m_thr.code.code1, m_thr.code.data);
// LOG_NOTICE(GENERAL, "arg = 0x%08x", m_thr.m_arg);
// Emu.Pause();
// old decoding algorithm
/*
for (auto& opcode : ARMv7_opcode_table)
{
if ((opcode.type < A1) == ((address & 0x1) == 0) && (m_thr.m_arg & opcode.mask) == opcode.code)
{
m_thr.code.data = opcode.length == 2 ? m_thr.code.code0 : m_thr.m_arg;
(*opcode.func)(&m_thr, opcode.type);
// LOG_NOTICE(GENERAL, "%s, %d \n\n", opcode.name, opcode.length);
return opcode.length;
}
}
ARMv7_instrs::UNK(&m_thr);
return address & 0x1 ? 4 : 2;
*/
execute_main_group(&m_thr);
// LOG_NOTICE(GENERAL, "%s, %d \n\n", m_thr.m_last_instr_name, m_thr.m_last_instr_size);
m_thr.m_last_instr_name = "Unknown";
return m_thr.m_last_instr_size;
}
};
void armv7_decoder_initialize(u32 addr, u32 end_addr, bool dump = false);

View File

@ -1,4 +1,5 @@
#include "stdafx.h"
#if 0
#include "ARMv7DisAsm.h"
void ARMv7DisAsm::UNK(const u32 data)
@ -1119,4 +1120,4 @@ void ARMv7DisAsm::UXTH(const u32 data, const ARMv7_encoding type)
{
Write(__FUNCTION__);
}
#endif

View File

@ -1,5 +1,4 @@
#pragma once
#include "Emu/ARMv7/ARMv7Opcodes.h"
#include "Emu/CPU/CPUDisAsm.h"
static const char* g_arm_cond_name[16] =
@ -10,6 +9,14 @@ static const char* g_arm_cond_name[16] =
"gt", "le", "al", "al",
};
static const char* g_arm_reg_name[16] =
{
"r0", "r1", "r2", "r3",
"r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11",
"r12", "sp", "lr", "pc",
};
class ARMv7DisAsm
: public CPUDisAsm
{
@ -24,6 +31,7 @@ protected:
return (u32)dump_pc + imm;
}
#if 0
std::string GetRegsListString(u16 regs_list)
{
std::string regs_str;
@ -316,4 +324,5 @@ protected:
virtual void UXTB(const u32 data, const ARMv7_encoding type);
virtual void UXTB16(const u32 data, const ARMv7_encoding type);
virtual void UXTH(const u32 data, const ARMv7_encoding type);
#endif
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,36 +1,25 @@
#pragma once
#if 0
#include "Emu/ARMv7/ARMv7Thread.h"
#include "Emu/ARMv7/ARMv7Interpreter.h"
#include "Emu/System.h"
#include "Utilities/Log.h"
static const char* g_arm_reg_name[16] =
{
"r0", "r1", "r2", "r3",
"r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11",
"r12", "sp", "lr", "pc",
};
using namespace ARMv7_instrs;
struct ARMv7_Instruction
{
void(*func)(ARMv7Thread* thr, const ARMv7_encoding type);
void(*func)(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
u8 size;
ARMv7_encoding type;
const char* name;
};
#define ARMv7_OP_2(func, type) { func, 2, type, #func "_" #type }
#define ARMv7_OP_4(func, type) { func, 4, type, #func "_" #type }
#define ARMv7_NULL_OP { NULL_OP, 2, T1, "NULL_OP" }
// 0x1...
static void group_0x1(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0x1(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static const ARMv7_Instruction g_table_0x1_main[] =
{
@ -56,7 +45,7 @@ static const ARMv7_Instruction g_table_0x1[] =
{ group_0x1 }
};
static void group_0x1(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0x1(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code0 & 0x0e00) >> 8;
@ -69,7 +58,7 @@ static void group_0x1(ARMv7Thread* thr, const ARMv7_encoding type)
}
// 0x2...
static void group_0x2(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0x2(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static const ARMv7_Instruction g_table_0x2_main[] =
{
@ -89,7 +78,7 @@ static const ARMv7_Instruction g_table_0x2[] =
{ group_0x2 }
};
static void group_0x2(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0x2(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code0 & 0x0800) >> 8;
thr->m_last_instr_name = g_table_0x2_main[index].name;
@ -99,7 +88,7 @@ static void group_0x2(ARMv7Thread* thr, const ARMv7_encoding type)
}
// 0x3...
static void group_0x3(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0x3(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static const ARMv7_Instruction g_table_0x3_main[] =
{
@ -119,7 +108,7 @@ static const ARMv7_Instruction g_table_0x3[] =
{ group_0x3 }
};
static void group_0x3(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0x3(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code0 & 0x0800) >> 8;
thr->m_last_instr_name = g_table_0x3_main[index].name;
@ -129,13 +118,13 @@ static void group_0x3(ARMv7Thread* thr, const ARMv7_encoding type)
}
// 0x4...
static void group_0x4(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0x40(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0x41(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0x42(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0x43(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0x44(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0x47(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0x4(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0x40(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0x41(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0x42(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0x43(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0x44(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0x47(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static const ARMv7_Instruction g_table_0x4[] =
{
@ -160,7 +149,7 @@ static const ARMv7_Instruction g_table_0x40[] =
ARMv7_OP_2(LSR_REG, T1) // C 0xffc0
};
static void group_0x40(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0x40(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code0 & 0x00c0) >> 4;
thr->m_last_instr_name = g_table_0x40[index].name;
@ -186,7 +175,7 @@ static const ARMv7_Instruction g_table_0x41[] =
ARMv7_OP_2(ROR_REG, T1) // C 0xffc0
};
static void group_0x41(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0x41(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code0 & 0x00c0) >> 4;
thr->m_last_instr_name = g_table_0x41[index].name;
@ -211,7 +200,7 @@ static const ARMv7_Instruction g_table_0x42[] =
ARMv7_OP_2(CMN_REG, T1) // C 0xffc0
};
static void group_0x42(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0x42(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code0 & 0x00c0) >> 4;
thr->m_last_instr_name = g_table_0x42[index].name;
@ -237,7 +226,7 @@ static const ARMv7_Instruction g_table_0x43[] =
ARMv7_OP_2(MVN_REG, T1) // C 0xffc0
};
static void group_0x43(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0x43(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code0 & 0x00c0) >> 4;
thr->m_last_instr_name = g_table_0x43[index].name;
@ -258,7 +247,7 @@ static const ARMv7_Instruction g_table_0x44[] =
ARMv7_OP_2(ADD_SPR, T2) // 8 0xff87
};
static void group_0x44(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0x44(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code0 & 0x0080) >> 4;
@ -284,7 +273,7 @@ static const ARMv7_Instruction g_table_0x47[] =
ARMv7_OP_2(BLX, T1) // 8 0xff80
};
static void group_0x47(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0x47(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code0 & 0x0080) >> 4;
thr->m_last_instr_name = g_table_0x47[index].name;
@ -306,7 +295,7 @@ static const ARMv7_Instruction g_table_0x4_main[] =
ARMv7_OP_2(LDR_LIT, T1) // 8 0xf800
};
static void group_0x4(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0x4(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code0 & 0x0f00) >> 8;
@ -319,7 +308,7 @@ static void group_0x4(ARMv7Thread* thr, const ARMv7_encoding type)
}
// 0x5...
static void group_0x5(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0x5(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static const ARMv7_Instruction g_table_0x5_main[] =
{
@ -345,7 +334,7 @@ static const ARMv7_Instruction g_table_0x5[] =
{ group_0x5 }
};
static void group_0x5(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0x5(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code0 & 0x0e00) >> 8;
thr->m_last_instr_name = g_table_0x5_main[index].name;
@ -355,7 +344,7 @@ static void group_0x5(ARMv7Thread* thr, const ARMv7_encoding type)
}
// 0x6...
static void group_0x6(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0x6(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static const ARMv7_Instruction g_table_0x6_main[] =
{
@ -375,7 +364,7 @@ static const ARMv7_Instruction g_table_0x6[] =
{ group_0x6 }
};
static void group_0x6(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0x6(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code0 & 0x0800) >> 8;
thr->m_last_instr_name = g_table_0x6_main[index].name;
@ -385,7 +374,7 @@ static void group_0x6(ARMv7Thread* thr, const ARMv7_encoding type)
}
// 0x7...
static void group_0x7(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0x7(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static const ARMv7_Instruction g_table_0x7_main[] =
{
@ -405,7 +394,7 @@ static const ARMv7_Instruction g_table_0x7[] =
{ group_0x7 }
};
static void group_0x7(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0x7(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code0 & 0x0800) >> 8;
thr->m_last_instr_name = g_table_0x7_main[index].name;
@ -415,7 +404,7 @@ static void group_0x7(ARMv7Thread* thr, const ARMv7_encoding type)
}
// 0x8...
static void group_0x8(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0x8(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static const ARMv7_Instruction g_table_0x8_main[] =
{
@ -427,7 +416,7 @@ static const ARMv7_Instruction g_table_0x8[] =
{ group_0x8 }
};
static void group_0x8(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0x8(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code0 & 0x0800) >> 8;
thr->m_last_instr_name = g_table_0x8_main[index].name;
@ -437,7 +426,7 @@ static void group_0x8(ARMv7Thread* thr, const ARMv7_encoding type)
}
// 0x9...
static void group_0x9(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0x9(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static const ARMv7_Instruction g_table_0x9_main[] =
{
@ -457,7 +446,7 @@ static const ARMv7_Instruction g_table_0x9[] =
{ group_0x9 }
};
static void group_0x9(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0x9(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code0 & 0x0800) >> 8;
thr->m_last_instr_name = g_table_0x9_main[index].name;
@ -467,7 +456,7 @@ static void group_0x9(ARMv7Thread* thr, const ARMv7_encoding type)
}
// 0xa...
static void group_0xa(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xa(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static const ARMv7_Instruction g_table_0xa_main[] =
{
@ -487,7 +476,7 @@ static const ARMv7_Instruction g_table_0xa[] =
{ group_0xa }
};
static void group_0xa(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xa(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code0 & 0x0800) >> 8;
thr->m_last_instr_name = g_table_0xa_main[index].name;
@ -497,9 +486,9 @@ static void group_0xa(ARMv7Thread* thr, const ARMv7_encoding type)
}
// 0xb...
static void group_0xb(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xb0(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xba(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xb(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xb0(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xba(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static const ARMv7_Instruction g_table_0xb0[] =
{
@ -514,7 +503,7 @@ static const ARMv7_Instruction g_table_0xb0[] =
ARMv7_OP_2(SUB_SPI, T1) // 8 0xff80
};
static void group_0xb0(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xb0(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code0 & 0x0080) >> 4;
thr->m_last_instr_name = g_table_0xb0[index].name;
@ -540,7 +529,7 @@ static const ARMv7_Instruction g_table_0xba[] =
ARMv7_OP_2(REVSH, T1) // C 0xffc0
};
static void group_0xba(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xba(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code0 & 0x00c0) >> 4; // mask 0xffc0
thr->m_last_instr_name = g_table_0xba[index].name;
@ -575,7 +564,7 @@ static const ARMv7_Instruction g_table_0xb[] =
{ group_0xb }
};
static void group_0xb(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xb(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code0 & 0x0e00) >> 8;
@ -591,7 +580,7 @@ static void group_0xb(ARMv7Thread* thr, const ARMv7_encoding type)
}
// 0xc...
static void group_0xc(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xc(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static const ARMv7_Instruction g_table_0xc_main[] =
{
@ -611,7 +600,7 @@ static const ARMv7_Instruction g_table_0xc[] =
{ group_0xc }
};
static void group_0xc(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xc(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code0 & 0x0800) >> 8;
thr->m_last_instr_name = g_table_0xc_main[index].name;
@ -621,7 +610,7 @@ static void group_0xc(ARMv7Thread* thr, const ARMv7_encoding type)
}
// 0xd...
static void group_0xd(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xd(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static const ARMv7_Instruction g_table_0xd_main[] =
{
@ -648,7 +637,7 @@ static const ARMv7_Instruction g_table_0xd[] =
{ group_0xd }
};
static void group_0xd(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xd(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
//u32 index = (thr->code.code0 & 0x0f00) >> 8;
//if ((thr->code.code0 & 0xf000) == 0xd000) index = 0;
@ -661,19 +650,19 @@ static void group_0xd(ARMv7Thread* thr, const ARMv7_encoding type)
}
// 0xe...
static void group_0xe(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xe85(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xe8(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xe9(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xea(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xea4(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xea4f(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xea4f0000(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xea4f0030(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xea6(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xeb(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xeb0(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xeba(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xe(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xe85(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xe8(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xe9(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xea(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xea4(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xea4f(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xea4f0000(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xea4f0030(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xea6(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xeb(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xeb0(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xeba(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static const ARMv7_Instruction g_table_0xe85[] =
@ -696,7 +685,7 @@ static const ARMv7_Instruction g_table_0xe85[] =
ARMv7_OP_4(LDRD_LIT, T1) // F 0xfe7f, 0x0000
};
static void group_0xe85(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xe85(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
//u32 index = thr->code.code0 & 0x000f;
//if ((thr->code.code0 & 0xfe50) == 0xe850) index = 0x0;
@ -726,7 +715,7 @@ static const ARMv7_Instruction g_table_0xe8[] =
ARMv7_OP_4(TB_, T1) // D 0xfff0, 0xffe0
};
static void group_0xe8(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xe8(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code0 & 0x00f0) >> 4;
@ -747,7 +736,7 @@ static const ARMv7_Instruction g_table_0xe9[] =
ARMv7_OP_4(PUSH, T2) // 2 0xffff, 0x0000
};
static void group_0xe9(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xe9(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code0 & 0x00d0) >> 4;
@ -779,7 +768,7 @@ static const ARMv7_Instruction g_table_0xea4[] =
{ group_0xea4f } // F
};
static void group_0xea4(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xea4(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = 0x0;
if ((thr->code.code0 & 0xffef) == 0xea4f) index = 0xf; // check me
@ -798,7 +787,7 @@ static const ARMv7_Instruction g_table_0xea4f[] =
{ group_0xea4f0030 } // 3
};
static void group_0xea4f(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xea4f(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code1 & 0x0030) >> 4;
thr->m_last_instr_name = g_table_0xea4f[index].name;
@ -813,7 +802,7 @@ static const ARMv7_Instruction g_table_0xea4f0000[] =
ARMv7_OP_4(LSL_IMM, T2) // 1 0xffef, 0x8030
};
static void group_0xea4f0000(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xea4f0000(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = thr->code.code1 & 0x8030 ? 0x0 : 0x1;
thr->m_last_instr_name = g_table_0xea4f0000[index].name;
@ -828,7 +817,7 @@ static const ARMv7_Instruction g_table_0xea4f0030[] =
ARMv7_OP_4(ROR_IMM, T1) // 2 0xffef, 0x8030
};
static void group_0xea4f0030(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xea4f0030(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = thr->code.code1 & 0x8030 ? 0x0 : 0x1;
thr->m_last_instr_name = g_table_0xea4f0030[index].name;
@ -857,7 +846,7 @@ static const ARMv7_Instruction g_table_0xea6[] =
ARMv7_OP_4(MVN_REG, T2) // F 0xffef, 0x8000
};
static void group_0xea6(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xea6(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = thr->code.code0 & 0x000f;
@ -886,7 +875,7 @@ static const ARMv7_Instruction g_table_0xea[] =
ARMv7_OP_4(PKH, T1) // C 0xfff0, 0x8010
};
static void group_0xea(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xea(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code0 & 0x00e0) >> 4;
@ -918,7 +907,7 @@ static const ARMv7_Instruction g_table_0xeb0[] =
ARMv7_OP_4(ADD_SPR, T3) // D 0xffef, 0x8000
};
static void group_0xeb0(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xeb0(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = thr->code.code0 & 0x000f;
@ -948,7 +937,7 @@ static const ARMv7_Instruction g_table_0xeba[] =
ARMv7_OP_4(SUB_SPR, T1) // D 0xffef, 0x8000
};
static void group_0xeba(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xeba(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = thr->code.code0 & 0x000f;
@ -977,7 +966,7 @@ static const ARMv7_Instruction g_table_0xeb[] =
ARMv7_OP_4(RSB_REG, T1) // C 0xffe0, 0x8000
};
static void group_0xeb(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xeb(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code0 & 0x00e0) >> 4;
@ -1015,7 +1004,7 @@ static const ARMv7_Instruction g_table_0xe[] =
{ group_0xe }
};
static void group_0xe(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xe(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code0 & 0x0f00) >> 8;
@ -1028,36 +1017,36 @@ static void group_0xe(ARMv7Thread* thr, const ARMv7_encoding type)
}
// 0xf...
static void group_0xf(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf000(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf04(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf06(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf0(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf1(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf1a(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf10(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf20(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf2a(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf2(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf36(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf3(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf810(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf800(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf81(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf820(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf840(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf84(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf850(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf85(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf8(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf910(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf91(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf930(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf93(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf9(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xfa00(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xfa90(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xfa(ARMv7Thread* thr, const ARMv7_encoding type);
static void group_0xf(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf000(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf04(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf06(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf0(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf1(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf1a(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf10(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf20(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf2a(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf2(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf36(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf3(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf810(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf800(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf81(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf820(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf840(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf84(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf850(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf85(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf8(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf910(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf91(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf930(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf93(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf9(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xfa00(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xfa90(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xfa(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static const ARMv7_Instruction g_table_0xf000[] =
{
@ -1077,7 +1066,7 @@ static const ARMv7_Instruction g_table_0xf000[] =
ARMv7_OP_4(BL, T1) // D 0xf800, 0xd000
};
static void group_0xf000(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf000(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code1 & 0xd000) >> 12;
@ -1110,7 +1099,7 @@ static const ARMv7_Instruction g_table_0xf04[] =
ARMv7_OP_4(MOV_IMM, T2) // F 0xfbef, 0x8000
};
static void group_0xf04(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf04(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = thr->code.code0 & 0x000f;
@ -1142,7 +1131,7 @@ static const ARMv7_Instruction g_table_0xf06[] =
ARMv7_OP_4(MVN_IMM, T1) // F 0xfbef, 0x8000
};
static void group_0xf06(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf06(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = thr->code.code0 & 0x000f;
@ -1194,7 +1183,7 @@ static const ARMv7_Instruction g_table_0xf0[] =
};
static void group_0xf0(ARMv7Thread* thr, const ARMv7_encoding type) // TODO: optimize this group
static void group_0xf0(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) // TODO: optimize this group
{
u32 index = 0;
if ((thr->m_arg & 0xfbe08000) == 0xf0000000) index = 0x0;
@ -1242,7 +1231,7 @@ static const ARMv7_Instruction g_table_0xf10[] =
ARMv7_OP_4(ADD_SPI, T3) // D 0xfbef, 0x8000
};
static void group_0xf10(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf10(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = thr->code.code0 & 0x000f;
@ -1272,7 +1261,7 @@ static const ARMv7_Instruction g_table_0xf1a[] =
ARMv7_OP_4(SUB_SPI, T2) // D 0xfbef, 0x8000
};
static void group_0xf1a(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf1a(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = thr->code.code0 & 0x000f;
@ -1301,7 +1290,7 @@ static const ARMv7_Instruction g_table_0xf1[] =
ARMv7_OP_4(RSB_IMM, T2) // C 0xfbe0, 0x8000
};
static void group_0xf1(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf1(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code0 & 0x00e0) >> 4;
@ -1334,7 +1323,7 @@ static const ARMv7_Instruction g_table_0xf20[] =
ARMv7_OP_4(ADR, T3) // F 0xfbff, 0x8000
};
static void group_0xf20(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf20(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = thr->code.code0 & 0x000f;
@ -1366,7 +1355,7 @@ static const ARMv7_Instruction g_table_0xf2a[] =
ARMv7_OP_4(ADR, T2) // F 0xfbff, 0x8000
};
static void group_0xf2a(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf2a(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = thr->code.code0 & 0x000f;
@ -1395,7 +1384,7 @@ static const ARMv7_Instruction g_table_0xf2[] =
ARMv7_OP_4(MOVT, T1) // C 0xfbf0, 0x8000
};
static void group_0xf2(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf2(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code0 & 0x00f0) >> 4; // mask 0xfbf0
thr->m_last_instr_name = g_table_0xf2[index].name;
@ -1424,7 +1413,7 @@ static const ARMv7_Instruction g_table_0xf36[] =
ARMv7_OP_4(BFC, T1) // F 0xffff, 0x8020
};
static void group_0xf36(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf36(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = thr->code.code0 & 0x000f;
@ -1455,7 +1444,7 @@ static const ARMv7_Instruction g_table_0xf3[] =
ARMv7_OP_4(MRS, T1), // E 0xffff, 0xf0ff
};
static void group_0xf3(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf3(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code0 & 0x00f0) >> 4;
thr->m_last_instr_name = g_table_0xf3[index].name;
@ -1477,7 +1466,7 @@ static const ARMv7_Instruction g_table_0xf800[] =
ARMv7_OP_4(STRB_IMM, T3) // 8 0xfff0, 0x0800
};
static void group_0xf800(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf800(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code1 & 0x0f00) >> 8;
@ -1502,7 +1491,7 @@ static const ARMv7_Instruction g_table_0xf810[] =
ARMv7_OP_4(LDRB_IMM, T3) // 8 0xfff0, 0x0800
};
static void group_0xf810(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf810(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code1 & 0x0f00) >> 8;
@ -1534,7 +1523,7 @@ static const ARMv7_Instruction g_table_0xf81[] =
ARMv7_OP_4(LDRB_LIT, T1) // F 0xff7f, 0x0000
};
static void group_0xf81(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf81(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = thr->code.code0 & 0x000f;
@ -1559,7 +1548,7 @@ static const ARMv7_Instruction g_table_0xf820[] =
ARMv7_OP_4(STRH_IMM, T3) // 8 0xfff0, 0x0800
};
static void group_0xf820(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf820(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code1 & 0x0f00) >> 8;
@ -1584,7 +1573,7 @@ static const ARMv7_Instruction g_table_0xf840[] =
ARMv7_OP_4(STR_IMM, T4) // 8 0xfff0, 0x0800
};
static void group_0xf840(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf840(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code1 & 0x0f00) >> 8;
@ -1614,7 +1603,7 @@ static const ARMv7_Instruction g_table_0xf84[] =
ARMv7_OP_4(PUSH, T3) // D 0xffff, 0x0fff
};
static void group_0xf84(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf84(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = thr->code.code0 & 0x000f;
@ -1639,7 +1628,7 @@ static const ARMv7_Instruction g_table_0xf850[] =
ARMv7_OP_4(LDR_IMM, T4) // 8 0xfff0, 0x0800
};
static void group_0xf850(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf850(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code1 & 0x0f00) >> 8;
@ -1671,7 +1660,7 @@ static const ARMv7_Instruction g_table_0xf85[] =
ARMv7_OP_4(LDR_LIT, T2) // F 0xff7f, 0x0000
};
static void group_0xf85(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf85(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = thr->code.code0 & 0x000f;
@ -1701,7 +1690,7 @@ static const ARMv7_Instruction g_table_0xf8[] =
ARMv7_OP_4(LDR_IMM, T3) // D 0xfff0, 0x0000
};
static void group_0xf8(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf8(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code0 & 0x00f0) >> 4;
thr->m_last_instr_name = g_table_0xf8[index].name;
@ -1723,7 +1712,7 @@ static const ARMv7_Instruction g_table_0xf910[] =
ARMv7_OP_4(LDRSB_IMM, T2) // 8 0xfff0, 0x0800
};
static void group_0xf910(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf910(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code1 & 0x0f00) >> 8;
@ -1755,7 +1744,7 @@ static const ARMv7_Instruction g_table_0xf91[] =
ARMv7_OP_4(LDRSB_LIT, T1) // F 0xff7f, 0x0000
};
static void group_0xf91(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf91(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = thr->code.code0 & 0x000f;
@ -1780,7 +1769,7 @@ static const ARMv7_Instruction g_table_0xf930[] =
ARMv7_OP_4(LDRSH_IMM, T2) // 8 0xfff0, 0x0800
};
static void group_0xf930(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf930(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code1 & 0x0f00) >> 8;
@ -1812,7 +1801,7 @@ static const ARMv7_Instruction g_table_0xf93[] =
ARMv7_OP_4(LDRSH_LIT, T1) // F 0xff7f, 0x0000
};
static void group_0xf93(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf93(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = thr->code.code0 & 0x000f;
@ -1840,7 +1829,7 @@ static const ARMv7_Instruction g_table_0xf9[] =
ARMv7_OP_4(LDRSH_IMM, T1), // B 0xfff0, 0x0000
};
static void group_0xf9(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf9(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code0 & 0x00f0) >> 4;
@ -1873,7 +1862,7 @@ static const ARMv7_Instruction g_table_0xfa00[] =
ARMv7_OP_4(LSL_REG, T2) // F 0xffe0, 0xf0f0
};
static void group_0xfa00(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xfa00(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code1 & 0xf0f0) == 0xf000 ? 0xf : 0x0;
thr->m_last_instr_name = g_table_0xfa00[index].name;
@ -1898,7 +1887,7 @@ static const ARMv7_Instruction g_table_0xfa90[] =
ARMv7_OP_4(REVSH, T2) // B 0xfff0, 0xf0f0
};
static void group_0xfa90(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xfa90(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
const u32 index = (thr->code.code1 & 0x00f0) >> 4;
thr->m_last_instr_name = g_table_0xfa90[index].name;
@ -1923,7 +1912,7 @@ static const ARMv7_Instruction g_table_0xfa[] =
ARMv7_OP_4(CLZ, T1) // B 0xfff0, 0xf0f0
};
static void group_0xfa(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xfa(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code0 & 0x00e0) >> 4;
@ -1958,7 +1947,7 @@ static const ARMv7_Instruction g_table_0xf_main[] =
};
static void group_0xf(ARMv7Thread* thr, const ARMv7_encoding type)
static void group_0xf(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
{
u32 index = (thr->code.code0 & 0x0b00) >> 8;
@ -2023,3 +2012,4 @@ static void execute_main_group(ARMv7Thread* thr)
#undef ARMv7_OP_2
#undef ARMv7_OP_4
#undef ARMv7_NULL_OP
#endif

View File

@ -10,22 +10,48 @@
#include "ARMv7DisAsm.h"
#include "ARMv7Interpreter.h"
void ARMv7Context::write_pc(u32 value)
{
thread.SetBranch(value);
}
u32 ARMv7Context::read_pc()
{
return thread.PC;
}
void ARMv7Context::put_stack_arg(u32 shift, u32 value)
{
vm::psv::write32(SP + shift, value);
}
u32 ARMv7Context::get_stack_arg(u32 pos)
{
return vm::psv::read32(SP + sizeof(u32) * (pos - 5));
}
void ARMv7Context::fast_call(u32 addr)
{
return thread.FastCall(addr);
}
ARMv7Thread::ARMv7Thread()
: CPUThread(CPU_THREAD_ARMv7)
, m_arg(0)
, m_last_instr_size(0)
, m_last_instr_name("UNK")
, context(*this)
//, m_arg(0)
//, m_last_instr_size(0)
//, m_last_instr_name("UNK")
{
}
void ARMv7Thread::InitRegs()
{
memset(GPR, 0, sizeof(GPR[0]) * 15);
APSR.APSR = 0;
IPSR.IPSR = 0;
ISET = Thumb;
ITSTATE.IT = 0;
SP = m_stack_addr + m_stack_size;
memset(context.GPR, 0, sizeof(context.GPR[0]) * 15);
context.APSR.APSR = 0;
context.IPSR.IPSR = 0;
context.ISET = Thumb;
context.ITSTATE.IT = 0;
context.SP = m_stack_addr + m_stack_size;
}
void ARMv7Thread::InitStack()
@ -37,26 +63,21 @@ void ARMv7Thread::InitStack()
}
}
u32 ARMv7Thread::GetStackArg(u32 pos)
{
return vm::psv::read32(SP + sizeof(u32) * (pos - 5));
}
std::string ARMv7Thread::RegsToString()
{
std::string result = "Registers:\n=========\n";
for(int i=0; i<15; ++i)
{
result += fmt::Format("%s\t= 0x%08x\n", g_arm_reg_name[i], GPR[i]);
result += fmt::Format("%s\t= 0x%08x\n", g_arm_reg_name[i], context.GPR[i]);
}
result += fmt::Format("APSR\t= 0x%08x [N: %d, Z: %d, C: %d, V: %d, Q: %d]\n",
APSR.APSR,
fmt::by_value(APSR.N),
fmt::by_value(APSR.Z),
fmt::by_value(APSR.C),
fmt::by_value(APSR.V),
fmt::by_value(APSR.Q));
context.APSR.APSR,
fmt::by_value(context.APSR.N),
fmt::by_value(context.APSR.Z),
fmt::by_value(context.APSR.C),
fmt::by_value(context.APSR.V),
fmt::by_value(context.APSR.Q));
return result;
}
@ -85,7 +106,7 @@ void ARMv7Thread::DoRun()
case 1:
case 2:
m_dec = new ARMv7Decoder(*this);
m_dec = new ARMv7Decoder(context);
break;
}
}
@ -110,21 +131,21 @@ void ARMv7Thread::FastCall(u32 addr)
{
auto old_status = m_status;
auto old_PC = PC;
auto old_stack = SP;
auto old_LR = LR;
auto old_stack = context.SP;
auto old_LR = context.LR;
auto old_thread = GetCurrentNamedThread();
m_status = Running;
PC = addr;
LR = Emu.GetCPUThreadStop();
context.LR = Emu.GetCPUThreadStop();
SetCurrentNamedThread(this);
CPUThread::Task();
m_status = old_status;
PC = old_PC;
SP = old_stack;
LR = old_LR;
context.SP = old_stack;
context.LR = old_LR;
SetCurrentNamedThread(old_thread);
}

View File

@ -1,147 +1,24 @@
#pragma once
#include "Emu/CPU/CPUThread.h"
#include "Emu/Memory/Memory.h"
enum ARMv7InstructionSet
{
ARM,
Thumb,
Jazelle,
ThumbEE
};
#include "ARMv7Context.h"
class ARMv7Thread : public CPUThread
{
public:
u32 m_arg;
u8 m_last_instr_size;
const char* m_last_instr_name;
ARMv7Context context;
//u32 m_arg;
//u8 m_last_instr_size;
//const char* m_last_instr_name;
ARMv7Thread();
union
{
u32 GPR[15];
struct
{
u32 pad[13];
union
{
u32 SP;
struct { u16 SP_main, SP_process; };
};
u32 LR;
};
};
union
{
struct
{
u32 N : 1; //Negative condition code flag
u32 Z : 1; //Zero condition code flag
u32 C : 1; //Carry condition code flag
u32 V : 1; //Overflow condition code flag
u32 Q : 1; //Set to 1 if an SSAT or USAT instruction changes (saturates) the input value for the signed or unsigned range of the result
u32 : 27;
};
u32 APSR;
} APSR;
union
{
struct
{
u32 : 24;
u32 exception : 8;
};
u32 IPSR;
} IPSR;
union
{
struct
{
u32 code1 : 16;
u32 code0 : 16;
};
u32 data;
} code;
ARMv7InstructionSet ISET;
union
{
struct
{
u8 cond : 3;
u8 state : 5;
};
u8 IT;
u32 advance()
{
const u32 res = (state & 0xf) ? (cond << 1 | state >> 4) : 0xe /* true */;
state <<= 1;
if ((state & 0xf) == 0) // if no d
{
IT = 0; // clear ITSTATE
}
return res;
}
operator bool() const
{
return (state & 0xf) != 0;
}
} ITSTATE;
void write_gpr(u32 n, u32 value)
{
assert(n < 16);
if(n < 15)
{
GPR[n] = value;
}
else
{
SetBranch(value & ~1);
}
}
u32 read_gpr(u32 n)
{
assert(n < 16);
if(n < 15)
{
return GPR[n];
}
return PC;
}
void update_code(const u32 address)
{
code.code0 = vm::psv::read16(address & ~1);
code.code1 = vm::psv::read16(address + 2 & ~1);
m_arg = address & 0x1 ? code.code1 << 16 | code.code0 : code.data;
}
//void update_code(const u32 address)
//{
// code.code0 = vm::psv::read16(address & ~1);
// code.code1 = vm::psv::read16(address + 2 & ~1);
// m_arg = address & 0x1 ? code.code1 << 16 | code.code0 : code.data;
//}
public:
virtual void InitRegs();
@ -209,131 +86,3 @@ public:
return *this;
}
};
template<typename T, bool is_enum = std::is_enum<T>::value>
struct cast_armv7_gpr
{
static_assert(is_enum, "Invalid type for cast_armv7_gpr");
typedef typename std::underlying_type<T>::type underlying_type;
__forceinline static u32 to_gpr(const T& value)
{
return cast_armv7_gpr<underlying_type>::to_gpr(static_cast<underlying_type>(value));
}
__forceinline static T from_gpr(const u32 reg)
{
return static_cast<T>(cast_armv7_gpr<underlying_type>::from_gpr(reg));
}
};
template<>
struct cast_armv7_gpr<u8, false>
{
__forceinline static u32 to_gpr(const u8& value)
{
return value;
}
__forceinline static u8 from_gpr(const u32 reg)
{
return static_cast<u8>(reg);
}
};
template<>
struct cast_armv7_gpr<u16, false>
{
__forceinline static u32 to_gpr(const u16& value)
{
return value;
}
__forceinline static u16 from_gpr(const u32 reg)
{
return static_cast<u16>(reg);
}
};
template<>
struct cast_armv7_gpr<u32, false>
{
__forceinline static u32 to_gpr(const u32& value)
{
return value;
}
__forceinline static u32 from_gpr(const u32 reg)
{
return reg;
}
};
template<>
struct cast_armv7_gpr<s8, false>
{
__forceinline static u32 to_gpr(const s8& value)
{
return value;
}
__forceinline static s8 from_gpr(const u32 reg)
{
return static_cast<s8>(reg);
}
};
template<>
struct cast_armv7_gpr<s16, false>
{
__forceinline static u32 to_gpr(const s16& value)
{
return value;
}
__forceinline static s16 from_gpr(const u32 reg)
{
return static_cast<s16>(reg);
}
};
template<>
struct cast_armv7_gpr<s32, false>
{
__forceinline static u32 to_gpr(const s32& value)
{
return value;
}
__forceinline static s32 from_gpr(const u32 reg)
{
return static_cast<s32>(reg);
}
};
template<>
struct cast_armv7_gpr<bool, false>
{
__forceinline static u32 to_gpr(const bool& value)
{
return value;
}
__forceinline static bool from_gpr(const u32 reg)
{
return reinterpret_cast<const bool&>(reg);
}
};
template<typename T>
__forceinline u32 cast_to_armv7_gpr(const T& value)
{
return cast_armv7_gpr<T>::to_gpr(value);
}
template<typename T>
__forceinline T cast_from_armv7_gpr(const u32 reg)
{
return cast_armv7_gpr<T>::from_gpr(reg);
}

View File

@ -1,9 +1,10 @@
#include "stdafx.h"
#include "Emu/System.h"
#include "Emu/Memory/Memory.h"
#include "Emu/ARMv7/PSVFuncList.h"
#include "Emu/CPU/CPUThreadManager.h"
#include "Emu/ARMv7/ARMv7Thread.h"
#include "Emu/ARMv7/PSVFuncList.h"
extern psv_log_base sceLibKernel;
@ -86,7 +87,7 @@ struct SceKernelSystemInfo
#pragma pack(pop)
s32 sceKernelCreateThread(
u32 sceKernelCreateThread(
vm::psv::ptr<const char> pName,
vm::psv::ptr<SceKernelThreadEntry> entry,
s32 initPriority,
@ -100,24 +101,21 @@ s32 sceKernelCreateThread(
ARMv7Thread& new_thread = static_cast<ARMv7Thread&>(Emu.GetCPU().AddThread(CPU_THREAD_ARMv7));
u32 id = new_thread.GetId();
const auto id = new_thread.GetId();
new_thread.SetEntry(entry.addr() ^ 1);
new_thread.SetPrio(initPriority);
new_thread.SetStackSize(stackSize);
new_thread.SetName(pName.get_ptr());
sceLibKernel.Error("*** New ARMv7 Thread [%s] (entry=0x%x)^1: id = %d", pName.get_ptr(), entry, id);
sceLibKernel.Error("*** New ARMv7 Thread [%s] (entry=0x%x)^1: id -> 0x%x", pName.get_ptr(), entry, id);
new_thread.Run();
Emu.Pause();
return id;
}
s32 sceKernelStartThread(s32 threadId, u32 argSize, vm::psv::ptr<const void> pArgBlock)
s32 sceKernelStartThread(u32 threadId, u32 argSize, vm::psv::ptr<const void> pArgBlock)
{
sceLibKernel.Error("sceKernelStartThread(threadId=%d, argSize=%d, pArgBlock=0x%x)", threadId, argSize, pArgBlock);
sceLibKernel.Error("sceKernelStartThread(threadId=0x%x, argSize=0x%x, pArgBlock=0x%x)", threadId, argSize, pArgBlock);
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(threadId);
@ -129,30 +127,30 @@ s32 sceKernelStartThread(s32 threadId, u32 argSize, vm::psv::ptr<const void> pAr
ARMv7Thread& thread = static_cast<ARMv7Thread&>(*t);
// push arg block onto the stack
const u32 pos = (thread.SP -= argSize);
const u32 pos = (thread.context.SP -= argSize);
memcpy(vm::get_ptr<void>(pos), pArgBlock.get_ptr(), argSize);
// set SceKernelThreadEntry function arguments
thread.write_gpr(0, argSize);
thread.write_gpr(1, pos);
thread.context.GPR[0] = argSize;
thread.context.GPR[1] = pos;
thread.Exec();
return SCE_OK;
}
s32 sceKernelExitThread(ARMv7Thread& CPU, s32 exitStatus)
s32 sceKernelExitThread(ARMv7Context& context, s32 exitStatus)
{
sceLibKernel.Error("sceKernelExitThread(exitStatus=0x%x)", exitStatus);
// exit status is stored in r0
CPU.Stop();
context.thread.Stop();
return SCE_OK;
}
s32 sceKernelDeleteThread(s32 threadId)
s32 sceKernelDeleteThread(u32 threadId)
{
sceLibKernel.Todo("sceKernelDeleteThread(threadId=%d)", threadId);
sceLibKernel.Todo("sceKernelDeleteThread(threadId=0x%x)", threadId);
return SCE_OK;
}
@ -164,21 +162,21 @@ s32 sceKernelExitDeleteThread(s32 exitStatus)
return SCE_OK;
}
s32 sceKernelChangeThreadCpuAffinityMask(s32 threadId, s32 cpuAffinityMask)
s32 sceKernelChangeThreadCpuAffinityMask(u32 threadId, s32 cpuAffinityMask)
{
sceLibKernel.Todo("sceKernelChangeThreadCpuAffinityMask(threadId=%d, cpuAffinityMask=0x%x)", threadId, cpuAffinityMask);
sceLibKernel.Todo("sceKernelChangeThreadCpuAffinityMask(threadId=0x%x, cpuAffinityMask=0x%x)", threadId, cpuAffinityMask);
return SCE_OK;
}
s32 sceKernelGetThreadCpuAffinityMask(s32 threadId)
s32 sceKernelGetThreadCpuAffinityMask(u32 threadId)
{
sceLibKernel.Todo("sceKernelGetThreadCpuAffinityMask(threadId=0x%x)", threadId);
return SCE_OK;
}
s32 sceKernelChangeThreadPriority(s32 threadId, s32 priority)
s32 sceKernelChangeThreadPriority(u32 threadId, s32 priority)
{
sceLibKernel.Todo("sceKernelChangeThreadPriority(threadId=0x%x, priority=%d)", threadId, priority);
@ -192,11 +190,11 @@ s32 sceKernelGetThreadCurrentPriority()
return SCE_OK;
}
s32 sceKernelGetThreadId()
u32 sceKernelGetThreadId(ARMv7Context& context)
{
sceLibKernel.Todo("sceKernelGetThreadId()");
sceLibKernel.Log("sceKernelGetThreadId()");
return SCE_OK;
return context.thread.GetId();
}
s32 sceKernelChangeCurrentThreadAttr(u32 clearAttr, u32 setAttr)
@ -206,9 +204,9 @@ s32 sceKernelChangeCurrentThreadAttr(u32 clearAttr, u32 setAttr)
return SCE_OK;
}
s32 sceKernelGetThreadExitStatus(s32 threadId, vm::psv::ptr<s32> pExitStatus)
s32 sceKernelGetThreadExitStatus(u32 threadId, vm::psv::ptr<s32> pExitStatus)
{
sceLibKernel.Todo("sceKernelGetThreadExitStatus(threadId=%d, pExitStatus=0x%x)", threadId, pExitStatus);
sceLibKernel.Todo("sceKernelGetThreadExitStatus(threadId=0x%x, pExitStatus=0x%x)", threadId, pExitStatus);
return SCE_OK;
}
@ -227,9 +225,9 @@ s32 sceKernelCheckWaitableStatus()
return SCE_OK;
}
s32 sceKernelGetThreadInfo(s32 threadId, vm::psv::ptr<SceKernelThreadInfo> pInfo)
s32 sceKernelGetThreadInfo(u32 threadId, vm::psv::ptr<SceKernelThreadInfo> pInfo)
{
sceLibKernel.Todo("sceKernelGetThreadInfo(threadId=%d, pInfo=0x%x)", threadId, pInfo);
sceLibKernel.Todo("sceKernelGetThreadInfo(threadId=0x%x, pInfo=0x%x)", threadId, pInfo);
return SCE_OK;
}
@ -250,7 +248,7 @@ s32 sceKernelGetSystemInfo(vm::psv::ptr<SceKernelSystemInfo> pInfo)
s32 sceKernelGetThreadmgrUIDClass(s32 uid)
{
sceLibKernel.Todo("sceKernelGetThreadmgrUIDClass(uid=%d)", uid);
sceLibKernel.Todo("sceKernelGetThreadmgrUIDClass(uid=0x%x)", uid);
return SCE_OK;
}
@ -283,24 +281,56 @@ s32 sceKernelDelayThreadCB(u32 usec)
return SCE_OK;
}
s32 sceKernelWaitThreadEnd(s32 threadId, vm::psv::ptr<s32> pExitStatus, vm::psv::ptr<u32> pTimeout)
s32 sceKernelWaitThreadEnd(u32 threadId, vm::psv::ptr<s32> pExitStatus, vm::psv::ptr<u32> pTimeout)
{
sceLibKernel.Todo("sceKernelWaitThreadEnd(threadId=%d, pExitStatus=0x%x, pTimeout=0x%x)", threadId, pExitStatus, pTimeout);
sceLibKernel.Error("sceKernelWaitThreadEnd(threadId=0x%x, pExitStatus=0x%x, pTimeout=0x%x)", threadId, pExitStatus, pTimeout);
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(threadId);
if (!t || t->GetType() != CPU_THREAD_ARMv7)
{
RETURN_ERROR(SCE_KERNEL_ERROR_INVALID_UID);
}
ARMv7Thread& thread = static_cast<ARMv7Thread&>(*t);
if (pTimeout)
{
}
while (thread.IsAlive())
{
if (Emu.IsStopped())
{
sceLibKernel.Warning("sceKernelWaitThreadEnd(0x%x) aborted", threadId);
return SCE_OK;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
}
if (pExitStatus)
{
*pExitStatus = thread.context.GPR[0];
}
return SCE_OK;
}
s32 sceKernelWaitThreadEndCB(s32 threadId, vm::psv::ptr<s32> pExitStatus, vm::psv::ptr<u32> pTimeout)
s32 sceKernelWaitThreadEndCB(u32 threadId, vm::psv::ptr<s32> pExitStatus, vm::psv::ptr<u32> pTimeout)
{
sceLibKernel.Todo("sceKernelWaitThreadEndCB(threadId=%d, pExitStatus=0x%x, pTimeout=0x%x)", threadId, pExitStatus, pTimeout);
sceLibKernel.Todo("sceKernelWaitThreadEndCB(threadId=0x%x, pExitStatus=0x%x, pTimeout=0x%x)", threadId, pExitStatus, pTimeout);
return SCE_OK;
}
#define REG_FUNC(nid, name) reg_psv_func(nid, &sceLibKernel, #name, &name)
psv_log_base sceLibKernel = []() -> psv_log_base
psv_log_base sceLibKernel("sceLibKernel", []()
{
sceLibKernel.on_load = nullptr;
sceLibKernel.on_unload = nullptr;
sceLibKernel.on_stop = nullptr;
//REG_FUNC(0x23EAA62, sceKernelPuts);
//REG_FUNC(0xB0335388, sceClibToupper);
//REG_FUNC(0x4C5471BC, sceClibTolower);
@ -665,6 +695,4 @@ psv_log_base sceLibKernel = []() -> psv_log_base
/* SceDebugLed */
//REG_FUNC(0x78E702D3, sceKernelSetGPO);
return psv_log_base("sceLibKernel");
}();
});

View File

@ -1,41 +1,142 @@
#include "stdafx.h"
#include "stdafx.h"
#include "Utilities/Log.h"
#include "Emu/System.h"
#include "Emu/Memory/Memory.h"
#include "Emu/ARMv7/PSVFuncList.h"
#include "Emu/ARMv7/ARMv7Callback.h"
extern psv_log_base sceLibc;
vm::psv::ptr<void> g_dso;
typedef void(*atexit_func_t)(vm::psv::ptr<void>);
std::vector<std::function<void(ARMv7Context&)>> g_atexit;
namespace sce_libc_func
{
void __cxa_atexit()
void __cxa_atexit(vm::psv::ptr<atexit_func_t> func, vm::psv::ptr<void> arg, vm::psv::ptr<void> dso)
{
sceLibc.Todo(__FUNCTION__);
Emu.Pause();
sceLibc.Error("__cxa_atexit(func=0x%x, arg=0x%x, dso=0x%x)", func, arg, dso);
g_atexit.insert(g_atexit.begin(), [func, arg, dso](ARMv7Context& context)
{
func(context, arg);
});
}
void exit()
void __aeabi_atexit(vm::psv::ptr<void> arg, vm::psv::ptr<atexit_func_t> func, vm::psv::ptr<void> dso)
{
sceLibc.Error("__aeabi_atexit(arg=0x%x, func=0x%x, dso=0x%x)", arg, func, dso);
g_atexit.insert(g_atexit.begin(), [func, arg, dso](ARMv7Context& context)
{
func(context, arg);
});
}
void exit(ARMv7Context& context)
{
sceLibc.Error("exit()");
Emu.Pause();
for (auto func : g_atexit)
{
func(context);
}
g_atexit.clear();
sceLibc.Success("Process finished");
CallAfter([]()
{
Emu.Stop();
});
}
void printf(vm::psv::ptr<const char> fmt) // va_args...
std::string armv7_fmt(ARMv7Context& context, vm::psv::ptr<const char> fmt, u32 g_count, u32 f_count, u32 v_count)
{
std::string result;
for (char c = *fmt++; c; c = *fmt++)
{
switch (c)
{
case '%':
{
const auto start = fmt - 1;
const bool number_sign = *fmt == '#' ? fmt++, true : false;
switch (*fmt++)
{
case '%':
{
result += '%';
continue;
}
case 'd':
case 'i':
{
// signed decimal
const s64 value = context.get_next_gpr_arg(g_count, f_count, v_count);
result += fmt::to_sdec(value);
continue;
}
case 'x':
{
// hexadecimal
const u64 value = context.get_next_gpr_arg(g_count, f_count, v_count);
if (number_sign && value)
{
result += "0x";
}
result += fmt::to_hex(value);
continue;
}
default:
{
throw fmt::Format("armv7_fmt(): unknown formatting: '%s'", start.get_ptr());
}
}
}
}
result += c;
}
return result;
}
void printf(ARMv7Context& context, vm::psv::ptr<const char> fmt) // va_args...
{
sceLibc.Error("printf(fmt=0x%x)", fmt);
LOG_NOTICE(TTY, "%s", fmt.get_ptr());
sceLibc.Notice("*** *fmt = '%s'", fmt.get_ptr());
LOG_NOTICE(TTY, armv7_fmt(context, fmt, 1, 0, 0));
}
void __cxa_set_dso_handle_main()
void sprintf(ARMv7Context& context, vm::psv::ptr<char> str, vm::psv::ptr<const char> fmt) // va_args...
{
sceLibc.Error("__cxa_set_dso_handle_main()");
sceLibc.Error("sprintf(str=0x%x, fmt=0x%x)", str, fmt);
sceLibc.Notice("*** *fmt = '%s'", fmt.get_ptr());
const std::string& result = armv7_fmt(context, fmt, 2, 0, 0);
sceLibc.Notice("*** res -> '%s'", result);
::memcpy(str.get_ptr(), result.c_str(), result.size() + 1);
}
void __cxa_set_dso_handle_main(vm::psv::ptr<void> dso)
{
sceLibc.Error("__cxa_set_dso_handle_main(dso=0x%x)", dso);
g_dso = dso;
}
void memcpy(vm::psv::ptr<void> dst, vm::psv::ptr<const void> src, u32 size)
@ -45,6 +146,13 @@ namespace sce_libc_func
::memcpy(dst.get_ptr(), src.get_ptr(), size);
}
void memset(vm::psv::ptr<void> dst, s32 value, u32 size)
{
sceLibc.Error("memset(dst=0x%x, value=%d, size=0x%x)", dst, value, size);
::memset(dst.get_ptr(), value, size);
}
void _Assert(vm::psv::ptr<const char> text, vm::psv::ptr<const char> func)
{
sceLibc.Error("_Assert(text=0x%x, func=0x%x)", text, func);
@ -56,8 +164,15 @@ namespace sce_libc_func
#define REG_FUNC(nid, name) reg_psv_func(nid, &sceLibc, #name, &sce_libc_func::name)
psv_log_base sceLibc = []() -> psv_log_base
psv_log_base sceLibc("SceLibc", []()
{
g_dso.set(0);
g_atexit.clear();
sceLibc.on_load = nullptr;
sceLibc.on_unload = nullptr;
sceLibc.on_stop = nullptr;
REG_FUNC(0xE4531F85, _Assert);
//REG_FUNC(0xE71C5CDE, _Stoul);
//REG_FUNC(0x7A5CA6A3, _Stoulx);
@ -147,7 +262,7 @@ psv_log_base sceLibc = []() -> psv_log_base
//REG_FUNC(0x395490DA, setbuf);
//REG_FUNC(0x2CA980A0, setvbuf);
//REG_FUNC(0xA1BFF606, snprintf);
//REG_FUNC(0x7449B359, sprintf);
REG_FUNC(0x7449B359, sprintf);
//REG_FUNC(0xEC585241, sscanf);
//REG_FUNC(0x2BCB3F01, ungetc);
//REG_FUNC(0xF7915685, vfprintf);
@ -200,7 +315,7 @@ psv_log_base sceLibc = []() -> psv_log_base
//REG_FUNC(0x7747F6D7, memcmp);
REG_FUNC(0x7205BFDB, memcpy);
//REG_FUNC(0xAF5C218D, memmove);
//REG_FUNC(0x6DC1F0D8, memset);
REG_FUNC(0x6DC1F0D8, memset);
//REG_FUNC(0x1434FA46, strcat);
//REG_FUNC(0xB9336E16, strchr);
//REG_FUNC(0x1B58FA3B, strcmp);
@ -317,7 +432,7 @@ psv_log_base sceLibc = []() -> psv_log_base
//REG_FUNC(0x9D885076, _Towctrans);
//REG_FUNC(0xE980110A, _Iswctype);
REG_FUNC(0x33b83b70, __cxa_atexit);
//REG_FUNC(0xEDC939E1, __aeabi_atexit);
REG_FUNC(0xEDC939E1, __aeabi_atexit);
//REG_FUNC(0xB538BF48, __cxa_finalize);
//REG_FUNC(0xD0310E31, __cxa_guard_acquire);
//REG_FUNC(0x4ED1056F, __cxa_guard_release);
@ -350,6 +465,4 @@ psv_log_base sceLibc = []() -> psv_log_base
//REG_FUNC(0x677CDE35, _Snan);
//REG_FUNC(0x7D35108B, _FSnan);
//REG_FUNC(0x48AEEF2A, _LSnan);
return psv_log_base("SceLibc");
}();
});

View File

@ -12,8 +12,12 @@ namespace sce_libm_func
#define REG_FUNC(nid, name) reg_psv_func(nid, &sceLibm, #name, &sce_libm_func::name)
psv_log_base sceLibm = []() -> psv_log_base
psv_log_base sceLibm("SceLibm", []()
{
sceLibm.on_load = nullptr;
sceLibm.on_unload = nullptr;
sceLibm.on_stop = nullptr;
//REG_FUNC(0xC73FE76D, _Exp);
//REG_FUNC(0xFF4EAE04, _FExp);
//REG_FUNC(0xB363D7D4, _LExp);
@ -212,6 +216,4 @@ psv_log_base sceLibm = []() -> psv_log_base
//REG_FUNC(0x5BD0F71C, _Dsign);
//REG_FUNC(0xC4F7E42C, _FDsign);
//REG_FUNC(0x1DF73D2B, _LDsign);
return psv_log_base("SceLibm");
}();
});

View File

@ -28,8 +28,12 @@ namespace sce_libstdcxx_func
#define REG_FUNC(nid, name) reg_psv_func(nid, &sceLibstdcxx, #name, &sce_libstdcxx_func::name)
psv_log_base sceLibstdcxx = []() -> psv_log_base
psv_log_base sceLibstdcxx("SceLibstdcxx", []()
{
sceLibstdcxx.on_load = nullptr;
sceLibstdcxx.on_unload = nullptr;
sceLibstdcxx.on_stop = nullptr;
//REG_FUNC(0x52B0C625, std::bad_typeid::what() const);
//REG_FUNC(0x64D7D074, std::bad_typeid::_Doraise() const);
//REG_FUNC(0x15FB88E2, std::logic_error::what() const);
@ -976,9 +980,7 @@ psv_log_base sceLibstdcxx = []() -> psv_log_base
//REG_FUNC(0x7321E731, vtable for __cxxabiv1::__vmi_class_type_info);
//REG_FUNC(0x33836375, vtable for __cxxabiv1::__fundamental_type_info);
//REG_FUNC(0x94664DEB, vtable for __cxxabiv1::__pointer_to_member_type_info);
return psv_log_base("SceLibstdcxx");
}();
});
/*
// original names

View File

@ -1,29 +1,12 @@
#include "stdafx.h"
#include <unordered_map>
#include "Utilities/Log.h"
#include "Emu/System.h"
#include "ARMv7Thread.h"
#include "PSVFuncList.h"
std::vector<psv_func> g_psv_func_list;
std::vector<psv_log_base*> g_psv_modules;
void add_psv_func(psv_func& data)
{
// setup special functions (without NIDs)
if (!g_psv_func_list.size())
{
psv_func unimplemented;
unimplemented.nid = 0;
unimplemented.name = "Special function (unimplemented stub)";
unimplemented.func.reset(new psv_func_detail::func_binder<void, ARMv7Thread&>([](ARMv7Thread& CPU){ CPU.m_last_syscall = vm::psv::read32(CPU.PC + 4); throw "Unimplemented function executed"; }));
g_psv_func_list.push_back(unimplemented);
psv_func hle_return;
hle_return.nid = 1;
hle_return.name = "Special function (return from HLE)";
hle_return.func.reset(new psv_func_detail::func_binder<void, ARMv7Thread&>([](ARMv7Thread& CPU){ CPU.FastStop(); }));
g_psv_func_list.push_back(hle_return);
}
g_psv_func_list.push_back(data);
}
@ -49,16 +32,16 @@ u32 get_psv_func_index(psv_func* func)
return (u32)res;
}
void execute_psv_func_by_index(ARMv7Thread& CPU, u32 index)
void execute_psv_func_by_index(ARMv7Context& context, u32 index)
{
assert(index < g_psv_func_list.size());
auto old_last_syscall = CPU.m_last_syscall;
CPU.m_last_syscall = g_psv_func_list[index].nid;
auto old_last_syscall = context.thread.m_last_syscall;
context.thread.m_last_syscall = g_psv_func_list[index].nid;
(*g_psv_func_list[index].func)(CPU);
(*g_psv_func_list[index].func)(context);
CPU.m_last_syscall = old_last_syscall;
context.thread.m_last_syscall = old_last_syscall;
}
extern psv_log_base sceLibc;
@ -66,10 +49,53 @@ extern psv_log_base sceLibm;
extern psv_log_base sceLibstdcxx;
extern psv_log_base sceLibKernel;
void list_known_psv_modules()
void initialize_psv_modules()
{
sceLibc.Log("");
sceLibm.Log("");
sceLibstdcxx.Log("");
sceLibKernel.Log("");
assert(!g_psv_func_list.size() && !g_psv_modules.size());
// fill module list
g_psv_modules.push_back(&sceLibc);
g_psv_modules.push_back(&sceLibm);
g_psv_modules.push_back(&sceLibstdcxx);
g_psv_modules.push_back(&sceLibKernel);
// setup special functions (without NIDs)
psv_func unimplemented;
unimplemented.nid = 0;
unimplemented.name = "Special function (unimplemented stub)";
unimplemented.func.reset(new psv_func_detail::func_binder<void, ARMv7Context&>([](ARMv7Context& context)
{
context.thread.m_last_syscall = vm::psv::read32(context.thread.PC + 4);
throw "Unimplemented function executed";
}));
g_psv_func_list.push_back(unimplemented);
psv_func hle_return;
hle_return.nid = 1;
hle_return.name = "Special function (return from HLE)";
hle_return.func.reset(new psv_func_detail::func_binder<void, ARMv7Context&>([](ARMv7Context& context)
{
context.thread.FastStop();
}));
g_psv_func_list.push_back(hle_return);
// load functions
for (auto module : g_psv_modules)
{
module->Init();
}
}
void finalize_psv_modules()
{
for (auto module : g_psv_modules)
{
if (module->on_stop)
{
module->on_stop();
}
}
g_psv_func_list.clear();
g_psv_modules.clear();
}

View File

@ -1,17 +1,29 @@
#pragma once
#include "ARMv7Thread.h"
#include "ARMv7Context.h"
#include "Emu/SysCalls/LogBase.h"
class psv_log_base : public LogBase
{
std::string m_name;
void(*m_init_func)();
public:
psv_log_base(const std::string& name)
std::function<void()> on_load;
std::function<void()> on_unload;
std::function<void()> on_stop;
public:
psv_log_base(const std::string& name, void(*init_func)())
: m_name(name)
, m_init_func(init_func)
{
}
void Init()
{
m_init_func();
}
virtual const std::string& GetName() const override
{
return m_name;
@ -401,7 +413,7 @@ enum psv_error_codes
class psv_func_caller
{
public:
virtual void operator()(ARMv7Thread& CPU) = 0;
virtual void operator()(ARMv7Context& CPU) = 0;
virtual ~psv_func_caller(){};
};
@ -415,6 +427,8 @@ namespace psv_func_detail
ARG_STACK,
};
static const auto FIXED_STACK_FRAME_SIZE = 0x100; // described in CB_FUNC.h
template<typename T, bind_arg_type type, int g_count, int f_count, int v_count>
struct bind_arg;
@ -423,9 +437,14 @@ namespace psv_func_detail
{
static_assert(sizeof(T) <= 4, "Invalid function argument type for ARG_GENERAL");
static __forceinline T func(ARMv7Thread& CPU)
__forceinline static T get_arg(ARMv7Context& context)
{
return cast_from_armv7_gpr<T>(CPU.GPR[g_count - 1]);
return cast_from_armv7_gpr<T>(context.GPR[g_count - 1]);
}
__forceinline static void put_arg(ARMv7Context& context, const T& arg)
{
context.GPR[g_count - 1] = cast_to_armv7_gpr<T>(arg);
}
};
@ -435,7 +454,11 @@ namespace psv_func_detail
static_assert(f_count <= 0, "TODO: Unsupported argument type (float)");
static_assert(sizeof(T) <= 8, "Invalid function argument type for ARG_FLOAT");
static __forceinline T func(ARMv7Thread& CPU)
__forceinline static T get_arg(ARMv7Context& context)
{
}
__forceinline static void put_arg(ARMv7Context& context, const T& arg)
{
}
};
@ -446,7 +469,11 @@ namespace psv_func_detail
static_assert(v_count <= 0, "TODO: Unsupported argument type (vector)");
static_assert(std::is_same<T, u128>::value, "Invalid function argument type for ARG_VECTOR");
static __forceinline T func(ARMv7Thread& CPU)
__forceinline static T get_arg(ARMv7Context& context)
{
}
__forceinline static void put_arg(ARMv7Context& context, const T& arg)
{
}
};
@ -458,11 +485,19 @@ namespace psv_func_detail
static_assert(v_count <= 0, "TODO: Unsupported stack argument type (vector)");
static_assert(sizeof(T) <= 4, "Invalid function argument type for ARG_STACK");
static __forceinline T func(ARMv7Thread& CPU)
__forceinline static T get_arg(ARMv7Context& context)
{
// TODO: check
const u32 res = CPU.GetStackArg(g_count);
return cast_from_armv7_gpr<T>(res);
return cast_from_armv7_gpr<T>(context.get_stack_arg(g_count));
}
__forceinline static void put_arg(ARMv7Context& context, const T& arg)
{
// TODO: check
const int stack_pos = (g_count - 5) * 4 - FIXED_STACK_FRAME_SIZE;
static_assert(stack_pos < 0, "TODO: Increase fixed stack frame size (arg count limit broken)");
context.put_stack_arg(stack_pos, cast_to_armv7_gpr<T>(arg));
}
};
@ -474,9 +509,14 @@ namespace psv_func_detail
static_assert(type == ARG_GENERAL, "Wrong use of bind_result template");
static_assert(sizeof(T) <= 4, "Invalid function result type for ARG_GENERAL");
static __forceinline void func(ARMv7Thread& CPU, const T& result)
__forceinline static T get_result(ARMv7Context& context)
{
CPU.GPR[0] = cast_to_armv7_gpr<T>(result);
return cast_from_armv7_gpr<T>(context.GPR[0]);
}
__forceinline static void put_result(ARMv7Context& context, const T& result)
{
context.GPR[0] = cast_to_armv7_gpr<T>(result);
}
};
@ -485,7 +525,7 @@ namespace psv_func_detail
//{
// static_assert(sizeof(T) <= 8, "Invalid function result type for ARG_FLOAT");
// static __forceinline void func(ARMv7Thread& CPU, const T& result)
// static __forceinline void put_result(ARMv7Context& context, const T& result)
// {
// }
//};
@ -495,11 +535,37 @@ namespace psv_func_detail
//{
// static_assert(std::is_same<T, u128>::value, "Invalid function result type for ARG_VECTOR");
// static __forceinline void func(ARMv7Thread& CPU, const T& result)
// static __forceinline void put_result(ARMv7Context& context, const T& result)
// {
// }
//};
template<typename RT>
struct result_type
{
static_assert(!std::is_pointer<RT>::value, "Invalid function result type (pointer)");
static_assert(!std::is_reference<RT>::value, "Invalid function result type (reference)");
static const bool is_float = std::is_floating_point<RT>::value;
static const bool is_vector = std::is_same<RT, u128>::value;
static const bind_arg_type value = is_float ? ARG_FLOAT : (is_vector ? ARG_VECTOR : ARG_GENERAL);
};
template<typename T, int g_count, int f_count, int v_count>
struct arg_type
{
static_assert(!std::is_pointer<T>::value, "Invalid function argument type (pointer)");
static_assert(!std::is_reference<T>::value, "Invalid function argument type (reference)");
// TODO: check calculations
static const bool is_float = std::is_floating_point<T>::value;
static const bool is_vector = std::is_same<T, u128>::value;
static const bind_arg_type value = is_float
? ((f_count >= 4) ? ARG_STACK : ARG_FLOAT)
: (is_vector ? ((v_count >= 4) ? ARG_STACK : ARG_VECTOR) : ((g_count >= 4) ? ARG_STACK : ARG_GENERAL));
static const int g_value = g_count + (is_float || is_vector ? 0 : 1);
static const int f_value = f_count + (is_float ? 1 : 0);
static const int v_value = v_count + (is_vector ? 1 : 0);
};
template <typename RT, typename F, typename Tuple, bool Done, int Total, int... N>
struct call_impl
{
@ -526,39 +592,45 @@ namespace psv_func_detail
}
template<int g_count, int f_count, int v_count>
__forceinline std::tuple<> iterate(ARMv7Thread& CPU)
__forceinline std::tuple<> get_func_args(ARMv7Context& context)
{
// terminator
return std::tuple<>();
}
template<int g_count, int f_count, int v_count, typename T, typename... A>
__forceinline std::tuple<T, A...> iterate(ARMv7Thread& CPU)
__forceinline std::tuple<T, A...> get_func_args(ARMv7Context& context)
{
static_assert(!std::is_pointer<T>::value, "Invalid function argument type (pointer)");
static_assert(!std::is_reference<T>::value, "Invalid function argument type (reference)");
// TODO: check calculations
const bool is_float = std::is_floating_point<T>::value;
const bool is_vector = std::is_same<T, u128>::value;
const bind_arg_type t = is_float
? ((f_count >= 4) ? ARG_STACK : ARG_FLOAT)
: (is_vector ? ((v_count >= 4) ? ARG_STACK : ARG_VECTOR) : ((g_count >= 4) ? ARG_STACK : ARG_GENERAL));
const int g = g_count + (is_float || is_vector ? 0 : 1);
const int f = f_count + (is_float ? 1 : 0);
const int v = v_count + (is_vector ? 1 : 0);
typedef arg_type<T, g_count, f_count, v_count> type;
const bind_arg_type t = type::value;
const int g = type::g_value;
const int f = type::f_value;
const int v = type::v_value;
return std::tuple_cat(std::tuple<T>(bind_arg<T, t, g, f, v>::func(CPU)), iterate<g, f, v, A...>(CPU));
return std::tuple_cat(std::tuple<T>(bind_arg<T, t, g, f, v>::get_arg(context)), get_func_args<g, f, v, A...>(context));
}
template<typename RT>
struct result_type
template<int g_count, int f_count, int v_count>
__forceinline static bool put_func_args(ARMv7Context& context)
{
static_assert(!std::is_pointer<RT>::value, "Invalid function result type (pointer)");
static_assert(!std::is_reference<RT>::value, "Invalid function result type (reference)");
static const bool is_float = std::is_floating_point<RT>::value;
static const bool is_vector = std::is_same<RT, u128>::value;
static const bind_arg_type value = is_float ? ARG_FLOAT : (is_vector ? ARG_VECTOR : ARG_GENERAL);
};
// terminator
return false;
}
template<int g_count, int f_count, int v_count, typename T1, typename... T>
__forceinline static bool put_func_args(ARMv7Context& context, T1 arg, T... args)
{
typedef arg_type<T1, g_count, f_count, v_count> type;
const bind_arg_type t = type::value;
const int g = type::g_value;
const int f = type::f_value;
const int v = type::v_value;
bind_arg<T1, t, g, f, v>::put_arg(context, arg);
// return true if stack was used
return put_func_args<g, f, v>(context, args...) || (t == ARG_STACK);
}
template<typename RT, typename... T>
class func_binder;
@ -576,16 +648,16 @@ namespace psv_func_detail
{
}
virtual void operator()(ARMv7Thread& CPU)
virtual void operator()(ARMv7Context& context)
{
call<void>(m_call, iterate<0, 0, 0, T...>(CPU));
call<void>(m_call, get_func_args<0, 0, 0, T...>(context));
}
};
template<typename... T>
class func_binder<void, ARMv7Thread&, T...> : public psv_func_caller
class func_binder<void, ARMv7Context&, T...> : public psv_func_caller
{
typedef void(*func_t)(ARMv7Thread&, T...);
typedef void(*func_t)(ARMv7Context&, T...);
const func_t m_call;
public:
@ -595,9 +667,9 @@ namespace psv_func_detail
{
}
virtual void operator()(ARMv7Thread& CPU)
virtual void operator()(ARMv7Context& context)
{
call<void>(m_call, std::tuple_cat(std::tuple<ARMv7Thread&>(CPU), iterate<0, 0, 0, T...>(CPU)));
call<void>(m_call, std::tuple_cat(std::tuple<ARMv7Context&>(context), get_func_args<0, 0, 0, T...>(context)));
}
};
@ -614,16 +686,16 @@ namespace psv_func_detail
{
}
virtual void operator()(ARMv7Thread& CPU)
virtual void operator()(ARMv7Context& context)
{
bind_result<RT, result_type<RT>::value>::func(CPU, call<RT>(m_call, iterate<0, 0, 0, T...>(CPU)));
bind_result<RT, result_type<RT>::value>::put_result(context, call<RT>(m_call, get_func_args<0, 0, 0, T...>(context)));
}
};
template<typename RT, typename... T>
class func_binder<RT, ARMv7Thread&, T...> : public psv_func_caller
class func_binder<RT, ARMv7Context&, T...> : public psv_func_caller
{
typedef RT(*func_t)(ARMv7Thread&, T...);
typedef RT(*func_t)(ARMv7Context&, T...);
const func_t m_call;
public:
@ -633,9 +705,38 @@ namespace psv_func_detail
{
}
virtual void operator()(ARMv7Thread& CPU)
virtual void operator()(ARMv7Context& context)
{
bind_result<RT, result_type<RT>::value>::func(CPU, call<RT>(m_call, std::tuple_cat(std::tuple<ARMv7Thread&>(CPU), iterate<0, 0, 0, T...>(CPU))));
bind_result<RT, result_type<RT>::value>::put_result(context, call<RT>(m_call, std::tuple_cat(std::tuple<ARMv7Context&>(context), get_func_args<0, 0, 0, T...>(context))));
}
};
template<typename RT, typename... T>
struct func_caller
{
__forceinline static RT call(ARMv7Context& context, u32 addr, T... args)
{
func_caller<void, T...>::call(context, addr, args...);
return bind_result<RT, result_type<RT>::value>::get_result(context);
}
};
template<typename... T>
struct func_caller<void, T...>
{
__forceinline static void call(ARMv7Context& context, u32 addr, T... args)
{
if (put_func_args<0, 0, 0, T...>(context, args...))
{
context.SP -= FIXED_STACK_FRAME_SIZE;
context.fast_call(addr);
context.SP += FIXED_STACK_FRAME_SIZE;
}
else
{
context.fast_call(addr);
}
}
};
}
@ -665,5 +766,6 @@ void reg_psv_func(u32 nid, psv_log_base* module, const char* name, RT(*func)(T..
psv_func* get_psv_func_by_nid(u32 nid);
u32 get_psv_func_index(psv_func* func);
void execute_psv_func_by_index(ARMv7Thread& CPU, u32 index);
void list_known_psv_modules();
void execute_psv_func_by_index(ARMv7Context& context, u32 index);
void initialize_psv_modules();
void finalize_psv_modules();

View File

@ -5,7 +5,7 @@
class CPUDecoder
{
public:
virtual u8 DecodeMemory(const u32 address)=0;
virtual u32 DecodeMemory(const u32 address) = 0;
virtual ~CPUDecoder() = default;
};

View File

@ -115,7 +115,7 @@ void CPUThread::SetEntry(const u32 pc)
entry = pc;
}
void CPUThread::NextPc(u8 instr_size)
void CPUThread::NextPc(u32 instr_size)
{
if(m_is_branch)
{

View File

@ -132,7 +132,7 @@ public:
int ThreadStatus();
void NextPc(u8 instr_size);
void NextPc(u32 instr_size);
void SetBranch(const u32 pc, bool record_branch = false);
void SetPc(const u32 pc);
void SetEntry(const u32 entry);

View File

@ -2,7 +2,7 @@
#include "Emu/Memory/Memory.h"
#include "PPCDecoder.h"
u8 PPCDecoder::DecodeMemory(const u32 address)
u32 PPCDecoder::DecodeMemory(const u32 address)
{
u32 instr = vm::read32(address);
Decode(instr);

View File

@ -5,9 +5,9 @@
class PPCDecoder : public CPUDecoder
{
public:
virtual void Decode(const u32 code)=0;
virtual void Decode(const u32 code) = 0;
virtual u8 DecodeMemory(const u32 address);
virtual u32 DecodeMemory(const u32 address);
virtual ~PPCDecoder() = default;
};

View File

@ -6030,7 +6030,7 @@ ppu_recompiler_llvm::ExecutionEngine::~ExecutionEngine() {
}
u8 ppu_recompiler_llvm::ExecutionEngine::DecodeMemory(const u32 address) {
u32 ppu_recompiler_llvm::ExecutionEngine::DecodeMemory(const u32 address) {
ExecuteFunction(&m_ppu, 0);
return 0;
}

View File

@ -1128,7 +1128,7 @@ namespace ppu_recompiler_llvm {
ExecutionEngine & operator = (const ExecutionEngine & other) = delete;
ExecutionEngine & operator = (ExecutionEngine && other) = delete;
u8 DecodeMemory(const u32 address) override;
u32 DecodeMemory(const u32 address) override;
private:
/// PPU processor context

View File

@ -45,7 +45,7 @@ public:
virtual void Decode(const u32 code);
virtual u8 DecodeMemory(const u32 address);
virtual u32 DecodeMemory(const u32 address);
};
#define c (*compiler)

View File

@ -180,7 +180,7 @@ void SPURecompilerCore::Compile(u16 pos)
first = false;
}
u8 SPURecompilerCore::DecodeMemory(const u32 address)
u32 SPURecompilerCore::DecodeMemory(const u32 address)
{
assert(CPU.ls_offset == address - CPU.PC);
const u32 m_offset = CPU.ls_offset;

View File

@ -70,7 +70,7 @@ namespace vm
const u32 res = static_cast<u32>(addr);
if (res != addr)
{
throw fmt::Format("%s(): invalid address 0x%llx", func, addr);
throw fmt::format("%s(): invalid address 0x%llx", func, addr);
}
return res;

View File

@ -1,6 +1,7 @@
#pragma once
class CPUThread;
struct ARMv7Context;
namespace vm
{
@ -332,9 +333,11 @@ namespace vm
public:
typedef RT(*type)(T...);
RT operator()(CPUThread& CPU, T... args) const; // defined in CB_FUNC.h, call using specified CPU thread context
RT operator()(CPUThread& CPU, T... args) const; // defined in CB_FUNC.h, call using specified PPU thread context
RT operator()(T... args) const; // defined in CB_FUNC.h, call using current CPU thread context
RT operator()(ARMv7Context& context, T... args) const; // defined in ARMv7Callback.h, passing context is mandatory
RT operator()(T... args) const; // defined in CB_FUNC.h, call using current PPU thread context
AT addr() const
{

View File

@ -5,6 +5,7 @@
#include "Emu/System.h"
#include "Emu/GameInfo.h"
#include "Emu/ARMv7/PSVFuncList.h"
#include "Emu/SysCalls/Static.h"
#include "Emu/SysCalls/ModuleManager.h"
#include "Emu/Cell/PPUThread.h"
@ -361,6 +362,7 @@ void Emulator::Stop()
LOG_NOTICE(HLE, "All threads stopped...");
finalize_psv_modules();
m_rsx_callback = 0;
// TODO: check finalization order

View File

@ -6,6 +6,7 @@
#include "ELF32.h"
#include "Emu/Cell/SPUThread.h"
#include "Emu/ARMv7/ARMv7Thread.h"
#include "Emu/ARMv7/ARMv7Decoder.h"
#include "Emu/ARMv7/PSVFuncList.h"
#include "Emu/System.h"
@ -89,7 +90,7 @@ namespace loader
case MACHINE_MIPS: break;
case MACHINE_ARM:
{
list_known_psv_modules();
initialize_psv_modules();
auto armv7_thr_stop_data = vm::psv::ptr<u32>::make(Memory.PSV.RAM.AllocAlign(3 * 4));
armv7_thr_stop_data[0] = 0xf870; // HACK instruction (Thumb)
@ -98,17 +99,8 @@ namespace loader
u32 entry = 0; // actual entry point (ELFs entry point is ignored)
u32 fnid_addr = 0;
// load section names
//assert(m_ehdr.data_le.e_shstrndx < m_shdrs.size());
//const u32 sname_off = m_shdrs[m_ehdr.data_le.e_shstrndx].data_le.sh_offset;
//const u32 sname_size = m_shdrs[m_ehdr.data_le.e_shstrndx].data_le.sh_size;
//const u32 sname_base = sname_size ? Memory.PSV.RAM.AllocAlign(sname_size) : 0;
//if (sname_base)
//{
// m_stream->Seek(handler::get_stream_offset() + sname_off);
// m_stream->Read(vm::get_ptr<void>(sname_base), sname_size);
//}
u32 code_start = 0;
u32 code_end = 0;
for (auto& shdr : m_shdrs)
{
@ -125,7 +117,14 @@ namespace loader
name.push_back(c);
}
if (!strcmp(name.c_str(), ".sceModuleInfo.rodata"))
if (!strcmp(name.c_str(), ".text"))
{
LOG_NOTICE(LOADER, ".text analysis...");
code_start = shdr.data_le.sh_addr;
code_end = shdr.data_le.sh_size + code_start;
}
else if (!strcmp(name.c_str(), ".sceModuleInfo.rodata"))
{
LOG_NOTICE(LOADER, ".sceModuleInfo.rodata analysis...");
@ -190,6 +189,8 @@ namespace loader
vm::psv::write16(addr + 2, 0); // index 0 (unimplemented stub)
vm::psv::write32(addr + 4, nid); // nid
}
code_end = std::min<u32>(addr, code_end);
}
}
else if (!strcmp(name.c_str(), ".sceRefs.rodata"))
@ -214,6 +215,7 @@ namespace loader
const u32 addr = *++code;
vm::psv::write16(addr + 0, 0xf240 | (data & 0x800) >> 1 | (data & 0xf000) >> 12); // MOVW
vm::psv::write16(addr + 2, 0x0c00 | (data & 0x700) << 4 | (data & 0xff));
LOG_NOTICE(LOADER, "sceRefs: movw written at 0x%x (data=0x%x)", addr, data);
break;
}
case 0x00000030:
@ -222,22 +224,26 @@ namespace loader
const u32 addr = *++code;
vm::psv::write16(addr + 0, 0xf2c0 | (data & 0x8000000) >> 17 | (data & 0xf0000000) >> 28); // MOVT
vm::psv::write16(addr + 2, 0x0c00 | (data & 0x7000000) >> 12 | (data & 0xff0000) >> 16);
LOG_NOTICE(LOADER, "sceRefs: movt written at 0x%x (data=0x%x)", addr, data);
break;
}
case 0x00000000:
{
// probably, no operation
LOG_NOTICE(LOADER, "sceRefs: zero code");
break;
}
default:
{
LOG_NOTICE(LOADER, "sceRefs: unknown code found (0x%08x)", *code);
LOG_ERROR(LOADER, "sceRefs: unknown code found (0x%08x)", *code);
}
}
}
}
}
armv7_decoder_initialize(code_start, code_end);
arm7_thread(entry & ~1 /* TODO: Thumb/ARM encoding selection */, "main_thread").args({ Emu.GetPath()/*, "-emu"*/ }).run();
break;
}

View File

@ -516,7 +516,7 @@ namespace loader
if (module && !module->Load(nid))
{
LOG_WARNING(LOADER, "Unimplemented function '%s' in '%s' module (HLE)", SysCalls::GetHLEFuncName(nid).c_str(), module_name.c_str());
LOG_ERROR(LOADER, "Unimplemented function '%s' in '%s' module (HLE)", SysCalls::GetHLEFuncName(nid).c_str(), module_name.c_str());
}
else //if (Ini.HLELogging.GetValue())
{

View File

@ -52,6 +52,7 @@
<ClCompile Include="Crypto\unpkg.cpp" />
<ClCompile Include="Crypto\unself.cpp" />
<ClCompile Include="Crypto\utils.cpp" />
<ClCompile Include="Emu\ARMv7\ARMv7Decoder.cpp" />
<ClCompile Include="Emu\ARMv7\ARMv7DisAsm.cpp" />
<ClCompile Include="Emu\ARMv7\ARMv7Interpreter.cpp" />
<ClCompile Include="Emu\ARMv7\ARMv7Thread.cpp" />
@ -266,6 +267,8 @@
<ClInclude Include="Crypto\unself.h" />
<ClInclude Include="Crypto\utils.h" />
<ClInclude Include="define_new_memleakdetect.h" />
<ClInclude Include="Emu\ARMv7\ARMv7Callback.h" />
<ClInclude Include="Emu\ARMv7\ARMv7Context.h" />
<ClInclude Include="Emu\ARMv7\ARMv7Decoder.h" />
<ClInclude Include="Emu\ARMv7\ARMv7DisAsm.h" />
<ClInclude Include="Emu\ARMv7\ARMv7Interpreter.h" />

View File

@ -662,6 +662,9 @@
<ClCompile Include="Emu\Audio\XAudio2\XAudio2Thread.cpp">
<Filter>Emu\Audio\XAudio2</Filter>
</ClCompile>
<ClCompile Include="Emu\ARMv7\ARMv7Decoder.cpp">
<Filter>Emu\CPU\ARMv7</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Crypto\aes.h">
@ -1282,5 +1285,11 @@
<ClInclude Include="Emu\SysCalls\Modules\cellAudio.h">
<Filter>Emu\SysCalls\Modules</Filter>
</ClInclude>
<ClInclude Include="Emu\ARMv7\ARMv7Context.h">
<Filter>Emu\CPU\ARMv7</Filter>
</ClInclude>
<ClInclude Include="Emu\ARMv7\ARMv7Callback.h">
<Filter>Emu\CPU\ARMv7</Filter>
</ClInclude>
</ItemGroup>
</Project>