diff --git a/cmake/Configuration.cmake b/cmake/Configuration.cmake index 16e95fa8..e236d5c8 100644 --- a/cmake/Configuration.cmake +++ b/cmake/Configuration.cmake @@ -1,25 +1,38 @@ include(cmake/Variables.cmake) +function(append_compile_flags flag) + set(TMP_CXX_FLAGS "${TMP_CXX_FLAGS} ${flag}") +endfunction() + +function(append_link_flags flag) + set(TMP_LINK_FLAGS "${TMP_LINK_FLAGS} ${flag}") +endfunction() + function(set_compile_flags) + if ((NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Release") AND (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") AND (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "RelWWithDebInfo")) + message(FATAL_ERROR "Unknown CMAKE_BUILD_TYPE specified") + endif() + + set(TMP_CXX_FLAGS "" PARENT_SCOPE) + set(TMP_LINK_FLAGS "" PARENT_SCOPE) + if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") - add_compile_options(${FAST_COMPILE_FLAGS}) + set(TMP_CXX_FLAGS "${FAST_COMPILE_FLAGS}") elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - add_compile_options(${DEBUG_COMPILE_FLAGS}) + set(TMP_CXX_FLAGS "${DEBUG_COMPILE_FLAGS}") elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo") - add_compile_options(${FAST_COMPILE_FLAGS} -ggdb3) - else() - message(FATAL_ERROR "Unknown CMAKE_BUILD_TYPE specified") - endif() + set(TMP_CXX_FLAGS "${FAST_COMPILE_FLAGS} -ggdb3") + endif() get_property(CAN_USE_LLVM_LTO GLOBAL PROPERTY CAN_USE_LLVM_LTO) if ("${HCPU_LTO}" STREQUAL "ON" AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - add_compile_options(-flto) - add_link_options(-flto) + append_compile_flags("-flto") + append_link_flags("-flto") message(STATUS "Enabled LTO") elseif("${HCPU_LTO}" STREQUAL "ON" AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND "${CAN_USE_LLVM_LTO}" STREQUAL "YES") - add_compile_options(-flto=thin) - add_link_options(-flto=thin) + append_compile_flags("-flto=thin") + append_link_flags("-flto=thin") message(STATUS "Enabled LTO") else() message(STATUS "LTO wasn't enabled") @@ -27,14 +40,20 @@ function(set_compile_flags) string(TOLOWER "${HCPU_MARCH_NATIVE}" HCPU_MARCH_NATIVE) if ("${HCPU_MARCH_NATIVE}" STREQUAL "on") - add_compile_options(-march=native) + append_compile_flags("-march=native") message(STATUS "Enabled -march=native flag") endif() + string(TOLOWER "${HCPU_X86_32}" HCPU_X86_32) + if ("${HCPU_X86_32}" STREQUAL "on") + append_compile_flags("-m32") + message(STATUS "Enabled x86_32 building mode") + endif() + string(TOLOWER "${HCPU_SANITIZERS}" HCPU_SANITIZERS) if (NOT "${HCPU_SANITIZERS}" STREQUAL "off") - add_compile_options(-fsanitize=address,leak) - add_link_options(-fsanitize=address,leak) + append_compile_flags("-fsanitize=address,leak") + append_link_flags("-fsanitize=address,leak") message(STATUS "Enabling sanitizers") endif() @@ -42,9 +61,11 @@ function(set_compile_flags) set(LIBUNWIND ${LIBUNWIND} PARENT_SCOPE) if (LIBUNWIND) message(STATUS "Found libunwind") - add_compile_options(-DHCPU_ENABLE_LIBUNWIND) - add_link_options(-L${ROOT_DIR}/dist/libbacktrace -lunwind -lbacktrace) + append_compile_flags(-DHCPU_ENABLE_LIBUNWIND) + append_link_flags(-L${ROOT_DIR}/dist/libbacktrace -lunwind -lbacktrace) endif() + set_property(GLOBAL PROPERTY HCPU_COMPILE_FLAGS "${TMP_CXX_FLAGS}") + set_property(GLOBAL PROPERTY HCPU_LINK_FLAGS "${TMP_LINK_FLAGS}") endfunction() function(detect_compilers) diff --git a/src/Assembler/Core/Tokenizers.cpp b/src/Assembler/Core/Tokenizers.cpp index 66fd9584..3054ec97 100644 --- a/src/Assembler/Core/Tokenizers.cpp +++ b/src/Assembler/Core/Tokenizers.cpp @@ -27,7 +27,7 @@ Value HCAsm::TokenizeSignedInt(std::string_view str) { } Value HCAsm::TokenizeUnsignedInt(std::string_view str) { - return { std::stoul(str.begin() + 2) }; + return { std::stoull(str.begin() + 2) }; } Value HCAsm::TokenizeString(std::string_view str) { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d2a1f379..4ee5dc8e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -23,27 +23,35 @@ ExternalProject_Add( ${ROOT_DIR}/dist/libbacktrace/libbacktrace.la ) +get_property(HCPU_CXX_FLAGS GLOBAL PROPERTY HCPU_CXX_FLAGS) +get_property(HCPU_LINK_FLAGS GLOBAL PROPERTY HCPU_LINK_FLAGS) + add_library(emulator-core STATIC ${SOURCES_emulator-core}) +target_compile_options(emulator-core PUBLIC "${HCPU_CXX_FLAGS}") target_include_directories(emulator-core PUBLIC ${GENERIC_INCLUDE_DIR} ${ROOT_DIR}/src/Emulator) target_link_libraries(emulator-core ${LD_FLAGS} fmt) target_precompile_headers(emulator-core PRIVATE pch.hpp) add_library(assembler-core STATIC ${SOURCES_assembler-core}) +target_compile_options(assembler-core PUBLIC "${HCPU_CXX_FLAGS}") target_include_directories(assembler-core PUBLIC ${GENERIC_INCLUDE_DIR} ${ROOT_DIR}/src/Assembler) target_link_libraries(assembler-core pog) target_precompile_headers(assembler-core PRIVATE pch.hpp) add_library(backtrace-provider STATIC ${SOURCES_backtrace-provider}) +target_compile_options(backtrace-provider PUBLIC "${HCPU_CXX_FLAGS}") target_include_directories(backtrace-provider PUBLIC ${GENERIC_INCLUDE_DIR}) add_dependencies(backtrace-provider libbacktrace) target_precompile_headers(backtrace-provider PRIVATE pch.hpp) add_executable(hcasm ${SOURCES_assembler-main}) +target_compile_options(hcasm PUBLIC "${HCPU_CXX_FLAGS}") target_include_directories(hcasm PUBLIC ${GENERIC_INCLUDE_DIR} ${ROOT_DIR}/src/Assembler) target_link_libraries(hcasm assembler-core pog) target_precompile_headers(hcasm PRIVATE pch.hpp) add_executable(hcemul ${SOURCES_emulator-main}) +target_compile_options(hcemul PUBLIC "${HCPU_CXX_FLAGS}") target_include_directories(hcemul PUBLIC ${GENERIC_INCLUDE_DIR} ${ROOT_DIR}/src/Emulator) target_link_libraries(hcemul emulator-core assembler-core) target_precompile_headers(hcemul PRIVATE pch.hpp) diff --git a/src/Emulator/Core/CPU/CPU.cpp b/src/Emulator/Core/CPU/CPU.cpp index 345f16c8..6bb4aecb 100644 --- a/src/Emulator/Core/CPU/CPU.cpp +++ b/src/Emulator/Core/CPU/CPU.cpp @@ -1,3 +1,4 @@ +#include "Core/CPU/Instructions/Opcodes.hpp" #include "Logger/Logger.hpp" #include @@ -6,7 +7,7 @@ #include #include -HyperCPU::CPU::CPU(std::size_t core_count, std::size_t mem_size, char* binary, std::uint64_t binary_size) : +HyperCPU::CPU::CPU(std::uint16_t core_count, std::uint64_t mem_size, char* binary, std::uint64_t binary_size) : mem_controller(dynamic_cast(new MemoryControllerST(mem_size, this))), logger(LogLevel::ERROR), core_count(core_count), @@ -71,73 +72,73 @@ HyperCPU::CPU::CPU(std::size_t core_count, std::size_t mem_size, char* binary, s // TODO: Use std::bind instead of lambdas opcode_handler_assoc[static_cast(HyperCPU::Opcode::HALT)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecHALT(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecHALT(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::ADD)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecADD(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecADD(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::ADC)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecADC(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecADC(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::AND)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecAND(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecAND(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::ANDN)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecANDN(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecANDN(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::BSWAP)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecBSWAP(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecBSWAP(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::CALL)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecCALL(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecCALL(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::CCRF)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecCCRF(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecCCRF(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::COVF)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecCOVF(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecCOVF(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::CUDF)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecCUDF(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecCUDF(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::INC)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecINC(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecINC(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::DEC)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecDEC(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecDEC(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::HID)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecHID(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecHID(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::MUL)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecMUL(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecMUL(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::OR)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecOR(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecOR(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::SUB)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecSUB(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecSUB(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::SHFL)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecSHFL(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecSHFL(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::SHFR)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecSHFR(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecSHFR(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::DIV)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecDIV(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecDIV(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::LOIVT)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecLOIVT(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecLOIVT(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::INTR)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecINTR(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecINTR(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::MOV)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecMOV(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecMOV(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::READ)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecREAD(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecREAD(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::WRITE)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecWRITE(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecWRITE(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::JMP)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecJMP(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecJMP(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::PUSH)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecPUSH(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecPUSH(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::POP)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecPOP(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecPOP(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::CALLE)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecCALLE(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecCALLE(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::CALLGR)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecCALLGR(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecCALLGR(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::CALLL)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecCALLL(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecCALLL(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::JME)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecJME(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecJME(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::JMGR)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecJMGR(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecJMGR(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::JML)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecJML(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecJML(instr, op1, op2); }; opcode_handler_assoc[static_cast(HyperCPU::Opcode::CMP)] = - [this](const IInstruction& instr, void* op1, void* op2) -> void { this->ExecCMP(instr, op1, op2); }; + [this](const IInstruction& instr, OperandContainer op1, OperandContainer op2) -> void { this->ExecCMP(instr, op1, op2); }; read_io_handlers[0] = io_ctl->GetGetchar(); @@ -222,7 +223,7 @@ void HyperCPU::CPU::ExecutingThread() { current = buffer_used.load(std::memory_order_acquire); } - std::pair operands = GetOperands(buffer.m_op_types, buffer.m_opcode_mode, buffer.m_op1, buffer.m_op2); + std::pair operands = GetOperands(buffer.m_op_types, buffer.m_opcode_mode, buffer.m_op1, buffer.m_op2); opcode_handler_assoc[static_cast(buffer.m_opcode)](buffer, operands.first, operands.second); buffer_used.store(false, std::memory_order_release); @@ -266,7 +267,7 @@ void HyperCPU::CPU::Run() { break; } - std::pair operands = GetOperands(buffer.m_op_types, buffer.m_opcode_mode, buffer.m_op1, buffer.m_op2); + std::pair operands = GetOperands(buffer.m_op_types, buffer.m_opcode_mode, buffer.m_op1, buffer.m_op2); opcode_handler_assoc[static_cast(buffer.m_opcode)](buffer, operands.first, operands.second); } } diff --git a/src/Emulator/Core/CPU/CPU.hpp b/src/Emulator/Core/CPU/CPU.hpp index 44ce8c9d..18cb9d01 100644 --- a/src/Emulator/Core/CPU/CPU.hpp +++ b/src/Emulator/Core/CPU/CPU.hpp @@ -8,29 +8,30 @@ #include #include #include +#include -#define DECLARE_INSTR(name) void Exec##name(const IInstruction& instr, void* op1, void* op2) +#define DECLARE_INSTR(name) void Exec##name(const IInstruction& instr, OperandContainer op1, OperandContainer op2) namespace HyperCPU { - using opcode_handler = std::function; - using read_operation_handler = std::function; - using write_operation_handler = std::function; - class MemoryControllerST; class CPU { private: friend class Decoder; - friend class MemoryControllerST; - friend class MemoryControllerMT; + friend class MemoryControllerST; + + using opcode_handler = std::function; + using read_operation_handler = std::function; + using write_operation_handler = std::function; + // Components IMemoryController* mem_controller; std::unique_ptr m_decoder; // Data const HyperCPU::Logger logger; - std::size_t core_count; - std::size_t total_mem; + std::uint16_t core_count; + std::uint64_t total_mem; bool halted; // General space for registers @@ -53,8 +54,8 @@ namespace HyperCPU { std::array opcode_handler_assoc; - std::pair GetOperands(OperandTypes op_types, Mode md, std::size_t& op1, std::size_t& op2); - void* GetRegister(std::size_t& op1); + std::pair GetOperands(OperandTypes op_types, Mode md, OperandContainer& op1, OperandContainer& op2); + OperandContainer GetRegister(OperandContainer& op1); // Stack void StackPush8(std::uint8_t) noexcept; @@ -120,7 +121,7 @@ namespace HyperCPU { std::unique_ptr io_ctl; public: - CPU(std::size_t core_count, std::size_t mem_size, char* binary = nullptr, std::uint64_t binary_size = 0); + CPU(std::uint16_t core_count, std::uint64_t mem_size, char* binary = nullptr, std::uint64_t binary_size = 0); void Run(); diff --git a/src/Emulator/Core/CPU/Decoders/StdDecoder.cpp b/src/Emulator/Core/CPU/Decoders/StdDecoder.cpp index ab71cc04..1b3ec5ae 100644 --- a/src/Emulator/Core/CPU/Decoders/StdDecoder.cpp +++ b/src/Emulator/Core/CPU/Decoders/StdDecoder.cpp @@ -13,7 +13,7 @@ #include -#define dcdr_assert(expr) RaiseException((expr)); if (cpu && cpu->pending_interrupt.has_value()) return {.m_opcode = _CONT, .m_opcode_mode = b64, .m_op_types = NONE, .m_op1 = 0, .m_op2 = 0, .addr_extension_status = HyperCPU::AddrExtensionStatus::Disabled, .extension = 0} +#define dcdr_assert(expr) RaiseException((expr)); if (cpu && cpu->pending_interrupt.has_value()) return {.m_opcode = _CONT, .m_opcode_mode = b64, .m_op_types = NONE, .m_op1 = {}, .m_op2 = {}, .addr_extension_status = HyperCPU::AddrExtensionStatus::Disabled, .extension = 0} void HyperCPU::Decoder::RaiseException(bool expr) noexcept { if (!(expr)) { @@ -88,11 +88,11 @@ HyperCPU::IInstruction HyperCPU::Decoder::FetchAndDecode() { case R_RM: { std::uint8_t tmp = mem_controller->Fetch8(*xip); dcdr_assert(Validator::IsValidRegister(tmp)); - memcpy(&instruction.m_op1, &tmp, sizeof(std::uint8_t)); + instruction.m_op1 = OperandContainer(HyperCPU::bit_cast(tmp)); tmp = mem_controller->Fetch8(*xip); dcdr_assert(Validator::IsValidRegister(tmp)); - memcpy(&instruction.m_op2, &tmp, sizeof(std::uint8_t)); + instruction.m_op2 = OperandContainer(HyperCPU::bit_cast(tmp)); break; } @@ -100,9 +100,9 @@ HyperCPU::IInstruction HyperCPU::Decoder::FetchAndDecode() { case R_M: { std::uint8_t tmp = mem_controller->Fetch8(*xip); dcdr_assert(Validator::IsValidRegister(tmp)); - memcpy(&instruction.m_op1, &tmp, sizeof(std::uint8_t)); + instruction.m_op1 = OperandContainer(HyperCPU::bit_cast(tmp)); - instruction.m_op2 = mem_controller->Fetch64(*xip); + instruction.m_op2 = OperandContainer{mem_controller->Fetch64(*xip)}; break; } @@ -110,29 +110,29 @@ HyperCPU::IInstruction HyperCPU::Decoder::FetchAndDecode() { case R_IMM: { std::uint8_t tmp = mem_controller->Fetch8(*xip); dcdr_assert(Validator::IsValidRegister(tmp)); - memcpy(&instruction.m_op1, &tmp, sizeof(std::uint8_t)); + instruction.m_op1 = OperandContainer(HyperCPU::bit_cast(tmp)); switch (instruction.m_opcode_mode) { case b8: { std::uint8_t vtmp = mem_controller->Fetch8(*xip); - memcpy(&instruction.m_op2, &vtmp, sizeof(std::uint8_t)); + instruction.m_op2 = OperandContainer(HyperCPU::bit_cast(vtmp)); break; } case b16: { std::uint16_t vtmp = mem_controller->Fetch16(*xip); - memcpy(&instruction.m_op2, &vtmp, sizeof(std::uint16_t)); + instruction.m_op2 = OperandContainer(HyperCPU::bit_cast(vtmp)); break; } case b32: { std::uint32_t vtmp = mem_controller->Fetch32(*xip); - memcpy(&instruction.m_op2, &vtmp, sizeof(std::uint32_t)); + instruction.m_op2 = OperandContainer(HyperCPU::bit_cast(vtmp)); break; } case b64: { - instruction.m_op2 = mem_controller->Fetch64(*xip); + instruction.m_op2 = OperandContainer{mem_controller->Fetch64(*xip)}; break; } } @@ -140,47 +140,47 @@ HyperCPU::IInstruction HyperCPU::Decoder::FetchAndDecode() { } case M_R: { - instruction.m_op1 = mem_controller->Fetch64(*xip); + instruction.m_op1 = OperandContainer{mem_controller->Fetch64(*xip)}; std::uint8_t tmp = mem_controller->Fetch8(*xip); dcdr_assert(Validator::IsValidRegister(tmp)); - memcpy(&instruction.m_op2, &tmp, sizeof(std::uint8_t)); + instruction.m_op2 = OperandContainer(HyperCPU::bit_cast(tmp)); break; } case R: { std::uint8_t tmp = mem_controller->Fetch8(*xip); dcdr_assert(Validator::IsValidRegister(tmp)); - memcpy(&instruction.m_op1, &tmp, sizeof(std::uint8_t)); + instruction.m_op1 = OperandContainer(HyperCPU::bit_cast(tmp)); break; } case M: - instruction.m_op1 = mem_controller->Fetch64(*xip); + instruction.m_op1 = OperandContainer{mem_controller->Fetch64(*xip)}; break; case IMM: switch (instruction.m_opcode_mode) { case b8: { std::uint8_t vtmp = mem_controller->Fetch8(*xip); - memcpy(&instruction.m_op1, &vtmp, sizeof(std::uint8_t)); + instruction.m_op1 = OperandContainer(HyperCPU::bit_cast(vtmp)); break; } case b16: { std::uint16_t vtmp = mem_controller->Fetch16(*xip); - memcpy(&instruction.m_op1, &vtmp, sizeof(std::uint16_t)); + instruction.m_op1 = OperandContainer(HyperCPU::bit_cast(vtmp)); break; } case b32: { std::uint32_t vtmp = mem_controller->Fetch32(*xip); - memcpy(&instruction.m_op1, &vtmp, sizeof(std::uint32_t)); + instruction.m_op1 = OperandContainer(HyperCPU::bit_cast(vtmp)); break; } case b64: { - instruction.m_op1 = mem_controller->Fetch64(*xip); + instruction.m_op1 = OperandContainer{mem_controller->Fetch64(*xip)}; break; } } diff --git a/src/Emulator/Core/CPU/Decoders/StdDecoder.hpp b/src/Emulator/Core/CPU/Decoders/StdDecoder.hpp index 2fd729be..3741a485 100644 --- a/src/Emulator/Core/CPU/Decoders/StdDecoder.hpp +++ b/src/Emulator/Core/CPU/Decoders/StdDecoder.hpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include namespace HyperCPU { @@ -13,11 +15,48 @@ namespace HyperCPU { EnabledOp2 = 0b11 }; + struct OperandContainer { + public: + OperandContainer() : value(0) { } + OperandContainer(std::nullptr_t) : value(0) { } + explicit OperandContainer(std::uint64_t value) : value(value) { } + template + explicit OperandContainer(T* ptr) : value(HyperCPU::bit_cast(ptr)) { } // Supposed to be executed from GetRegister() + + operator std::uint8_t() const noexcept { return HyperCPU::bit_cast(value); } + operator std::uint16_t() const noexcept { return HyperCPU::bit_cast(value); } + operator std::uint32_t() const noexcept { return HyperCPU::bit_cast(value); } + operator std::uint64_t() const noexcept { return value; } + + std::uint64_t& ref() noexcept { + return value; + } + + template + operator T*() const noexcept { + return HyperCPU::bit_cast(value); + } + + template + T& deref() const noexcept { + return *static_cast(*this); + } + + template + T* ptr() const noexcept { + return static_cast(*this); + } + + ~OperandContainer() { } + private: + std::uint64_t value; + }; + struct IInstruction { Opcode m_opcode; Mode m_opcode_mode; OperandTypes m_op_types; - std::size_t m_op1, m_op2; + OperandContainer m_op1, m_op2; AddrExtensionStatus addr_extension_status; std::uint8_t extension; }; diff --git a/src/Emulator/Core/CPU/InstructionsImpl/ADC.cpp b/src/Emulator/Core/CPU/InstructionsImpl/ADC.cpp index 7ac39356..fb8e257a 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/ADC.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/ADC.cpp @@ -7,70 +7,70 @@ using namespace HyperALU; -void HyperCPU::CPU::ExecADC(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecADC(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { switch (instr.m_op_types) { case R_R: { switch (instr.m_opcode_mode) { case b8: - ovf = AdditionWillOverflow(deref(op1), deref(op2)); - deref(op1) = HyperALU::__hcpu_add(deref(op1), HyperCPU::bit_cast_from(op2)); - if (crf) ++deref(op1); + ovf = AdditionWillOverflow(op1.deref(), op2.deref()); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); + if (crf) ++op1.deref(); break; case b16: - ovf = AdditionWillOverflow(deref(op1), deref(op2)); - deref(op1) = HyperALU::__hcpu_add(deref(op1), HyperCPU::bit_cast_from(op2)); - if (crf) ++deref(op1); + ovf = AdditionWillOverflow(op1.deref(), op2.deref()); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); + if (crf) ++op1.deref(); break; case b32: - ovf = AdditionWillOverflow(deref(op1), deref(op2)); - deref(op1) = HyperALU::__hcpu_add(deref(op1), HyperCPU::bit_cast_from(op2)); - if (crf) ++deref(op1); + ovf = AdditionWillOverflow(op1.deref(), op2.deref()); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); + if (crf) ++op1.deref(); break; case b64: - ovf = AdditionWillOverflow(deref(op1), deref(op2)); - deref(op1) = HyperALU::__hcpu_add(deref(op1), HyperCPU::bit_cast_from(op2)); - if (crf) ++deref(op1); + ovf = AdditionWillOverflow(op1.deref(), op2.deref()); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); + if (crf) ++op1.deref(); break; } break; } case R_RM: { - std::uint64_t ptr = HyperCPU::bit_cast_from(op2); + std::uint64_t ptr = HyperCPU::bit_cast_from(op2.ptr()); switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = mem_controller->Read8(ptr); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); - if (crf) ++deref(op1); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); + if (crf) ++op1.deref(); break; } case b16: { std::uint16_t val = mem_controller->Read16(ptr); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); - if (crf) ++deref(op1); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); + if (crf) ++op1.deref(); break; } case b32: { std::uint32_t val = mem_controller->Read32(ptr); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); - if (crf) ++deref(op1); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); + if (crf) ++op1.deref(); break; } case b64: { std::uint64_t val = mem_controller->Read64(ptr); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); - if (crf) ++deref(op1); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); + if (crf) ++op1.deref(); break; } } @@ -83,33 +83,33 @@ void HyperCPU::CPU::ExecADC(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = mem_controller->Read8(ptr); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); - if (crf) ++deref(op1); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); + if (crf) ++op1.deref(); break; } case b16: { std::uint16_t val = mem_controller->Read16(ptr); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); - if (crf) ++deref(op1); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); + if (crf) ++op1.deref(); break; } case b32: { std::uint32_t val = mem_controller->Read32(ptr); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); - if (crf) ++deref(op1); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); + if (crf) ++op1.deref(); break; } case b64: { std::uint64_t val = mem_controller->Read64(ptr); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); - if (crf) ++deref(op1); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); + if (crf) ++op1.deref(); break; } } @@ -120,33 +120,33 @@ void HyperCPU::CPU::ExecADC(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = HyperCPU::bit_cast(op2); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); - if (crf) ++deref(op1); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); + if (crf) ++op1.deref(); break; } case b16: { std::uint16_t val = HyperCPU::bit_cast(op2); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); - if (crf) ++deref(op1); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); + if (crf) ++op1.deref(); break; } case b32: { std::uint32_t val = HyperCPU::bit_cast(op2); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); - if (crf) ++deref(op1); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); + if (crf) ++op1.deref(); break; } case b64: { std::uint64_t val = HyperCPU::bit_cast(op2); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); - if (crf) ++deref(op1); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); + if (crf) ++op1.deref(); break; } } diff --git a/src/Emulator/Core/CPU/InstructionsImpl/ADD.cpp b/src/Emulator/Core/CPU/InstructionsImpl/ADD.cpp index 4dd85f8c..832db1aa 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/ADD.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/ADD.cpp @@ -6,62 +6,62 @@ #include -void HyperCPU::CPU::ExecADD(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecADD(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { switch (instr.m_op_types) { case R_R: { switch (instr.m_opcode_mode) { case b8: - ovf = AdditionWillOverflow(deref(op1), deref(op2)); - deref(op1) = HyperALU::__hcpu_add(deref(op1), HyperCPU::bit_cast_from(op2)); + ovf = AdditionWillOverflow(op1.deref(), op2.deref()); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; case b16: - ovf = AdditionWillOverflow(deref(op1), deref(op2)); - deref(op1) = HyperALU::__hcpu_add(deref(op1), HyperCPU::bit_cast_from(op2)); + ovf = AdditionWillOverflow(op1.deref(), op2.deref()); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; case b32: - ovf = AdditionWillOverflow(deref(op1), deref(op2)); - deref(op1) = HyperALU::__hcpu_add(deref(op1), HyperCPU::bit_cast_from(op2)); + ovf = AdditionWillOverflow(op1.deref(), op2.deref()); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; case b64: - ovf = AdditionWillOverflow(deref(op1), deref(op2)); - deref(op1) = HyperALU::__hcpu_add(deref(op1), HyperCPU::bit_cast_from(op2)); + ovf = AdditionWillOverflow(op1.deref(), op2.deref()); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; } break; } case R_RM: { - std::uint64_t ptr = HyperCPU::bit_cast_from(op2); + std::uint64_t ptr = HyperCPU::bit_cast_from(op2.ptr()); switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = mem_controller->Read8(ptr); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); break; } case b16: { std::uint16_t val = mem_controller->Read16(ptr); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); break; } case b32: { std::uint32_t val = mem_controller->Read32(ptr); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); break; } case b64: { std::uint64_t val = mem_controller->Read64(ptr); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); break; } } @@ -74,29 +74,29 @@ void HyperCPU::CPU::ExecADD(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = mem_controller->Read8(ptr); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); break; } case b16: { std::uint16_t val = mem_controller->Read16(ptr); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); break; } case b32: { std::uint32_t val = mem_controller->Read32(ptr); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); break; } case b64: { std::uint64_t val = mem_controller->Read64(ptr); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); break; } } @@ -107,29 +107,29 @@ void HyperCPU::CPU::ExecADD(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = HyperCPU::bit_cast(op2); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); break; } case b16: { std::uint16_t val = HyperCPU::bit_cast(op2); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); break; } case b32: { std::uint32_t val = HyperCPU::bit_cast(op2); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); break; } case b64: { std::uint64_t val = HyperCPU::bit_cast(op2); - ovf = AdditionWillOverflow(deref(op1), val); - deref(op1) = HyperALU::__hcpu_add(deref(op1), val); + ovf = AdditionWillOverflow(op1.deref(), val); + op1.deref() = HyperALU::__hcpu_add(op1.deref(), val); break; } } diff --git a/src/Emulator/Core/CPU/InstructionsImpl/AND.cpp b/src/Emulator/Core/CPU/InstructionsImpl/AND.cpp index 2d840e90..99dffd26 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/AND.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/AND.cpp @@ -7,54 +7,54 @@ using namespace HyperALU; -void HyperCPU::CPU::ExecAND(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecAND(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { switch (instr.m_op_types) { case R_R: { switch (instr.m_opcode_mode) { case b8: - deref(op1) = __hcpu_and(deref(op1), HyperCPU::bit_cast_from(op2)); + op1.deref() = __hcpu_and(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; case b16: - deref(op1) = __hcpu_and(deref(op1), HyperCPU::bit_cast_from(op2)); + op1.deref() = __hcpu_and(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; case b32: - deref(op1) = __hcpu_and(deref(op1), HyperCPU::bit_cast_from(op2)); + op1.deref() = __hcpu_and(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; case b64: - deref(op1) = __hcpu_and(deref(op1), HyperCPU::bit_cast_from(op2)); + op1.deref() = __hcpu_and(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; } break; } case R_RM: { - std::uint64_t ptr = HyperCPU::bit_cast_from(op2); + std::uint64_t ptr = HyperCPU::bit_cast_from(op2.ptr()); switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = mem_controller->Read8(ptr); - deref(op1) = __hcpu_and(deref(op1), val); + op1.deref() = __hcpu_and(op1.deref(), val); break; } case b16: { std::uint16_t val = mem_controller->Read16(ptr); - deref(op1) = __hcpu_and(deref(op1), val); + op1.deref() = __hcpu_and(op1.deref(), val); break; } case b32: { std::uint32_t val = mem_controller->Read32(ptr); - deref(op1) = __hcpu_and(deref(op1), val); + op1.deref() = __hcpu_and(op1.deref(), val); break; } case b64: { std::uint64_t val = mem_controller->Read64(ptr); - deref(op1) = __hcpu_and(deref(op1), val); + op1.deref() = __hcpu_and(op1.deref(), val); break; } } @@ -67,25 +67,25 @@ void HyperCPU::CPU::ExecAND(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = mem_controller->Read8(ptr); - deref(op1) = __hcpu_and(deref(op1), val); + op1.deref() = __hcpu_and(op1.deref(), val); break; } case b16: { std::uint16_t val = mem_controller->Read16(ptr); - deref(op1) = __hcpu_and(deref(op1), val); + op1.deref() = __hcpu_and(op1.deref(), val); break; } case b32: { std::uint32_t val = mem_controller->Read32(ptr); - deref(op1) = __hcpu_and(deref(op1), val); + op1.deref() = __hcpu_and(op1.deref(), val); break; } case b64: { std::uint64_t val = mem_controller->Read64(ptr); - deref(op1) = __hcpu_and(deref(op1), val); + op1.deref() = __hcpu_and(op1.deref(), val); break; } } @@ -96,25 +96,25 @@ void HyperCPU::CPU::ExecAND(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = HyperCPU::bit_cast(op2); - deref(op1) = __hcpu_and(deref(op1), val); + op1.deref() = __hcpu_and(op1.deref(), val); break; } case b16: { std::uint16_t val = HyperCPU::bit_cast(op2); - deref(op1) = __hcpu_and(deref(op1), val); + op1.deref() = __hcpu_and(op1.deref(), val); break; } case b32: { std::uint32_t val = HyperCPU::bit_cast(op2); - deref(op1) = __hcpu_and(deref(op1), val); + op1.deref() = __hcpu_and(op1.deref(), val); break; } case b64: { std::uint64_t val = HyperCPU::bit_cast(op2); - deref(op1) = __hcpu_and(deref(op1), val); + op1.deref() = __hcpu_and(op1.deref(), val); break; } } diff --git a/src/Emulator/Core/CPU/InstructionsImpl/ANDN.cpp b/src/Emulator/Core/CPU/InstructionsImpl/ANDN.cpp index ff02107a..ba6ee7f7 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/ANDN.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/ANDN.cpp @@ -7,31 +7,31 @@ using namespace HyperALU; -void HyperCPU::CPU::ExecANDN(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecANDN(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { switch (instr.m_op_types) { case R_R: { switch (instr.m_opcode_mode) { case b8: { - auto& dst = deref(op1); - dst = __hcpu_and(__hcpu_not(dst), HyperCPU::bit_cast_from(op2)); + auto& dst = op1.deref(); + dst = __hcpu_and(__hcpu_not(dst), HyperCPU::bit_cast_from(op2.ptr())); break; } case b16: { - auto& dst = deref(op1); - dst = __hcpu_and(__hcpu_not(dst), HyperCPU::bit_cast_from(op2)); + auto& dst = op1.deref(); + dst = __hcpu_and(__hcpu_not(dst), HyperCPU::bit_cast_from(op2.ptr())); break; } case b32: { - auto& dst = deref(op1); - dst = __hcpu_and(__hcpu_not(dst), HyperCPU::bit_cast_from(op2)); + auto& dst = op1.deref(); + dst = __hcpu_and(__hcpu_not(dst), HyperCPU::bit_cast_from(op2.ptr())); break; } case b64: { - auto& dst = deref(op1); - dst = __hcpu_and(__hcpu_not(dst), HyperCPU::bit_cast_from(op2)); + auto& dst = op1.deref(); + dst = __hcpu_and(__hcpu_not(dst), HyperCPU::bit_cast_from(op2.ptr())); break; } } @@ -39,33 +39,33 @@ void HyperCPU::CPU::ExecANDN(const IInstruction& instr, void* op1, void* op2) { } case R_RM: { - std::uint64_t ptr = HyperCPU::bit_cast_from(op2); + std::uint64_t ptr = HyperCPU::bit_cast_from(op2.ptr()); switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = mem_controller->Read8(ptr); - auto& dst = deref(op1); + auto& dst = op1.deref(); dst = __hcpu_and(__hcpu_not(dst), val); break; } case b16: { std::uint16_t val = mem_controller->Read16(ptr); - auto& dst = deref(op1); + auto& dst = op1.deref(); dst = __hcpu_and(__hcpu_not(dst), val); break; } case b32: { std::uint32_t val = mem_controller->Read32(ptr); - auto& dst = deref(op1); + auto& dst = op1.deref(); dst = __hcpu_and(__hcpu_not(dst), val); break; } case b64: { std::uint64_t val = mem_controller->Read64(ptr); - auto& dst = deref(op1); + auto& dst = op1.deref(); dst = __hcpu_and(__hcpu_not(dst), val); break; } @@ -79,28 +79,28 @@ void HyperCPU::CPU::ExecANDN(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = mem_controller->Read8(ptr); - auto& dst = deref(op1); + auto& dst = op1.deref(); dst = __hcpu_and(__hcpu_not(dst), val); break; } case b16: { std::uint16_t val = mem_controller->Read16(ptr); - auto& dst = deref(op1); + auto& dst = op1.deref(); dst = __hcpu_and(__hcpu_not(dst), val); break; } case b32: { std::uint32_t val = mem_controller->Read32(ptr); - auto& dst = deref(op1); + auto& dst = op1.deref(); dst = __hcpu_and(__hcpu_not(dst), val); break; } case b64: { std::uint64_t val = mem_controller->Read64(ptr); - auto& dst = deref(op1); + auto& dst = op1.deref(); dst = __hcpu_and(__hcpu_not(dst), val); break; } @@ -112,28 +112,28 @@ void HyperCPU::CPU::ExecANDN(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = HyperCPU::bit_cast(op2); - auto& dst = deref(op1); + auto& dst = op1.deref(); dst = __hcpu_and(__hcpu_not(dst), val); break; } case b16: { std::uint16_t val = HyperCPU::bit_cast(op2); - auto& dst = deref(op1); + auto& dst = op1.deref(); dst = __hcpu_and(__hcpu_not(dst), val); break; } case b32: { std::uint32_t val = HyperCPU::bit_cast(op2); - auto& dst = deref(op1); + auto& dst = op1.deref(); dst = __hcpu_and(__hcpu_not(dst), val); break; } case b64: { std::uint64_t val = HyperCPU::bit_cast(op2); - auto& dst = deref(op1); + auto& dst = op1.deref(); dst = __hcpu_and(__hcpu_not(dst), val); break; } diff --git a/src/Emulator/Core/CPU/InstructionsImpl/BSWAP.cpp b/src/Emulator/Core/CPU/InstructionsImpl/BSWAP.cpp index 8cc39a3f..de2e73d4 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/BSWAP.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/BSWAP.cpp @@ -11,25 +11,25 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecBSWAP(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecBSWAP(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { switch (instr.m_opcode_mode) { case b8: break; case b16: { - auto& dst = deref(op1); + auto& dst = op1.deref(); dst = HyperCPU::byteswap(dst); break; } case b32: { - auto& dst = deref(op1); + auto& dst = op1.deref(); dst = HyperCPU::byteswap(dst); break; } case b64: { - auto& dst = deref(op1); + auto& dst = op1.deref(); dst = HyperCPU::byteswap(dst); break; } diff --git a/src/Emulator/Core/CPU/InstructionsImpl/CALL.cpp b/src/Emulator/Core/CPU/InstructionsImpl/CALL.cpp index 578652f8..1276cb66 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/CALL.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/CALL.cpp @@ -11,11 +11,11 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecCALL(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecCALL(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { switch (instr.m_op_types) { // Placeholders case R: StackPush64(*xip); - *xip = deref(op1); + *xip = op1.deref(); break; case IMM: StackPush64(*xip); diff --git a/src/Emulator/Core/CPU/InstructionsImpl/CALLE.cpp b/src/Emulator/Core/CPU/InstructionsImpl/CALLE.cpp index ce575297..3077884e 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/CALLE.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/CALLE.cpp @@ -11,7 +11,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecCALLE(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecCALLE(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { if (!(zrf && !crf)) { return; } @@ -19,7 +19,7 @@ void HyperCPU::CPU::ExecCALLE(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_op_types) { // Placeholders case R: StackPush64(*xip); - *xip = deref(op1); + *xip = op1.deref(); break; case IMM: StackPush64(*xip); diff --git a/src/Emulator/Core/CPU/InstructionsImpl/CALLGR.cpp b/src/Emulator/Core/CPU/InstructionsImpl/CALLGR.cpp index 77b71281..7bc060e7 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/CALLGR.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/CALLGR.cpp @@ -11,7 +11,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecCALLGR(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecCALLGR(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { if (!(!zrf && !crf)) { return; } @@ -19,7 +19,7 @@ void HyperCPU::CPU::ExecCALLGR(const IInstruction& instr, void* op1, void* op2) switch (instr.m_op_types) { // Placeholders case R: StackPush64(*xip); - *xip = deref(op1); + *xip = op1.deref(); break; case IMM: StackPush64(*xip); diff --git a/src/Emulator/Core/CPU/InstructionsImpl/CALLL.cpp b/src/Emulator/Core/CPU/InstructionsImpl/CALLL.cpp index 5a5d3f89..f3d2cae3 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/CALLL.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/CALLL.cpp @@ -11,7 +11,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecCALLL(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecCALLL(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { if (!(!zrf && crf)) { return; } @@ -19,7 +19,7 @@ void HyperCPU::CPU::ExecCALLL(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_op_types) { // Placeholders case R: StackPush64(*xip); - *xip = deref(op1); + *xip = op1.deref(); break; case IMM: StackPush64(*xip); diff --git a/src/Emulator/Core/CPU/InstructionsImpl/CCRF.cpp b/src/Emulator/Core/CPU/InstructionsImpl/CCRF.cpp index 86a526e0..3b935b48 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/CCRF.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/CCRF.cpp @@ -4,7 +4,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecCCRF(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecCCRF(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { crf = false; } diff --git a/src/Emulator/Core/CPU/InstructionsImpl/CMP.cpp b/src/Emulator/Core/CPU/InstructionsImpl/CMP.cpp index 92ee5170..b9f4f733 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/CMP.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/CMP.cpp @@ -4,25 +4,25 @@ #include -void HyperCPU::CPU::ExecCMP(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecCMP(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { std::int8_t res = 0; switch (instr.m_op_types) { case R_R: { switch (instr.m_opcode_mode) { case b8: - res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1), HyperCPU::bit_cast_from(op2)); + res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1.ptr()), HyperCPU::bit_cast_from(op2.ptr())); break; case b16: - res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1), HyperCPU::bit_cast_from(op2)); + res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1.ptr()), HyperCPU::bit_cast_from(op2.ptr())); break; case b32: - res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1), HyperCPU::bit_cast_from(op2)); + res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1.ptr()), HyperCPU::bit_cast_from(op2.ptr())); break; case b64: - res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1), HyperCPU::bit_cast_from(op2)); + res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1.ptr()), HyperCPU::bit_cast_from(op2.ptr())); break; } break; @@ -30,46 +30,46 @@ void HyperCPU::CPU::ExecCMP(const IInstruction& instr, void* op1, void* op2) { case R_RM: { std::uint64_t ptr; - std::memcpy(&ptr, op2, 8); + std::memcpy(&ptr, op2.ptr(), 8); switch (instr.m_opcode_mode) { case b8: - res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1), mem_controller->Read8(ptr)); + res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1.ptr()), mem_controller->Read8(ptr)); break; case b16: - res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1), mem_controller->Read16(ptr)); + res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1.ptr()), mem_controller->Read16(ptr)); break; case b32: - res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1), mem_controller->Read32(ptr)); + res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1.ptr()), mem_controller->Read32(ptr)); break; case b64: - res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1), mem_controller->Read64(ptr)); + res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1.ptr()), mem_controller->Read64(ptr)); break; } break; } case R_M: { - std::uint64_t ptr = reinterpret_cast(op2); + std::uint64_t ptr = op2; switch (instr.m_opcode_mode) { case b8: - res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1), mem_controller->Read8(ptr)); + res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1.ptr()), mem_controller->Read8(ptr)); break; case b16: - res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1), mem_controller->Read16(ptr)); + res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1.ptr()), mem_controller->Read16(ptr)); break; case b32: - res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1), mem_controller->Read32(ptr)); + res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1.ptr()), mem_controller->Read32(ptr)); break; case b64: - res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1), mem_controller->Read64(ptr)); + res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1.ptr()), mem_controller->Read64(ptr)); break; } break; @@ -78,28 +78,28 @@ void HyperCPU::CPU::ExecCMP(const IInstruction& instr, void* op1, void* op2) { case R_IMM: { switch (instr.m_opcode_mode) { case b8: - res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1), HyperCPU::bit_cast(op2)); + res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1.ptr()), HyperCPU::bit_cast(op2)); break; case b16: - res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1), HyperCPU::bit_cast(op2)); + res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1.ptr()), HyperCPU::bit_cast(op2)); break; case b32: - res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1), HyperCPU::bit_cast(op2)); + res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1.ptr()), HyperCPU::bit_cast(op2)); break; case b64: - res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1), HyperCPU::bit_cast(op2)); + res = StdALU::__hcpu_cmp(HyperCPU::bit_cast_from(op1.ptr()), HyperCPU::bit_cast(op2)); break; } break; } case RM_M: { - std::size_t ptr1, ptr2 = 0; - std::memcpy(&ptr1, op1, 8); - ptr2 = HyperCPU::bit_cast(op2); + std::uint64_t ptr1, ptr2 = 0; + std::memcpy(&ptr1, op1.ptr(), 8); + ptr2 = HyperCPU::bit_cast(op2); switch (instr.m_opcode_mode) { case b8: @@ -122,30 +122,30 @@ void HyperCPU::CPU::ExecCMP(const IInstruction& instr, void* op1, void* op2) { } case RM_R: { - std::size_t ptr = HyperCPU::bit_cast_from(op1); + std::uint64_t ptr = op1.deref(); switch (instr.m_opcode_mode) { case b8: - res = StdALU::__hcpu_cmp(mem_controller->Read8(ptr), HyperCPU::bit_cast_from(op2)); + res = StdALU::__hcpu_cmp(mem_controller->Read8(ptr), HyperCPU::bit_cast_from(op2.ptr())); break; case b16: - res = StdALU::__hcpu_cmp(mem_controller->Read16(ptr), HyperCPU::bit_cast_from(op2)); + res = StdALU::__hcpu_cmp(mem_controller->Read16(ptr), HyperCPU::bit_cast_from(op2.ptr())); break; case b32: - res = StdALU::__hcpu_cmp(mem_controller->Read32(ptr), HyperCPU::bit_cast_from(op2)); + res = StdALU::__hcpu_cmp(mem_controller->Read32(ptr), HyperCPU::bit_cast_from(op2.ptr())); break; case b64: - res = StdALU::__hcpu_cmp(mem_controller->Read64(ptr), HyperCPU::bit_cast_from(op2)); + res = StdALU::__hcpu_cmp(mem_controller->Read64(ptr), HyperCPU::bit_cast_from(op2.ptr())); break; } break; } case RM_IMM: { - std::size_t ptr = HyperCPU::bit_cast_from(op1); + std::uint64_t ptr = op1.deref(); switch (instr.m_opcode_mode) { case b8: @@ -172,19 +172,19 @@ void HyperCPU::CPU::ExecCMP(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_opcode_mode) { case b8: - res = StdALU::__hcpu_cmp(mem_controller->Read8(ptr), HyperCPU::bit_cast_from(op2)); + res = StdALU::__hcpu_cmp(mem_controller->Read8(ptr), HyperCPU::bit_cast_from(op2.ptr())); break; case b16: - res = StdALU::__hcpu_cmp(mem_controller->Read16(ptr), HyperCPU::bit_cast_from(op2)); + res = StdALU::__hcpu_cmp(mem_controller->Read16(ptr), HyperCPU::bit_cast_from(op2.ptr())); break; case b32: - res = StdALU::__hcpu_cmp(mem_controller->Read32(ptr), HyperCPU::bit_cast_from(op2)); + res = StdALU::__hcpu_cmp(mem_controller->Read32(ptr), HyperCPU::bit_cast_from(op2.ptr())); break; case b64: - res = StdALU::__hcpu_cmp(mem_controller->Read64(ptr), HyperCPU::bit_cast_from(op2)); + res = StdALU::__hcpu_cmp(mem_controller->Read64(ptr), HyperCPU::bit_cast_from(op2.ptr())); break; } break; diff --git a/src/Emulator/Core/CPU/InstructionsImpl/COVF.cpp b/src/Emulator/Core/CPU/InstructionsImpl/COVF.cpp index 584da2a9..ffc0f62e 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/COVF.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/COVF.cpp @@ -4,7 +4,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecCOVF(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecCOVF(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { ovf = false; } diff --git a/src/Emulator/Core/CPU/InstructionsImpl/CUDF.cpp b/src/Emulator/Core/CPU/InstructionsImpl/CUDF.cpp index 9676aaa9..3b7ee95b 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/CUDF.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/CUDF.cpp @@ -4,7 +4,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecCUDF(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecCUDF(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { udf = false; } diff --git a/src/Emulator/Core/CPU/InstructionsImpl/DEC.cpp b/src/Emulator/Core/CPU/InstructionsImpl/DEC.cpp index a7fead40..1c50ab7e 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/DEC.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/DEC.cpp @@ -8,31 +8,31 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecDEC(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecDEC(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { switch (instr.m_opcode_mode) { case b8: { - auto& dst = deref(op1); + auto& dst = op1.deref(); udf = (dst == 0); --dst; break; } case b16: { - auto& dst = deref(op1); + auto& dst = op1.deref(); udf = (dst == 0); --dst; break; } case b32: { - auto& dst = deref(op1); + auto& dst = op1.deref(); udf = (dst == 0); --dst; break; } case b64: { - auto& dst = deref(op1); + auto& dst = op1.deref(); udf = (dst == 0); --dst; break; diff --git a/src/Emulator/Core/CPU/InstructionsImpl/DIV.cpp b/src/Emulator/Core/CPU/InstructionsImpl/DIV.cpp index 9a76bb85..9165ba8d 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/DIV.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/DIV.cpp @@ -11,7 +11,7 @@ using namespace HyperALU; -void HyperCPU::CPU::ExecDIV(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecDIV(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { if (!(*x2)) { TriggerInterrupt(cpu_exceptions::ZRDIV); return; @@ -19,28 +19,28 @@ void HyperCPU::CPU::ExecDIV(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_opcode_mode) { case b8: { - std::uint8_t& dst = deref(op1); + std::uint8_t& dst = op1.deref(); *x1 = __hcpu_div_remainder(dst, static_cast(*x2)); dst = __hcpu_div(dst, static_cast(*x2)); break; } case b16: { - auto& dst = deref(op1); + auto& dst = op1.deref(); *x1 = __hcpu_div_remainder(dst, static_cast(*x2)); dst = __hcpu_div(dst, static_cast(*x2)); break; } case b32: { - auto& dst = deref(op1); + auto& dst = op1.deref(); *x1 = __hcpu_div_remainder(dst, static_cast(*x2)); dst = __hcpu_div(dst, static_cast(*x2)); break; } case b64: { - auto& dst = deref(op1); + auto& dst = op1.deref(); *x1 = __hcpu_div_remainder(dst, static_cast(*x2)); dst = __hcpu_div(dst, static_cast(*x2)); break; diff --git a/src/Emulator/Core/CPU/InstructionsImpl/HALT.cpp b/src/Emulator/Core/CPU/InstructionsImpl/HALT.cpp index 4d10eec0..a445b20c 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/HALT.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/HALT.cpp @@ -4,7 +4,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecHALT(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecHALT(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { halted = true; } diff --git a/src/Emulator/Core/CPU/InstructionsImpl/HID.cpp b/src/Emulator/Core/CPU/InstructionsImpl/HID.cpp index 4d7015fa..0cb55eb0 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/HID.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/HID.cpp @@ -10,7 +10,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecHID(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecHID(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { switch (*x0) { case 0: *x0 = 2; diff --git a/src/Emulator/Core/CPU/InstructionsImpl/INC.cpp b/src/Emulator/Core/CPU/InstructionsImpl/INC.cpp index 5a5d3dc1..c7aea1da 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/INC.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/INC.cpp @@ -8,31 +8,31 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecINC(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecINC(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { switch (instr.m_opcode_mode) { case b8: { - auto& dst = deref(op1); + auto& dst = op1.deref(); ++dst; ovf = (dst == 0); break; } case b16: { - auto& dst = deref(op1); + auto& dst = op1.deref(); ++dst; ovf = (dst == 0); break; } case b32: { - auto& dst = deref(op1); + auto& dst = op1.deref(); ++dst; ovf = (dst == 0); break; } case b64: { - auto& dst = deref(op1); + auto& dst = op1.deref(); ++dst; ovf = (dst == 0); break; diff --git a/src/Emulator/Core/CPU/InstructionsImpl/INTR.cpp b/src/Emulator/Core/CPU/InstructionsImpl/INTR.cpp index 3b78114e..36101995 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/INTR.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/INTR.cpp @@ -9,14 +9,14 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecINTR(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecINTR(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { std::uint64_t num = 0; switch (instr.m_opcode_mode) { - case b8: num = HyperCPU::bit_cast_from(op1); break; - case b16: num = HyperCPU::bit_cast_from(op1); break; - case b32: num = HyperCPU::bit_cast_from(op1); break; - case b64: num = HyperCPU::bit_cast_from(op1); break; + case b8: num = HyperCPU::bit_cast_from(op1.ptr()); break; + case b16: num = HyperCPU::bit_cast_from(op1.ptr()); break; + case b32: num = HyperCPU::bit_cast_from(op1.ptr()); break; + case b64: num = HyperCPU::bit_cast_from(op1.ptr()); break; } if (num > 255) { diff --git a/src/Emulator/Core/CPU/InstructionsImpl/JME.cpp b/src/Emulator/Core/CPU/InstructionsImpl/JME.cpp index 103c0582..8c41e6e2 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/JME.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/JME.cpp @@ -11,14 +11,14 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecJME(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecJME(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { if (!(zrf && !crf)) { return; } switch (instr.m_op_types) { // Placeholders case R: - *xip = deref(op1); + *xip = op1.deref(); break; case IMM: *xip = HyperCPU::bit_cast(op1); diff --git a/src/Emulator/Core/CPU/InstructionsImpl/JMGR.cpp b/src/Emulator/Core/CPU/InstructionsImpl/JMGR.cpp index e80b1c60..b8d45b30 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/JMGR.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/JMGR.cpp @@ -11,14 +11,14 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecJMGR(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecJMGR(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { if (!(!zrf && !crf)) { return; } switch (instr.m_op_types) { // Placeholders case R: - *xip = deref(op1); + *xip = op1.deref(); break; case IMM: *xip = HyperCPU::bit_cast(op1); diff --git a/src/Emulator/Core/CPU/InstructionsImpl/JML.cpp b/src/Emulator/Core/CPU/InstructionsImpl/JML.cpp index 7bd9fb21..6ac2e875 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/JML.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/JML.cpp @@ -11,14 +11,14 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecJML(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecJML(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { if (!(!zrf && crf)) { return; } switch (instr.m_op_types) { // Placeholders case R: - *xip = deref(op1); + *xip = op1.deref(); break; case IMM: *xip = HyperCPU::bit_cast(op1); diff --git a/src/Emulator/Core/CPU/InstructionsImpl/JMP.cpp b/src/Emulator/Core/CPU/InstructionsImpl/JMP.cpp index 624c6d10..44ce86ae 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/JMP.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/JMP.cpp @@ -11,10 +11,10 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecJMP(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecJMP(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { switch (instr.m_op_types) { // Placeholders case R: - *xip = deref(op1); + *xip = op1.deref(); break; case IMM: *xip = HyperCPU::bit_cast(op1); diff --git a/src/Emulator/Core/CPU/InstructionsImpl/LOIVT.cpp b/src/Emulator/Core/CPU/InstructionsImpl/LOIVT.cpp index dd292c79..5f34e3c4 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/LOIVT.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/LOIVT.cpp @@ -9,13 +9,13 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecLOIVT(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecLOIVT(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { switch (instr.m_op_types) { case IMM: *xivt = HyperCPU::bit_cast(op1); break; case R: - *xivt = HyperCPU::bit_cast_from(op1); + *xivt = HyperCPU::bit_cast_from(op1.ptr()); break; default: ABORT(); } diff --git a/src/Emulator/Core/CPU/InstructionsImpl/MOV.cpp b/src/Emulator/Core/CPU/InstructionsImpl/MOV.cpp index 48342acc..393723ab 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/MOV.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/MOV.cpp @@ -3,24 +3,24 @@ #include -void HyperCPU::CPU::ExecMOV(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecMOV(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { switch (instr.m_op_types) { case R_R: { switch (instr.m_opcode_mode) { case b8: - std::memcpy(op1, op2, 1); + std::memcpy(op1, op2.ptr(), 1); break; case b16: - std::memcpy(op1, op2, 2); + std::memcpy(op1, op2.ptr(), 2); break; case b32: - std::memcpy(op1, op2, 4); + std::memcpy(op1, op2.ptr(), 4); break; case b64: - std::memcpy(op1, op2, 8); + std::memcpy(op1, op2.ptr(), 8); break; } break; @@ -28,7 +28,7 @@ void HyperCPU::CPU::ExecMOV(const IInstruction& instr, void* op1, void* op2) { case R_RM: { std::uint64_t ptr; - std::memcpy(&ptr, op2, 8); + std::memcpy(&ptr, op2.ptr(), 8); switch (instr.m_opcode_mode) { case b8: @@ -51,7 +51,7 @@ void HyperCPU::CPU::ExecMOV(const IInstruction& instr, void* op1, void* op2) { } case R_M: { - std::uint64_t ptr = reinterpret_cast(op2); + std::uint64_t ptr = op2; switch (instr.m_opcode_mode) { case b8: @@ -76,28 +76,28 @@ void HyperCPU::CPU::ExecMOV(const IInstruction& instr, void* op1, void* op2) { case R_IMM: { switch (instr.m_opcode_mode) { case b8: - std::memcpy(op1, &op2, 1); + std::memcpy(op1, &op2.ref(), 1); break; case b16: - std::memcpy(op1, &op2, 2); + std::memcpy(op1, &op2.ref(), 2); break; case b32: - std::memcpy(op1, &op2, 4); + std::memcpy(op1, &op2.ref(), 4); break; case b64: - std::memcpy(op1, &op2, 8); + std::memcpy(op1, &op2.ref(), 8); break; } break; } case RM_M: { - std::size_t ptr1, ptr2 = 0; - std::memcpy(&ptr1, op1, 8); - ptr2 = reinterpret_cast(op2); + std::uint64_t ptr1, ptr2 = 0; + std::memcpy(&ptr1, op1.ptr(), 8); + ptr2 = op2; switch (instr.m_opcode_mode) { case b8: @@ -120,7 +120,7 @@ void HyperCPU::CPU::ExecMOV(const IInstruction& instr, void* op1, void* op2) { } case RM_R: { - std::size_t ptr = HyperCPU::bit_cast_from(op1); + std::uint64_t ptr = op1.deref(); switch (instr.m_opcode_mode) { case b8: { @@ -147,7 +147,7 @@ void HyperCPU::CPU::ExecMOV(const IInstruction& instr, void* op1, void* op2) { } case RM_IMM: { - std::size_t ptr1 = HyperCPU::bit_cast_from(op1); + std::uint64_t ptr1 = op1.deref(); switch (instr.m_opcode_mode) { case b8: @@ -174,22 +174,22 @@ void HyperCPU::CPU::ExecMOV(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_opcode_mode) { case b8: { - mem_controller->Load8(ptr1, HyperCPU::bit_cast_from(op2)); + mem_controller->Load8(ptr1, HyperCPU::bit_cast_from(op2.ptr())); break; } case b16: { - mem_controller->Load16(ptr1, HyperCPU::bit_cast_from(op2)); + mem_controller->Load16(ptr1, HyperCPU::bit_cast_from(op2.ptr())); break; } case b32: { - mem_controller->Load32(ptr1, HyperCPU::bit_cast_from(op2)); + mem_controller->Load32(ptr1, HyperCPU::bit_cast_from(op2.ptr())); break; } case b64: { - mem_controller->Load64(ptr1, HyperCPU::bit_cast_from(op2)); + mem_controller->Load64(ptr1, HyperCPU::bit_cast_from(op2.ptr())); break; } } diff --git a/src/Emulator/Core/CPU/InstructionsImpl/MUL.cpp b/src/Emulator/Core/CPU/InstructionsImpl/MUL.cpp index 789b6b70..6ca04a7c 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/MUL.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/MUL.cpp @@ -9,62 +9,62 @@ using namespace HyperALU; -void HyperCPU::CPU::ExecMUL(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecMUL(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { switch (instr.m_op_types) { case R_R: { switch (instr.m_opcode_mode) { case b8: - ovf = multiplication_will_overflow(deref(op1), deref(op2)); - deref(op1) = __hcpu_mul(deref(op1), HyperCPU::bit_cast_from(op2)); + ovf = multiplication_will_overflow(op1.deref(), op2.deref()); + op1.deref() = __hcpu_mul(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; case b16: - ovf = multiplication_will_overflow(deref(op1), deref(op2)); - deref(op1) = __hcpu_mul(deref(op1), HyperCPU::bit_cast_from(op2)); + ovf = multiplication_will_overflow(op1.deref(), op2.deref()); + op1.deref() = __hcpu_mul(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; case b32: - ovf = multiplication_will_overflow(deref(op1), deref(op2)); - deref(op1) = __hcpu_mul(deref(op1), HyperCPU::bit_cast_from(op2)); + ovf = multiplication_will_overflow(op1.deref(), op2.deref()); + op1.deref() = __hcpu_mul(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; case b64: - ovf = multiplication_will_overflow(deref(op1), deref(op2)); - deref(op1) = __hcpu_mul(deref(op1), HyperCPU::bit_cast_from(op2)); + ovf = multiplication_will_overflow(op1.deref(), op2.deref()); + op1.deref() = __hcpu_mul(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; } break; } case R_RM: { - std::uint64_t ptr = HyperCPU::bit_cast_from(op2); + std::uint64_t ptr = HyperCPU::bit_cast_from(op2.ptr()); switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = mem_controller->Read8(ptr); - ovf = multiplication_will_overflow(deref(op1), val); - deref(op1) = __hcpu_mul(deref(op1), val); + ovf = multiplication_will_overflow(op1.deref(), val); + op1.deref() = __hcpu_mul(op1.deref(), val); break; } case b16: { std::uint16_t val = mem_controller->Read16(ptr); - ovf = multiplication_will_overflow(deref(op1), val); - deref(op1) = __hcpu_mul(deref(op1), val); + ovf = multiplication_will_overflow(op1.deref(), val); + op1.deref() = __hcpu_mul(op1.deref(), val); break; } case b32: { std::uint32_t val = mem_controller->Read32(ptr); - ovf = multiplication_will_overflow(deref(op1), val); - deref(op1) = __hcpu_mul(deref(op1), val); + ovf = multiplication_will_overflow(op1.deref(), val); + op1.deref() = __hcpu_mul(op1.deref(), val); break; } case b64: { std::uint64_t val = mem_controller->Read64(ptr); - ovf = multiplication_will_overflow(deref(op1), val); - deref(op1) = __hcpu_mul(deref(op1), val); + ovf = multiplication_will_overflow(op1.deref(), val); + op1.deref() = __hcpu_mul(op1.deref(), val); break; } } @@ -77,29 +77,29 @@ void HyperCPU::CPU::ExecMUL(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = mem_controller->Read8(ptr); - ovf = multiplication_will_overflow(deref(op1), val); - deref(op1) = __hcpu_mul(deref(op1), val); + ovf = multiplication_will_overflow(op1.deref(), val); + op1.deref() = __hcpu_mul(op1.deref(), val); break; } case b16: { std::uint16_t val = mem_controller->Read16(ptr); - ovf = multiplication_will_overflow(deref(op1), val); - deref(op1) = __hcpu_mul(deref(op1), val); + ovf = multiplication_will_overflow(op1.deref(), val); + op1.deref() = __hcpu_mul(op1.deref(), val); break; } case b32: { std::uint32_t val = mem_controller->Read32(ptr); - ovf = multiplication_will_overflow(deref(op1), val); - deref(op1) = __hcpu_mul(deref(op1), val); + ovf = multiplication_will_overflow(op1.deref(), val); + op1.deref() = __hcpu_mul(op1.deref(), val); break; } case b64: { std::uint64_t val = mem_controller->Read64(ptr); - ovf = multiplication_will_overflow(deref(op1), val); - deref(op1) = __hcpu_mul(deref(op1), val); + ovf = multiplication_will_overflow(op1.deref(), val); + op1.deref() = __hcpu_mul(op1.deref(), val); break; } } @@ -110,29 +110,29 @@ void HyperCPU::CPU::ExecMUL(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = HyperCPU::bit_cast(op2); - ovf = multiplication_will_overflow(deref(op1), val); - deref(op1) = __hcpu_mul(deref(op1), val); + ovf = multiplication_will_overflow(op1.deref(), val); + op1.deref() = __hcpu_mul(op1.deref(), val); break; } case b16: { std::uint16_t val = HyperCPU::bit_cast(op2); - ovf = multiplication_will_overflow(deref(op1), val); - deref(op1) = __hcpu_mul(deref(op1), val); + ovf = multiplication_will_overflow(op1.deref(), val); + op1.deref() = __hcpu_mul(op1.deref(), val); break; } case b32: { std::uint32_t val = HyperCPU::bit_cast(op2); - ovf = multiplication_will_overflow(deref(op1), val); - deref(op1) = __hcpu_mul(deref(op1), val); + ovf = multiplication_will_overflow(op1.deref(), val); + op1.deref() = __hcpu_mul(op1.deref(), val); break; } case b64: { std::uint64_t val = HyperCPU::bit_cast(op2); - ovf = multiplication_will_overflow(deref(op1), val); - deref(op1) = __hcpu_mul(deref(op1), val); + ovf = multiplication_will_overflow(op1.deref(), val); + op1.deref() = __hcpu_mul(op1.deref(), val); break; } } diff --git a/src/Emulator/Core/CPU/InstructionsImpl/OR.cpp b/src/Emulator/Core/CPU/InstructionsImpl/OR.cpp index a56eea8f..bfd92f8e 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/OR.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/OR.cpp @@ -7,54 +7,54 @@ using namespace HyperALU; -void HyperCPU::CPU::ExecOR(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecOR(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { switch (instr.m_op_types) { case R_R: { switch (instr.m_opcode_mode) { case b8: - deref(op1) = __hcpu_or(deref(op1), HyperCPU::bit_cast_from(op2)); + op1.deref() = __hcpu_or(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; case b16: - deref(op1) = __hcpu_or(deref(op1), HyperCPU::bit_cast_from(op2)); + op1.deref() = __hcpu_or(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; case b32: - deref(op1) = __hcpu_or(deref(op1), HyperCPU::bit_cast_from(op2)); + op1.deref() = __hcpu_or(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; case b64: - deref(op1) = __hcpu_or(deref(op1), HyperCPU::bit_cast_from(op2)); + op1.deref() = __hcpu_or(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; } break; } case R_RM: { - std::uint64_t ptr = HyperCPU::bit_cast_from(op2); + std::uint64_t ptr = HyperCPU::bit_cast_from(op2.ptr()); switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = mem_controller->Read8(ptr); - deref(op1) = __hcpu_or(deref(op1), val); + op1.deref() = __hcpu_or(op1.deref(), val); break; } case b16: { std::uint16_t val = mem_controller->Read16(ptr); - deref(op1) = __hcpu_or(deref(op1), val); + op1.deref() = __hcpu_or(op1.deref(), val); break; } case b32: { std::uint32_t val = mem_controller->Read32(ptr); - deref(op1) = __hcpu_or(deref(op1), val); + op1.deref() = __hcpu_or(op1.deref(), val); break; } case b64: { std::uint64_t val = mem_controller->Read64(ptr); - deref(op1) = __hcpu_or(deref(op1), val); + op1.deref() = __hcpu_or(op1.deref(), val); break; } } @@ -67,25 +67,25 @@ void HyperCPU::CPU::ExecOR(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = mem_controller->Read8(ptr); - deref(op1) = __hcpu_or(deref(op1), val); + op1.deref() = __hcpu_or(op1.deref(), val); break; } case b16: { std::uint16_t val = mem_controller->Read16(ptr); - deref(op1) = __hcpu_or(deref(op1), val); + op1.deref() = __hcpu_or(op1.deref(), val); break; } case b32: { std::uint32_t val = mem_controller->Read32(ptr); - deref(op1) = __hcpu_or(deref(op1), val); + op1.deref() = __hcpu_or(op1.deref(), val); break; } case b64: { std::uint64_t val = mem_controller->Read64(ptr); - deref(op1) = __hcpu_or(deref(op1), val); + op1.deref() = __hcpu_or(op1.deref(), val); break; } } @@ -96,25 +96,25 @@ void HyperCPU::CPU::ExecOR(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = HyperCPU::bit_cast(op2); - deref(op1) = __hcpu_or(deref(op1), val); + op1.deref() = __hcpu_or(op1.deref(), val); break; } case b16: { std::uint16_t val = HyperCPU::bit_cast(op2); - deref(op1) = __hcpu_or(deref(op1), val); + op1.deref() = __hcpu_or(op1.deref(), val); break; } case b32: { std::uint32_t val = HyperCPU::bit_cast(op2); - deref(op1) = __hcpu_or(deref(op1), val); + op1.deref() = __hcpu_or(op1.deref(), val); break; } case b64: { std::uint64_t val = HyperCPU::bit_cast(op2); - deref(op1) = __hcpu_or(deref(op1), val); + op1.deref() = __hcpu_or(op1.deref(), val); break; } } diff --git a/src/Emulator/Core/CPU/InstructionsImpl/POP.cpp b/src/Emulator/Core/CPU/InstructionsImpl/POP.cpp index 2121566e..afca8c11 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/POP.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/POP.cpp @@ -8,14 +8,14 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecPOP(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecPOP(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { switch (instr.m_op_types) { case R: switch (instr.m_opcode_mode) { - case HyperCPU::Mode::b8: deref(op1) = StackPop8(); break; - case HyperCPU::Mode::b16: deref(op1) = StackPop16(); break; - case HyperCPU::Mode::b32: deref(op1) = StackPop32(); break; - case HyperCPU::Mode::b64: deref(op1) = StackPop64(); break; + case HyperCPU::Mode::b8: op1.deref() = StackPop8(); break; + case HyperCPU::Mode::b16: op1.deref() = StackPop16(); break; + case HyperCPU::Mode::b32: op1.deref() = StackPop32(); break; + case HyperCPU::Mode::b64: op1.deref() = StackPop64(); break; default: UNREACHABLE(); } break; diff --git a/src/Emulator/Core/CPU/InstructionsImpl/PUSH.cpp b/src/Emulator/Core/CPU/InstructionsImpl/PUSH.cpp index 24e164d5..29b8f5db 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/PUSH.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/PUSH.cpp @@ -10,14 +10,14 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecPUSH(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecPUSH(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { switch (instr.m_op_types) { case R: switch (instr.m_opcode_mode) { - case HyperCPU::Mode::b8: StackPush8(HyperCPU::bit_cast_from(op1)); break; - case HyperCPU::Mode::b16: StackPush16(HyperCPU::bit_cast_from(op1)); break; - case HyperCPU::Mode::b32: StackPush32(HyperCPU::bit_cast_from(op1)); break; - case HyperCPU::Mode::b64: StackPush64(HyperCPU::bit_cast_from(op1)); break; + case HyperCPU::Mode::b8: StackPush8(HyperCPU::bit_cast_from(op1.ptr())); break; + case HyperCPU::Mode::b16: StackPush16(HyperCPU::bit_cast_from(op1.ptr())); break; + case HyperCPU::Mode::b32: StackPush32(HyperCPU::bit_cast_from(op1.ptr())); break; + case HyperCPU::Mode::b64: StackPush64(HyperCPU::bit_cast_from(op1.ptr())); break; default: UNREACHABLE(); } break; diff --git a/src/Emulator/Core/CPU/InstructionsImpl/READ.cpp b/src/Emulator/Core/CPU/InstructionsImpl/READ.cpp index 058925f6..04a478a2 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/READ.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/READ.cpp @@ -7,14 +7,14 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecREAD(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecREAD(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { read_operation_handler* handler = nullptr; switch (instr.m_op_types) { case HyperCPU::IMM: handler = &read_io_handlers[HyperCPU::bit_cast(op1)]; break; case HyperCPU::R: - handler = &read_io_handlers[HyperCPU::bit_cast_from(op1)]; + handler = &read_io_handlers[HyperCPU::bit_cast_from(op1.ptr())]; break; default: UNREACHABLE(); diff --git a/src/Emulator/Core/CPU/InstructionsImpl/SHFL.cpp b/src/Emulator/Core/CPU/InstructionsImpl/SHFL.cpp index 675348ff..90df5fe3 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/SHFL.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/SHFL.cpp @@ -5,24 +5,24 @@ #include -void HyperCPU::CPU::ExecSHFL(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecSHFL(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { switch (instr.m_op_types) { case R_R: { switch (instr.m_opcode_mode) { case b8: - deref(op1) <<= HyperCPU::bit_cast_from(op2); + op1.deref() <<= HyperCPU::bit_cast_from(op2.ptr()); break; case b16: - deref(op1) <<= HyperCPU::bit_cast_from(op2); + op1.deref() <<= HyperCPU::bit_cast_from(op2.ptr()); break; case b32: - deref(op1) <<= HyperCPU::bit_cast_from(op2); + op1.deref() <<= HyperCPU::bit_cast_from(op2.ptr()); break; case b64: - deref(op1) <<= HyperCPU::bit_cast_from(op2); + op1.deref() <<= HyperCPU::bit_cast_from(op2.ptr()); break; } break; @@ -32,25 +32,25 @@ void HyperCPU::CPU::ExecSHFL(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = HyperCPU::bit_cast(op2); - deref(op1) <<= val; + op1.deref() <<= val; break; } case b16: { std::uint16_t val = HyperCPU::bit_cast(op2); - deref(op1) <<= val; + op1.deref() <<= val; break; } case b32: { std::uint32_t val = HyperCPU::bit_cast(op2); - deref(op1) <<= val; + op1.deref() <<= val; break; } case b64: { std::uint64_t val = HyperCPU::bit_cast(op2); - deref(op1) <<= val; + op1.deref() <<= val; break; } } diff --git a/src/Emulator/Core/CPU/InstructionsImpl/SHFR.cpp b/src/Emulator/Core/CPU/InstructionsImpl/SHFR.cpp index f21d9b56..b51c0f4d 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/SHFR.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/SHFR.cpp @@ -1,3 +1,4 @@ +#include "Core/CPU/Instructions/Flags.hpp" #include #include @@ -5,24 +6,24 @@ #include -void HyperCPU::CPU::ExecSHFR(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecSHFR(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { switch (instr.m_op_types) { case R_R: { switch (instr.m_opcode_mode) { case b8: - deref(op1) >>= HyperCPU::bit_cast_from(op2); + op1.deref() >>= op2.deref(); break; case b16: - deref(op1) >>= HyperCPU::bit_cast_from(op2); + op1.deref() >>= op2.deref(); break; case b32: - deref(op1) >>= HyperCPU::bit_cast_from(op2); + op1.deref() >>= op2.deref(); break; case b64: - deref(op1) >>= HyperCPU::bit_cast_from(op2); + op1.deref() >>= op2.deref(); break; } break; @@ -32,25 +33,25 @@ void HyperCPU::CPU::ExecSHFR(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = HyperCPU::bit_cast(op2); - deref(op1) >>= val; + op1.deref() >>= val; break; } case b16: { std::uint16_t val = HyperCPU::bit_cast(op2); - deref(op1) >>= val; + op1.deref() >>= val; break; } case b32: { std::uint32_t val = HyperCPU::bit_cast(op2); - deref(op1) >>= val; + op1.deref() >>= val; break; } case b64: { std::uint64_t val = HyperCPU::bit_cast(op2); - deref(op1) >>= val; + op1.deref() >>= val; break; } } diff --git a/src/Emulator/Core/CPU/InstructionsImpl/SUB.cpp b/src/Emulator/Core/CPU/InstructionsImpl/SUB.cpp index 48a4490c..79841f99 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/SUB.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/SUB.cpp @@ -7,62 +7,62 @@ using namespace HyperALU; -void HyperCPU::CPU::ExecSUB(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecSUB(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { switch (instr.m_op_types) { case R_R: { switch (instr.m_opcode_mode) { case b8: - udf = SubtractionWillUnderflow(deref(op1), deref(op2)); - deref(op1) = __hcpu_sub(deref(op1), HyperCPU::bit_cast_from(op2)); + udf = SubtractionWillUnderflow(op1.deref(), op2.deref()); + op1.deref() = __hcpu_sub(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; case b16: - udf = SubtractionWillUnderflow(deref(op1), deref(op2)); - deref(op1) = __hcpu_sub(deref(op1), HyperCPU::bit_cast_from(op2)); + udf = SubtractionWillUnderflow(op1.deref(), op2.deref()); + op1.deref() = __hcpu_sub(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; case b32: - udf = SubtractionWillUnderflow(deref(op1), deref(op2)); - deref(op1) = __hcpu_sub(deref(op1), HyperCPU::bit_cast_from(op2)); + udf = SubtractionWillUnderflow(op1.deref(), op2.deref()); + op1.deref() = __hcpu_sub(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; case b64: - udf = SubtractionWillUnderflow(deref(op1), deref(op2)); - deref(op1) = __hcpu_sub(deref(op1), HyperCPU::bit_cast_from(op2)); + udf = SubtractionWillUnderflow(op1.deref(), op2.deref()); + op1.deref() = __hcpu_sub(op1.deref(), HyperCPU::bit_cast_from(op2.ptr())); break; } // TODO: mark defaults as std::unreachable() break; } case R_RM: { - std::uint64_t ptr = HyperCPU::bit_cast_from(op2); + std::uint64_t ptr = op2.deref(); switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = mem_controller->Read8(ptr); - udf = SubtractionWillUnderflow(deref(op1), val); - deref(op1) = __hcpu_sub(deref(op1), val); + udf = SubtractionWillUnderflow(op1.deref(), val); + op1.deref() = __hcpu_sub(op1.deref(), val); break; } case b16: { std::uint16_t val = mem_controller->Read16(ptr); - udf = SubtractionWillUnderflow(deref(op1), val); - deref(op1) = __hcpu_sub(deref(op1), val); + udf = SubtractionWillUnderflow(op1.deref(), val); + op1.deref() = __hcpu_sub(op1.deref(), val); break; } case b32: { std::uint32_t val = mem_controller->Read32(ptr); - udf = SubtractionWillUnderflow(deref(op1), val); - deref(op1) = __hcpu_sub(deref(op1), val); + udf = SubtractionWillUnderflow(op1.deref(), val); + op1.deref() = __hcpu_sub(op1.deref(), val); break; } case b64: { std::uint64_t val = mem_controller->Read64(ptr); - udf = SubtractionWillUnderflow(deref(op1), val); - deref(op1) = __hcpu_sub(deref(op1), val); + udf = SubtractionWillUnderflow(op1.deref(), val); + op1.deref() = __hcpu_sub(op1.deref(), val); break; } } @@ -70,34 +70,34 @@ void HyperCPU::CPU::ExecSUB(const IInstruction& instr, void* op1, void* op2) { } case R_M: { - std::uint64_t ptr = HyperCPU::bit_cast(op2); + std::uint64_t ptr = op2; switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = mem_controller->Read8(ptr); - udf = SubtractionWillUnderflow(deref(op1), val); - deref(op1) = __hcpu_sub(deref(op1), val); + udf = SubtractionWillUnderflow(op1.deref(), val); + op1.deref() = __hcpu_sub(op1.deref(), val); break; } case b16: { std::uint16_t val = mem_controller->Read16(ptr); - udf = SubtractionWillUnderflow(deref(op1), val); - deref(op1) = __hcpu_sub(deref(op1), val); + udf = SubtractionWillUnderflow(op1.deref(), val); + op1.deref() = __hcpu_sub(op1.deref(), val); break; } case b32: { std::uint32_t val = mem_controller->Read32(ptr); - udf = SubtractionWillUnderflow(deref(op1), val); - deref(op1) = __hcpu_sub(deref(op1), val); + udf = SubtractionWillUnderflow(op1.deref(), val); + op1.deref() = __hcpu_sub(op1.deref(), val); break; } case b64: { std::uint64_t val = mem_controller->Read64(ptr); - udf = SubtractionWillUnderflow(deref(op1), val); - deref(op1) = __hcpu_sub(deref(op1), val); + udf = SubtractionWillUnderflow(op1.deref(), val); + op1.deref() = __hcpu_sub(op1.deref(), val); break; } } @@ -108,29 +108,29 @@ void HyperCPU::CPU::ExecSUB(const IInstruction& instr, void* op1, void* op2) { switch (instr.m_opcode_mode) { case b8: { std::uint8_t val = HyperCPU::bit_cast(op2); - udf = SubtractionWillUnderflow(deref(op1), val); - deref(op1) = __hcpu_sub(deref(op1), val); + udf = SubtractionWillUnderflow(op1.deref(), val); + op1.deref() = __hcpu_sub(op1.deref(), val); break; } case b16: { std::uint16_t val = HyperCPU::bit_cast(op2); - udf = SubtractionWillUnderflow(deref(op1), val); - deref(op1) = __hcpu_sub(deref(op1), val); + udf = SubtractionWillUnderflow(op1.deref(), val); + op1.deref() = __hcpu_sub(op1.deref(), val); break; } case b32: { std::uint32_t val = HyperCPU::bit_cast(op2); - udf = SubtractionWillUnderflow(deref(op1), val); - deref(op1) = __hcpu_sub(deref(op1), val); + udf = SubtractionWillUnderflow(op1.deref(), val); + op1.deref() = __hcpu_sub(op1.deref(), val); break; } case b64: { std::uint64_t val = HyperCPU::bit_cast(op2); - udf = SubtractionWillUnderflow(deref(op1), val); - deref(op1) = __hcpu_sub(deref(op1), val); + udf = SubtractionWillUnderflow(op1.deref(), val); + op1.deref() = __hcpu_sub(op1.deref(), val); break; } } diff --git a/src/Emulator/Core/CPU/InstructionsImpl/WRITE.cpp b/src/Emulator/Core/CPU/InstructionsImpl/WRITE.cpp index 6e1fd529..de573bb6 100644 --- a/src/Emulator/Core/CPU/InstructionsImpl/WRITE.cpp +++ b/src/Emulator/Core/CPU/InstructionsImpl/WRITE.cpp @@ -9,7 +9,7 @@ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -void HyperCPU::CPU::ExecWRITE(const IInstruction& instr, void* op1, void* op2) { +void HyperCPU::CPU::ExecWRITE(const IInstruction& instr, OperandContainer op1, OperandContainer op2) { write_operation_handler& handler = write_io_handlers[*static_cast(op1)]; if (handler) { diff --git a/src/Emulator/Core/CPU/Interrupts/InterruptHandler.cpp b/src/Emulator/Core/CPU/Interrupts/InterruptHandler.cpp index 6c25e43a..6df98bd9 100644 --- a/src/Emulator/Core/CPU/Interrupts/InterruptHandler.cpp +++ b/src/Emulator/Core/CPU/Interrupts/InterruptHandler.cpp @@ -32,7 +32,7 @@ void HyperCPU::CPU::RunInterruptSubroutine() { if (instr.m_opcode == Opcode::IRET) { return; } - std::pair operands = GetOperands(instr.m_op_types, instr.m_opcode_mode, instr.m_op1, instr.m_op2); + std::pair operands = GetOperands(instr.m_op_types, instr.m_opcode_mode, instr.m_op1, instr.m_op2); opcode_handler_assoc[static_cast(instr.m_opcode)](instr, operands.first, operands.second); } } diff --git a/src/Emulator/Core/CPU/OperandsEvaluation.cpp b/src/Emulator/Core/CPU/OperandsEvaluation.cpp index ba8968e7..b775f9b0 100644 --- a/src/Emulator/Core/CPU/OperandsEvaluation.cpp +++ b/src/Emulator/Core/CPU/OperandsEvaluation.cpp @@ -4,68 +4,68 @@ #include -void* HyperCPU::CPU::GetRegister(std::size_t& op1) { +HyperCPU::OperandContainer HyperCPU::CPU::GetRegister(OperandContainer& op1) { HyperCPU::Registers reg; memcpy(®, &op1, sizeof(HyperCPU::Registers)); switch (reg) { - case X0: return reinterpret_cast(x0); - case X1: return reinterpret_cast(x1); - case X2: return reinterpret_cast(x2); - case X3: return reinterpret_cast(x3); - case X4: return reinterpret_cast(x4); - case X5: return reinterpret_cast(x5); - case X6: return reinterpret_cast(x6); - case X7: return reinterpret_cast(x7); + case X0: return OperandContainer{x0}; + case X1: return OperandContainer{x1}; + case X2: return OperandContainer{x2}; + case X3: return OperandContainer{x3}; + case X4: return OperandContainer{x4}; + case X5: return OperandContainer{x5}; + case X6: return OperandContainer{x6}; + case X7: return OperandContainer{x7}; - case XH0: return reinterpret_cast(xh0); - case XH1: return reinterpret_cast(xh1); - case XH2: return reinterpret_cast(xh2); - case XH3: return reinterpret_cast(xh3); - case XH4: return reinterpret_cast(xh4); - case XH5: return reinterpret_cast(xh5); - case XH6: return reinterpret_cast(xh6); - case XH7: return reinterpret_cast(xh7); + case XH0: return OperandContainer{xh0}; + case XH1: return OperandContainer{xh1}; + case XH2: return OperandContainer{xh2}; + case XH3: return OperandContainer{xh3}; + case XH4: return OperandContainer{xh4}; + case XH5: return OperandContainer{xh5}; + case XH6: return OperandContainer{xh6}; + case XH7: return OperandContainer{xh7}; - case XL0: return reinterpret_cast(xl0); - case XL1: return reinterpret_cast(xl1); - case XL2: return reinterpret_cast(xl2); - case XL3: return reinterpret_cast(xl3); - case XL4: return reinterpret_cast(xl4); - case XL5: return reinterpret_cast(xl5); - case XL6: return reinterpret_cast(xl6); - case XL7: return reinterpret_cast(xl7); + case XL0: return OperandContainer{xl0}; + case XL1: return OperandContainer{xl1}; + case XL2: return OperandContainer{xl2}; + case XL3: return OperandContainer{xl3}; + case XL4: return OperandContainer{xl4}; + case XL5: return OperandContainer{xl5}; + case XL6: return OperandContainer{xl6}; + case XL7: return OperandContainer{xl7}; - case XLL0: return reinterpret_cast(xll0); - case XLL1: return reinterpret_cast(xll1); - case XLL2: return reinterpret_cast(xll2); - case XLL3: return reinterpret_cast(xll3); + case XLL0: return OperandContainer{xll0}; + case XLL1: return OperandContainer{xll1}; + case XLL2: return OperandContainer{xll2}; + case XLL3: return OperandContainer{xll3}; - case XLLH0: return reinterpret_cast(xllh0); - case XLLH1: return reinterpret_cast(xllh1); - case XLLH2: return reinterpret_cast(xllh2); - case XLLH3: return reinterpret_cast(xllh3); + case XLLH0: return OperandContainer{xllh0}; + case XLLH1: return OperandContainer{xllh1}; + case XLLH2: return OperandContainer{xllh2}; + case XLLH3: return OperandContainer{xllh3}; - case XLLL0: return reinterpret_cast(xlll0); - case XLLL1: return reinterpret_cast(xlll1); - case XLLL2: return reinterpret_cast(xlll2); - case XLLL3: return reinterpret_cast(xlll3); + case XLLL0: return OperandContainer{xlll0}; + case XLLL1: return OperandContainer{xlll1}; + case XLLL2: return OperandContainer{xlll2}; + case XLLL3: return OperandContainer{xlll3}; - case XBP: return reinterpret_cast(xbp); - case XSP: return reinterpret_cast(xsp); - case XIP: return reinterpret_cast(xip); - case XGDP: return reinterpret_cast(xgdp); - case XIVT: return reinterpret_cast(xivt); + case XBP: return OperandContainer{xbp}; + case XSP: return OperandContainer{xsp}; + case XIP: return OperandContainer{xip}; + case XGDP: return OperandContainer{xgdp}; + case XIVT: return OperandContainer{xivt}; default: throw std::runtime_error("Invalid register"); } } -std::pair HyperCPU::CPU::GetOperands(OperandTypes op_types, Mode md, std::size_t& op1, std::size_t& op2) { +std::pair HyperCPU::CPU::GetOperands(OperandTypes op_types, Mode md, OperandContainer& op1, OperandContainer& op2) { switch (op_types) { case R_R: case R_RM: case RM_R: { - void *op_1, *op_2; + OperandContainer op_1, op_2; op_1 = GetRegister(op1); op_2 = GetRegister(op2); return std::make_pair(op_1, op_2); @@ -73,7 +73,7 @@ std::pair HyperCPU::CPU::GetOperands(OperandTypes op_types, Mode m case RM_M: case R_M: - return std::make_pair(GetRegister(op1), std::bit_cast(op2)); + return std::make_pair(GetRegister(op1), op2); case RM_IMM: case R_IMM:{ @@ -81,36 +81,36 @@ std::pair HyperCPU::CPU::GetOperands(OperandTypes op_types, Mode m case b8:{ std::uint8_t imm8; std::memcpy(&imm8, &op2, sizeof(std::uint8_t)); - return std::make_pair(GetRegister(op1), HyperCPU::bit_cast(imm8)); + return std::make_pair(GetRegister(op1), OperandContainer{HyperCPU::bit_cast(imm8)}); } case b16:{ std::uint16_t imm16; std::memcpy(&imm16, &op2, sizeof(std::uint16_t)); - return std::make_pair(GetRegister(op1), HyperCPU::bit_cast(imm16)); + return std::make_pair(GetRegister(op1), OperandContainer{HyperCPU::bit_cast(imm16)}); } case b32:{ std::uint32_t imm32; std::memcpy(&imm32, &op2, sizeof(std::uint32_t)); - return std::make_pair(GetRegister(op1), HyperCPU::bit_cast(imm32)); + return std::make_pair(GetRegister(op1), OperandContainer{HyperCPU::bit_cast(imm32)}); } case b64:{ std::uint64_t imm64; std::memcpy(&imm64, &op2, sizeof(std::uint64_t)); - return std::make_pair(GetRegister(op1), HyperCPU::bit_cast(imm64)); + return std::make_pair(GetRegister(op1), OperandContainer{HyperCPU::bit_cast(imm64)}); } } break; } case M_R: - return std::make_pair(std::bit_cast(op1), GetRegister(op2)); + return std::make_pair(op1, GetRegister(op2)); case R: return std::make_pair(GetRegister(op1), nullptr); case IMM: case M: - return std::make_pair(std::bit_cast(op1), nullptr); + return std::make_pair(op1, nullptr); case NONE: return std::make_pair(nullptr, nullptr); diff --git a/src/Emulator/Core/MemoryController/IMemoryController.hpp b/src/Emulator/Core/MemoryController/IMemoryController.hpp index 732aaf59..b8a7d6ab 100644 --- a/src/Emulator/Core/MemoryController/IMemoryController.hpp +++ b/src/Emulator/Core/MemoryController/IMemoryController.hpp @@ -17,20 +17,20 @@ namespace HyperCPU { class IMemoryController { public: - virtual std::uint8_t Fetch8(std::size_t&) = 0; - virtual std::uint16_t Fetch16(std::size_t&) = 0; - virtual std::uint32_t Fetch32(std::size_t&) = 0; - virtual std::uint64_t Fetch64(std::size_t&) = 0; - - virtual std::uint8_t Read8(std::size_t) = 0; - virtual std::uint16_t Read16(std::size_t) = 0; - virtual std::uint32_t Read32(std::size_t) = 0; - virtual std::uint64_t Read64(std::size_t) = 0; - - virtual void Load8(std::size_t, std::uint8_t) = 0; - virtual void Load16(std::size_t, std::uint16_t) = 0; - virtual void Load32(std::size_t, std::uint32_t) = 0; - virtual void Load64(std::size_t, std::uint64_t) = 0; + virtual std::uint8_t Fetch8(std::uint64_t&) = 0; + virtual std::uint16_t Fetch16(std::uint64_t&) = 0; + virtual std::uint32_t Fetch32(std::uint64_t&) = 0; + virtual std::uint64_t Fetch64(std::uint64_t&) = 0; + + virtual std::uint8_t Read8(std::uint64_t) = 0; + virtual std::uint16_t Read16(std::uint64_t) = 0; + virtual std::uint32_t Read32(std::uint64_t) = 0; + virtual std::uint64_t Read64(std::uint64_t) = 0; + + virtual void Load8(std::uint64_t, std::uint8_t) = 0; + virtual void Load16(std::uint64_t, std::uint16_t) = 0; + virtual void Load32(std::uint64_t, std::uint32_t) = 0; + virtual void Load64(std::uint64_t, std::uint64_t) = 0; virtual std::uint8_t* get_ptr() const noexcept = 0; diff --git a/src/Emulator/Core/MemoryController/MemoryControllerST.hpp b/src/Emulator/Core/MemoryController/MemoryControllerST.hpp index 98b14bf0..51577c28 100644 --- a/src/Emulator/Core/MemoryController/MemoryControllerST.hpp +++ b/src/Emulator/Core/MemoryController/MemoryControllerST.hpp @@ -18,7 +18,7 @@ namespace HyperCPU { if (!memory) throw std::runtime_error("Failed to allocate memory!"); } - inline std::uint8_t Fetch8(std::size_t& ptr) override { + inline std::uint8_t Fetch8(std::uint64_t& ptr) override { mem_ctlr_assert(ptr + sizeof(std::uint8_t) - 1 < total_mem); std::uint8_t data; memcpy(&data, &memory[ptr], sizeof(std::uint8_t)); @@ -26,7 +26,7 @@ namespace HyperCPU { return data; } - inline std::uint16_t Fetch16(std::size_t& ptr) override { + inline std::uint16_t Fetch16(std::uint64_t& ptr) override { mem_ctlr_assert(ptr + sizeof(std::uint16_t) - 1 < total_mem); std::uint16_t data; memcpy(&data, &memory[ptr], sizeof(std::uint16_t)); @@ -34,7 +34,7 @@ namespace HyperCPU { return data; } - inline std::uint32_t Fetch32(std::size_t& ptr) override { + inline std::uint32_t Fetch32(std::uint64_t& ptr) override { mem_ctlr_assert(ptr + sizeof(std::uint32_t) - 1 < total_mem); std::uint32_t data; memcpy(&data, &memory[ptr], sizeof(std::uint32_t)); @@ -42,7 +42,7 @@ namespace HyperCPU { return data; } - inline std::uint64_t Fetch64(std::size_t& ptr) override { + inline std::uint64_t Fetch64(std::uint64_t& ptr) override { mem_ctlr_assert(ptr + sizeof(std::uint64_t) - 1 < total_mem); std::uint64_t data; memcpy(&data, &memory[ptr], sizeof(std::uint64_t)); @@ -50,50 +50,50 @@ namespace HyperCPU { return data; } - inline std::uint8_t Read8(std::size_t ptr) override { + inline std::uint8_t Read8(std::uint64_t ptr) override { mem_ctlr_assert(ptr + sizeof(std::uint8_t) - 1 < total_mem); std::uint8_t data; memcpy(&data, &memory[ptr], sizeof(std::uint8_t)); return data; } - inline std::uint16_t Read16(std::size_t ptr) override { + inline std::uint16_t Read16(std::uint64_t ptr) override { mem_ctlr_assert(ptr + sizeof(std::uint16_t) - 1 < total_mem); std::uint16_t data; memcpy(&data, &memory[ptr], sizeof(std::uint16_t)); return data; } - inline std::uint32_t Read32(std::size_t ptr) override { + inline std::uint32_t Read32(std::uint64_t ptr) override { mem_ctlr_assert(ptr + sizeof(std::uint32_t) - 1 < total_mem); std::uint32_t data; memcpy(&data, &memory[ptr], sizeof(std::uint32_t)); return data; } - inline std::uint64_t Read64(std::size_t ptr) override { + inline std::uint64_t Read64(std::uint64_t ptr) override { mem_ctlr_assert(ptr + sizeof(std::uint64_t) - 1 < total_mem); std::uint64_t data; memcpy(&data, &memory[ptr], sizeof(std::uint64_t)); return data; } - inline void Load8(std::size_t ptr, std::uint8_t data) override { + inline void Load8(std::uint64_t ptr, std::uint8_t data) override { mem_ctlr_assert(ptr + sizeof(std::uint8_t) - 1 < total_mem); memcpy(&memory[ptr], &data, sizeof(std::uint8_t)); } - inline void Load16(std::size_t ptr, std::uint16_t data) override { + inline void Load16(std::uint64_t ptr, std::uint16_t data) override { mem_ctlr_assert(ptr + sizeof(std::uint16_t) - 1 < total_mem); memcpy(&memory[ptr], &data, sizeof(std::uint16_t)); } - inline void Load32(std::size_t ptr, std::uint32_t data) override { + inline void Load32(std::uint64_t ptr, std::uint32_t data) override { mem_ctlr_assert(ptr + sizeof(std::uint32_t) - 1 < total_mem); memcpy(&memory[ptr], &data, sizeof(std::uint32_t)); } - inline void Load64(std::size_t ptr, std::uint64_t data) override { + inline void Load64(std::uint64_t ptr, std::uint64_t data) override { mem_ctlr_assert(ptr + sizeof(std::uint64_t) - 1 < total_mem); memcpy(&memory[ptr], &data, sizeof(std::uint64_t)); } diff --git a/src/Emulator/Misc/deref.hpp b/src/Emulator/Misc/deref.hpp index 0b78bd48..6182de6a 100644 --- a/src/Emulator/Misc/deref.hpp +++ b/src/Emulator/Misc/deref.hpp @@ -2,7 +2,7 @@ namespace HyperCPU { template - constexpr T& deref(void* ptr) { + constexpr T& deref(std::uint64_t ptr) { return *static_cast(ptr); } } \ No newline at end of file diff --git a/test/Integration/EmulatorCore/CPU/CPU_CMP.cpp b/test/Integration/EmulatorCore/CPU/CPU_CMP.cpp index c0ebc594..27289628 100644 --- a/test/Integration/EmulatorCore/CPU/CPU_CMP.cpp +++ b/test/Integration/EmulatorCore/CPU/CPU_CMP.cpp @@ -4,11 +4,6 @@ #include -static constexpr std::uint8_t BYTE_DATA = 0x55; -static constexpr std::uint16_t WORD_DATA = 0x5555; -static constexpr std::uint32_t DWORD_DATA = 0x55555555; -static constexpr std::uint64_t QWORD_DATA = 0x5555555555555555; - TEST_F(CPU_TEST, INSTR_CMP_R_R_b8_LE) { cpu.mem_controller->Load16(*cpu.xip, HyperCPU::Opcode::CMP); cpu.mem_controller->Load8(*cpu.xip + 2, HyperCPU::Mode::b8 << 4 | HyperCPU::OperandTypes::R_R); diff --git a/test/Integration/EmulatorCore/CPU/OperandsEvaluation.cpp b/test/Integration/EmulatorCore/CPU/OperandsEvaluation.cpp index 490614be..8c69565f 100644 --- a/test/Integration/EmulatorCore/CPU/OperandsEvaluation.cpp +++ b/test/Integration/EmulatorCore/CPU/OperandsEvaluation.cpp @@ -1,392 +1,392 @@ +#include #include #include TEST_F(OPERAND_EVAL_TEST, PROPER_REGISTERS_EVALUATION) { - std::size_t arg = 0; + HyperCPU::OperandContainer arg = 0; HyperCPU::Registers reg; reg = HyperCPU::Registers::X0; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.x0); reg = HyperCPU::Registers::X1; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.x1); reg = HyperCPU::Registers::X2; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.x2); reg = HyperCPU::Registers::X3; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.x3); reg = HyperCPU::Registers::X4; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.x4); reg = HyperCPU::Registers::X5; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.x5); reg = HyperCPU::Registers::X6; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.x6); reg = HyperCPU::Registers::X7; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.x7); reg = HyperCPU::Registers::XH0; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xh0); reg = HyperCPU::Registers::XH1; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xh1); reg = HyperCPU::Registers::XH2; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xh2); reg = HyperCPU::Registers::XH3; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xh3); reg = HyperCPU::Registers::XH4; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xh4); reg = HyperCPU::Registers::XH5; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xh5); reg = HyperCPU::Registers::XH6; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xh6); reg = HyperCPU::Registers::XH7; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xh7); reg = HyperCPU::Registers::XL0; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xl0); reg = HyperCPU::Registers::XL1; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xl1); reg = HyperCPU::Registers::XL2; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xl2); reg = HyperCPU::Registers::XL3; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xl3); reg = HyperCPU::Registers::XL4; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xl4); reg = HyperCPU::Registers::XL5; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xl5); reg = HyperCPU::Registers::XL6; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xl6); reg = HyperCPU::Registers::XL7; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xl7); reg = HyperCPU::Registers::XLL0; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xll0); reg = HyperCPU::Registers::XLL1; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xll1); reg = HyperCPU::Registers::XLL2; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xll2); reg = HyperCPU::Registers::XLL3; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xll3); reg = HyperCPU::Registers::XLLL0; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xlll0); reg = HyperCPU::Registers::XLLL1; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xlll1); reg = HyperCPU::Registers::XLLL2; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xlll2); reg = HyperCPU::Registers::XLLL3; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xlll3); reg = HyperCPU::Registers::XLLH0; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xllh0); reg = HyperCPU::Registers::XLLH1; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xllh1); reg = HyperCPU::Registers::XLLH2; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xllh2); reg = HyperCPU::Registers::XLLH3; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xllh3); reg = HyperCPU::Registers::XBP; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xbp); reg = HyperCPU::Registers::XSP; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xsp); reg = HyperCPU::Registers::XIP; - std::memcpy(&arg, ®, sizeof(HyperCPU::Registers)); + arg = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg)}; ASSERT_EQ(cpu.GetRegister(arg), cpu.xip); } TEST_F(OPERAND_EVAL_TEST, PROPER_R_R_EVALUATION) { - std::size_t arg1, arg2; + HyperCPU::OperandContainer arg1, arg2; HyperCPU::Registers reg1 = HyperCPU::Registers::X0, reg2 = HyperCPU::Registers::X1; - std::memcpy(&arg1, ®1, sizeof(HyperCPU::Registers)); - std::memcpy(&arg2, ®2, sizeof(HyperCPU::Registers)); + arg1 = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg1)}; + arg2 = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg2)}; result = cpu.GetOperands(HyperCPU::OperandTypes::R_R, HyperCPU::Mode::b8, arg1, arg2); - ASSERT_EQ(result.first, cpu.x0); - ASSERT_EQ(result.second, cpu.x1); + ASSERT_EQ(result.first.ptr(), cpu.x0); + ASSERT_EQ(result.second.ptr(), cpu.x1); } TEST_F(OPERAND_EVAL_TEST, PROPER_R_RM_EVALUATION) { - std::size_t arg1, arg2; + HyperCPU::OperandContainer arg1, arg2; HyperCPU::Registers reg1 = HyperCPU::Registers::X0, reg2 = HyperCPU::Registers::X1; - std::memcpy(&arg1, ®1, sizeof(HyperCPU::Registers)); - std::memcpy(&arg2, ®2, sizeof(HyperCPU::Registers)); + arg1 = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg1)}; + arg2 = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg2)}; result = cpu.GetOperands(HyperCPU::OperandTypes::R_RM, HyperCPU::Mode::b8, arg1, arg2); - ASSERT_EQ(result.first, cpu.x0); - ASSERT_EQ(result.second, cpu.x1); + ASSERT_EQ(result.first.ptr(), cpu.x0); + ASSERT_EQ(result.second.ptr(), cpu.x1); } TEST_F(OPERAND_EVAL_TEST, PROPER_RM_R_EVALUATION) { - std::size_t arg1, arg2; + HyperCPU::OperandContainer arg1, arg2; HyperCPU::Registers reg1 = HyperCPU::Registers::X0, reg2 = HyperCPU::Registers::X1; - std::memcpy(&arg1, ®1, sizeof(HyperCPU::Registers)); - std::memcpy(&arg2, ®2, sizeof(HyperCPU::Registers)); + arg1 = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg1)}; + arg2 = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg2)}; result = cpu.GetOperands(HyperCPU::OperandTypes::RM_R, HyperCPU::Mode::b8, arg1, arg2); - ASSERT_EQ(result.first, cpu.x0); - ASSERT_EQ(result.second, cpu.x1); + ASSERT_EQ(result.first.ptr(), cpu.x0); + ASSERT_EQ(result.second.ptr(), cpu.x1); } TEST_F(OPERAND_EVAL_TEST, PROPER_RM_M_EVALUATION) { - std::size_t arg1, arg2 = 1024; + HyperCPU::OperandContainer arg1, arg2 = HyperCPU::OperandContainer{1024ULL}; HyperCPU::Registers reg1 = HyperCPU::Registers::X0; - std::memcpy(&arg1, ®1, sizeof(HyperCPU::Registers)); + arg1 = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg1)}; result = cpu.GetOperands(HyperCPU::OperandTypes::RM_M, HyperCPU::Mode::b8, arg1, arg2); - ASSERT_EQ(result.first, cpu.x0); - ASSERT_EQ(result.second, reinterpret_cast(arg2)); + ASSERT_EQ(result.first.ptr(), cpu.x0); + ASSERT_EQ(result.second.ref(), arg2.ref()); } TEST_F(OPERAND_EVAL_TEST, PROPER_R_M_EVALUATION) { - std::size_t arg1, arg2 = 1024; + HyperCPU::OperandContainer arg1, arg2 = HyperCPU::OperandContainer{1024}; HyperCPU::Registers reg1 = HyperCPU::Registers::X0; - std::memcpy(&arg1, ®1, sizeof(HyperCPU::Registers)); + arg1 = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg1)}; result = cpu.GetOperands(HyperCPU::OperandTypes::R_M, HyperCPU::Mode::b8, arg1, arg2); - ASSERT_EQ(result.first, cpu.x0); - ASSERT_EQ(result.second, reinterpret_cast(arg2)); + ASSERT_EQ(result.first.ptr(), cpu.x0); + ASSERT_EQ(result.second.ref(), arg2.ref()); } TEST_F(OPERAND_EVAL_TEST, PROPER_RM_IMM_B8_EVALUATION) { - std::size_t arg1, arg2, arg3 = 0xFF; + HyperCPU::OperandContainer arg1, arg2, arg3 = HyperCPU::OperandContainer{0xFF}; std::uint8_t imm; HyperCPU::Registers reg1 = HyperCPU::Registers::X0; - std::memcpy(&arg1, ®1, sizeof(HyperCPU::Registers)); - std::memcpy(&arg2, &arg3, sizeof(std::uint8_t)); + arg1 = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg1)}; + arg2 = HyperCPU::OperandContainer{HyperCPU::bit_cast(arg3)}; result = cpu.GetOperands(HyperCPU::OperandTypes::RM_IMM, HyperCPU::Mode::b8, arg1, arg2); std::memcpy(&imm, &result.second, sizeof(std::uint8_t)); - ASSERT_EQ(result.first, cpu.x0); - ASSERT_EQ(imm, arg3); + ASSERT_EQ(result.first.ptr(), cpu.x0); + ASSERT_EQ(imm, arg3.ref()); } TEST_F(OPERAND_EVAL_TEST, PROPER_RM_IMM_B16_EVALUATION) { - std::size_t arg1, arg2, arg3 = 0xFFFF; + HyperCPU::OperandContainer arg1, arg2, arg3 = HyperCPU::OperandContainer{0xFFFF}; std::uint16_t imm; HyperCPU::Registers reg1 = HyperCPU::Registers::X0; - std::memcpy(&arg1, ®1, sizeof(HyperCPU::Registers)); - std::memcpy(&arg2, &arg3, sizeof(std::uint16_t)); - + arg1 = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg1)}; + arg2 = HyperCPU::OperandContainer{HyperCPU::bit_cast(arg3)}; result = cpu.GetOperands(HyperCPU::OperandTypes::RM_IMM, HyperCPU::Mode::b16, arg1, arg2); std::memcpy(&imm, &result.second, sizeof(std::uint16_t)); - ASSERT_EQ(result.first, cpu.x0); - ASSERT_EQ(imm, arg3); + ASSERT_EQ(result.first.ptr(), cpu.x0); + ASSERT_EQ(imm, arg3.ref()); } TEST_F(OPERAND_EVAL_TEST, PROPER_RM_IMM_B32_EVALUATION) { - std::size_t arg1, arg2, arg3 = 0xFFFFFFFF; + HyperCPU::OperandContainer arg1, arg2, arg3 = HyperCPU::OperandContainer{0xFFFFFFFF}; std::uint32_t imm; HyperCPU::Registers reg1 = HyperCPU::Registers::X0; - std::memcpy(&arg1, ®1, sizeof(HyperCPU::Registers)); - std::memcpy(&arg2, &arg3, sizeof(std::uint32_t)); + arg1 = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg1)}; + arg2 = HyperCPU::OperandContainer{HyperCPU::bit_cast(arg3)}; result = cpu.GetOperands(HyperCPU::OperandTypes::RM_IMM, HyperCPU::Mode::b32, arg1, arg2); std::memcpy(&imm, &result.second, sizeof(std::uint32_t)); - ASSERT_EQ(result.first, cpu.x0); - ASSERT_EQ(imm, arg3); + ASSERT_EQ(result.first.ptr(), cpu.x0); + ASSERT_EQ(imm, arg3.ref()); } TEST_F(OPERAND_EVAL_TEST, PROPER_RM_IMM_B64_EVALUATION) { - std::size_t arg1, arg2, arg3 = 0xFFFFFFFFFFFFFFFF; + HyperCPU::OperandContainer arg1, arg2, arg3 = HyperCPU::OperandContainer{0xFFFFFFFFFFFFFFFF}; std::uint64_t imm; HyperCPU::Registers reg1 = HyperCPU::Registers::X0; - std::memcpy(&arg1, ®1, sizeof(HyperCPU::Registers)); - std::memcpy(&arg2, &arg3, sizeof(std::uint64_t)); + arg1 = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg1)}; + arg2 = HyperCPU::OperandContainer{HyperCPU::bit_cast(arg3)}; result = cpu.GetOperands(HyperCPU::OperandTypes::RM_IMM, HyperCPU::Mode::b64, arg1, arg2); std::memcpy(&imm, &result.second, sizeof(std::uint64_t)); - ASSERT_EQ(result.first, cpu.x0); - ASSERT_EQ(imm, arg3); + ASSERT_EQ(result.first.ptr(), cpu.x0); + ASSERT_EQ(imm, arg3.ref()); } TEST_F(OPERAND_EVAL_TEST, PROPER_R_IMM_B8_EVALUATION) { - std::size_t arg1, arg2, arg3 = 0xFF; + HyperCPU::OperandContainer arg1, arg2, arg3 = HyperCPU::OperandContainer{0xFF}; std::uint8_t imm; HyperCPU::Registers reg1 = HyperCPU::Registers::X0; - std::memcpy(&arg1, ®1, sizeof(HyperCPU::Registers)); - std::memcpy(&arg2, &arg3, sizeof(std::uint8_t)); + arg1 = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg1)}; + arg2 = HyperCPU::OperandContainer{HyperCPU::bit_cast(arg3)}; result = cpu.GetOperands(HyperCPU::OperandTypes::R_IMM, HyperCPU::Mode::b8, arg1, arg2); std::memcpy(&imm, &result.second, sizeof(std::uint8_t)); - ASSERT_EQ(result.first, cpu.x0); - ASSERT_EQ(imm, arg3); + ASSERT_EQ(result.first.ptr(), cpu.x0); + ASSERT_EQ(imm, arg3.ref()); } TEST_F(OPERAND_EVAL_TEST, PROPER_R_IMM_B16_EVALUATION) { - std::size_t arg1, arg2, arg3 = 0xFFFF; + HyperCPU::OperandContainer arg1, arg2, arg3 = HyperCPU::OperandContainer{0xFFFF}; std::uint16_t imm; HyperCPU::Registers reg1 = HyperCPU::Registers::X0; - std::memcpy(&arg1, ®1, sizeof(HyperCPU::Registers)); - std::memcpy(&arg2, &arg3, sizeof(std::uint16_t)); + arg1 = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg1)}; + arg2 = HyperCPU::OperandContainer{HyperCPU::bit_cast(arg3)}; result = cpu.GetOperands(HyperCPU::OperandTypes::R_IMM, HyperCPU::Mode::b16, arg1, arg2); std::memcpy(&imm, &result.second, sizeof(std::uint16_t)); - ASSERT_EQ(result.first, cpu.x0); - ASSERT_EQ(imm, arg3); + ASSERT_EQ(result.first.ptr(), cpu.x0); + ASSERT_EQ(imm, arg3.ref()); } TEST_F(OPERAND_EVAL_TEST, PROPER_R_IMM_B32_EVALUATION) { - std::size_t arg1, arg2, arg3 = 0xFFFFFFFF; + HyperCPU::OperandContainer arg1, arg2, arg3 = HyperCPU::OperandContainer{0xFFFFFFFF}; std::uint32_t imm; HyperCPU::Registers reg1 = HyperCPU::Registers::X0; - std::memcpy(&arg1, ®1, sizeof(HyperCPU::Registers)); - std::memcpy(&arg2, &arg3, sizeof(std::uint32_t)); + arg1 = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg1)}; + arg2 = HyperCPU::OperandContainer{HyperCPU::bit_cast(arg3)}; result = cpu.GetOperands(HyperCPU::OperandTypes::R_IMM, HyperCPU::Mode::b32, arg1, arg2); std::memcpy(&imm, &result.second, sizeof(std::uint32_t)); - ASSERT_EQ(result.first, cpu.x0); - ASSERT_EQ(imm, arg3); + ASSERT_EQ(result.first.ptr(), cpu.x0); + ASSERT_EQ(imm, arg3.ref()); } TEST_F(OPERAND_EVAL_TEST, PROPER_R_IMM_B64_EVALUATION) { - std::size_t arg1, arg2, arg3 = 0xFFFFFFFFFFFFFFFF; + HyperCPU::OperandContainer arg1, arg2, arg3 = HyperCPU::OperandContainer{0xFFFFFFFFFFFFFFFF}; std::uint64_t imm; HyperCPU::Registers reg1 = HyperCPU::Registers::X0; - std::memcpy(&arg1, ®1, sizeof(HyperCPU::Registers)); - std::memcpy(&arg2, &arg3, sizeof(std::uint64_t)); + arg1 = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg1)}; + arg2 = HyperCPU::OperandContainer{HyperCPU::bit_cast(arg3)}; result = cpu.GetOperands(HyperCPU::OperandTypes::R_IMM, HyperCPU::Mode::b64, arg1, arg2); std::memcpy(&imm, &result.second, sizeof(std::uint64_t)); - ASSERT_EQ(result.first, cpu.x0); - ASSERT_EQ(imm, arg3); + ASSERT_EQ(result.first.ptr(), cpu.x0); + ASSERT_EQ(imm, arg3.ref()); } TEST_F(OPERAND_EVAL_TEST, PROPER_M_R_EVALUATION) { - std::size_t arg1 = 1024, arg2; + HyperCPU::OperandContainer arg1 = HyperCPU::OperandContainer{1024}, arg2; HyperCPU::Registers reg2 = HyperCPU::Registers::X0; - std::memcpy(&arg2, ®2, sizeof(HyperCPU::Registers)); + arg2 = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg2)}; result = cpu.GetOperands(HyperCPU::OperandTypes::M_R, HyperCPU::Mode::b8, arg1, arg2); - ASSERT_EQ(result.first, reinterpret_cast(arg1)); - ASSERT_EQ(result.second, cpu.x0); + ASSERT_EQ(result.first.ref(), arg1.ref()); + ASSERT_EQ(result.second.ptr(), cpu.x0); } TEST_F(OPERAND_EVAL_TEST, PROPER_R_EVALUATION) { - std::size_t arg1, arg2; + HyperCPU::OperandContainer arg1, arg2; HyperCPU::Registers reg1 = HyperCPU::Registers::X0; - std::memcpy(&arg1, ®1, sizeof(HyperCPU::Registers)); + arg1 = HyperCPU::OperandContainer{HyperCPU::bit_cast(reg1)}; result = cpu.GetOperands(HyperCPU::OperandTypes::R, HyperCPU::Mode::b8, arg1, arg2); - ASSERT_EQ(result.first, cpu.x0); - ASSERT_EQ(result.second, nullptr); + ASSERT_EQ(result.first.ptr(), cpu.x0); + ASSERT_EQ(result.second.ptr(), nullptr); } TEST_F(OPERAND_EVAL_TEST, PROPER_M_EVALUATION) { - std::size_t arg1 = 1024, arg2; + HyperCPU::OperandContainer arg1 = HyperCPU::OperandContainer{1024}, arg2; result = cpu.GetOperands(HyperCPU::OperandTypes::M, HyperCPU::Mode::b8, arg1, arg2); - ASSERT_EQ(result.first, reinterpret_cast(arg1)); - ASSERT_EQ(result.second, nullptr); + ASSERT_EQ(result.first.ref(), arg1.ref()); + ASSERT_EQ(result.second.ptr(), nullptr); } TEST_F(OPERAND_EVAL_TEST, PROPER_NONE_EVALUATION) { - std::size_t arg1, arg2; + HyperCPU::OperandContainer arg1, arg2; result = cpu.GetOperands(HyperCPU::OperandTypes::NONE, HyperCPU::Mode::b8, arg1, arg2); - ASSERT_EQ(result.first, nullptr); - ASSERT_EQ(result.second, nullptr); + ASSERT_EQ(result.first.ptr(), nullptr); + ASSERT_EQ(result.second.ptr(), nullptr); } \ No newline at end of file diff --git a/test/fixtures.hpp b/test/fixtures.hpp index 1b642695..03137514 100644 --- a/test/fixtures.hpp +++ b/test/fixtures.hpp @@ -15,9 +15,9 @@ #include -static constexpr std::size_t MEM_SIZE = 4096; -static constexpr std::size_t MEM_FIXTURE_MEM_SIZE = 1024; -static constexpr std::size_t MEM_PTR = 0x0102030405060708; +static constexpr std::uint64_t MEM_SIZE = 4096; +static constexpr std::uint64_t MEM_FIXTURE_MEM_SIZE = 1024; +static constexpr std::uint64_t MEM_PTR = 0x0102030405060708; class TempDir { public: @@ -42,7 +42,7 @@ class MC_ST_TEST : public testing::Test { protected: HyperCPU::MemoryControllerST mcmt; char tmp_buffer[MEM_FIXTURE_MEM_SIZE]; - std::size_t counter; + std::uint64_t counter; MC_ST_TEST() : mcmt(MEM_FIXTURE_MEM_SIZE), counter(0) { std::memset(tmp_buffer, 0x55, MEM_FIXTURE_MEM_SIZE); } @@ -52,7 +52,7 @@ class MC_ST_FAILTEST : public testing::Test { protected: HyperCPU::MemoryControllerST mcmt; char tmp_buffer[MEM_FIXTURE_MEM_SIZE]; - std::size_t counter; + std::uint64_t counter; MC_ST_FAILTEST() : mcmt(MEM_FIXTURE_MEM_SIZE), counter(LONG_MAX) { std::memset(tmp_buffer, 0x55, MEM_FIXTURE_MEM_SIZE); } @@ -61,24 +61,25 @@ class MC_ST_FAILTEST : public testing::Test { class MC_ST_NEARFAILTEST : public testing::Test { protected: HyperCPU::MemoryControllerST mcmt; - std::size_t counter; + std::uint64_t counter; MC_ST_NEARFAILTEST() : mcmt(MEM_FIXTURE_MEM_SIZE) {} }; class DECODER_TEST : public ::testing::Test { protected: HyperCPU::Decoder decoder; - std::size_t counter; + std::uint64_t counter; + std::unique_ptr mem_ctrl; DECODER_TEST() = default; void SetUp() { - decoder = HyperCPU::Decoder(new HyperCPU::MemoryControllerST(MEM_SIZE), &counter, nullptr); + mem_ctrl = std::make_unique(MEM_SIZE); + decoder = HyperCPU::Decoder(mem_ctrl.get(), &counter, nullptr); counter = 0; } void TearDown() { - delete dynamic_cast(decoder.mem_controller); decoder.~Decoder(); } }; @@ -95,7 +96,7 @@ class OPERAND_EVAL_TEST : public ::testing::Test { protected: HyperCPU::Logger logger; HyperCPU::CPU cpu; - std::pair result; + std::pair result; OPERAND_EVAL_TEST() : logger(HyperCPU::LogLevel::ERROR), cpu(1, 4096) { } };