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

Attempt a more compact retelling.

This commit is contained in:
Thomas Harte 2022-04-24 14:47:14 -04:00
parent b965f2053a
commit 94e5436f6e

View File

@ -143,140 +143,95 @@ constexpr Operation Predecoder<model>::operation(OpT op) {
template <Model model> template <Model model>
template <uint8_t op> uint32_t Predecoder<model>::invalid_operands() { template <uint8_t op> uint32_t Predecoder<model>::invalid_operands() {
constexpr auto Dn = Mask< AddressingMode::DataRegisterDirect >::value;
constexpr auto An = Mask< AddressingMode::AddressRegisterDirect >::value;
constexpr auto Ind = Mask< AddressingMode::AddressRegisterIndirect >::value;
constexpr auto PostInc = Mask< AddressingMode::AddressRegisterIndirectWithPostincrement >::value;
constexpr auto PreDec = Mask< AddressingMode::AddressRegisterIndirectWithPredecrement >::value;
constexpr auto d16An = Mask< AddressingMode::AddressRegisterIndirectWithDisplacement >::value;
constexpr auto d8AnXn = Mask< AddressingMode::AddressRegisterIndirectWithIndex8bitDisplacement >::value;
constexpr auto XXXw = Mask< AddressingMode::AbsoluteShort >::value;
constexpr auto XXXl = Mask< AddressingMode::AbsoluteLong >::value;
constexpr auto d16PC = Mask< AddressingMode::ProgramCounterIndirectWithDisplacement >::value;
constexpr auto d8PCXn = Mask< AddressingMode::ProgramCounterIndirectWithIndex8bitDisplacement >::value;
constexpr auto Imm = Mask< AddressingMode::ImmediateData >::value;
constexpr auto Quick = Mask< AddressingMode::Quick >::value;
// A few recurring combinations; terminology is directly from // A few recurring combinations; terminology is directly from
// the Programmers' Reference Manual. // the Programmers' Reference Manual.
// //
// All modes: the complete set. // All modes: the complete set (other than Quick).
// //
// (and the complete set without AddressRegisterDirect, for byte operations). // (and the complete set without AddressRegisterDirect, for byte operations).
static constexpr uint32_t AllModes = Mask< static constexpr auto AllModes = Dn | An | Ind | PostInc | PreDec | d16An | d8AnXn | XXXw | XXXl | d16PC | d8PCXn | Imm;
AddressingMode::DataRegisterDirect, static constexpr auto AllModes_b = AllModes & ~An;
AddressingMode::AddressRegisterDirect,
AddressingMode::AddressRegisterIndirect,
AddressingMode::AddressRegisterIndirectWithPostincrement,
AddressingMode::AddressRegisterIndirectWithPredecrement,
AddressingMode::AddressRegisterIndirectWithDisplacement,
AddressingMode::AddressRegisterIndirectWithIndex8bitDisplacement,
AddressingMode::AbsoluteShort,
AddressingMode::AbsoluteLong,
AddressingMode::ImmediateData,
AddressingMode::ProgramCounterIndirectWithDisplacement,
AddressingMode::ProgramCounterIndirectWithIndex8bitDisplacement
>::value;
static constexpr uint32_t AllModes_b = Mask<
AddressingMode::DataRegisterDirect,
AddressingMode::AddressRegisterIndirect,
AddressingMode::AddressRegisterIndirectWithPostincrement,
AddressingMode::AddressRegisterIndirectWithPredecrement,
AddressingMode::AddressRegisterIndirectWithDisplacement,
AddressingMode::AddressRegisterIndirectWithIndex8bitDisplacement,
AddressingMode::AbsoluteShort,
AddressingMode::AbsoluteLong,
AddressingMode::ImmediateData,
AddressingMode::ProgramCounterIndirectWithDisplacement,
AddressingMode::ProgramCounterIndirectWithIndex8bitDisplacement
>::value;
// //
// Alterable addressing modes (with and without AddressRegisterDirect). // Alterable addressing modes (with and without AddressRegisterDirect).
// //
// Dn, An, (An), (An)+, -(An), (d16, An), (d8, An, Xn), (xxx).W, (xxx).L // Dn, An, (An), (An)+, -(An), (d16, An), (d8, An, Xn), (xxx).W, (xxx).L
// (and sans An for _b) // (and sans An for _b)
static constexpr uint32_t AlterableAddressingModes = Mask< static constexpr auto AlterableAddressingModes = Dn | An | Ind | PostInc | PreDec | d16An | d8AnXn | XXXw | XXXl;
AddressingMode::DataRegisterDirect, static constexpr auto AlterableAddressingModes_b = AlterableAddressingModes & ~An;
AddressingMode::AddressRegisterDirect,
AddressingMode::AddressRegisterIndirect,
AddressingMode::AddressRegisterIndirectWithPostincrement,
AddressingMode::AddressRegisterIndirectWithPredecrement,
AddressingMode::AddressRegisterIndirectWithDisplacement,
AddressingMode::AddressRegisterIndirectWithIndex8bitDisplacement,
AddressingMode::AbsoluteShort,
AddressingMode::AbsoluteLong
>::value;
static constexpr uint32_t AlterableAddressingModes_b = Mask<
AddressingMode::DataRegisterDirect,
AddressingMode::AddressRegisterIndirect,
AddressingMode::AddressRegisterIndirectWithPostincrement,
AddressingMode::AddressRegisterIndirectWithPredecrement,
AddressingMode::AddressRegisterIndirectWithDisplacement,
AddressingMode::AddressRegisterIndirectWithIndex8bitDisplacement,
AddressingMode::AbsoluteShort,
AddressingMode::AbsoluteLong
>::value;
switch(op) { switch(op) {
default: return NoOperandMask::value; default: return NoOperandMask::value;
case OpT(Operation::ABCD): case OpT(Operation::ABCD):
case OpT(Operation::ADDXb): case OpT(Operation::ADDXw): case OpT(Operation::ADDXl): case OpT(Operation::ADDXb): case OpT(Operation::ADDXw): case OpT(Operation::ADDXl):
return ~TwoOperandMask<Mask< return ~TwoOperandMask<
AddressingMode::DataRegisterDirect, Dn | PreDec,
AddressingMode::AddressRegisterIndirectWithPredecrement Dn | PreDec
>::value, Mask< >::value;
AddressingMode::DataRegisterDirect,
AddressingMode::AddressRegisterIndirectWithPredecrement
>::value>::value;
case ADDtoRb: case ADDtoRb:
return ~TwoOperandMask< return ~TwoOperandMask<
AllModes_b AllModes_b,
, Mask< Dn
AddressingMode::DataRegisterDirect >::value;
>::value>::value;
case ADDtoRw: case ADDtoRl: case ADDtoRw: case ADDtoRl:
return ~TwoOperandMask< return ~TwoOperandMask<
AllModes AllModes,
, Mask< Dn
AddressingMode::DataRegisterDirect >::value;
>::value>::value;
case ADDtoMb: case ADDtoMw: case ADDtoMl: case ADDtoMb: case ADDtoMw: case ADDtoMl:
return ~TwoOperandMask<Mask< return ~TwoOperandMask<
AddressingMode::DataRegisterDirect Dn,
>::value, Mask< Ind | PostInc | PreDec | d16An | d8AnXn | XXXw | XXXl
// TODO: I strongly suspect this should be AlterableAddressingModes regardless >::value;
// of the documentation. Verify.
AddressingMode::AddressRegisterIndirect,
AddressingMode::AddressRegisterIndirectWithPostincrement,
AddressingMode::AddressRegisterIndirectWithPredecrement,
AddressingMode::AddressRegisterIndirectWithDisplacement,
AddressingMode::AddressRegisterIndirectWithIndex8bitDisplacement,
AddressingMode::AbsoluteShort,
AddressingMode::AbsoluteLong
>::value>::value;
case OpT(Operation::ADDAw): case OpT(Operation::ADDAl): case OpT(Operation::ADDAw): case OpT(Operation::ADDAl):
return ~TwoOperandMask< return ~TwoOperandMask<
AllModes AllModes,
, Mask< An
AddressingMode::AddressRegisterDirect >::value;
>::value>::value;
case ADDIb: case ADDIl: case ADDIw: case ADDIb: case ADDIl: case ADDIw:
return ~TwoOperandMask<Mask< return ~TwoOperandMask<
AddressingMode::ImmediateData Imm,
>::value,
AlterableAddressingModes_b AlterableAddressingModes_b
>::value; >::value;
case ADDQb: case ADDQb:
return ~TwoOperandMask<Mask< return ~TwoOperandMask<
AddressingMode::Quick Quick,
>::value,
AlterableAddressingModes_b AlterableAddressingModes_b
>::value; >::value;
case ADDQw: case ADDQl: case ADDQw: case ADDQl:
return ~TwoOperandMask<Mask< return ~TwoOperandMask<
AddressingMode::Quick Quick,
>::value,
AlterableAddressingModes AlterableAddressingModes
>::value; >::value;
case OpT(Operation::NBCD): case OpT(Operation::NBCD):
return ~OneOperandMask<AlterableAddressingModes_b>::value; return ~OneOperandMask<
AlterableAddressingModes_b
>::value;
} }
} }
@ -363,11 +318,9 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::validated
} }
// ADD, SUB, MOVE, MOVEA // ADD, SUB, MOVE, MOVEA
// case ADDQb: case ADDQw: case ADDQl:
case SUBQb: case SUBQw: case SUBQl: 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):
case OpT(Operation::ANDb): case OpT(Operation::ANDw): case OpT(Operation::ANDl):
case OpT(Operation::EORb): case OpT(Operation::EORw): case OpT(Operation::EORl): case OpT(Operation::EORb): case OpT(Operation::EORw): case OpT(Operation::EORl):
case OpT(Operation::ORb): case OpT(Operation::ORw): case OpT(Operation::ORl): { case OpT(Operation::ORb): case OpT(Operation::ORw): case OpT(Operation::ORl): {
// TODO: I'm going to need get-size-by-operation elsewhere; use that here when implemented. // TODO: I'm going to need get-size-by-operation elsewhere; use that here when implemented.
@ -724,31 +677,7 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
// b0b2 and b3b5: an effective address; // b0b2 and b3b5: an effective address;
// b6b8: an opmode, i.e. source + direction. // b6b8: an opmode, i.e. source + direction.
// //
case OpT(Operation::SUBb): case OpT(Operation::SUBw): case OpT(Operation::SUBl):
case OpT(Operation::ANDb): case OpT(Operation::ANDw): case OpT(Operation::ANDl):
case OpT(Operation::ORb): case OpT(Operation::ORw): case OpT(Operation::ORl): {
const auto ea_combined_mode = combined_mode(ea_mode, ea_register);
// TODO: make this decision outside of this function.
if(opmode & 4) {
// Dn, <ea>
return validated<op, validate>(
Preinstruction(operation,
AddressingMode::DataRegisterDirect, data_register,
ea_combined_mode, ea_register));
} else {
// <ea>, Dn
return validated<op, validate>(
Preinstruction(operation,
ea_combined_mode, ea_register,
AddressingMode::DataRegisterDirect, data_register));
}
return Preinstruction();
}
case ADDtoRb: case ADDtoRw: case ADDtoRl: case ADDtoRb: case ADDtoRw: case ADDtoRl: