Files
BloomPatched/src/Targets/Microchip/AVR/AVR8/OpcodeDecoder/Decoder.cpp

221 lines
15 KiB
C++
Raw Normal View History

2023-09-07 23:31:29 +01:00
#include "Decoder.hpp"
#include <iterator>
#include "Opcodes.hpp"
#include "Exceptions/DecodeFailure.hpp"
namespace Targets::Microchip::Avr::Avr8Bit::OpcodeDecoder
{
Decoder::InstructionMapping Decoder::decode(
Targets::TargetMemoryAddress startByteAddress,
const TargetMemoryBuffer& data,
bool throwOnFailure
) {
auto output = Decoder::InstructionMapping();
static const auto decoders = Decoder::opcodeDecoders();
auto instructionByteAddress = startByteAddress;
auto dataIt = data.begin();
const auto dataEndIt = data.end();
while(dataIt != dataEndIt) {
auto opcodeMatched = false;
const auto wordAvailable = std::distance(dataIt, dataEndIt) >= 2;
2023-09-07 23:31:29 +01:00
for (const auto& decoder : decoders) {
auto instruction = decoder(dataIt, dataEndIt);
if (instruction.has_value()) {
const auto instructionSize = instruction->byteSize;
output.insert(std::pair(instructionByteAddress, std::move(*instruction)));
dataIt += instructionSize;
instructionByteAddress += instructionSize;
opcodeMatched = true;
break;
}
}
if (!opcodeMatched) {
if (throwOnFailure) {
throw Exceptions::DecodeFailure(
instructionByteAddress,
wordAvailable
2023-09-07 23:31:29 +01:00
? static_cast<std::uint32_t>(*(dataIt + 1) << 8) | *dataIt
: *dataIt
);
}
output.insert(std::pair(instructionByteAddress, std::nullopt));
if (!wordAvailable) {
2023-09-07 23:31:29 +01:00
break;
}
dataIt += 2;
instructionByteAddress += 2;
}
}
return output;
}
Decoder::OpcodeDecoders Decoder::opcodeDecoders() {
/*
* The decoders will be used in the order given here.
*
* I've used the same order that is used in the AVR implementation of GDB.
*/
return Decoder::OpcodeDecoders({
std::bind(&Opcodes::UndefinedOrErased::decode, std::placeholders::_1, std::placeholders::_2),
2023-09-07 23:31:29 +01:00
std::bind(&Opcodes::Clc::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Clh::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Cli::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Cln::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Cls::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Clt::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Clv::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Clz::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Sec::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Seh::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Sei::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Sen::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Ses::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Set::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Sev::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Sez::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Bclr::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Bset::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Icall::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Ijmp::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Lpm1::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Lpm2::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Lpm3::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Elpm1::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Elpm2::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Elpm3::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Nop::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Ret::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Reti::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Sleep::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Break::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Wdr::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Spm1::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Spm2::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Adc::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Add::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::And::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Cp::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Cpc::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Cpse::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Eor::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Mov::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Mul::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Or::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Sbc::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Sub::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Clr::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Lsl::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Rol::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Tst::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Andi::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Cbr::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Ldi::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Ser::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Ori::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Sbr::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Cpi::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Sbci::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Subi::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Sbrc::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Sbrs::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Bld::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Bst::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::In::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Out::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Adiw::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Sbiw::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Cbi::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Sbi::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Sbic::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Sbis::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Brcc::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Brcs::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Breq::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Brge::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Brhc::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Brhs::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Brid::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Brie::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Brlo::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Brlt::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Brmi::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Brne::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Brpl::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Brsh::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Brtc::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Brts::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Brvc::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Brvs::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Brbc::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Brbs::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Rcall::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Rjmp::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Call::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Jmp::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Asr::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Com::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Dec::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Inc::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Lsr::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Neg::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Pop::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Push::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Ror::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Swap::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Xch::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Las::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Lac::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Lat::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Movw::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Muls::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Mulsu::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Fmul::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Fmuls::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Fmulsu::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Sts1::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Sts2::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Lds1::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Lds2::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::LddY::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::LddZ::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::LdX1::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::LdX2::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::LdX3::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::LdY1::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::LdY2::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::LdY3::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::LdZ1::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::LdZ2::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::LdZ3::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::StdY::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::StdZ::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::StX1::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::StX2::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::StX3::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::StY1::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::StY2::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::StY3::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::StZ1::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::StZ2::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::StZ3::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Eicall::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Eijmp::decode, std::placeholders::_1, std::placeholders::_2),
std::bind(&Opcodes::Des::decode, std::placeholders::_1, std::placeholders::_2),
});
}
}