Merge pull request #881 from O1L/master

ARMv7 decoder reworked.
This commit is contained in:
B1ackDaemon
2014-12-10 13:47:26 +02:00
11 changed files with 3628 additions and 1806 deletions
+27 -14
View File
@@ -1,35 +1,48 @@
#pragma once
#include "Emu/CPU/CPUDecoder.h"
#include "ARMv7Opcodes.h"
#include "Emu/CPU/CPUDecoder.h"
#include "ARMv7Thread.h"
#include "ARMv7Interpreter.h"
#include "ARMv7Opcodes.h"
#include "Utilities/Log.h"
class ARMv7Decoder : public CPUDecoder
{
ARMv7Opcodes& m_op;
u8 m_last_instr_size;
ARMv7Thread& m_thr;
public:
ARMv7Decoder(ARMv7Opcodes& op) : m_op(op)
ARMv7Decoder(ARMv7Thread& thr) : m_thr(thr)
{
}
virtual u8 DecodeMemory(const u32 address)
{
const u32 code0 = vm::psv::read16(address & ~1);
const u32 code1 = vm::psv::read16(address + 2 & ~1);
const u32 data = code0 << 16 | code1;
const u32 arg = address & 1 ? code1 << 16 | code0 : data;
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);
// 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 & 1) == 0) && (arg & opcode.mask) == opcode.code)
if ((opcode.type < A1) == ((address & 0x1) == 0) && (m_thr.m_arg & opcode.mask) == opcode.code)
{
(m_op.*opcode.func)(opcode.length == 2 ? code0 : arg, opcode.type);
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;
}
}
m_op.UNK(data);
return address & 1 ? 4 : 2;
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;
}
};
};
+1 -2
View File
@@ -12,10 +12,9 @@ static const char* g_arm_cond_name[16] =
class ARMv7DisAsm
: public CPUDisAsm
, public ARMv7Opcodes
{
public:
ARMv7DisAsm(CPUDisAsmMode mode) : CPUDisAsm(mode)
ARMv7DisAsm() : CPUDisAsm(CPUDisAsm_InterpreterMode)
{
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+6 -2
View File
@@ -10,7 +10,11 @@
#include "ARMv7DisAsm.h"
#include "ARMv7Interpreter.h"
ARMv7Thread::ARMv7Thread() : CPUThread(CPU_THREAD_ARMv7)
ARMv7Thread::ARMv7Thread()
: CPUThread(CPU_THREAD_ARMv7)
, m_arg(0)
, m_last_instr_size(0)
, m_last_instr_name("UNK")
{
}
@@ -81,7 +85,7 @@ void ARMv7Thread::DoRun()
case 1:
case 2:
m_dec = new ARMv7Decoder(*new ARMv7Interpreter(*this));
m_dec = new ARMv7Decoder(*this);
break;
}
}
+26 -1
View File
@@ -1,17 +1,23 @@
#pragma once
#include "Emu/CPU/CPUThread.h"
#include "Emu/Memory/Memory.h"
enum ARMv7InstructionSet
{
ARM,
Thumb,
Jazelle,
ThumbEE,
ThumbEE
};
class ARMv7Thread : public CPUThread
{
public:
u32 m_arg;
u8 m_last_instr_size;
const char* m_last_instr_name;
ARMv7Thread();
union
@@ -61,6 +67,18 @@ public:
} IPSR;
union
{
struct
{
u32 code1 : 16;
u32 code0 : 16;
};
u32 data;
} code;
ARMv7InstructionSet ISET;
union
@@ -119,6 +137,13 @@ public:
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:
virtual void InitRegs();
virtual void InitStack();
+5 -4
View File
@@ -112,7 +112,8 @@ void InterpreterDisAsmFrame::UpdateUnitList()
for(uint i=0; i<thrs.size(); ++i)
{
m_choice_units->Append(thrs[i]->GetFName(), thrs[i]);
if (thrs[i]->GetType() != CPU_THREAD_ARMv7)
m_choice_units->Append(thrs[i]->GetFName(), thrs[i]);
}
m_choice_units->Thaw();
@@ -150,9 +151,9 @@ void InterpreterDisAsmFrame::OnSelectUnit(wxCommandEvent& event)
case CPU_THREAD_ARMv7:
{
ARMv7DisAsm& dis_asm = *new ARMv7DisAsm(CPUDisAsm_InterpreterMode);
decoder = new ARMv7Decoder(dis_asm);
disasm = &dis_asm;
//ARMv7DisAsm& dis_asm = *new ARMv7DisAsm(CPUDisAsm_InterpreterMode);
//decoder = new ARMv7Decoder(dis_asm);
//disasm = &dis_asm;
}
break;
}
-1
View File
@@ -118,7 +118,6 @@ void KernelExplorer::Update()
const auto& node = m_tree->AppendItem(root, name);
const auto& objects = Emu.GetIdManager().GetTypeIDs(TYPE_LWCOND);
u32 index = 0;
for (const auto& id : objects)
{
sprintf(name, "LW Condition Variable: ID = 0x%08x '%s'", id, Emu.GetSyncPrimManager().GetSyncPrimName(TYPE_LWCOND, id).c_str());
+7 -2
View File
@@ -10,14 +10,19 @@ namespace loader
{
for (auto i : m_handlers)
{
if (i->init(stream) == handler::ok)
i->set_status(i->init(stream));
if (i->get_status() == handler::ok)
{
if (i->load() == handler::ok)
i->set_status(i->load());
if (i->get_status() == handler::ok)
{
return true;
}
LOG_ERROR(LOADER, "loader::load() failed: %s", i->get_error_code().c_str());
}
LOG_ERROR(LOADER, "loader::init() failed: %s", i->get_error_code().c_str());
stream.Seek(i->get_stream_offset());
}
+32 -4
View File
@@ -15,7 +15,7 @@ enum Elf_Machine
MACHINE_MIPS = 0x08,
MACHINE_PPC64 = 0x15,
MACHINE_SPU = 0x17,
MACHINE_ARM = 0x28,
MACHINE_ARM = 0x28
};
enum ShdrType
@@ -31,7 +31,7 @@ enum ShdrType
SHT_NOBITS,
SHT_REL,
SHT_SHLIB,
SHT_DYNSYM,
SHT_DYNSYM
};
enum ShdrFlag
@@ -39,7 +39,7 @@ enum ShdrFlag
SHF_WRITE = 0x1,
SHF_ALLOC = 0x2,
SHF_EXECINSTR = 0x4,
SHF_MASKPROC = 0xf0000000,
SHF_MASKPROC = 0xf0000000
};
const std::string Ehdr_DataToString(const u8 data);
@@ -117,7 +117,7 @@ namespace loader
broken_file = -3,
loading_error = -4,
bad_relocation_type = -5,
ok = 0,
ok = 0
};
virtual ~handler() = default;
@@ -128,6 +128,34 @@ namespace loader
{
return m_stream_offset;
}
void set_status(const error_code& code)
{
m_status = code;
}
error_code get_status() const
{
return m_status;
}
const std::string get_error_code() const
{
switch (m_status)
{
case bad_version: return "Bad version";
case bad_file: return "Bad file";
case broken_file: return "Broken file";
case loading_error: return "Loading error";
case bad_relocation_type: return "Bad relocation type";
case ok: return "Ok";
default: return "Unknown error code";
}
}
protected:
error_code m_status;
};
class loader