1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-08-07 23:25:00 +00:00

Take another crack at neatness; make LEA overt.

This commit is contained in:
Thomas Harte
2022-04-15 20:33:59 -04:00
parent f86e455a87
commit bfb29a58f3
2 changed files with 229 additions and 202 deletions

View File

@@ -42,8 +42,8 @@ template <
/// a Preinstruction with an operation of AND, the former just happens to specify an /// a Preinstruction with an operation of AND, the former just happens to specify an
/// immediate operand. /// immediate operand.
template <Model model> template <Model model>
constexpr Operation Predecoder<model>::operation(Op op) { constexpr Operation Predecoder<model>::operation(OpT op) {
if(op < Op(Operation::Max)) { if(op < OpT(Operation::Max)) {
return Operation(op); return Operation(op);
} }
@@ -68,6 +68,8 @@ constexpr Operation Predecoder<model>::operation(Op op) {
case BCLRI: return Operation::BCLR; case BCLRI: return Operation::BCLR;
case BSETI: return Operation::BSET; case BSETI: return Operation::BSET;
case LEA: return Operation::MOVEAl;
default: break; default: break;
} }
@@ -94,7 +96,7 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
// //
// MARK: ABCD, SBCD. // MARK: ABCD, SBCD.
// //
case Op(Operation::ABCD): case Op(Operation::SBCD): { case OpT(Operation::ABCD): case OpT(Operation::SBCD): {
const auto addressing_mode = (instruction & 8) ? const auto addressing_mode = (instruction & 8) ?
AddressingMode::AddressRegisterIndirectWithPredecrement : AddressingMode::DataRegisterDirect; AddressingMode::AddressRegisterIndirectWithPredecrement : AddressingMode::DataRegisterDirect;
@@ -106,9 +108,9 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
// //
// MARK: AND, OR, EOR. // MARK: AND, OR, EOR.
// //
case Op(Operation::ANDb): case Op(Operation::ANDw): case Op(Operation::ANDl): case OpT(Operation::ANDb): case OpT(Operation::ANDw): case OpT(Operation::ANDl):
case Op(Operation::ORb): case Op(Operation::ORw): case Op(Operation::ORl): case OpT(Operation::ORb): case OpT(Operation::ORw): case OpT(Operation::ORl):
case Op(Operation::EORb): case Op(Operation::EORw): case Op(Operation::EORl): { case OpT(Operation::EORb): case OpT(Operation::EORw): case OpT(Operation::EORl): {
// Opmode 7 is illegal. // Opmode 7 is illegal.
if(opmode == 7) { if(opmode == 7) {
return Preinstruction(); return Preinstruction();
@@ -171,8 +173,8 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
// //
// MARK: BTST, BCLR, BCHG, BSET // MARK: BTST, BCLR, BCHG, BSET
// //
case Op(Operation::BTST): case Op(Operation::BCLR): case OpT(Operation::BTST): case OpT(Operation::BCLR):
case Op(Operation::BCHG): case Op(Operation::BSET): case OpT(Operation::BCHG): case OpT(Operation::BSET):
return Preinstruction(operation, return Preinstruction(operation,
AddressingMode::DataRegisterDirect, data_register, AddressingMode::DataRegisterDirect, data_register,
combined_mode(ea_mode, ea_register), ea_register); combined_mode(ea_mode, ea_register), ea_register);
@@ -180,9 +182,9 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
// //
// MARK: ANDItoCCR, ANDItoSR, EORItoCCR, EORItoSR, ORItoCCR, ORItoSR // MARK: ANDItoCCR, ANDItoSR, EORItoCCR, EORItoSR, ORItoCCR, ORItoSR
// //
case Op(Operation::ORItoSR): case Op(Operation::ORItoCCR): case OpT(Operation::ORItoSR): case OpT(Operation::ORItoCCR):
case Op(Operation::ANDItoSR): case Op(Operation::ANDItoCCR): case OpT(Operation::ANDItoSR): case OpT(Operation::ANDItoCCR):
case Op(Operation::EORItoSR): case Op(Operation::EORItoCCR): case OpT(Operation::EORItoSR): case OpT(Operation::EORItoCCR):
return Preinstruction(operation, return Preinstruction(operation,
AddressingMode::ImmediateData, 0, AddressingMode::ImmediateData, 0,
operation == Operation::ORItoSR || operation == Operation::ANDItoSR || operation == Operation::EORItoSR); operation == Operation::ORItoSR || operation == Operation::ANDItoSR || operation == Operation::EORItoSR);
@@ -190,7 +192,7 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
// //
// MARK: EXG. // MARK: EXG.
// //
case Op(Operation::EXG): case OpT(Operation::EXG):
switch((instruction >> 3)&31) { switch((instruction >> 3)&31) {
default: return Preinstruction(); default: return Preinstruction();
@@ -210,8 +212,8 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
// //
// MARK: MULU, MULS, DIVU, DIVS. // MARK: MULU, MULS, DIVU, DIVS.
// //
case Op(Operation::DIVU): case Op(Operation::DIVS): case OpT(Operation::DIVU): case OpT(Operation::DIVS):
case Op(Operation::MULU): case Op(Operation::MULS): case OpT(Operation::MULU): case OpT(Operation::MULS):
return Preinstruction(operation, return Preinstruction(operation,
combined_mode(ea_mode, ea_register), ea_register, combined_mode(ea_mode, ea_register), ea_register,
AddressingMode::DataRegisterDirect, data_register); AddressingMode::DataRegisterDirect, data_register);
@@ -219,12 +221,12 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
// //
// MARK: MOVEPtoRw, MOVEPtoRl // MARK: MOVEPtoRw, MOVEPtoRl
// //
case Op(MOVEPtoRw): case Op(MOVEPtoRl): case OpT(MOVEPtoRw): case OpT(MOVEPtoRl):
return Preinstruction(operation, return Preinstruction(operation,
AddressingMode::AddressRegisterIndirectWithDisplacement, ea_register, AddressingMode::AddressRegisterIndirectWithDisplacement, ea_register,
AddressingMode::DataRegisterDirect, data_register); AddressingMode::DataRegisterDirect, data_register);
case Op(MOVEPtoMw): case Op(MOVEPtoMl): case OpT(MOVEPtoMw): case OpT(MOVEPtoMl):
return Preinstruction(operation, return Preinstruction(operation,
AddressingMode::DataRegisterDirect, data_register, AddressingMode::DataRegisterDirect, data_register,
AddressingMode::AddressRegisterIndirectWithDisplacement, ea_register); AddressingMode::AddressRegisterIndirectWithDisplacement, ea_register);
@@ -232,7 +234,7 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
// //
// MARK: MOVE // MARK: MOVE
// //
case Op(Operation::MOVEb): case Op(Operation::MOVEl): case Op(Operation::MOVEw): case OpT(Operation::MOVEb): case OpT(Operation::MOVEl): case OpT(Operation::MOVEw):
return Preinstruction(operation, return Preinstruction(operation,
combined_mode(ea_mode, ea_register), ea_register, combined_mode(ea_mode, ea_register), ea_register,
combined_mode<false, false>(opmode, data_register), data_register); combined_mode<false, false>(opmode, data_register), data_register);
@@ -240,24 +242,24 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
// //
// MARK: STOP, RESET, NOP RTE, RTS, TRAPV, RTR // MARK: STOP, RESET, NOP RTE, RTS, TRAPV, RTR
// //
case Op(Operation::STOP): case Op(Operation::RESET): case Op(Operation::NOP): case OpT(Operation::STOP): case OpT(Operation::RESET): case OpT(Operation::NOP):
case Op(Operation::RTE): case Op(Operation::RTS): case Op(Operation::TRAPV): case OpT(Operation::RTE): case OpT(Operation::RTS): case OpT(Operation::TRAPV):
case Op(Operation::RTR): case OpT(Operation::RTR):
return Preinstruction(operation); return Preinstruction(operation);
// //
// MARK: NEGX, CLR, NEG, MOVEtoCCR, MOVEtoSR, NOT, NBCD, PEA, TST // MARK: NEGX, CLR, NEG, MOVEtoCCR, MOVEtoSR, NOT, NBCD, PEA, TST
// //
case Op(Operation::CLRb): case Op(Operation::CLRw): case Op(Operation::CLRl): case OpT(Operation::CLRb): case OpT(Operation::CLRw): case OpT(Operation::CLRl):
case Op(Operation::JMP): case Op(Operation::JSR): case OpT(Operation::JMP): case OpT(Operation::JSR):
case Op(Operation::MOVEtoSR): case Op(Operation::MOVEfromSR): case Op(Operation::MOVEtoCCR): case OpT(Operation::MOVEtoSR): case OpT(Operation::MOVEfromSR): case OpT(Operation::MOVEtoCCR):
case Op(Operation::NBCD): case OpT(Operation::NBCD):
case Op(Operation::NEGb): case Op(Operation::NEGw): case Op(Operation::NEGl): case OpT(Operation::NEGb): case OpT(Operation::NEGw): case OpT(Operation::NEGl):
case Op(Operation::NEGXb): case Op(Operation::NEGXw): case Op(Operation::NEGXl): case OpT(Operation::NEGXb): case OpT(Operation::NEGXw): case OpT(Operation::NEGXl):
case Op(Operation::NOTb): case Op(Operation::NOTw): case Op(Operation::NOTl): case OpT(Operation::NOTb): case OpT(Operation::NOTw): case OpT(Operation::NOTl):
case Op(Operation::PEA): case OpT(Operation::PEA):
case Op(Operation::TAS): case OpT(Operation::TAS):
case Op(Operation::TSTb): case Op(Operation::TSTw): case Op(Operation::TSTl): case OpT(Operation::TSTb): case OpT(Operation::TSTw): case OpT(Operation::TSTl):
return Preinstruction(operation, return Preinstruction(operation,
combined_mode<false, false>(ea_mode, ea_register), ea_register); combined_mode<false, false>(ea_mode, ea_register), ea_register);
@@ -287,88 +289,87 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
// TODO: be willing to mutate Scc into DBcc. // TODO: be willing to mutate Scc into DBcc.
} }
#undef Op
// MARK: - Page decoders. // MARK: - Page decoders.
#define DecodeOp(y) return decode<Op(Operation::y)>(instruction) #define Decode(y) return decode<OpT(y)>(instruction)
#define DecodeEop(y) return decode<Op(y)>(instruction)
template <Model model> template <Model model>
Preinstruction Predecoder<model>::decode0(uint16_t instruction) { Preinstruction Predecoder<model>::decode0(uint16_t instruction) {
using Op = Operation;
switch(instruction & 0xfff) { switch(instruction & 0xfff) {
case 0x03c: DecodeOp(ORItoCCR); // 4-155 (p259) case 0x03c: Decode(Op::ORItoCCR); // 4-155 (p259)
case 0x07c: DecodeOp(ORItoSR); // 6-27 (p481) case 0x07c: Decode(Op::ORItoSR); // 6-27 (p481)
case 0x23c: DecodeOp(ANDItoCCR); // 4-20 (p124) case 0x23c: Decode(Op::ANDItoCCR); // 4-20 (p124)
case 0x27c: DecodeOp(ANDItoSR); // 6-2 (p456) case 0x27c: Decode(Op::ANDItoSR); // 6-2 (p456)
case 0xa3c: DecodeOp(EORItoCCR); // 4-104 (p208) case 0xa3c: Decode(Op::EORItoCCR); // 4-104 (p208)
case 0xa7c: DecodeOp(EORItoSR); // 6-10 (p464) case 0xa7c: Decode(Op::EORItoSR); // 6-10 (p464)
default: break; default: break;
} }
switch(instruction & 0xfc0) { switch(instruction & 0xfc0) {
// 4-153 (p257) // 4-153 (p257)
case 0x000: DecodeEop(ORIb); case 0x000: Decode(ORIb);
case 0x040: DecodeEop(ORIw); case 0x040: Decode(ORIw);
case 0x080: DecodeEop(ORIl); case 0x080: Decode(ORIl);
// 4-18 (p122) // 4-18 (p122)
case 0x200: DecodeEop(ANDIb); case 0x200: Decode(ANDIb);
case 0x240: DecodeEop(ANDIw); case 0x240: Decode(ANDIw);
case 0x280: DecodeEop(ANDIl); case 0x280: Decode(ANDIl);
// 4-179 (p283) // 4-179 (p283)
case 0x400: DecodeEop(SUBIb); case 0x400: Decode(SUBIb);
case 0x440: DecodeEop(SUBIw); case 0x440: Decode(SUBIw);
case 0x480: DecodeEop(SUBIl); case 0x480: Decode(SUBIl);
// 4-9 (p113) // 4-9 (p113)
case 0x600: DecodeEop(ADDIb); case 0x600: Decode(ADDIb);
case 0x640: DecodeEop(ADDIw); case 0x640: Decode(ADDIw);
case 0x680: DecodeEop(ADDIl); case 0x680: Decode(ADDIl);
// 4-63 (p167) // 4-63 (p167)
case 0x800: DecodeEop(BTSTI); case 0x800: Decode(BTSTI);
// 4-29 (p133) // 4-29 (p133)
case 0x840: DecodeEop(BCHGI); case 0x840: Decode(BCHGI);
// 4-32 (p136) // 4-32 (p136)
case 0x880: DecodeEop(BCLRI); case 0x880: Decode(BCLRI);
// 4-58 (p162) // 4-58 (p162)
case 0x8c0: DecodeEop(BSETI); case 0x8c0: Decode(BSETI);
// 4-102 (p206) // 4-102 (p206)
case 0xa00: DecodeEop(EORIb); case 0xa00: Decode(EORIb);
case 0xa40: DecodeEop(EORIw); case 0xa40: Decode(EORIw);
case 0xa80: DecodeEop(EORIl); case 0xa80: Decode(EORIl);
// 4-79 (p183) // 4-79 (p183)
case 0xc00: DecodeEop(CMPIb); case 0xc00: Decode(CMPIb);
case 0xc40: DecodeEop(CMPIw); case 0xc40: Decode(CMPIw);
case 0xc80: DecodeEop(CMPIl); case 0xc80: Decode(CMPIl);
default: break; default: break;
} }
switch(instruction & 0x1c0) { switch(instruction & 0x1c0) {
case 0x100: DecodeOp(BTST); // 4-62 (p166) case 0x100: Decode(Op::BTST); // 4-62 (p166)
case 0x180: DecodeOp(BCLR); // 4-31 (p135) case 0x180: Decode(Op::BCLR); // 4-31 (p135)
case 0x140: DecodeOp(BCHG); // 4-28 (p132) case 0x140: Decode(Op::BCHG); // 4-28 (p132)
case 0x1c0: DecodeOp(BSET); // 4-57 (p161) case 0x1c0: Decode(Op::BSET); // 4-57 (p161)
default: break; default: break;
} }
switch(instruction & 0x1f8) { switch(instruction & 0x1f8) {
// 4-133 (p237) // 4-133 (p237)
case 0x108: DecodeEop(MOVEPtoRw); case 0x108: Decode(MOVEPtoRw);
case 0x148: DecodeEop(MOVEPtoRl); case 0x148: Decode(MOVEPtoRl);
case 0x188: DecodeEop(MOVEPtoMw); case 0x188: Decode(MOVEPtoMw);
case 0x1c8: DecodeEop(MOVEPtoMl); case 0x1c8: Decode(MOVEPtoMl);
default: break; default: break;
} }
@@ -378,113 +379,120 @@ Preinstruction Predecoder<model>::decode0(uint16_t instruction) {
template <Model model> template <Model model>
Preinstruction Predecoder<model>::decode1(uint16_t instruction) { Preinstruction Predecoder<model>::decode1(uint16_t instruction) {
// 4-116 (p220) using Op = Operation;
DecodeOp(MOVEb);
}
// 4-116 (p220)
Decode(Op::MOVEb);
}
template <Model model> template <Model model>
Preinstruction Predecoder<model>::decode2(uint16_t instruction) { Preinstruction Predecoder<model>::decode2(uint16_t instruction) {
using Op = Operation;
// 4-116 (p220) // 4-116 (p220)
DecodeOp(MOVEl); Decode(Op::MOVEl);
} }
template <Model model> template <Model model>
Preinstruction Predecoder<model>::decode3(uint16_t instruction) { Preinstruction Predecoder<model>::decode3(uint16_t instruction) {
using Op = Operation;
// 4-116 (p220) // 4-116 (p220)
DecodeOp(MOVEw); Decode(Op::MOVEw);
} }
template <Model model> template <Model model>
Preinstruction Predecoder<model>::decode4(uint16_t instruction) { Preinstruction Predecoder<model>::decode4(uint16_t instruction) {
using Op = Operation;
switch(instruction & 0xfff) { switch(instruction & 0xfff) {
case 0xe70: DecodeOp(RESET); // 6-83 (p537) case 0xe70: Decode(Op::RESET); // 6-83 (p537)
case 0xe71: DecodeOp(NOP); // 4-147 (p251) case 0xe71: Decode(Op::NOP); // 4-147 (p251)
case 0xe73: DecodeOp(RTE); // 6-84 (p538) case 0xe73: Decode(Op::RTE); // 6-84 (p538)
case 0xe75: DecodeOp(RTS); // 4-169 (p273) case 0xe75: Decode(Op::RTS); // 4-169 (p273)
case 0xe76: DecodeOp(TRAPV); // 4-191 (p295) case 0xe76: Decode(Op::TRAPV); // 4-191 (p295)
case 0xe77: DecodeOp(RTR); // 4-168 (p272) case 0xe77: Decode(Op::RTR); // 4-168 (p272)
default: break; default: break;
} }
switch(instruction & 0xfc0) { switch(instruction & 0xfc0) {
// 4-146 (p250) // 4-146 (p250)
case 0x000: DecodeOp(NEGXb); case 0x000: Decode(Op::NEGXb);
case 0x040: DecodeOp(NEGXw); case 0x040: Decode(Op::NEGXw);
case 0x080: DecodeOp(NEGXl); case 0x080: Decode(Op::NEGXl);
// 6-17 (p471) // 6-17 (p471)
case 0x0c0: DecodeOp(MOVEfromSR); case 0x0c0: Decode(Op::MOVEfromSR);
// 4-73 (p177) // 4-73 (p177)
case 0x200: DecodeOp(CLRb); case 0x200: Decode(Op::CLRb);
case 0x240: DecodeOp(CLRw); case 0x240: Decode(Op::CLRw);
case 0x280: DecodeOp(CLRl); case 0x280: Decode(Op::CLRl);
// 4-144 (p247) // 4-144 (p247)
case 0x400: DecodeOp(NEGb); case 0x400: Decode(Op::NEGb);
case 0x440: DecodeOp(NEGw); case 0x440: Decode(Op::NEGw);
case 0x480: DecodeOp(NEGl); case 0x480: Decode(Op::NEGl);
// 4-123 (p227) // 4-123 (p227)
case 0x4c0: DecodeOp(MOVEtoCCR); case 0x4c0: Decode(Op::MOVEtoCCR);
// 4-148 (p252) // 4-148 (p252)
case 0x600: DecodeOp(NOTb); case 0x600: Decode(Op::NOTb);
case 0x640: DecodeOp(NOTw); case 0x640: Decode(Op::NOTw);
case 0x680: DecodeOp(NOTl); case 0x680: Decode(Op::NOTl);
// 4-123 (p227) // 4-123 (p227)
case 0x6c0: DecodeOp(MOVEtoSR); case 0x6c0: Decode(Op::MOVEtoSR);
// 4-142 (p246) // 4-142 (p246)
case 0x800: DecodeOp(NBCD); case 0x800: Decode(Op::NBCD);
// 4-159 (p263) // 4-159 (p263)
case 0x840: DecodeOp(PEA); case 0x840: Decode(Op::PEA);
// 4-128 (p232) // 4-128 (p232)
case 0x880: DecodeEop(MOVEMtoMw); case 0x880: Decode(MOVEMtoMw);
case 0x8c0: DecodeEop(MOVEMtoMl); case 0x8c0: Decode(MOVEMtoMl);
case 0xc80: DecodeEop(MOVEMtoRw); case 0xc80: Decode(MOVEMtoRw);
case 0xcc0: DecodeEop(MOVEMtoRl); case 0xcc0: Decode(MOVEMtoRl);
// 4-192 (p296) // 4-192 (p296)
case 0xa00: DecodeOp(TSTb); case 0xa00: Decode(Op::TSTb);
case 0xa40: DecodeOp(TSTw); case 0xa40: Decode(Op::TSTw);
case 0xa80: DecodeOp(TSTl); case 0xa80: Decode(Op::TSTl);
// 4-186 (p290) // 4-186 (p290)
case 0xac0: DecodeOp(TAS); case 0xac0: Decode(Op::TAS);
// 4-109 (p213) // 4-109 (p213)
case 0xe80: DecodeOp(JSR); case 0xe80: Decode(Op::JSR);
// 4-108 (p212) // 4-108 (p212)
case 0xec0: DecodeOp(JMP); case 0xec0: Decode(Op::JMP);
default: break; default: break;
} }
switch(instruction & 0x1c0) { switch(instruction & 0x1c0) {
case 0x1c0: DecodeOp(MOVEAl); // 4-110 (p214) TODO: In this I assume that LEA is just a special MOVEAl. Consider. case 0x1c0: Decode(LEA); // 4-110 (p214)
case 0x180: DecodeOp(CHK); // 4-69 (p173) case 0x180: Decode(Op::CHK); // 4-69 (p173)
default: break; default: break;
} }
switch(instruction & 0xff0) { switch(instruction & 0xff0) {
case 0xe40: DecodeOp(TRAP); // 4-188 (p292) case 0xe40: Decode(Op::TRAP); // 4-188 (p292)
default: break; default: break;
} }
switch(instruction & 0xff8) { switch(instruction & 0xff8) {
case 0x860: DecodeOp(SWAP); // 4-185 (p289) case 0x860: Decode(Op::SWAP); // 4-185 (p289)
case 0x880: DecodeOp(EXTbtow); // 4-106 (p210) case 0x880: Decode(Op::EXTbtow); // 4-106 (p210)
case 0x8c0: DecodeOp(EXTwtol); // 4-106 (p210) case 0x8c0: Decode(Op::EXTwtol); // 4-106 (p210)
case 0xe50: DecodeOp(LINKw); // 4-111 (p215) case 0xe50: Decode(Op::LINKw); // 4-111 (p215)
case 0xe58: DecodeOp(UNLINK); // 4-194 (p298) case 0xe58: Decode(Op::UNLINK); // 4-194 (p298)
case 0xe60: DecodeOp(MOVEtoUSP); // 6-21 (p475) case 0xe60: Decode(Op::MOVEtoUSP); // 6-21 (p475)
case 0xe68: DecodeOp(MOVEfromUSP); // 6-21 (p475) case 0xe68: Decode(Op::MOVEfromUSP); // 6-21 (p475)
default: break; default: break;
} }
@@ -493,23 +501,25 @@ Preinstruction Predecoder<model>::decode4(uint16_t instruction) {
template <Model model> template <Model model>
Preinstruction Predecoder<model>::decode5(uint16_t instruction) { Preinstruction Predecoder<model>::decode5(uint16_t instruction) {
using Op = Operation;
switch(instruction & 0x1c0) { switch(instruction & 0x1c0) {
// 4-11 (p115) // 4-11 (p115)
case 0x000: DecodeEop(ADDQb); case 0x000: Decode(ADDQb);
case 0x040: DecodeEop(ADDQw); case 0x040: Decode(ADDQw);
case 0x080: DecodeEop(ADDQl); case 0x080: Decode(ADDQl);
// 4-181 (p285) // 4-181 (p285)
case 0x100: DecodeEop(SUBQb); case 0x100: Decode(SUBQb);
case 0x140: DecodeEop(SUBQw); case 0x140: Decode(SUBQw);
case 0x180: DecodeEop(SUBQl); case 0x180: Decode(SUBQl);
default: break; default: break;
} }
switch(instruction & 0x0c0) { switch(instruction & 0x0c0) {
// 4-173 (p276), though this'll also hit DBcc 4-91 (p195) // 4-173 (p276), though this'll also hit DBcc 4-91 (p195)
case 0x0c0: DecodeOp(Scc); case 0x0c0: Decode(Op::Scc);
default: break; default: break;
} }
@@ -518,32 +528,38 @@ Preinstruction Predecoder<model>::decode5(uint16_t instruction) {
template <Model model> template <Model model>
Preinstruction Predecoder<model>::decode6(uint16_t instruction) { Preinstruction Predecoder<model>::decode6(uint16_t instruction) {
using Op = Operation;
// 4-25 (p129), 4-59 (p163) and 4-55 (p159) // 4-25 (p129), 4-59 (p163) and 4-55 (p159)
DecodeOp(Bcc); Decode(Op::Bcc);
} }
template <Model model> template <Model model>
Preinstruction Predecoder<model>::decode7(uint16_t instruction) { Preinstruction Predecoder<model>::decode7(uint16_t instruction) {
using Op = Operation;
// 4-134 (p238) // 4-134 (p238)
DecodeOp(MOVEq); Decode(Op::MOVEq);
} }
template <Model model> template <Model model>
Preinstruction Predecoder<model>::decode8(uint16_t instruction) { Preinstruction Predecoder<model>::decode8(uint16_t instruction) {
using Op = Operation;
// 4-171 (p275) // 4-171 (p275)
if((instruction & 0x1f0) == 0x100) DecodeOp(SBCD); if((instruction & 0x1f0) == 0x100) Decode(Op::SBCD);
// 4-150 (p254) // 4-150 (p254)
switch(instruction & 0x0c0) { switch(instruction & 0x0c0) {
case 0x00: DecodeOp(ORb); case 0x00: Decode(Op::ORb);
case 0x40: DecodeOp(ORw); case 0x40: Decode(Op::ORw);
case 0x80: DecodeOp(ORl); case 0x80: Decode(Op::ORl);
default: break; default: break;
} }
switch(instruction & 0x1c0) { switch(instruction & 0x1c0) {
case 0x0c0: DecodeOp(DIVU); // 4-97 (p201) case 0x0c0: Decode(Op::DIVU); // 4-97 (p201)
case 0x1c0: DecodeOp(DIVS); // 4-93 (p197) case 0x1c0: Decode(Op::DIVS); // 4-93 (p197)
default: break; default: break;
} }
@@ -552,28 +568,30 @@ Preinstruction Predecoder<model>::decode8(uint16_t instruction) {
template <Model model> template <Model model>
Preinstruction Predecoder<model>::decode9(uint16_t instruction) { Preinstruction Predecoder<model>::decode9(uint16_t instruction) {
using Op = Operation;
switch(instruction & 0x0c0) { switch(instruction & 0x0c0) {
// 4-174 (p278) // 4-174 (p278)
case 0x00: DecodeOp(SUBb); case 0x00: Decode(Op::SUBb);
case 0x40: DecodeOp(SUBw); case 0x40: Decode(Op::SUBw);
case 0x80: DecodeOp(SUBl); case 0x80: Decode(Op::SUBl);
default: break; default: break;
} }
switch(instruction & 0x1c0) { switch(instruction & 0x1c0) {
// 4-177 (p281) // 4-177 (p281)
case 0x0c0: DecodeOp(SUBAw); case 0x0c0: Decode(Op::SUBAw);
case 0x1c0: DecodeOp(SUBAl); case 0x1c0: Decode(Op::SUBAl);
default: break; default: break;
} }
switch(instruction & 0x1f0) { switch(instruction & 0x1f0) {
// 4-184 (p288) // 4-184 (p288)
case 0x100: DecodeOp(SUBXb); case 0x100: Decode(Op::SUBXb);
case 0x140: DecodeOp(SUBXw); case 0x140: Decode(Op::SUBXw);
case 0x180: DecodeOp(SUBXl); case 0x180: Decode(Op::SUBXl);
default: break; default: break;
} }
@@ -588,23 +606,25 @@ Preinstruction Predecoder<model>::decodeA(uint16_t) {
template <Model model> template <Model model>
Preinstruction Predecoder<model>::decodeB(uint16_t instruction) { Preinstruction Predecoder<model>::decodeB(uint16_t instruction) {
using Op = Operation;
switch(instruction & 0x0c0) { switch(instruction & 0x0c0) {
// 4-100 (p204) // 4-100 (p204)
case 0x000: DecodeOp(EORb); case 0x000: Decode(Op::EORb);
case 0x040: DecodeOp(EORw); case 0x040: Decode(Op::EORw);
case 0x080: DecodeOp(EORl); case 0x080: Decode(Op::EORl);
default: break; default: break;
} }
switch(instruction & 0x1c0) { switch(instruction & 0x1c0) {
// 4-75 (p179) // 4-75 (p179)
case 0x000: DecodeOp(CMPb); case 0x000: Decode(Op::CMPb);
case 0x040: DecodeOp(CMPw); case 0x040: Decode(Op::CMPw);
case 0x080: DecodeOp(CMPl); case 0x080: Decode(Op::CMPl);
// 4-77 (p181) // 4-77 (p181)
case 0x0c0: DecodeOp(CMPAw); case 0x0c0: Decode(Op::CMPAw);
case 0x1c0: DecodeOp(CMPAl); case 0x1c0: Decode(Op::CMPAl);
default: break; default: break;
} }
@@ -614,22 +634,24 @@ Preinstruction Predecoder<model>::decodeB(uint16_t instruction) {
template <Model model> template <Model model>
Preinstruction Predecoder<model>::decodeC(uint16_t instruction) { Preinstruction Predecoder<model>::decodeC(uint16_t instruction) {
using Op = Operation;
switch(instruction & 0x1f0) { switch(instruction & 0x1f0) {
case 0x100: DecodeOp(ABCD); // 4-3 (p107) case 0x100: Decode(Op::ABCD); // 4-3 (p107)
default: break; default: break;
} }
switch(instruction & 0x0c0) { switch(instruction & 0x0c0) {
// 4-15 (p119) // 4-15 (p119)
case 0x00: DecodeOp(ANDb); case 0x00: Decode(Op::ANDb);
case 0x40: DecodeOp(ANDw); case 0x40: Decode(Op::ANDw);
case 0x80: DecodeOp(ANDl); case 0x80: Decode(Op::ANDl);
default: break; default: break;
} }
switch(instruction & 0x1c0) { switch(instruction & 0x1c0) {
case 0x0c0: DecodeOp(MULU); // 4-139 (p243) case 0x0c0: Decode(Op::MULU); // 4-139 (p243)
case 0x1c0: DecodeOp(MULS); // 4-136 (p240) case 0x1c0: Decode(Op::MULS); // 4-136 (p240)
default: break; default: break;
} }
@@ -637,7 +659,7 @@ Preinstruction Predecoder<model>::decodeC(uint16_t instruction) {
switch(instruction & 0x1f8) { switch(instruction & 0x1f8) {
case 0x140: case 0x140:
case 0x148: case 0x148:
case 0x188: DecodeOp(EXG); case 0x188: Decode(Op::EXG);
default: break; default: break;
} }
@@ -646,28 +668,30 @@ Preinstruction Predecoder<model>::decodeC(uint16_t instruction) {
template <Model model> template <Model model>
Preinstruction Predecoder<model>::decodeD(uint16_t instruction) { Preinstruction Predecoder<model>::decodeD(uint16_t instruction) {
using Op = Operation;
switch(instruction & 0x0c0) { switch(instruction & 0x0c0) {
// 4-4 (p108) // 4-4 (p108)
case 0x000: DecodeOp(ADDb); case 0x000: Decode(Op::ADDb);
case 0x040: DecodeOp(ADDw); case 0x040: Decode(Op::ADDw);
case 0x080: DecodeOp(ADDl); case 0x080: Decode(Op::ADDl);
default: break; default: break;
} }
switch(instruction & 0x1c0) { switch(instruction & 0x1c0) {
// 4-7 (p111) // 4-7 (p111)
case 0x0c0: DecodeOp(ADDAw); case 0x0c0: Decode(Op::ADDAw);
case 0x1c0: DecodeOp(ADDAl); case 0x1c0: Decode(Op::ADDAl);
default: break; default: break;
} }
switch(instruction & 0x1f0) { switch(instruction & 0x1f0) {
// 4-14 (p118) // 4-14 (p118)
case 0x100: DecodeOp(ADDXb); case 0x100: Decode(Op::ADDXb);
case 0x140: DecodeOp(ADDXw); case 0x140: Decode(Op::ADDXw);
case 0x180: DecodeOp(ADDXl); case 0x180: Decode(Op::ADDXl);
default: break; default: break;
} }
@@ -677,59 +701,61 @@ Preinstruction Predecoder<model>::decodeD(uint16_t instruction) {
template <Model model> template <Model model>
Preinstruction Predecoder<model>::decodeE(uint16_t instruction) { Preinstruction Predecoder<model>::decodeE(uint16_t instruction) {
using Op = Operation;
switch(instruction & 0x1d8) { switch(instruction & 0x1d8) {
// 4-22 (p126) // 4-22 (p126)
case 0x000: DecodeOp(ASRb); case 0x000: Decode(Op::ASRb);
case 0x040: DecodeOp(ASRw); case 0x040: Decode(Op::ASRw);
case 0x080: DecodeOp(ASRl); case 0x080: Decode(Op::ASRl);
// 4-113 (p217) // 4-113 (p217)
case 0x008: DecodeOp(LSRb); case 0x008: Decode(Op::LSRb);
case 0x048: DecodeOp(LSRw); case 0x048: Decode(Op::LSRw);
case 0x088: DecodeOp(LSRl); case 0x088: Decode(Op::LSRl);
// 4-163 (p267) // 4-163 (p267)
case 0x010: DecodeOp(ROXRb); case 0x010: Decode(Op::ROXRb);
case 0x050: DecodeOp(ROXRw); case 0x050: Decode(Op::ROXRw);
case 0x090: DecodeOp(ROXRl); case 0x090: Decode(Op::ROXRl);
// 4-160 (p264) // 4-160 (p264)
case 0x018: DecodeOp(RORb); case 0x018: Decode(Op::RORb);
case 0x058: DecodeOp(RORw); case 0x058: Decode(Op::RORw);
case 0x098: DecodeOp(RORl); case 0x098: Decode(Op::RORl);
// 4-22 (p126) // 4-22 (p126)
case 0x100: DecodeOp(ASLb); case 0x100: Decode(Op::ASLb);
case 0x140: DecodeOp(ASLw); case 0x140: Decode(Op::ASLw);
case 0x180: DecodeOp(ASLl); case 0x180: Decode(Op::ASLl);
// 4-113 (p217) // 4-113 (p217)
case 0x108: DecodeOp(LSLb); case 0x108: Decode(Op::LSLb);
case 0x148: DecodeOp(LSLw); case 0x148: Decode(Op::LSLw);
case 0x188: DecodeOp(LSLl); case 0x188: Decode(Op::LSLl);
// 4-163 (p267) // 4-163 (p267)
case 0x110: DecodeOp(ROXLb); case 0x110: Decode(Op::ROXLb);
case 0x150: DecodeOp(ROXLw); case 0x150: Decode(Op::ROXLw);
case 0x190: DecodeOp(ROXLl); case 0x190: Decode(Op::ROXLl);
// 4-160 (p264) // 4-160 (p264)
case 0x118: DecodeOp(ROLb); case 0x118: Decode(Op::ROLb);
case 0x158: DecodeOp(ROLw); case 0x158: Decode(Op::ROLw);
case 0x198: DecodeOp(ROLl); case 0x198: Decode(Op::ROLl);
default: break; default: break;
} }
switch(instruction & 0xfc0) { switch(instruction & 0xfc0) {
case 0x0c0: DecodeOp(ASRm); // 4-22 (p126) case 0x0c0: Decode(Op::ASRm); // 4-22 (p126)
case 0x1c0: DecodeOp(ASLm); // 4-22 (p126) case 0x1c0: Decode(Op::ASLm); // 4-22 (p126)
case 0x2c0: DecodeOp(LSRm); // 4-113 (p217) case 0x2c0: Decode(Op::LSRm); // 4-113 (p217)
case 0x3c0: DecodeOp(LSLm); // 4-113 (p217) case 0x3c0: Decode(Op::LSLm); // 4-113 (p217)
case 0x4c0: DecodeOp(ROXRm); // 4-163 (p267) case 0x4c0: Decode(Op::ROXRm); // 4-163 (p267)
case 0x5c0: DecodeOp(ROXLm); // 4-163 (p267) case 0x5c0: Decode(Op::ROXLm); // 4-163 (p267)
case 0x6c0: DecodeOp(RORm); // 4-160 (p264) case 0x6c0: Decode(Op::RORm); // 4-160 (p264)
case 0x7c0: DecodeOp(ROLm); // 4-160 (p264) case 0x7c0: Decode(Op::ROLm); // 4-160 (p264)
default: break; default: break;
} }
@@ -742,8 +768,7 @@ Preinstruction Predecoder<model>::decodeF(uint16_t) {
return Preinstruction(); return Preinstruction();
} }
#undef DecodeOp #undef Decode
#undef DecodeEop
// MARK: - Main decoder. // MARK: - Main decoder.

View File

@@ -44,16 +44,16 @@ template <Model model> class Predecoder {
Preinstruction decodeE(uint16_t instruction); Preinstruction decodeE(uint16_t instruction);
Preinstruction decodeF(uint16_t instruction); Preinstruction decodeF(uint16_t instruction);
using Op = uint8_t; using OpT = uint8_t;
// Specific instruction decoders. // Specific instruction decoders.
template <Op operation, bool validate> Preinstruction decode(uint16_t instruction); template <OpT operation, bool validate> Preinstruction decode(uint16_t instruction);
// Extended operation list; collapses into a single byte enough information to // Extended operation list; collapses into a single byte enough information to
// know both the type of operation and how to decode the operands. Most of the // know both the type of operation and how to decode the operands. Most of the
// time that's knowable from the Operation alone, hence the rather awkward // time that's knowable from the Operation alone, hence the rather awkward
// extension of @c Operation. // extension of @c Operation.
enum ExtendedOperation: Op { enum ExtendedOperation: OpT {
MOVEMtoRl = uint8_t(Operation::Max), MOVEMtoRw, MOVEMtoRl = uint8_t(Operation::Max), MOVEMtoRw,
MOVEMtoMl, MOVEMtoMw, MOVEMtoMl, MOVEMtoMw,
@@ -74,10 +74,12 @@ template <Model model> class Predecoder {
BTSTI, BCHGI, BCLRI, BSETI, BTSTI, BCHGI, BCLRI, BSETI,
LEA,
MOVEq, MOVEq,
}; };
static constexpr Operation operation(Op op); static constexpr Operation operation(OpT op);
}; };
} }