74 lines
1.4 KiB
C++
74 lines
1.4 KiB
C++
#include <fxos/disassembly.h>
|
|
#include <optional>
|
|
#include <array>
|
|
|
|
namespace FxOS {
|
|
|
|
/* Instruction map */
|
|
static std::array<std::optional<Instruction>,65536> insmap;
|
|
|
|
/* Register an instruction at a given opcode. */
|
|
|
|
void register_instruction(Instruction ins)
|
|
{
|
|
uint16_t opcode = ins.opcode;
|
|
|
|
if(insmap[opcode])
|
|
{
|
|
throw std::logic_error("opcode collision");
|
|
}
|
|
|
|
insmap[opcode] = ins;
|
|
}
|
|
|
|
//---
|
|
// Concrete (instanciated) arguments and instructions
|
|
//---
|
|
|
|
ConcreteInstructionArg::ConcreteInstructionArg():
|
|
loc {}, type {}, syscall_id {-1}
|
|
{
|
|
reg_address = -1;
|
|
}
|
|
|
|
ConcreteInstruction::ConcreteInstruction(Instruction &inst):
|
|
inst {inst}, jmpt {}, jmpf {}, leader {false}
|
|
{
|
|
}
|
|
|
|
//---
|
|
// Disassembler interface
|
|
//---
|
|
|
|
Disassembly::Disassembly(Target &target):
|
|
m_target {target}, m_instructions {}
|
|
{
|
|
}
|
|
|
|
ConcreteInstruction &Disassembly::readins(uint32_t pc)
|
|
{
|
|
if(pc & 1) throw std::runtime_error("Disassembly::readins at odd PC");
|
|
|
|
try
|
|
{
|
|
return m_instructions.at(pc);
|
|
}
|
|
catch(std::out_of_range &e)
|
|
{
|
|
uint16_t opcode = m_target.read_u16(pc);
|
|
if(!insmap[opcode])
|
|
{
|
|
throw std::runtime_error("No instruction for opcode");
|
|
}
|
|
|
|
Instruction &inst = *insmap[opcode];
|
|
|
|
ConcreteInstruction ci(inst);
|
|
// std::pair<uint32_t, ConcreteInstruction> p(pc, ci);
|
|
// m_instructions.emplace(std::make_pair(pc, ci));
|
|
return m_instructions.at(pc);
|
|
}
|
|
}
|
|
|
|
} /* namespace FxOS */
|