mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-08 14:25:05 +00:00
Add decodes for TRAPcc and PACK, discovering it's three operand (sort of).
This commit is contained in:
@@ -340,17 +340,22 @@ template <uint8_t op> uint32_t Predecoder<model>::invalid_operands() {
|
|||||||
case OpT(Operation::BFCHG): case OpT(Operation::BFCLR): case OpT(Operation::BFSET):
|
case OpT(Operation::BFCHG): case OpT(Operation::BFCLR): case OpT(Operation::BFSET):
|
||||||
case OpT(Operation::BFINS):
|
case OpT(Operation::BFINS):
|
||||||
return ~TwoOperandMask<
|
return ~TwoOperandMask<
|
||||||
Imm,
|
Ext,
|
||||||
Dn | Ind | d16An | d8AnXn | XXXw | XXXl
|
Dn | Ind | d16An | d8AnXn | XXXw | XXXl
|
||||||
>::value;
|
>::value;
|
||||||
|
|
||||||
case OpT(Operation::BFTST): case OpT(Operation::BFFFO): case OpT(Operation::BFEXTU):
|
case OpT(Operation::BFTST): case OpT(Operation::BFFFO): case OpT(Operation::BFEXTU):
|
||||||
case OpT(Operation::BFEXTS):
|
case OpT(Operation::BFEXTS):
|
||||||
return ~TwoOperandMask<
|
return ~TwoOperandMask<
|
||||||
Imm,
|
Ext,
|
||||||
Dn | Ind | d16An | d8AnXn | XXXw | XXXl | d16PC | d8PCXn
|
Dn | Ind | d16An | d8AnXn | XXXw | XXXl | d16PC | d8PCXn
|
||||||
>::value;
|
>::value;
|
||||||
|
|
||||||
|
case OpT(Operation::PACK):
|
||||||
|
return ~OneOperandMask<
|
||||||
|
Imm
|
||||||
|
>::value;
|
||||||
|
|
||||||
case CMPIb: case CMPIl: case CMPIw:
|
case CMPIb: case CMPIl: case CMPIw:
|
||||||
if constexpr (model == Model::M68000) {
|
if constexpr (model == Model::M68000) {
|
||||||
return ~TwoOperandMask<
|
return ~TwoOperandMask<
|
||||||
@@ -527,6 +532,7 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::validated
|
|||||||
op1_mode, op1_reg,
|
op1_mode, op1_reg,
|
||||||
op2_mode, op2_reg,
|
op2_mode, op2_reg,
|
||||||
requires_supervisor<model>(operation),
|
requires_supervisor<model>(operation),
|
||||||
|
requires_extension_word(operation),
|
||||||
operand_size(operation),
|
operand_size(operation),
|
||||||
condition);
|
condition);
|
||||||
}
|
}
|
||||||
@@ -540,6 +546,7 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::validated
|
|||||||
op1_mode, op1_reg,
|
op1_mode, op1_reg,
|
||||||
op2_mode, op2_reg,
|
op2_mode, op2_reg,
|
||||||
requires_supervisor<model>(operation),
|
requires_supervisor<model>(operation),
|
||||||
|
requires_extension_word(operation),
|
||||||
operand_size(operation),
|
operand_size(operation),
|
||||||
condition);
|
condition);
|
||||||
}
|
}
|
||||||
@@ -940,7 +947,7 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
|
|||||||
case OpT(Operation::BFEXTU): case OpT(Operation::BFEXTS): case OpT(Operation::BFCLR):
|
case OpT(Operation::BFEXTU): case OpT(Operation::BFEXTS): case OpT(Operation::BFCLR):
|
||||||
case OpT(Operation::BFSET): case OpT(Operation::BFINS):
|
case OpT(Operation::BFSET): case OpT(Operation::BFINS):
|
||||||
return validated<op, validate>(
|
return validated<op, validate>(
|
||||||
AddressingMode::ImmediateData, 0,
|
AddressingMode::ExtensionWord, 0,
|
||||||
combined_mode(ea_mode, ea_register), ea_register);
|
combined_mode(ea_mode, ea_register), ea_register);
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -973,6 +980,18 @@ template <uint8_t op, bool validate> Preinstruction Predecoder<model>::decode(ui
|
|||||||
return validated<op, validate>(addressing_mode, ea_register);
|
return validated<op, validate>(addressing_mode, ea_register);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// MARK: PACK
|
||||||
|
//
|
||||||
|
// b0–b2: a register number;
|
||||||
|
// b3: address/data register selection — if address registers, then this is predec;
|
||||||
|
// b9–b11: an additional register number.
|
||||||
|
// This instruction is also followed by a 16-bit adjustment extension.
|
||||||
|
//
|
||||||
|
case OpT(Operation::PACK):
|
||||||
|
// TODO; need to square the wheel on a prima-facie three operands.
|
||||||
|
return Preinstruction();
|
||||||
|
|
||||||
//
|
//
|
||||||
// MARK: DIVl
|
// MARK: DIVl
|
||||||
//
|
//
|
||||||
@@ -1291,12 +1310,23 @@ Preinstruction Predecoder<model>::decode5(uint16_t instruction) {
|
|||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch(instruction & 0x0ff) {
|
||||||
|
// 4-173 (p276)
|
||||||
|
case 0x0f8: case 0x0f9: Decode(Op::Scc);
|
||||||
|
|
||||||
|
// 4-189 (p294)
|
||||||
|
case 0x0fa: case 0x0fb: case 0x0fc:
|
||||||
|
DecodeReq(model >= Model::M68020, Op::TRAPcc);
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
switch(instruction & 0x0f8) {
|
switch(instruction & 0x0f8) {
|
||||||
// 4-173 (p276)
|
// 4-173 (p276)
|
||||||
case 0x0c0:
|
case 0x0c0:
|
||||||
case 0x0d0: case 0x0d8:
|
case 0x0d0: case 0x0d8:
|
||||||
case 0x0e0: case 0x0e8:
|
case 0x0e0: case 0x0e8:
|
||||||
case 0x0f0: case 0x0f8: Decode(Op::Scc);
|
case 0x0f0: Decode(Op::Scc);
|
||||||
|
|
||||||
// 4-91 (p195)
|
// 4-91 (p195)
|
||||||
case 0x0c8: Decode(Op::DBcc);
|
case 0x0c8: Decode(Op::DBcc);
|
||||||
@@ -1352,8 +1382,13 @@ template <Model model>
|
|||||||
Preinstruction Predecoder<model>::decode8(uint16_t instruction) {
|
Preinstruction Predecoder<model>::decode8(uint16_t instruction) {
|
||||||
using Op = Operation;
|
using Op = Operation;
|
||||||
|
|
||||||
// 4-171 (p275)
|
|
||||||
if((instruction & 0x1f0) == 0x100) Decode(Op::SBCD);
|
switch(instruction & 0x1f0) {
|
||||||
|
case 0x100: Decode(Op::SBCD); // 4-171 (p275)
|
||||||
|
case 0x1f0: DecodeReq(model >= Model::M68020, Op::PACK); // 4-157 (p261)
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
switch(instruction & 0x1c0) {
|
switch(instruction & 0x1c0) {
|
||||||
case 0x0c0: Decode(Op::DIVUw); // 4-97 (p201)
|
case 0x0c0: Decode(Op::DIVUw); // 4-97 (p201)
|
||||||
|
@@ -168,6 +168,16 @@ constexpr bool requires_supervisor(Operation op) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline constexpr bool requires_extension_word(Operation op) {
|
||||||
|
switch(op) {
|
||||||
|
case Operation::PACK:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum class DataSize {
|
enum class DataSize {
|
||||||
Byte = 0,
|
Byte = 0,
|
||||||
Word = 1,
|
Word = 1,
|
||||||
@@ -356,13 +366,16 @@ class Preinstruction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool requires_supervisor() const {
|
bool requires_supervisor() const {
|
||||||
return flags_ & 0x80;
|
return flags_ & Flags::IsSupervisor;
|
||||||
|
}
|
||||||
|
bool requires_extension_word() const {
|
||||||
|
return flags_ & Flags::RequiresExtensionWord;
|
||||||
}
|
}
|
||||||
DataSize operand_size() const {
|
DataSize operand_size() const {
|
||||||
return DataSize(flags_ & 0x03);
|
return DataSize((flags_ & Flags::SizeMask) >> Flags::SizeShift);
|
||||||
}
|
}
|
||||||
Condition condition() const {
|
Condition condition() const {
|
||||||
return Condition((flags_ >> 2) & 0x0f);
|
return Condition((flags_ & Flags::ConditionMask) >> Flags::ConditionShift);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -377,18 +390,30 @@ class Preinstruction {
|
|||||||
AddressingMode op1_mode, int op1_reg,
|
AddressingMode op1_mode, int op1_reg,
|
||||||
AddressingMode op2_mode, int op2_reg,
|
AddressingMode op2_mode, int op2_reg,
|
||||||
bool is_supervisor,
|
bool is_supervisor,
|
||||||
|
bool requires_extension_word,
|
||||||
DataSize size,
|
DataSize size,
|
||||||
Condition condition) : operation(operation)
|
Condition condition) : operation(operation)
|
||||||
{
|
{
|
||||||
operands_[0] = uint8_t((uint8_t(op1_mode) << 3) | op1_reg);
|
operands_[0] = uint8_t((uint8_t(op1_mode) << 3) | op1_reg);
|
||||||
operands_[1] = uint8_t((uint8_t(op2_mode) << 3) | op2_reg);
|
operands_[1] = uint8_t((uint8_t(op2_mode) << 3) | op2_reg);
|
||||||
flags_ = uint8_t(
|
flags_ = uint8_t(
|
||||||
(is_supervisor ? 0x80 : 0x00) |
|
(is_supervisor ? Flags::IsSupervisor : 0x00) |
|
||||||
(int(condition) << 2) |
|
(requires_extension_word ? Flags::RequiresExtensionWord : 0x00) |
|
||||||
int(size)
|
(int(condition) << Flags::ConditionShift) |
|
||||||
|
(int(size) << Flags::SizeShift)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Flags {
|
||||||
|
static constexpr uint8_t IsSupervisor = 0b1000'0000;
|
||||||
|
static constexpr uint8_t RequiresExtensionWord = 0b0100'0000;
|
||||||
|
static constexpr uint8_t ConditionMask = 0b0011'1100;
|
||||||
|
static constexpr uint8_t SizeMask = 0b0000'0011;
|
||||||
|
|
||||||
|
static constexpr int ConditionShift = 2;
|
||||||
|
static constexpr int SizeShift = 0;
|
||||||
|
};
|
||||||
|
|
||||||
Preinstruction() {}
|
Preinstruction() {}
|
||||||
|
|
||||||
/// Produces a string description of this instruction; if @c opcode
|
/// Produces a string description of this instruction; if @c opcode
|
||||||
|
Reference in New Issue
Block a user