mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-26 15:32:04 +00:00
Include decoded condition in Preinstruction.
This commit is contained in:
parent
872b941b20
commit
8d24c00df2
@ -479,7 +479,8 @@ template <uint8_t op> uint32_t Predecoder<model>::invalid_operands() {
|
||||
template <Model model>
|
||||
template <uint8_t op, bool validate> Preinstruction Predecoder<model>::validated(
|
||||
AddressingMode op1_mode, int op1_reg,
|
||||
AddressingMode op2_mode, int op2_reg
|
||||
AddressingMode op2_mode, int op2_reg,
|
||||
Condition condition
|
||||
) {
|
||||
constexpr auto operation = Predecoder<model>::operation(op);
|
||||
|
||||
@ -489,7 +490,8 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::validated
|
||||
op1_mode, op1_reg,
|
||||
op2_mode, op2_reg,
|
||||
requires_supervisor<model>(operation),
|
||||
size(operation));
|
||||
size(operation),
|
||||
condition);
|
||||
}
|
||||
|
||||
const auto invalid = invalid_operands<op>();
|
||||
@ -501,7 +503,8 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::validated
|
||||
op1_mode, op1_reg,
|
||||
op2_mode, op2_reg,
|
||||
requires_supervisor<model>(operation),
|
||||
size(operation));
|
||||
size(operation),
|
||||
condition);
|
||||
}
|
||||
|
||||
/// Decodes the fields within an instruction and constructs a `Preinstruction`, given that the operation has already been
|
||||
@ -601,18 +604,29 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
|
||||
combined_mode(ea_mode, ea_register), ea_register);
|
||||
|
||||
//
|
||||
// MARK: STOP, ANDItoCCR, ANDItoSR, EORItoCCR, EORItoSR, ORItoCCR, ORItoSR, Bccl, Bccw, BSRl, BSRw
|
||||
// MARK: STOP, ANDItoCCR, ANDItoSR, EORItoCCR, EORItoSR, ORItoCCR, ORItoSR, BSRl, BSRw
|
||||
//
|
||||
// Operand is an immedate; destination/source (if any) is implied by the operation.
|
||||
// Operand is an immedate; destination/source (if any) is implied by the operation,
|
||||
// e.g. ORItoSR has a destination of SR.
|
||||
//
|
||||
case OpT(Operation::STOP):
|
||||
case OpT(Operation::Bccl): case OpT(Operation::Bccw):
|
||||
case OpT(Operation::BSRl): case OpT(Operation::BSRw):
|
||||
case OpT(Operation::ORItoSR): case OpT(Operation::ORItoCCR):
|
||||
case OpT(Operation::ANDItoSR): case OpT(Operation::ANDItoCCR):
|
||||
case OpT(Operation::EORItoSR): case OpT(Operation::EORItoCCR):
|
||||
return validated<op, validate>(AddressingMode::ImmediateData);
|
||||
|
||||
//
|
||||
// MARK: Bccl, Bccw
|
||||
//
|
||||
// Operand is an immedate; b8–b11 are a condition code.
|
||||
//
|
||||
case OpT(Operation::Bccl): case OpT(Operation::Bccw):
|
||||
return validated<op, validate>(
|
||||
AddressingMode::ImmediateData, 0,
|
||||
AddressingMode::None, 0,
|
||||
Condition((instruction >> 8) & 0xf));
|
||||
|
||||
//
|
||||
// MARK: CHK
|
||||
//
|
||||
@ -724,9 +738,20 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
|
||||
case OpT(Operation::PEA):
|
||||
case OpT(Operation::TAS):
|
||||
case OpT(Operation::TSTb): case OpT(Operation::TSTw): case OpT(Operation::TSTl):
|
||||
case OpT(Operation::Scc):
|
||||
return validated<op, validate>(combined_mode(ea_mode, ea_register), ea_register);
|
||||
|
||||
//
|
||||
// MARK: Scc
|
||||
//
|
||||
// b0–b2 and b3–b5: effective address;
|
||||
// b8–b11: a condition.
|
||||
//
|
||||
case OpT(Operation::Scc):
|
||||
return validated<op, validate>(
|
||||
combined_mode(ea_mode, ea_register), ea_register,
|
||||
AddressingMode::None, 0,
|
||||
Condition((instruction >> 8) & 0xf));
|
||||
|
||||
//
|
||||
// MARK: UNLINK, MOVEtoUSP, MOVEfromUSP
|
||||
//
|
||||
@ -739,13 +764,15 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
|
||||
//
|
||||
// MARK: DBcc
|
||||
//
|
||||
// b0–b2: a data register.
|
||||
// b0–b2: a data register;
|
||||
// b8–b11: a condition.
|
||||
// Followed by an immediate value.
|
||||
//
|
||||
case OpT(Operation::DBcc):
|
||||
return validated<op, validate>(
|
||||
AddressingMode::DataRegisterDirect, ea_register,
|
||||
AddressingMode::ImmediateData, 0);
|
||||
AddressingMode::ImmediateData, 0,
|
||||
Condition((instruction >> 8) & 0xf));
|
||||
|
||||
//
|
||||
// MARK: SWAP, EXTbtow, EXTwtol
|
||||
|
@ -56,7 +56,8 @@ template <Model model> class Predecoder {
|
||||
template <OpT operation, bool validate = true> Preinstruction decode(uint16_t instruction);
|
||||
template <OpT operation, bool validate> Preinstruction validated(
|
||||
AddressingMode op1_mode = AddressingMode::None, int op1_reg = 0,
|
||||
AddressingMode op2_mode = AddressingMode::None, int op2_reg = 0
|
||||
AddressingMode op2_mode = AddressingMode::None, int op2_reg = 0,
|
||||
Condition condition = Condition::True
|
||||
);
|
||||
template <uint8_t op> uint32_t invalid_operands();
|
||||
|
||||
|
@ -252,6 +252,17 @@ constexpr uint32_t quick(Operation op, uint16_t instruction) {
|
||||
}
|
||||
}
|
||||
|
||||
enum class Condition {
|
||||
True = 0x00, False = 0x01,
|
||||
High = 0x02, LowOrSame = 0x03,
|
||||
CarryClear = 0x04, CarrySet = 0x05,
|
||||
NotEqual = 0x06, Equal = 0x07,
|
||||
OverflowClear = 0x08, OverflowSet = 0x09,
|
||||
Positive = 0x0a, Negative = 0x0b,
|
||||
GreaterThanOrEqual = 0x0c, LessThan = 0x0d,
|
||||
GreaterThan = 0x0e, LessThanOrEqual = 0x0f,
|
||||
};
|
||||
|
||||
/// Indicates the addressing mode applicable to an operand.
|
||||
///
|
||||
/// Implementation notes:
|
||||
@ -363,7 +374,10 @@ class Preinstruction {
|
||||
return flags_ & 0x80;
|
||||
}
|
||||
DataSize size() {
|
||||
return DataSize(flags_ & 0x7f);
|
||||
return DataSize(flags_ & 0x03);
|
||||
}
|
||||
Condition condition() {
|
||||
return Condition((flags_ >> 2) & 0x0f);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -376,11 +390,16 @@ class Preinstruction {
|
||||
AddressingMode op1_mode, int op1_reg,
|
||||
AddressingMode op2_mode, int op2_reg,
|
||||
bool is_supervisor,
|
||||
DataSize size) : operation(operation)
|
||||
DataSize size,
|
||||
Condition condition) : operation(operation)
|
||||
{
|
||||
operands_[0] = uint8_t(op1_mode) | uint8_t(op1_reg << 5);
|
||||
operands_[1] = uint8_t(op2_mode) | uint8_t(op2_reg << 5);
|
||||
flags_ = (is_supervisor ? 0x80 : 0x00) | uint8_t(size);
|
||||
flags_ = uint8_t(
|
||||
(is_supervisor ? 0x80 : 0x00) |
|
||||
(int(condition) << 2) |
|
||||
int(size)
|
||||
);
|
||||
}
|
||||
|
||||
Preinstruction() {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user