diff options
| author | 0x221E <0x221E@0xinfinity.dev> | 2026-04-12 16:59:40 +0200 |
|---|---|---|
| committer | 0x221E <0x221E@0xinfinity.dev> | 2026-04-12 16:59:40 +0200 |
| commit | a66c7433c2c11b8b6c99142277ed4e16b1a2a465 (patch) | |
| tree | e54bcfb59c303acf6118fd11f06d5c0bd5f24e5d /src/ExecutorCases.cpp | |
Diffstat (limited to 'src/ExecutorCases.cpp')
| -rw-r--r-- | src/ExecutorCases.cpp | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/ExecutorCases.cpp b/src/ExecutorCases.cpp new file mode 100644 index 0000000..34587be --- /dev/null +++ b/src/ExecutorCases.cpp @@ -0,0 +1,97 @@ +#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 <algorithm> +#include <bitset> +#include <iostream> +#include <utility> + +constexpr std::array<InstructionEntry, 256> GenerateInstructionTable(){ + std::array<InstructionEntry, 256> 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<uint32_t, 0xB8>, (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<InstructionEntry, 256> s_InstructionTable = GenerateInstructionTable(); + +const std::array<InstructionEntry, 256>& GetInstructionTable() { + return s_InstructionTable; +} + +namespace executor_cases::helpers { + + // template<uint8_t... I> + // constexpr std::array<ExecutorCase, 256> GenerateEffectiveAddressCases(std::integer_sequence<uint8_t, I...>) { + // return std::array<ExecutorCase, 256> { + // []<uint8_t S>() { + // return [](CPUContext& c){}; + // }.template operator()<I>()... + // }; + // } + + // constexpr static std::array<ExecutorCase, 256> s_EffectiveAddressCases = GenerateEffectiveAddressCases(std::make_integer_sequence<uint8_t, 255>()); + + // 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; + } +} |
