1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-09-29 16:55:59 +00:00

Add 'quick' decoding and testing.

This commit is contained in:
Thomas Harte 2022-04-21 16:05:00 -04:00
parent 45c02c31f8
commit 549e440f7c
3 changed files with 51 additions and 13 deletions

View File

@ -172,14 +172,20 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::validated
// ADD, SUB, MOVE, MOVEA // ADD, SUB, MOVE, MOVEA
case OpT(Operation::ADDb): case OpT(Operation::ADDw): case OpT(Operation::ADDl): 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 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::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>()) { switch(original.mode<0>()) {
default: break; default: break;
case AddressingMode::AddressRegisterDirect: case AddressingMode::AddressRegisterDirect:
// TODO: I'm going to need get-size-by-operation elsewhere; use that here when implemented. if constexpr (!is_byte) {
if constexpr (op != OpT(Operation::ADDb) && op != OpT(Operation::SUBb) && op != OpT(Operation::MOVEb)) {
break; break;
} }
[[fallthrough]]; [[fallthrough]];
@ -191,7 +197,7 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::validated
default: return original; default: return original;
case AddressingMode::AddressRegisterDirect: case AddressingMode::AddressRegisterDirect:
if constexpr (op == OpT(Operation::MOVEAw) || op == OpT(Operation::MOVEAl)) { if constexpr (!is_byte) {
return original; return original;
} }
[[fallthrough]]; [[fallthrough]];
@ -201,6 +207,7 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::validated
case AddressingMode::None: case AddressingMode::None:
return Preinstruction(); return Preinstruction();
} }
}
// ADDA, SUBA. // ADDA, SUBA.
case OpT(Operation::ADDAw): case OpT(Operation::ADDAl): case OpT(Operation::ADDAw): case OpT(Operation::ADDAl):
@ -1061,7 +1068,11 @@ Preinstruction Predecoder<model>::decode7(uint16_t instruction) {
using Op = Operation; using Op = Operation;
// 4-134 (p238) // 4-134 (p238)
if(!(instruction & 0x100)) {
Decode(Op::MOVEq); Decode(Op::MOVEq);
} else {
return Preinstruction();
}
} }
template <Model model> template <Model model>

View File

@ -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. /// Indicates the addressing mode applicable to an operand.
/// ///
/// Implementation notes: /// Implementation notes:

View File

@ -17,7 +17,7 @@ using namespace InstructionSet::M68k;
namespace { namespace {
template <int index> NSString *operand(Preinstruction instruction) { template <int index> NSString *operand(Preinstruction instruction, uint16_t opcode) {
switch(instruction.mode<index>()) { switch(instruction.mode<index>()) {
default: return [NSString stringWithFormat:@"[Mode %d?]", int(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: case AddressingMode::ImmediateData:
return @"#"; 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::ROXRl: instruction = @"ROXR.l"; break;
case Operation::ROXRm: instruction = @"ROXR.w"; break; case Operation::ROXRm: instruction = @"ROXR.w"; break;
// case Operation::MOVEMl: instruction = @"MOVEM.l"; break;
// case Operation::MOVEMw: instruction = @"MOVEM.w"; break;
/* /*
TODO: TODO:
MOVEMl, MOVEMw,
MOVEPl, MOVEPw, MOVEPl, MOVEPw,
ANDb, ANDw, ANDl, ANDb, ANDw, ANDl,
@ -252,17 +257,17 @@ template <int index> NSString *operand(Preinstruction instruction) {
continue; continue;
} }
NSString *const operand1 = operand<0>(found); NSString *const operand1 = operand<0>(found, uint16_t(instr));
NSString *const operand2 = operand<1>(found); NSString *const operand2 = operand<1>(found, uint16_t(instr));
if(operand1.length) instruction = [instruction stringByAppendingFormat:@" %@", operand1]; if(operand1.length) instruction = [instruction stringByAppendingFormat:@" %@", operand1];
if(operand2.length) instruction = [instruction stringByAppendingFormat:@", %@", operand2]; if(operand2.length) instruction = [instruction stringByAppendingFormat:@", %@", operand2];
// Quick decoding not yet supported. TODO. // Quick decoding not yet supported. TODO.
if(found.mode<0>() == AddressingMode::Quick || found.mode<1>() == AddressingMode::Quick) { // if(found.mode<0>() == AddressingMode::Quick || found.mode<1>() == AddressingMode::Quick) {
++skipped; // ++skipped;
continue; // continue;
} // }
XCTAssertFalse(found.mode<0>() == AddressingMode::None && found.mode<1>() != AddressingMode::None, @"Decoding of %@ provided a second operand but not a first", instrName); 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); XCTAssertEqualObjects(instruction, expected, "%@ should decode as %@; got %@", instrName, expected, instruction);