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; fmt += 2;
len -= 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++; res++;
fmt++; fmt++;
len--; len--;

View file

@ -198,7 +198,7 @@ namespace fmt
{ {
return to_hex(arg, get_fmt_precision(fmt, len)); 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); return to_udec(arg);
} }
@ -220,7 +220,7 @@ namespace fmt
{ {
return to_hex(arg, get_fmt_precision(fmt, len)); 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); return to_udec(arg);
} }
@ -242,7 +242,7 @@ namespace fmt
{ {
return to_hex(arg, get_fmt_precision(fmt, len)); 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); return to_udec(arg);
} }
@ -264,7 +264,7 @@ namespace fmt
{ {
return to_hex(arg, get_fmt_precision(fmt, len)); 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); return to_udec(arg);
} }
@ -418,7 +418,7 @@ namespace fmt
{ {
return to_hex(arg, get_fmt_precision(fmt, len)); 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"; 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<> template<>
struct get_fmt<const char*> 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 std::string format(const char* fmt, size_t len); // terminator
template<typename T, typename... Args> 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> template<size_t N>
struct unveil<const char[N], false> struct unveil<const char[N], false>
{ {
@ -563,11 +502,11 @@ namespace fmt
template<> template<>
struct unveil<std::string, false> 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) __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) float (%x, %f)
double (%x, %f) double (%x, %f)
bool (%x, %d, %s) 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) be_t<> of any appropriate type in this list (fmt::unveil)
enum 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 #pragma once
#include "Emu/CPU/CPUDecoder.h" #include "Emu/CPU/CPUDecoder.h"
#include "ARMv7Thread.h"
#include "ARMv7Interpreter.h" struct ARMv7Context;
#include "ARMv7Opcodes.h"
#include "Utilities/Log.h"
class ARMv7Decoder : public CPUDecoder class ARMv7Decoder : public CPUDecoder
{ {
ARMv7Thread& m_thr; ARMv7Context& m_ctx;
public: public:
ARMv7Decoder(ARMv7Thread& thr) : m_thr(thr) ARMv7Decoder(ARMv7Context& context) : m_ctx(context)
{ {
} }
virtual u8 DecodeMemory(const u32 address) virtual u32 DecodeMemory(const u32 address);
{ };
m_thr.update_code(address & ~1);
// LOG_NOTICE(GENERAL, "code0 = 0x%04x, code1 = 0x%04x, data = 0x%08x", m_thr.code.code0, m_thr.code.code1, m_thr.code.data); void armv7_decoder_initialize(u32 addr, u32 end_addr, bool dump = false);
// 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;
}
};

View file

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

View file

@ -1,5 +1,4 @@
#pragma once #pragma once
#include "Emu/ARMv7/ARMv7Opcodes.h"
#include "Emu/CPU/CPUDisAsm.h" #include "Emu/CPU/CPUDisAsm.h"
static const char* g_arm_cond_name[16] = static const char* g_arm_cond_name[16] =
@ -10,6 +9,14 @@ static const char* g_arm_cond_name[16] =
"gt", "le", "al", "al", "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 class ARMv7DisAsm
: public CPUDisAsm : public CPUDisAsm
{ {
@ -24,6 +31,7 @@ protected:
return (u32)dump_pc + imm; return (u32)dump_pc + imm;
} }
#if 0
std::string GetRegsListString(u16 regs_list) std::string GetRegsListString(u16 regs_list)
{ {
std::string regs_str; std::string regs_str;
@ -316,4 +324,5 @@ protected:
virtual void UXTB(const u32 data, const ARMv7_encoding type); virtual void UXTB(const u32 data, const ARMv7_encoding type);
virtual void UXTB16(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); 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 #pragma once
#if 0
#include "Emu/ARMv7/ARMv7Thread.h" #include "Emu/ARMv7/ARMv7Thread.h"
#include "Emu/ARMv7/ARMv7Interpreter.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; using namespace ARMv7_instrs;
struct ARMv7_Instruction struct ARMv7_Instruction
{ {
void(*func)(ARMv7Thread* thr, const ARMv7_encoding type); void(*func)(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
u8 size; u8 size;
ARMv7_encoding type; ARMv7_encoding type;
const char* name; const char* name;
}; };
#define ARMv7_OP_2(func, type) { func, 2, type, #func "_" #type } #define ARMv7_OP_2(func, type) { func, 2, type, #func "_" #type }
#define ARMv7_OP_4(func, type) { func, 4, type, #func "_" #type } #define ARMv7_OP_4(func, type) { func, 4, type, #func "_" #type }
#define ARMv7_NULL_OP { NULL_OP, 2, T1, "NULL_OP" } #define ARMv7_NULL_OP { NULL_OP, 2, T1, "NULL_OP" }
// 0x1... // 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[] = static const ARMv7_Instruction g_table_0x1_main[] =
{ {
@ -56,7 +45,7 @@ static const ARMv7_Instruction g_table_0x1[] =
{ group_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; u32 index = (thr->code.code0 & 0x0e00) >> 8;
@ -69,7 +58,7 @@ static void group_0x1(ARMv7Thread* thr, const ARMv7_encoding type)
} }
// 0x2... // 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[] = static const ARMv7_Instruction g_table_0x2_main[] =
{ {
@ -89,7 +78,7 @@ static const ARMv7_Instruction g_table_0x2[] =
{ group_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; const u32 index = (thr->code.code0 & 0x0800) >> 8;
thr->m_last_instr_name = g_table_0x2_main[index].name; 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... // 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[] = static const ARMv7_Instruction g_table_0x3_main[] =
{ {
@ -119,7 +108,7 @@ static const ARMv7_Instruction g_table_0x3[] =
{ group_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; const u32 index = (thr->code.code0 & 0x0800) >> 8;
thr->m_last_instr_name = g_table_0x3_main[index].name; 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... // 0x4...
static void group_0x4(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0x4(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0x40(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0x40(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0x41(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0x41(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0x42(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0x42(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0x43(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0x43(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0x44(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0x44(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0x47(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0x47(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static const ARMv7_Instruction g_table_0x4[] = 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 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; const u32 index = (thr->code.code0 & 0x00c0) >> 4;
thr->m_last_instr_name = g_table_0x40[index].name; 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 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; const u32 index = (thr->code.code0 & 0x00c0) >> 4;
thr->m_last_instr_name = g_table_0x41[index].name; 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 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; const u32 index = (thr->code.code0 & 0x00c0) >> 4;
thr->m_last_instr_name = g_table_0x42[index].name; 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 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; const u32 index = (thr->code.code0 & 0x00c0) >> 4;
thr->m_last_instr_name = g_table_0x43[index].name; 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 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; 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 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; const u32 index = (thr->code.code0 & 0x0080) >> 4;
thr->m_last_instr_name = g_table_0x47[index].name; 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 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; u32 index = (thr->code.code0 & 0x0f00) >> 8;
@ -319,7 +308,7 @@ static void group_0x4(ARMv7Thread* thr, const ARMv7_encoding type)
} }
// 0x5... // 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[] = static const ARMv7_Instruction g_table_0x5_main[] =
{ {
@ -345,7 +334,7 @@ static const ARMv7_Instruction g_table_0x5[] =
{ group_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; const u32 index = (thr->code.code0 & 0x0e00) >> 8;
thr->m_last_instr_name = g_table_0x5_main[index].name; 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... // 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[] = static const ARMv7_Instruction g_table_0x6_main[] =
{ {
@ -375,7 +364,7 @@ static const ARMv7_Instruction g_table_0x6[] =
{ group_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; const u32 index = (thr->code.code0 & 0x0800) >> 8;
thr->m_last_instr_name = g_table_0x6_main[index].name; 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... // 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[] = static const ARMv7_Instruction g_table_0x7_main[] =
{ {
@ -405,7 +394,7 @@ static const ARMv7_Instruction g_table_0x7[] =
{ group_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; const u32 index = (thr->code.code0 & 0x0800) >> 8;
thr->m_last_instr_name = g_table_0x7_main[index].name; 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... // 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[] = static const ARMv7_Instruction g_table_0x8_main[] =
{ {
@ -427,7 +416,7 @@ static const ARMv7_Instruction g_table_0x8[] =
{ group_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; const u32 index = (thr->code.code0 & 0x0800) >> 8;
thr->m_last_instr_name = g_table_0x8_main[index].name; 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... // 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[] = static const ARMv7_Instruction g_table_0x9_main[] =
{ {
@ -457,7 +446,7 @@ static const ARMv7_Instruction g_table_0x9[] =
{ group_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; const u32 index = (thr->code.code0 & 0x0800) >> 8;
thr->m_last_instr_name = g_table_0x9_main[index].name; 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... // 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[] = static const ARMv7_Instruction g_table_0xa_main[] =
{ {
@ -487,7 +476,7 @@ static const ARMv7_Instruction g_table_0xa[] =
{ group_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; u32 index = (thr->code.code0 & 0x0800) >> 8;
thr->m_last_instr_name = g_table_0xa_main[index].name; 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... // 0xb...
static void group_0xb(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xb(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xb0(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xb0(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xba(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xba(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static const ARMv7_Instruction g_table_0xb0[] = 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 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; const u32 index = (thr->code.code0 & 0x0080) >> 4;
thr->m_last_instr_name = g_table_0xb0[index].name; 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 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 const u32 index = (thr->code.code0 & 0x00c0) >> 4; // mask 0xffc0
thr->m_last_instr_name = g_table_0xba[index].name; thr->m_last_instr_name = g_table_0xba[index].name;
@ -575,7 +564,7 @@ static const ARMv7_Instruction g_table_0xb[] =
{ group_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; u32 index = (thr->code.code0 & 0x0e00) >> 8;
@ -591,7 +580,7 @@ static void group_0xb(ARMv7Thread* thr, const ARMv7_encoding type)
} }
// 0xc... // 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[] = static const ARMv7_Instruction g_table_0xc_main[] =
{ {
@ -611,7 +600,7 @@ static const ARMv7_Instruction g_table_0xc[] =
{ group_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; const u32 index = (thr->code.code0 & 0x0800) >> 8;
thr->m_last_instr_name = g_table_0xc_main[index].name; 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... // 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[] = static const ARMv7_Instruction g_table_0xd_main[] =
{ {
@ -648,7 +637,7 @@ static const ARMv7_Instruction g_table_0xd[] =
{ group_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; //u32 index = (thr->code.code0 & 0x0f00) >> 8;
//if ((thr->code.code0 & 0xf000) == 0xd000) index = 0; //if ((thr->code.code0 & 0xf000) == 0xd000) index = 0;
@ -661,19 +650,19 @@ static void group_0xd(ARMv7Thread* thr, const ARMv7_encoding type)
} }
// 0xe... // 0xe...
static void group_0xe(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xe(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xe85(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xe85(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xe8(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xe8(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xe9(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xe9(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xea(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xea(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xea4(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xea4(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xea4f(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xea4f(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xea4f0000(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xea4f0000(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xea4f0030(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xea4f0030(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xea6(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xea6(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xeb(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xeb(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xeb0(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xeb0(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xeba(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xeba(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static const ARMv7_Instruction g_table_0xe85[] = 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 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; //u32 index = thr->code.code0 & 0x000f;
//if ((thr->code.code0 & 0xfe50) == 0xe850) index = 0x0; //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 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; 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 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; u32 index = (thr->code.code0 & 0x00d0) >> 4;
@ -779,7 +768,7 @@ static const ARMv7_Instruction g_table_0xea4[] =
{ group_0xea4f } // F { 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; u32 index = 0x0;
if ((thr->code.code0 & 0xffef) == 0xea4f) index = 0xf; // check me if ((thr->code.code0 & 0xffef) == 0xea4f) index = 0xf; // check me
@ -798,7 +787,7 @@ static const ARMv7_Instruction g_table_0xea4f[] =
{ group_0xea4f0030 } // 3 { 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; const u32 index = (thr->code.code1 & 0x0030) >> 4;
thr->m_last_instr_name = g_table_0xea4f[index].name; 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 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; const u32 index = thr->code.code1 & 0x8030 ? 0x0 : 0x1;
thr->m_last_instr_name = g_table_0xea4f0000[index].name; 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 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; const u32 index = thr->code.code1 & 0x8030 ? 0x0 : 0x1;
thr->m_last_instr_name = g_table_0xea4f0030[index].name; 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 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; 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 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; 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 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; 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 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; 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 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; u32 index = (thr->code.code0 & 0x00e0) >> 4;
@ -1015,7 +1004,7 @@ static const ARMv7_Instruction g_table_0xe[] =
{ group_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; u32 index = (thr->code.code0 & 0x0f00) >> 8;
@ -1028,36 +1017,36 @@ static void group_0xe(ARMv7Thread* thr, const ARMv7_encoding type)
} }
// 0xf... // 0xf...
static void group_0xf(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf000(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf000(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf04(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf04(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf06(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf06(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf0(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf0(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf1(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf1(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf1a(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf1a(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf10(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf10(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf20(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf20(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf2a(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf2a(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf2(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf2(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf36(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf36(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf3(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf3(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf810(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf810(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf800(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf800(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf81(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf81(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf820(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf820(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf840(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf840(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf84(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf84(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf850(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf850(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf85(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf85(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf8(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf8(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf910(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf910(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf91(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf91(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf930(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf930(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf93(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf93(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xf9(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xf9(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xfa00(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xfa00(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xfa90(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xfa90(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static void group_0xfa(ARMv7Thread* thr, const ARMv7_encoding type); static void group_0xfa(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type);
static const ARMv7_Instruction g_table_0xf000[] = 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 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; 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 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; 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 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; 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; u32 index = 0;
if ((thr->m_arg & 0xfbe08000) == 0xf0000000) index = 0x0; 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 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; 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 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; 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 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; 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 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; 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 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; 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 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 const u32 index = (thr->code.code0 & 0x00f0) >> 4; // mask 0xfbf0
thr->m_last_instr_name = g_table_0xf2[index].name; 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 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; 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 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; const u32 index = (thr->code.code0 & 0x00f0) >> 4;
thr->m_last_instr_name = g_table_0xf3[index].name; 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 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; 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 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; 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 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; 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 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; 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 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; 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 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; 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 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; 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 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; 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 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; const u32 index = (thr->code.code0 & 0x00f0) >> 4;
thr->m_last_instr_name = g_table_0xf8[index].name; 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 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; 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 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; 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 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; 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 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; 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 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; 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 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; const u32 index = (thr->code.code1 & 0xf0f0) == 0xf000 ? 0xf : 0x0;
thr->m_last_instr_name = g_table_0xfa00[index].name; 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 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; const u32 index = (thr->code.code1 & 0x00f0) >> 4;
thr->m_last_instr_name = g_table_0xfa90[index].name; 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 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; 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; 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_2
#undef ARMv7_OP_4 #undef ARMv7_OP_4
#undef ARMv7_NULL_OP #undef ARMv7_NULL_OP
#endif

View file

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

View file

@ -1,147 +1,24 @@
#pragma once #pragma once
#include "Emu/CPU/CPUThread.h" #include "Emu/CPU/CPUThread.h"
#include "Emu/Memory/Memory.h" #include "Emu/Memory/Memory.h"
#include "ARMv7Context.h"
enum ARMv7InstructionSet
{
ARM,
Thumb,
Jazelle,
ThumbEE
};
class ARMv7Thread : public CPUThread class ARMv7Thread : public CPUThread
{ {
public: public:
u32 m_arg; ARMv7Context context;
u8 m_last_instr_size; //u32 m_arg;
const char* m_last_instr_name; //u8 m_last_instr_size;
//const char* m_last_instr_name;
ARMv7Thread(); ARMv7Thread();
union //void update_code(const u32 address)
{ //{
u32 GPR[15]; // code.code0 = vm::psv::read16(address & ~1);
// code.code1 = vm::psv::read16(address + 2 & ~1);
struct // m_arg = address & 0x1 ? code.code1 << 16 | code.code0 : code.data;
{ //}
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;
}
public: public:
virtual void InitRegs(); virtual void InitRegs();
@ -209,131 +86,3 @@ public:
return *this; 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 "stdafx.h"
#include "Emu/System.h" #include "Emu/System.h"
#include "Emu/Memory/Memory.h" #include "Emu/Memory/Memory.h"
#include "Emu/ARMv7/PSVFuncList.h"
#include "Emu/CPU/CPUThreadManager.h" #include "Emu/CPU/CPUThreadManager.h"
#include "Emu/ARMv7/ARMv7Thread.h" #include "Emu/ARMv7/ARMv7Thread.h"
#include "Emu/ARMv7/PSVFuncList.h"
extern psv_log_base sceLibKernel; extern psv_log_base sceLibKernel;
@ -86,7 +87,7 @@ struct SceKernelSystemInfo
#pragma pack(pop) #pragma pack(pop)
s32 sceKernelCreateThread( u32 sceKernelCreateThread(
vm::psv::ptr<const char> pName, vm::psv::ptr<const char> pName,
vm::psv::ptr<SceKernelThreadEntry> entry, vm::psv::ptr<SceKernelThreadEntry> entry,
s32 initPriority, s32 initPriority,
@ -100,24 +101,21 @@ s32 sceKernelCreateThread(
ARMv7Thread& new_thread = static_cast<ARMv7Thread&>(Emu.GetCPU().AddThread(CPU_THREAD_ARMv7)); 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.SetEntry(entry.addr() ^ 1);
new_thread.SetPrio(initPriority); new_thread.SetPrio(initPriority);
new_thread.SetStackSize(stackSize); new_thread.SetStackSize(stackSize);
new_thread.SetName(pName.get_ptr()); 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(); new_thread.Run();
Emu.Pause();
return id; 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); 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); ARMv7Thread& thread = static_cast<ARMv7Thread&>(*t);
// push arg block onto the stack // 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); memcpy(vm::get_ptr<void>(pos), pArgBlock.get_ptr(), argSize);
// set SceKernelThreadEntry function arguments // set SceKernelThreadEntry function arguments
thread.write_gpr(0, argSize); thread.context.GPR[0] = argSize;
thread.write_gpr(1, pos); thread.context.GPR[1] = pos;
thread.Exec(); thread.Exec();
return SCE_OK; return SCE_OK;
} }
s32 sceKernelExitThread(ARMv7Thread& CPU, s32 exitStatus) s32 sceKernelExitThread(ARMv7Context& context, s32 exitStatus)
{ {
sceLibKernel.Error("sceKernelExitThread(exitStatus=0x%x)", exitStatus); sceLibKernel.Error("sceKernelExitThread(exitStatus=0x%x)", exitStatus);
// exit status is stored in r0 // exit status is stored in r0
CPU.Stop(); context.thread.Stop();
return SCE_OK; 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; return SCE_OK;
} }
@ -164,21 +162,21 @@ s32 sceKernelExitDeleteThread(s32 exitStatus)
return SCE_OK; 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; return SCE_OK;
} }
s32 sceKernelGetThreadCpuAffinityMask(s32 threadId) s32 sceKernelGetThreadCpuAffinityMask(u32 threadId)
{ {
sceLibKernel.Todo("sceKernelGetThreadCpuAffinityMask(threadId=0x%x)", threadId); sceLibKernel.Todo("sceKernelGetThreadCpuAffinityMask(threadId=0x%x)", threadId);
return SCE_OK; 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); sceLibKernel.Todo("sceKernelChangeThreadPriority(threadId=0x%x, priority=%d)", threadId, priority);
@ -192,11 +190,11 @@ s32 sceKernelGetThreadCurrentPriority()
return SCE_OK; 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) s32 sceKernelChangeCurrentThreadAttr(u32 clearAttr, u32 setAttr)
@ -206,9 +204,9 @@ s32 sceKernelChangeCurrentThreadAttr(u32 clearAttr, u32 setAttr)
return SCE_OK; 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; return SCE_OK;
} }
@ -227,9 +225,9 @@ s32 sceKernelCheckWaitableStatus()
return SCE_OK; 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; return SCE_OK;
} }
@ -250,7 +248,7 @@ s32 sceKernelGetSystemInfo(vm::psv::ptr<SceKernelSystemInfo> pInfo)
s32 sceKernelGetThreadmgrUIDClass(s32 uid) s32 sceKernelGetThreadmgrUIDClass(s32 uid)
{ {
sceLibKernel.Todo("sceKernelGetThreadmgrUIDClass(uid=%d)", uid); sceLibKernel.Todo("sceKernelGetThreadmgrUIDClass(uid=0x%x)", uid);
return SCE_OK; return SCE_OK;
} }
@ -283,24 +281,56 @@ s32 sceKernelDelayThreadCB(u32 usec)
return SCE_OK; 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; 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; return SCE_OK;
} }
#define REG_FUNC(nid, name) reg_psv_func(nid, &sceLibKernel, #name, &name) #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(0x23EAA62, sceKernelPuts);
//REG_FUNC(0xB0335388, sceClibToupper); //REG_FUNC(0xB0335388, sceClibToupper);
//REG_FUNC(0x4C5471BC, sceClibTolower); //REG_FUNC(0x4C5471BC, sceClibTolower);
@ -665,6 +695,4 @@ psv_log_base sceLibKernel = []() -> psv_log_base
/* SceDebugLed */ /* SceDebugLed */
//REG_FUNC(0x78E702D3, sceKernelSetGPO); //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 "Utilities/Log.h"
#include "Emu/System.h" #include "Emu/System.h"
#include "Emu/Memory/Memory.h" #include "Emu/Memory/Memory.h"
#include "Emu/ARMv7/PSVFuncList.h" #include "Emu/ARMv7/PSVFuncList.h"
#include "Emu/ARMv7/ARMv7Callback.h"
extern psv_log_base sceLibc; 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 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__); sceLibc.Error("__cxa_atexit(func=0x%x, arg=0x%x, dso=0x%x)", func, arg, dso);
Emu.Pause();
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()"); sceLibc.Error("exit()");
Emu.Pause();
for (auto func : g_atexit)
{
func(context);
}
g_atexit.clear();
sceLibc.Success("Process finished"); sceLibc.Success("Process finished");
CallAfter([]() CallAfter([]()
{ {
Emu.Stop(); 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); 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) 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); ::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) 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); 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) #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(0xE4531F85, _Assert);
//REG_FUNC(0xE71C5CDE, _Stoul); //REG_FUNC(0xE71C5CDE, _Stoul);
//REG_FUNC(0x7A5CA6A3, _Stoulx); //REG_FUNC(0x7A5CA6A3, _Stoulx);
@ -147,7 +262,7 @@ psv_log_base sceLibc = []() -> psv_log_base
//REG_FUNC(0x395490DA, setbuf); //REG_FUNC(0x395490DA, setbuf);
//REG_FUNC(0x2CA980A0, setvbuf); //REG_FUNC(0x2CA980A0, setvbuf);
//REG_FUNC(0xA1BFF606, snprintf); //REG_FUNC(0xA1BFF606, snprintf);
//REG_FUNC(0x7449B359, sprintf); REG_FUNC(0x7449B359, sprintf);
//REG_FUNC(0xEC585241, sscanf); //REG_FUNC(0xEC585241, sscanf);
//REG_FUNC(0x2BCB3F01, ungetc); //REG_FUNC(0x2BCB3F01, ungetc);
//REG_FUNC(0xF7915685, vfprintf); //REG_FUNC(0xF7915685, vfprintf);
@ -200,7 +315,7 @@ psv_log_base sceLibc = []() -> psv_log_base
//REG_FUNC(0x7747F6D7, memcmp); //REG_FUNC(0x7747F6D7, memcmp);
REG_FUNC(0x7205BFDB, memcpy); REG_FUNC(0x7205BFDB, memcpy);
//REG_FUNC(0xAF5C218D, memmove); //REG_FUNC(0xAF5C218D, memmove);
//REG_FUNC(0x6DC1F0D8, memset); REG_FUNC(0x6DC1F0D8, memset);
//REG_FUNC(0x1434FA46, strcat); //REG_FUNC(0x1434FA46, strcat);
//REG_FUNC(0xB9336E16, strchr); //REG_FUNC(0xB9336E16, strchr);
//REG_FUNC(0x1B58FA3B, strcmp); //REG_FUNC(0x1B58FA3B, strcmp);
@ -317,7 +432,7 @@ psv_log_base sceLibc = []() -> psv_log_base
//REG_FUNC(0x9D885076, _Towctrans); //REG_FUNC(0x9D885076, _Towctrans);
//REG_FUNC(0xE980110A, _Iswctype); //REG_FUNC(0xE980110A, _Iswctype);
REG_FUNC(0x33b83b70, __cxa_atexit); REG_FUNC(0x33b83b70, __cxa_atexit);
//REG_FUNC(0xEDC939E1, __aeabi_atexit); REG_FUNC(0xEDC939E1, __aeabi_atexit);
//REG_FUNC(0xB538BF48, __cxa_finalize); //REG_FUNC(0xB538BF48, __cxa_finalize);
//REG_FUNC(0xD0310E31, __cxa_guard_acquire); //REG_FUNC(0xD0310E31, __cxa_guard_acquire);
//REG_FUNC(0x4ED1056F, __cxa_guard_release); //REG_FUNC(0x4ED1056F, __cxa_guard_release);
@ -350,6 +465,4 @@ psv_log_base sceLibc = []() -> psv_log_base
//REG_FUNC(0x677CDE35, _Snan); //REG_FUNC(0x677CDE35, _Snan);
//REG_FUNC(0x7D35108B, _FSnan); //REG_FUNC(0x7D35108B, _FSnan);
//REG_FUNC(0x48AEEF2A, _LSnan); //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) #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(0xC73FE76D, _Exp);
//REG_FUNC(0xFF4EAE04, _FExp); //REG_FUNC(0xFF4EAE04, _FExp);
//REG_FUNC(0xB363D7D4, _LExp); //REG_FUNC(0xB363D7D4, _LExp);
@ -212,6 +216,4 @@ psv_log_base sceLibm = []() -> psv_log_base
//REG_FUNC(0x5BD0F71C, _Dsign); //REG_FUNC(0x5BD0F71C, _Dsign);
//REG_FUNC(0xC4F7E42C, _FDsign); //REG_FUNC(0xC4F7E42C, _FDsign);
//REG_FUNC(0x1DF73D2B, _LDsign); //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) #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(0x52B0C625, std::bad_typeid::what() const);
//REG_FUNC(0x64D7D074, std::bad_typeid::_Doraise() const); //REG_FUNC(0x64D7D074, std::bad_typeid::_Doraise() const);
//REG_FUNC(0x15FB88E2, std::logic_error::what() 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(0x7321E731, vtable for __cxxabiv1::__vmi_class_type_info);
//REG_FUNC(0x33836375, vtable for __cxxabiv1::__fundamental_type_info); //REG_FUNC(0x33836375, vtable for __cxxabiv1::__fundamental_type_info);
//REG_FUNC(0x94664DEB, vtable for __cxxabiv1::__pointer_to_member_type_info); //REG_FUNC(0x94664DEB, vtable for __cxxabiv1::__pointer_to_member_type_info);
});
return psv_log_base("SceLibstdcxx");
}();
/* /*
// original names // original names

View file

@ -1,29 +1,12 @@
#include "stdafx.h" #include "stdafx.h"
#include <unordered_map> #include "ARMv7Thread.h"
#include "Utilities/Log.h"
#include "Emu/System.h"
#include "PSVFuncList.h" #include "PSVFuncList.h"
std::vector<psv_func> g_psv_func_list; std::vector<psv_func> g_psv_func_list;
std::vector<psv_log_base*> g_psv_modules;
void add_psv_func(psv_func& data) 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); g_psv_func_list.push_back(data);
} }
@ -49,16 +32,16 @@ u32 get_psv_func_index(psv_func* func)
return (u32)res; 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()); assert(index < g_psv_func_list.size());
auto old_last_syscall = CPU.m_last_syscall; auto old_last_syscall = context.thread.m_last_syscall;
CPU.m_last_syscall = g_psv_func_list[index].nid; 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; extern psv_log_base sceLibc;
@ -66,10 +49,53 @@ extern psv_log_base sceLibm;
extern psv_log_base sceLibstdcxx; extern psv_log_base sceLibstdcxx;
extern psv_log_base sceLibKernel; extern psv_log_base sceLibKernel;
void list_known_psv_modules() void initialize_psv_modules()
{ {
sceLibc.Log(""); assert(!g_psv_func_list.size() && !g_psv_modules.size());
sceLibm.Log("");
sceLibstdcxx.Log(""); // fill module list
sceLibKernel.Log(""); 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 #pragma once
#include "ARMv7Thread.h" #include "ARMv7Context.h"
#include "Emu/SysCalls/LogBase.h" #include "Emu/SysCalls/LogBase.h"
class psv_log_base : public LogBase class psv_log_base : public LogBase
{ {
std::string m_name; std::string m_name;
void(*m_init_func)();
public: 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_name(name)
, m_init_func(init_func)
{ {
} }
void Init()
{
m_init_func();
}
virtual const std::string& GetName() const override virtual const std::string& GetName() const override
{ {
return m_name; return m_name;
@ -401,7 +413,7 @@ enum psv_error_codes
class psv_func_caller class psv_func_caller
{ {
public: public:
virtual void operator()(ARMv7Thread& CPU) = 0; virtual void operator()(ARMv7Context& CPU) = 0;
virtual ~psv_func_caller(){}; virtual ~psv_func_caller(){};
}; };
@ -415,6 +427,8 @@ namespace psv_func_detail
ARG_STACK, 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> template<typename T, bind_arg_type type, int g_count, int f_count, int v_count>
struct bind_arg; struct bind_arg;
@ -423,9 +437,14 @@ namespace psv_func_detail
{ {
static_assert(sizeof(T) <= 4, "Invalid function argument type for ARG_GENERAL"); 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(f_count <= 0, "TODO: Unsupported argument type (float)");
static_assert(sizeof(T) <= 8, "Invalid function argument type for ARG_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(v_count <= 0, "TODO: Unsupported argument type (vector)");
static_assert(std::is_same<T, u128>::value, "Invalid function argument type for ARG_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(v_count <= 0, "TODO: Unsupported stack argument type (vector)");
static_assert(sizeof(T) <= 4, "Invalid function argument type for ARG_STACK"); 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 // TODO: check
const u32 res = CPU.GetStackArg(g_count); return cast_from_armv7_gpr<T>(context.get_stack_arg(g_count));
return cast_from_armv7_gpr<T>(res); }
__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(type == ARG_GENERAL, "Wrong use of bind_result template");
static_assert(sizeof(T) <= 4, "Invalid function result type for ARG_GENERAL"); 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_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_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> template <typename RT, typename F, typename Tuple, bool Done, int Total, int... N>
struct call_impl struct call_impl
{ {
@ -526,39 +592,45 @@ namespace psv_func_detail
} }
template<int g_count, int f_count, int v_count> 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 // terminator
return std::tuple<>(); return std::tuple<>();
} }
template<int g_count, int f_count, int v_count, typename T, typename... A> 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)"); typedef arg_type<T, g_count, f_count, v_count> type;
static_assert(!std::is_reference<T>::value, "Invalid function argument type (reference)"); const bind_arg_type t = type::value;
// TODO: check calculations const int g = type::g_value;
const bool is_float = std::is_floating_point<T>::value; const int f = type::f_value;
const bool is_vector = std::is_same<T, u128>::value; const int v = type::v_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);
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> template<int g_count, int f_count, int v_count>
struct result_type __forceinline static bool put_func_args(ARMv7Context& context)
{ {
static_assert(!std::is_pointer<RT>::value, "Invalid function result type (pointer)"); // terminator
static_assert(!std::is_reference<RT>::value, "Invalid function result type (reference)"); return false;
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<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> template<typename RT, typename... T>
class func_binder; 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> 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; const func_t m_call;
public: 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> 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; const func_t m_call;
public: 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); psv_func* get_psv_func_by_nid(u32 nid);
u32 get_psv_func_index(psv_func* func); u32 get_psv_func_index(psv_func* func);
void execute_psv_func_by_index(ARMv7Thread& CPU, u32 index); void execute_psv_func_by_index(ARMv7Context& context, u32 index);
void list_known_psv_modules(); void initialize_psv_modules();
void finalize_psv_modules();

View file

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

View file

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

View file

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

View file

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

View file

@ -5,9 +5,9 @@
class PPCDecoder : public CPUDecoder class PPCDecoder : public CPUDecoder
{ {
public: 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; 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); ExecuteFunction(&m_ppu, 0);
return 0; return 0;
} }

View file

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

View file

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

View file

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

View file

@ -70,7 +70,7 @@ namespace vm
const u32 res = static_cast<u32>(addr); const u32 res = static_cast<u32>(addr);
if (res != 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; return res;

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
class CPUThread; class CPUThread;
struct ARMv7Context;
namespace vm namespace vm
{ {
@ -332,9 +333,11 @@ namespace vm
public: public:
typedef RT(*type)(T...); 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 AT addr() const
{ {

View file

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

View file

@ -6,6 +6,7 @@
#include "ELF32.h" #include "ELF32.h"
#include "Emu/Cell/SPUThread.h" #include "Emu/Cell/SPUThread.h"
#include "Emu/ARMv7/ARMv7Thread.h" #include "Emu/ARMv7/ARMv7Thread.h"
#include "Emu/ARMv7/ARMv7Decoder.h"
#include "Emu/ARMv7/PSVFuncList.h" #include "Emu/ARMv7/PSVFuncList.h"
#include "Emu/System.h" #include "Emu/System.h"
@ -89,7 +90,7 @@ namespace loader
case MACHINE_MIPS: break; case MACHINE_MIPS: break;
case MACHINE_ARM: 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)); 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) 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 entry = 0; // actual entry point (ELFs entry point is ignored)
u32 fnid_addr = 0; u32 fnid_addr = 0;
u32 code_start = 0;
// load section names u32 code_end = 0;
//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);
//}
for (auto& shdr : m_shdrs) for (auto& shdr : m_shdrs)
{ {
@ -125,7 +117,14 @@ namespace loader
name.push_back(c); 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..."); LOG_NOTICE(LOADER, ".sceModuleInfo.rodata analysis...");
@ -190,6 +189,8 @@ namespace loader
vm::psv::write16(addr + 2, 0); // index 0 (unimplemented stub) vm::psv::write16(addr + 2, 0); // index 0 (unimplemented stub)
vm::psv::write32(addr + 4, nid); // nid vm::psv::write32(addr + 4, nid); // nid
} }
code_end = std::min<u32>(addr, code_end);
} }
} }
else if (!strcmp(name.c_str(), ".sceRefs.rodata")) else if (!strcmp(name.c_str(), ".sceRefs.rodata"))
@ -214,6 +215,7 @@ namespace loader
const u32 addr = *++code; const u32 addr = *++code;
vm::psv::write16(addr + 0, 0xf240 | (data & 0x800) >> 1 | (data & 0xf000) >> 12); // MOVW vm::psv::write16(addr + 0, 0xf240 | (data & 0x800) >> 1 | (data & 0xf000) >> 12); // MOVW
vm::psv::write16(addr + 2, 0x0c00 | (data & 0x700) << 4 | (data & 0xff)); 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; break;
} }
case 0x00000030: case 0x00000030:
@ -222,22 +224,26 @@ namespace loader
const u32 addr = *++code; const u32 addr = *++code;
vm::psv::write16(addr + 0, 0xf2c0 | (data & 0x8000000) >> 17 | (data & 0xf0000000) >> 28); // MOVT 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); 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; break;
} }
case 0x00000000: case 0x00000000:
{ {
// probably, no operation // probably, no operation
LOG_NOTICE(LOADER, "sceRefs: zero code");
break; break;
} }
default: 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(); arm7_thread(entry & ~1 /* TODO: Thumb/ARM encoding selection */, "main_thread").args({ Emu.GetPath()/*, "-emu"*/ }).run();
break; break;
} }

View file

@ -516,7 +516,7 @@ namespace loader
if (module && !module->Load(nid)) 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()) else //if (Ini.HLELogging.GetValue())
{ {

View file

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

View file

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