#include "ExecutorCases.h" #include "DataTransfer.h" #include "ControlFlow.h" #include "Arithmetic.h" #include "Misc.h" #include "Instruction.h" #include "CPUContext.h" #include "Bus.h" #include #include #include #include constexpr std::array GenerateInstructionTable(){ std::array table{}; for(uint8_t i = 0; i < 255; i++) { table[i] = (InstructionEntry){nullptr, (OperandEncoding)0}; } table[Opcode::NOP] = (InstructionEntry){executor_cases::Nop, ZO}; table[Opcode::HLT] = (InstructionEntry){executor_cases::Hlt, ZO}; table[Opcode::MOV_R32_IMM32] = (InstructionEntry){executor_cases::Mov_rX_immX, (OperandEncoding)(I32 | OI)}; table[Opcode::MOV_RM32_R32] = (InstructionEntry){executor_cases::Mov_rm32_r32, MR}; table[Opcode::ADD_RM32_R32] = (InstructionEntry){executor_cases::Add_rm32_r32, MR}; table[Opcode::ADD_R32_RM32] = (InstructionEntry){executor_cases::Add_r32_rm32, RM}; for(uint8_t i = 0; i < 255;) { if((table[i].m_Encoding & OI) != 0) { uint8_t end_offset = std::min(i + 8, 255); std::fill(table.begin() + i, table.begin() + end_offset, table[i]); i += 8; } else { i++; } } return table; } static constexpr std::array s_InstructionTable = GenerateInstructionTable(); const std::array& GetInstructionTable() { return s_InstructionTable; } namespace executor_cases::helpers { // template // constexpr std::array GenerateEffectiveAddressCases(std::integer_sequence) { // return std::array { // []() { // return [](CPUContext& c){}; // }.template operator()()... // }; // } // constexpr static std::array s_EffectiveAddressCases = GenerateEffectiveAddressCases(std::make_integer_sequence()); // uint32_t ResolveEffectiveAddress(CPUContext &cc) { // // uint32_t req = cc.m_Instruction.m_ModRM.m_Rm << 24 | cc.m_Instruction.m_ModRM.m_Reg << 16 | cc.m_Instruction.m_ModRM.m_State << 8; // return 0; // } uint32_t ResolveModRMAddress(CPUContext& cc) { x86::ModRM modrm = cc.m_Instruction.m_ModRM; x86::SIB sib = cc.m_Instruction.m_SIB; 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_Displacement[0]; break; case x86::ModRMState::DISP32: std::memcpy(&value, &cc.m_Instruction.m_Displacement, 4); 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; } }