mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-17 08:11:51 +00:00
ARMv7 decoder reworked (needs more testing / fixes / optimisations). TODO: implement new ARMv7 disassembler (currently ARMv7DisAsm fully disabled), add 0x0 opcodes group.
This commit is contained in:
parent
b736b8616b
commit
c3696f7897
@ -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;
|
||||
}
|
||||
};
|
||||
};
|
@ -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
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user