2013-11-05 19:12:18 +01:00
|
|
|
#pragma once
|
|
|
|
|
#include "Emu/CPU/CPUDecoder.h"
|
2013-11-05 20:22:58 +01:00
|
|
|
#include "ARMv7Opcodes.h"
|
2013-11-05 19:12:18 +01:00
|
|
|
|
|
|
|
|
|
2013-11-05 20:22:58 +01:00
|
|
|
class ARMv7Decoder : public CPUDecoder
|
2013-11-05 19:12:18 +01:00
|
|
|
{
|
2013-11-05 20:22:58 +01:00
|
|
|
ARMv7Opcodes& m_op;
|
|
|
|
|
u8 m_last_instr_size;
|
2013-11-05 19:12:18 +01:00
|
|
|
|
|
|
|
|
public:
|
2013-11-05 20:22:58 +01:00
|
|
|
ARMv7Decoder(ARMv7Opcodes& op) : m_op(op)
|
2013-11-05 19:12:18 +01:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-15 00:17:24 +02:00
|
|
|
virtual u8 DecodeMemory(const u32 address)
|
2013-11-05 19:12:18 +01:00
|
|
|
{
|
2014-10-29 05:13:34 +01:00
|
|
|
const u32 code0 = vm::psv::read16(address & ~1);
|
|
|
|
|
const u32 code1 = vm::psv::read16(address + 2 & ~1);
|
|
|
|
|
const u32 data = code0 << 16 | code1;
|
2014-10-31 02:12:07 +01:00
|
|
|
const u32 arg = address & 1 ? code1 << 16 | code0 : data;
|
2013-11-05 19:12:18 +01:00
|
|
|
|
2014-10-29 05:13:34 +01:00
|
|
|
for (auto& opcode : ARMv7_opcode_table)
|
2013-11-05 19:12:18 +01:00
|
|
|
{
|
2014-10-31 02:12:07 +01:00
|
|
|
if ((opcode.type < A1) == ((address & 1) == 0) && (arg & opcode.mask) == opcode.code)
|
2013-11-06 02:01:15 +01:00
|
|
|
{
|
2014-10-29 16:30:35 +01:00
|
|
|
(m_op.*opcode.func)(opcode.length == 2 ? code0 : arg, opcode.type);
|
2014-10-29 05:13:34 +01:00
|
|
|
return opcode.length;
|
2013-11-06 02:01:15 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-29 05:13:34 +01:00
|
|
|
m_op.UNK(data);
|
2014-10-31 02:12:07 +01:00
|
|
|
return address & 1 ? 4 : 2;
|
2013-11-05 19:12:18 +01:00
|
|
|
}
|
|
|
|
|
};
|