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) {
|
while(dataIt != dataEndIt) {
|
||||||
auto opcodeMatched = false;
|
auto opcodeMatched = false;
|
||||||
|
const auto wordAvailable = std::distance(dataIt, dataEndIt) >= 2;
|
||||||
|
|
||||||
for (const auto& decoder : decoders) {
|
for (const auto& decoder : decoders) {
|
||||||
auto instruction = decoder(dataIt, dataEndIt);
|
auto instruction = decoder(dataIt, dataEndIt);
|
||||||
@@ -42,7 +43,7 @@ namespace Targets::Microchip::Avr::Avr8Bit::OpcodeDecoder
|
|||||||
if (throwOnFailure) {
|
if (throwOnFailure) {
|
||||||
throw Exceptions::DecodeFailure(
|
throw Exceptions::DecodeFailure(
|
||||||
instructionByteAddress,
|
instructionByteAddress,
|
||||||
std::distance(dataIt, dataEndIt) >= 2
|
wordAvailable
|
||||||
? static_cast<std::uint32_t>(*(dataIt + 1) << 8) | *dataIt
|
? static_cast<std::uint32_t>(*(dataIt + 1) << 8) | *dataIt
|
||||||
: *dataIt
|
: *dataIt
|
||||||
);
|
);
|
||||||
@@ -50,7 +51,7 @@ namespace Targets::Microchip::Avr::Avr8Bit::OpcodeDecoder
|
|||||||
|
|
||||||
output.insert(std::pair(instructionByteAddress, std::nullopt));
|
output.insert(std::pair(instructionByteAddress, std::nullopt));
|
||||||
|
|
||||||
if (std::distance(dataIt, dataEndIt) < 2) {
|
if (!wordAvailable) {
|
||||||
break;
|
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.
|
* I've used the same order that is used in the AVR implementation of GDB.
|
||||||
*/
|
*/
|
||||||
return Decoder::OpcodeDecoders({
|
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::Clc::decode, std::placeholders::_1, std::placeholders::_2),
|
||||||
std::bind(&Opcodes::Clh::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::Cli::decode, std::placeholders::_1, std::placeholders::_2),
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ namespace Targets::Microchip::Avr::Avr8Bit::OpcodeDecoder
|
|||||||
const Targets::TargetMemoryBuffer::const_iterator&
|
const Targets::TargetMemoryBuffer::const_iterator&
|
||||||
)
|
)
|
||||||
>;
|
>;
|
||||||
using OpcodeDecoders = std::array<Decoder::OpcodeDecoderFunction, 144>;
|
using OpcodeDecoders = std::array<Decoder::OpcodeDecoderFunction, 145>;
|
||||||
|
|
||||||
static OpcodeDecoders opcodeDecoders();
|
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,
|
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,
|
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,
|
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;
|
const std::string& name;
|
||||||
|
|||||||
@@ -1689,6 +1689,32 @@ namespace Targets::Microchip::Avr::Avr8Bit::OpcodeDecoder::Opcodes
|
|||||||
RegisterParameter({9, 10})
|
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<
|
using Wdr = Opcode<
|
||||||
"WDR",
|
"WDR",
|
||||||
0b1001010110101000,
|
0b1001010110101000,
|
||||||
|
|||||||
Reference in New Issue
Block a user