mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Implement PUSHA, POPA.
This commit is contained in:
parent
1552500b10
commit
6c405680f2
@ -348,8 +348,11 @@ template <
|
|||||||
Primitive::push<IntT, false>(source_rmw(), context); // PUSH SP modifies SP before pushing it;
|
Primitive::push<IntT, false>(source_rmw(), context); // PUSH SP modifies SP before pushing it;
|
||||||
// hence PUSH is sometimes read-modify-write.
|
// hence PUSH is sometimes read-modify-write.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Operation::POPF: Primitive::popf(context); return;
|
case Operation::POPF: Primitive::popf(context); return;
|
||||||
case Operation::PUSHF: Primitive::pushf(context); return;
|
case Operation::PUSHF: Primitive::pushf(context); return;
|
||||||
|
case Operation::POPA: Primitive::popa<IntT>(context); return;
|
||||||
|
case Operation::PUSHA: Primitive::pusha<IntT>(context); return;
|
||||||
|
|
||||||
case Operation::CMPS:
|
case Operation::CMPS:
|
||||||
Primitive::cmps<IntT, AddressT, Repetition::None>(instruction, eCX(), eSI(), eDI(), context);
|
Primitive::cmps<IntT, AddressT, Repetition::None>(instruction, eCX(), eSI(), eDI(), context);
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include "../AccessType.hpp"
|
#include "../AccessType.hpp"
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
namespace InstructionSet::x86::Primitive {
|
namespace InstructionSet::x86::Primitive {
|
||||||
|
|
||||||
// The below takes a reference in order properly to handle PUSH SP,
|
// The below takes a reference in order properly to handle PUSH SP,
|
||||||
@ -89,6 +91,63 @@ void pushf(
|
|||||||
push<uint16_t, false>(value, context);
|
push<uint16_t, false>(value, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename IntT, typename ContextT>
|
||||||
|
void popa(
|
||||||
|
ContextT &context
|
||||||
|
) {
|
||||||
|
if constexpr (!std::is_same_v<IntT, uint8_t>) {
|
||||||
|
context.memory.preauthorise_stack_read(sizeof(IntT) * 8);
|
||||||
|
if constexpr (std::is_same_v<IntT, uint32_t>) {
|
||||||
|
context.registers.edi() = pop<uint32_t, true>(context);
|
||||||
|
context.registers.esi() = pop<uint32_t, true>(context);
|
||||||
|
context.registers.ebp() = pop<uint32_t, true>(context);
|
||||||
|
context.registers.esp() += 4;
|
||||||
|
context.registers.ebx() = pop<uint32_t, true>(context);
|
||||||
|
context.registers.edx() = pop<uint32_t, true>(context);
|
||||||
|
context.registers.ecx() = pop<uint32_t, true>(context);
|
||||||
|
context.registers.eax() = pop<uint32_t, true>(context);
|
||||||
|
} else {
|
||||||
|
context.registers.di() = pop<uint16_t, true>(context);
|
||||||
|
context.registers.si() = pop<uint16_t, true>(context);
|
||||||
|
context.registers.bp() = pop<uint16_t, true>(context);
|
||||||
|
context.registers.sp() += 2;
|
||||||
|
context.registers.bx() = pop<uint16_t, true>(context);
|
||||||
|
context.registers.dx() = pop<uint16_t, true>(context);
|
||||||
|
context.registers.cx() = pop<uint16_t, true>(context);
|
||||||
|
context.registers.ax() = pop<uint16_t, true>(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename IntT, typename ContextT>
|
||||||
|
void pusha(
|
||||||
|
ContextT &context
|
||||||
|
) {
|
||||||
|
if constexpr (!std::is_same_v<IntT, uint8_t>) {
|
||||||
|
context.memory.preauthorise_stack_read(sizeof(IntT) * 8);
|
||||||
|
IntT initial_sp = context.registers.sp();
|
||||||
|
if constexpr (std::is_same_v<IntT, uint32_t>) {
|
||||||
|
push<uint32_t, true>(context.registers.eax(), context);
|
||||||
|
push<uint32_t, true>(context.registers.ecx(), context);
|
||||||
|
push<uint32_t, true>(context.registers.edx(), context);
|
||||||
|
push<uint32_t, true>(context.registers.ebx(), context);
|
||||||
|
push<uint32_t, true>(initial_sp, context);
|
||||||
|
push<uint32_t, true>(context.registers.ebp(), context);
|
||||||
|
push<uint32_t, true>(context.registers.esi(), context);
|
||||||
|
push<uint32_t, true>(context.registers.esi(), context);
|
||||||
|
} else {
|
||||||
|
push<uint16_t, true>(context.registers.ax(), context);
|
||||||
|
push<uint16_t, true>(context.registers.cx(), context);
|
||||||
|
push<uint16_t, true>(context.registers.dx(), context);
|
||||||
|
push<uint16_t, true>(context.registers.bx(), context);
|
||||||
|
push<uint16_t, true>(initial_sp, context);
|
||||||
|
push<uint16_t, true>(context.registers.bp(), context);
|
||||||
|
push<uint16_t, true>(context.registers.si(), context);
|
||||||
|
push<uint16_t, true>(context.registers.si(), context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Stack_hpp */
|
#endif /* Stack_hpp */
|
||||||
|
Loading…
Reference in New Issue
Block a user