mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-27 06:35:04 +00:00
Add 'quick' decoding and testing.
This commit is contained in:
parent
45c02c31f8
commit
549e440f7c
@ -172,14 +172,20 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::validated
|
||||
|
||||
// ADD, SUB, MOVE, MOVEA
|
||||
case OpT(Operation::ADDb): case OpT(Operation::ADDw): case OpT(Operation::ADDl):
|
||||
case ADDQb: case ADDQw: case ADDQl:
|
||||
case OpT(Operation::SUBb): case OpT(Operation::SUBw): case OpT(Operation::SUBl):
|
||||
case SUBQb: case SUBQw: case SUBQl:
|
||||
case OpT(Operation::MOVEb): case OpT(Operation::MOVEw): case OpT(Operation::MOVEl):
|
||||
case OpT(Operation::MOVEAw): case OpT(Operation::MOVEAl):
|
||||
case OpT(Operation::MOVEAw): case OpT(Operation::MOVEAl): {
|
||||
// TODO: I'm going to need get-size-by-operation elsewhere; use that here when implemented.
|
||||
constexpr bool is_byte =
|
||||
op == OpT(Operation::ADDb) || op == OpT(Operation::SUBb) || op == OpT(Operation::MOVEb) ||
|
||||
op == ADDQb || op == SUBQb;
|
||||
|
||||
switch(original.mode<0>()) {
|
||||
default: break;
|
||||
case AddressingMode::AddressRegisterDirect:
|
||||
// TODO: I'm going to need get-size-by-operation elsewhere; use that here when implemented.
|
||||
if constexpr (op != OpT(Operation::ADDb) && op != OpT(Operation::SUBb) && op != OpT(Operation::MOVEb)) {
|
||||
if constexpr (!is_byte) {
|
||||
break;
|
||||
}
|
||||
[[fallthrough]];
|
||||
@ -191,7 +197,7 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::validated
|
||||
default: return original;
|
||||
|
||||
case AddressingMode::AddressRegisterDirect:
|
||||
if constexpr (op == OpT(Operation::MOVEAw) || op == OpT(Operation::MOVEAl)) {
|
||||
if constexpr (!is_byte) {
|
||||
return original;
|
||||
}
|
||||
[[fallthrough]];
|
||||
@ -201,6 +207,7 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::validated
|
||||
case AddressingMode::None:
|
||||
return Preinstruction();
|
||||
}
|
||||
}
|
||||
|
||||
// ADDA, SUBA.
|
||||
case OpT(Operation::ADDAw): case OpT(Operation::ADDAl):
|
||||
@ -1061,7 +1068,11 @@ Preinstruction Predecoder<model>::decode7(uint16_t instruction) {
|
||||
using Op = Operation;
|
||||
|
||||
// 4-134 (p238)
|
||||
Decode(Op::MOVEq);
|
||||
if(!(instruction & 0x100)) {
|
||||
Decode(Op::MOVEq);
|
||||
} else {
|
||||
return Preinstruction();
|
||||
}
|
||||
}
|
||||
|
||||
template <Model model>
|
||||
|
@ -136,6 +136,28 @@ constexpr int size(Operation operation) {
|
||||
}
|
||||
}
|
||||
|
||||
template <Operation op>
|
||||
constexpr int8_t quick(uint16_t instruction) {
|
||||
switch(op) {
|
||||
case Operation::Bccb:
|
||||
case Operation::MOVEq: return int8_t(instruction);
|
||||
default: {
|
||||
int8_t value = (instruction >> 9) & 7;
|
||||
value |= (value - 1)&8;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constexpr int8_t quick(Operation op, uint16_t instruction) {
|
||||
if(op == Operation::MOVEq || op == Operation::Bccb) {
|
||||
return quick<Operation::MOVEq>(instruction);
|
||||
} else {
|
||||
// ADDw is arbitrary; anything other than MOVEq will do.
|
||||
return quick<Operation::ADDw>(instruction);
|
||||
}
|
||||
}
|
||||
|
||||
/// Indicates the addressing mode applicable to an operand.
|
||||
///
|
||||
/// Implementation notes:
|
||||
|
@ -17,7 +17,7 @@ using namespace InstructionSet::M68k;
|
||||
|
||||
namespace {
|
||||
|
||||
template <int index> NSString *operand(Preinstruction instruction) {
|
||||
template <int index> NSString *operand(Preinstruction instruction, uint16_t opcode) {
|
||||
switch(instruction.mode<index>()) {
|
||||
default: return [NSString stringWithFormat:@"[Mode %d?]", int(instruction.mode<index>())];
|
||||
|
||||
@ -52,6 +52,9 @@ template <int index> NSString *operand(Preinstruction instruction) {
|
||||
|
||||
case AddressingMode::ImmediateData:
|
||||
return @"#";
|
||||
|
||||
case AddressingMode::Quick:
|
||||
return [NSString stringWithFormat:@"%d", quick(instruction.operation, opcode)];
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,10 +219,12 @@ template <int index> NSString *operand(Preinstruction instruction) {
|
||||
case Operation::ROXRl: instruction = @"ROXR.l"; break;
|
||||
case Operation::ROXRm: instruction = @"ROXR.w"; break;
|
||||
|
||||
// case Operation::MOVEMl: instruction = @"MOVEM.l"; break;
|
||||
// case Operation::MOVEMw: instruction = @"MOVEM.w"; break;
|
||||
|
||||
/*
|
||||
TODO:
|
||||
|
||||
MOVEMl, MOVEMw,
|
||||
MOVEPl, MOVEPw,
|
||||
|
||||
ANDb, ANDw, ANDl,
|
||||
@ -252,17 +257,17 @@ template <int index> NSString *operand(Preinstruction instruction) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NSString *const operand1 = operand<0>(found);
|
||||
NSString *const operand2 = operand<1>(found);
|
||||
NSString *const operand1 = operand<0>(found, uint16_t(instr));
|
||||
NSString *const operand2 = operand<1>(found, uint16_t(instr));
|
||||
|
||||
if(operand1.length) instruction = [instruction stringByAppendingFormat:@" %@", operand1];
|
||||
if(operand2.length) instruction = [instruction stringByAppendingFormat:@", %@", operand2];
|
||||
|
||||
// Quick decoding not yet supported. TODO.
|
||||
if(found.mode<0>() == AddressingMode::Quick || found.mode<1>() == AddressingMode::Quick) {
|
||||
++skipped;
|
||||
continue;
|
||||
}
|
||||
// if(found.mode<0>() == AddressingMode::Quick || found.mode<1>() == AddressingMode::Quick) {
|
||||
// ++skipped;
|
||||
// continue;
|
||||
// }
|
||||
|
||||
XCTAssertFalse(found.mode<0>() == AddressingMode::None && found.mode<1>() != AddressingMode::None, @"Decoding of %@ provided a second operand but not a first", instrName);
|
||||
XCTAssertEqualObjects(instruction, expected, "%@ should decode as %@; got %@", instrName, expected, instruction);
|
||||
|
Loading…
x
Reference in New Issue
Block a user