1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 23:52:26 +00:00

Handle no-base case directly in existing switch.

This commit is contained in:
Thomas Harte 2022-03-09 20:20:32 -05:00
parent 520baa6ec8
commit cf6a910630

View File

@ -152,6 +152,7 @@ template <Model model, typename RegistersT, typename MemoryT> class DataPointerR
/// Computes the effective address of @c pointer including any displacement applied by @c instruction. /// Computes the effective address of @c pointer including any displacement applied by @c instruction.
/// @c pointer must be of type Source::Indirect. /// @c pointer must be of type Source::Indirect.
template <bool obscured_indirectNoBase = true, bool has_base = true>
static uint32_t effective_address( static uint32_t effective_address(
RegistersT &registers, RegistersT &registers,
const Instruction<is_32bit(model)> &instruction, const Instruction<is_32bit(model)> &instruction,
@ -211,6 +212,7 @@ template <typename DataT> void DataPointerResolver<model, RegistersT, MemoryT>::
rw(v, FS, i); rw(v, GS, i); rw(v, FS, i); rw(v, GS, i);
template <Model model, typename RegistersT, typename MemoryT> template <Model model, typename RegistersT, typename MemoryT>
template <bool obscured_indirectNoBase, bool has_base>
uint32_t DataPointerResolver<model, RegistersT, MemoryT>::effective_address( uint32_t DataPointerResolver<model, RegistersT, MemoryT>::effective_address(
RegistersT &registers, RegistersT &registers,
const Instruction<is_32bit(model)> &instruction, const Instruction<is_32bit(model)> &instruction,
@ -218,10 +220,12 @@ uint32_t DataPointerResolver<model, RegistersT, MemoryT>::effective_address(
using AddressT = typename Instruction<is_32bit(model)>::AddressT; using AddressT = typename Instruction<is_32bit(model)>::AddressT;
AddressT base = 0, index = 0; AddressT base = 0, index = 0;
switch(pointer.base()) { if constexpr (has_base) {
switch(pointer.base<obscured_indirectNoBase>()) {
default: break; default: break;
ALLREGS(base, false); ALLREGS(base, false);
} }
}
switch(pointer.index()) { switch(pointer.index()) {
default: break; default: break;
@ -257,7 +261,7 @@ template <bool is_write, typename DataT> void DataPointerResolver<model, Registe
const Instruction<is_32bit(model)> &instruction, const Instruction<is_32bit(model)> &instruction,
DataPointer pointer, DataPointer pointer,
DataT &value) { DataT &value) {
const Source source = pointer.source(); const Source source = pointer.source<false>();
switch(source) { switch(source) {
default: default:
@ -279,22 +283,32 @@ template <bool is_write, typename DataT> void DataPointerResolver<model, Registe
value = DataT(instruction.operand()); value = DataT(instruction.operand());
break; break;
case Source::Indirect: { #define indirect(has_base) { \
const auto address = effective_address(registers, instruction, pointer); const auto address = effective_address<false, has_base> \
(registers, instruction, pointer); \
\
if constexpr (is_write) { \
memory.template write( \
instruction.data_segment(), \
address, \
value \
); \
} else { \
value = memory.template read<DataT>( \
instruction.data_segment(), \
address \
); \
} \
}
case Source::IndirectNoBase:
indirect(false);
break;
case Source::Indirect:
indirect(true);
break;
#undef indirect
if constexpr (is_write) {
memory.template write(
instruction.data_segment(),
address,
value
);
} else {
value = memory.template read<DataT>(
instruction.data_segment(),
address
);
}
}
} }
} }
#undef ALLREGS #undef ALLREGS