1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-22 12:33:29 +00:00

Eliminate assumption.

This commit is contained in:
Thomas Harte 2022-05-23 08:18:37 -04:00
parent c8ede400eb
commit 1b3acf9cd8
2 changed files with 19 additions and 10 deletions

View File

@ -1249,21 +1249,24 @@ void Processor<BusHandler, dtack_is_implicit, permit_overrun, signal_will_perfor
MoveToNextOperand(StoreOperand_bw);
}
// Assumption enshrined here: there are no write-only Dn
// byte operations. i.e. anything that should technically
// write back only a byte will have read from the register
// before the operation, making it safe to write back the
// entire word.
//
// However there are write-only Dn word operations, and
// the sign-extended top half needs to be kept for An.
switch(instruction_.mode(next_operand_)) {
case Mode::DataRegisterDirect:
registers_[instruction_.lreg(next_operand_)].w = operand_[next_operand_].w;
// Data register: write only the part of the word that has changed.
case Mode::DataRegisterDirect: {
const uint32_t write_mask = size_masks[int(instruction_.operand_size())];
const int reg = instruction_.reg(next_operand_);
registers_[reg].l =
(operand_[next_operand_].l & write_mask) |
(registers_[reg].l & ~write_mask);
}
MoveToNextOperand(StoreOperand_bw);
// Address register: always rewrite the whole word; the smaller
// result will have been sign extended.
case Mode::AddressRegisterDirect:
registers_[instruction_.lreg(next_operand_)] = operand_[next_operand_];
MoveToNextOperand(StoreOperand_bw);
default: break;
}

View File

@ -112,6 +112,12 @@ struct ProcessorBase: public InstructionSet::M68k::NullFlowController {
{ 2, 2, 2, 2, 2, 2, 2, 2, },
{ 4, 4, 4, 4, 4, 4, 4, 4, },
};
// A lookup table that ensures write-back to data registers affects
// only the correct bits.
static constexpr uint32_t size_masks[3] = { 0xff, 0xffff, 0xffff'ffff };
// Assumptions used by the lookup tables above:
static_assert(int(InstructionSet::M68k::DataSize::Byte) == 0);
static_assert(int(InstructionSet::M68k::DataSize::Word) == 1);
static_assert(int(InstructionSet::M68k::DataSize::LongWord) == 2);