diff --git a/InstructionSets/x86/Implementation/PerformImplementation.hpp b/InstructionSets/x86/Implementation/PerformImplementation.hpp index 988c9b774..e1ff68393 100644 --- a/InstructionSets/x86/Implementation/PerformImplementation.hpp +++ b/InstructionSets/x86/Implementation/PerformImplementation.hpp @@ -216,8 +216,10 @@ template < Primitive::idiv(pair_high(), pair_low(), source_r(), context); break; } else { - // TODO: perform LEAVE as of the 80186. static_assert(int(Operation::IDIV_REP) == int(Operation::LEAVE)); + if constexpr (std::is_same_v || std::is_same_v) { + Primitive::leave(); + } } return; diff --git a/InstructionSets/x86/Implementation/Stack.hpp b/InstructionSets/x86/Implementation/Stack.hpp index 760ac6d9a..892b2f4e3 100644 --- a/InstructionSets/x86/Implementation/Stack.hpp +++ b/InstructionSets/x86/Implementation/Stack.hpp @@ -144,6 +144,21 @@ void pusha( } } +template +void leave( + ContextT &context +) { + // TODO: should use StackAddressSize to determine assignment of bp to sp. + // Probably make that a static constexpr on registers. + if constexpr (std::is_same_v) { + context.registers.esp() = context.registers.ebp(); + context.registers.ebp() = pop(context); + } else { + context.registers.sp() = context.registers.bp(); + context.registers.bp() = pop(context); + } +} + } #endif /* Stack_hpp */