#include "ExecutorCases.h" #include "DataTransfer.h" #include "ControlFlow.h" #include "Arithmetic.h" #include "Misc.h" #include "Instruction.h" #include "Bus.h" #include #include CPUContext::CPUContext(Instruction& i, uint32_t& ip, uint32_t& flags, uint32_t* reg, std::shared_ptr& bus, bool& isHalted) : m_Instruction(i), m_InstructionPointer(ip), m_Flags(flags), m_Registers(reg), m_Bus(bus), m_IsHalted(isHalted) { } CPUContext::~CPUContext() = default; constexpr std::array GenerateExecutorTable(){ std::array table{}; table[Opcode::NOP] = executor_cases::Nop; table[Opcode::HLT] = executor_cases::Hlt; table[Opcode::MOV_R32_IMM32] = executor_cases::Mov_r32_imm32; table[Opcode::MOV_RM32_R32] = executor_cases::Mov_rm32_r32; table[Opcode::ADD_RM32_R32] = executor_cases::Add_rm32_r32; return table; } static constexpr std::array s_ExecutorTable = GenerateExecutorTable(); const std::array& GetExecutorTable() { return s_ExecutorTable; } namespace executor_cases::helpers { uint32_t ResolveModRMAddress(CPUContext& cc) { x86::ModRM modrm = cc.m_Instruction.optional.m_ModRM; uint32_t value = 0; switch(modrm.m_State) { case x86::ModRMState::LR_DISP32: case x86::ModRMState::LR_DISP8: value = cc.m_Registers[modrm.m_Rm] + cc.m_Instruction.m_Operand1; break; case x86::ModRMState::DISP32: value = cc.m_Instruction.m_Operand1; break; case x86::ModRMState::LR: value = cc.m_Registers[modrm.m_Rm]; break; case x86::ModRMState::R: std::cout << "x86::ModRM reached x86::ModRMState::R during ResolveModRMAddress()" << std::endl; std::cout << "This behavior is unexpected." << std::endl; break; default: throw std::runtime_error("Undefined MODRM state encountered!"); } return value; } }