mirror of
https://github.com/TomHarte/CLK.git
synced 2024-10-11 08:23:43 +00:00
Attempt a more compact retelling.
This commit is contained in:
parent
b965f2053a
commit
94e5436f6e
@ -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
|
|||||||
// b0–b2 and b3–b5: an effective address;
|
// b0–b2 and b3–b5: an effective address;
|
||||||
// b6–b8: an opmode, i.e. source + direction.
|
// b6–b8: 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:
|
||||||
|
Loading…
Reference in New Issue
Block a user