Added 0xFFFF opcode as some AVRs treat it as an SBRS instruction.
Also some tidying
This commit is contained in:
@@ -23,6 +23,7 @@ namespace Targets::Microchip::Avr::Avr8Bit::OpcodeDecoder
|
||||
|
||||
while(dataIt != dataEndIt) {
|
||||
auto opcodeMatched = false;
|
||||
const auto wordAvailable = std::distance(dataIt, dataEndIt) >= 2;
|
||||
|
||||
for (const auto& decoder : decoders) {
|
||||
auto instruction = decoder(dataIt, dataEndIt);
|
||||
@@ -42,7 +43,7 @@ namespace Targets::Microchip::Avr::Avr8Bit::OpcodeDecoder
|
||||
if (throwOnFailure) {
|
||||
throw Exceptions::DecodeFailure(
|
||||
instructionByteAddress,
|
||||
std::distance(dataIt, dataEndIt) >= 2
|
||||
wordAvailable
|
||||
? static_cast<std::uint32_t>(*(dataIt + 1) << 8) | *dataIt
|
||||
: *dataIt
|
||||
);
|
||||
@@ -50,7 +51,7 @@ namespace Targets::Microchip::Avr::Avr8Bit::OpcodeDecoder
|
||||
|
||||
output.insert(std::pair(instructionByteAddress, std::nullopt));
|
||||
|
||||
if (std::distance(dataIt, dataEndIt) < 2) {
|
||||
if (!wordAvailable) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -69,6 +70,7 @@ namespace Targets::Microchip::Avr::Avr8Bit::OpcodeDecoder
|
||||
* 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),
|
||||
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),
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Targets::Microchip::Avr::Avr8Bit::OpcodeDecoder
|
||||
const Targets::TargetMemoryBuffer::const_iterator&
|
||||
)
|
||||
>;
|
||||
using OpcodeDecoders = std::array<Decoder::OpcodeDecoderFunction, 144>;
|
||||
using OpcodeDecoders = std::array<Decoder::OpcodeDecoderFunction, 145>;
|
||||
|
||||
static OpcodeDecoders opcodeDecoders();
|
||||
};
|
||||
|
||||
@@ -19,6 +19,13 @@ namespace Targets::Microchip::Avr::Avr8Bit::OpcodeDecoder
|
||||
MUL, MULS, MULSU, NEG, NOP, OR, ORI, OUT, POP, PUSH, RCALL, RET, RETI, RJMP, ROL, ROR, SBC, SBCI, SBI,
|
||||
SBIC, SBIS, SBIW, SBR, SBRC, SBRS, SEC, SEH, SEI, SEN, SER, SES, SET, SEV, SEZ, SLEEP, SPM, ST, STD, STS,
|
||||
SUB, SUBI, SWAP, TST, WDR, XCH,
|
||||
|
||||
/*
|
||||
* For undefined opcodes that we've had to define, because the hardware doesn't treat them as undefined.
|
||||
*
|
||||
* For example, see the 0xFFFF opcode.
|
||||
*/
|
||||
UNDEFINED,
|
||||
};
|
||||
|
||||
const std::string& name;
|
||||
|
||||
@@ -1689,6 +1689,32 @@ namespace Targets::Microchip::Avr::Avr8Bit::OpcodeDecoder::Opcodes
|
||||
RegisterParameter({9, 10})
|
||||
>;
|
||||
|
||||
/*
|
||||
* So apparently, some AVRs treat the undefined 0xFFFF opcode as 0xFFF7 (SBRS R31, 7).
|
||||
*
|
||||
* See https://www.avrfreaks.net/s/topic/a5C3l000000UL4NEAW/t094785
|
||||
*
|
||||
* For this reason, we have to define it here.
|
||||
*/
|
||||
using UndefinedOrErased = Opcode<
|
||||
"????",
|
||||
0b1111111111111111,
|
||||
1,
|
||||
Instruction::Mnemonic::UNDEFINED,
|
||||
true,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
true
|
||||
>;
|
||||
|
||||
using Wdr = Opcode<
|
||||
"WDR",
|
||||
0b1001010110101000,
|
||||
|
||||
Reference in New Issue
Block a user