From 32e0a666108e422d90eae9a538f471806c601ea1 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 23 Dec 2021 16:28:55 -0500 Subject: [PATCH] Trust the compiler with this bit field. --- .../Implementation/68000Implementation.hpp | 6 ++-- .../68000/Implementation/68000Storage.hpp | 35 +++++++++++++------ 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/Processors/68000/Implementation/68000Implementation.hpp b/Processors/68000/Implementation/68000Implementation.hpp index ca8449fb4..380e6a977 100644 --- a/Processors/68000/Implementation/68000Implementation.hpp +++ b/Processors/68000/Implementation/68000Implementation.hpp @@ -333,7 +333,7 @@ template void Proces #endif if(instructions[decoded_instruction_.full].micro_operations != std::numeric_limits::max()) { - if((instructions[decoded_instruction_.full].source_dest & 0x80) && !is_supervisor_) { + if((instructions[decoded_instruction_.full].requires_supervisor) && !is_supervisor_) { // A privilege violation has been detected. active_program_ = nullptr; active_micro_op_ = short_exception_micro_ops_; @@ -387,9 +387,9 @@ template void Proces #define offset_pointer(x) reinterpret_cast(&reinterpret_cast(static_cast(this))[x]) #define source() offset_pointer(active_program_->source_offset) -#define source_address() address_[(active_program_->source_dest >> 4) & 7] +#define source_address() address_[active_program_->source] #define destination() offset_pointer(active_program_->destination_offset) -#define destination_address() address_[active_program_->source_dest & 7] +#define destination_address() address_[active_program_->dest] case int_type(MicroOp::Action::PerformOperation): #define sub_overflow() ((result ^ destination) & (destination ^ source)) diff --git a/Processors/68000/Implementation/68000Storage.hpp b/Processors/68000/Implementation/68000Storage.hpp index e2b03d948..c87f40b55 100644 --- a/Processors/68000/Implementation/68000Storage.hpp +++ b/Processors/68000/Implementation/68000Storage.hpp @@ -359,6 +359,15 @@ class ProcessorStorage { remaining fields, with no additional padding being inserted by the compiler. */ struct Program { + Program() { + // Initialisers for bitfields aren't available until C++20. So, yuck, do it manually. + requires_supervisor = 0; + source = 0; + dest = 0; + destination_offset = 0; + source_offset = 0; + } + /// The offset into the all_micro_ops_ at which micro-ops for this instruction begin, /// or std::numeric_limits::max() if this is an invalid Program. uint32_t micro_operations = std::numeric_limits::max(); @@ -366,26 +375,30 @@ class ProcessorStorage { Operation operation; /// The number of bytes after the beginning of an instance of ProcessorStorage that the RegisterPair32 containing /// a source value for this operation lies at. - uint8_t source_offset = 0; + uint8_t source_offset: 7; /// The number of bytes after the beginning of an instance of ProcessorStorage that the RegisterPair32 containing /// a destination value for this operation lies at. - uint8_t destination_offset = 0; - /// A bitfield comprised of: - /// b7 = set if this program requires supervisor mode; - /// b0–b2 = the source address register (for pre-decrement and post-increment actions); and - /// b4-b6 = destination address register. - uint8_t source_dest = 0; + uint8_t destination_offset: 7; + /// Set if this program requires supervisor mode. + bool requires_supervisor: 1; + /// The source address register (for pre-decrement and post-increment actions). + uint8_t source: 3; + /// Destination address register. + uint8_t dest: 3; void set_source_address([[maybe_unused]] ProcessorStorage &storage, int index) { - source_dest = uint8_t((source_dest & 0x0f) | (index << 4)); + source = uint8_t(index); + assert(int(source) == index); } void set_destination_address([[maybe_unused]] ProcessorStorage &storage, int index) { - source_dest = uint8_t((source_dest & 0xf0) | index); + dest = uint8_t(index); + assert(int(dest) == index); } - void set_requires_supervisor(bool requires_supervisor) { - source_dest = (source_dest & 0x7f) | (requires_supervisor ? 0x80 : 0x00); + void set_requires_supervisor(bool req) { + requires_supervisor = req; + assert(requires_supervisor == req); } void set_source(ProcessorStorage &storage, RegisterPair32 *target) {