1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-30 07:29:06 +00:00

Merge pull request #1030 from TomHarte/68000cc

Include decoded condition in Preinstruction.
This commit is contained in:
Thomas Harte 2022-04-30 13:56:49 -04:00 committed by GitHub
commit 4293ab2acb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 13 deletions

View File

@ -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; b8b11 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
//
// b0b2 and b3b5: effective address;
// b8b11: 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
//
// b0b2: a data register.
// b0b2: a data register;
// b8b11: 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

View File

@ -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();

View File

@ -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() {}