diff --git a/InstructionSets/CachingExecutor.hpp b/InstructionSets/CachingExecutor.hpp index ccb27e368..469ebbf82 100644 --- a/InstructionSets/CachingExecutor.hpp +++ b/InstructionSets/CachingExecutor.hpp @@ -127,7 +127,8 @@ template < // and until one branches. has_branched_ = false; for(auto index: program_) { - performers_[index](); + const auto performer = performers_[index]; + (static_cast(this)->*performer)(); if(has_branched_) break; } } diff --git a/InstructionSets/M50740/Executor.cpp b/InstructionSets/M50740/Executor.cpp index ecb7498f6..a3067f14a 100644 --- a/InstructionSets/M50740/Executor.cpp +++ b/InstructionSets/M50740/Executor.cpp @@ -144,7 +144,7 @@ template void Executor::pe } template void Executor::perform(uint8_t *operand [[maybe_unused]]) { - switch(operation) { - default: assert(false); - } +// switch(operation) { +// default: assert(false); +// } } diff --git a/InstructionSets/M50740/Executor.hpp b/InstructionSets/M50740/Executor.hpp index 64b8133d9..29ecd3605 100644 --- a/InstructionSets/M50740/Executor.hpp +++ b/InstructionSets/M50740/Executor.hpp @@ -20,7 +20,7 @@ namespace InstructionSet { namespace M50740 { class Executor; -using CachingExecutor = CachingExecutor; +using CachingExecutor = CachingExecutor; class Executor: public CachingExecutor { public: @@ -58,28 +58,35 @@ class Executor: public CachingExecutor { class PerformerLookup { public: PerformerLookup() { - fill(performers); + fill(performers_); } Performer performer(Operation operation, AddressingMode addressing_mode) { - return performers[int(addressing_mode) * (MaxOperation - MinOperation) + int(operation) - MinOperation]; + const auto index = + (int(operation) - MinOperation) * (1 + MaxAddressingMode - MinAddressingMode) + + (int(addressing_mode) - MinAddressingMode); + + assert(index < decltype(index)(sizeof(performers_)/sizeof(*performers_))); + return performers_[index]; } private: - Performer performers[(MaxAddressingMode - MinAddressingMode) * (MaxOperation - MinOperation)]; + Performer performers_[(1 + MaxAddressingMode - MinAddressingMode) * (1 + MaxOperation - MinOperation)]; template void fill_operation(Performer *target) { *target = &Executor::perform; - if constexpr (addressing_mode+1 < MaxAddressingMode) { + + if constexpr (addressing_mode+1 <= MaxAddressingMode) { fill_operation(target + 1); } } - template void fill(Performer *target) { - fill_operation(target); - target += MaxOperation - MinOperation; - if constexpr (operation+1 < MaxOperation) { - fill(target); + template void fill(Performer *target) { + fill_operation(target); + target += 1 + MaxAddressingMode - MinAddressingMode; + + if constexpr (operation+1 <= MaxOperation) { + fill(target); } } };