diff --git a/InstructionSets/x86/Implementation/FlowControl.hpp b/InstructionSets/x86/Implementation/FlowControl.hpp index 63965cde6..793f1c911 100644 --- a/InstructionSets/x86/Implementation/FlowControl.hpp +++ b/InstructionSets/x86/Implementation/FlowControl.hpp @@ -36,7 +36,7 @@ void jump( // TODO: proper behaviour in 32-bit. if(condition) { - context.flow_controller.jump(uint16_t(context.registers.ip() + displacement)); + context.flow_controller.template jump(uint16_t(context.registers.ip() + displacement)); } } @@ -48,7 +48,7 @@ void loop( ) { --counter; if(counter) { - context.flow_controller.jump(context.registers.ip() + displacement); + context.flow_controller.template jump(context.registers.ip() + displacement); } } @@ -60,7 +60,7 @@ void loope( ) { --counter; if(counter && context.flags.template flag()) { - context.flow_controller.jump(context.registers.ip() + displacement); + context.flow_controller.template jump(context.registers.ip() + displacement); } } @@ -72,26 +72,30 @@ void loopne( ) { --counter; if(counter && !context.flags.template flag()) { - context.flow_controller.jump(context.registers.ip() + displacement); + context.flow_controller.template jump(context.registers.ip() + displacement); } } -template +template void call_relative( - typename std::make_signed::type offset, + typename std::make_signed::type offset, ContextT &context ) { - push(context.registers.ip(), context); - context.flow_controller.jump(context.registers.ip() + offset); + if constexpr (std::is_same_v) { + push(context.registers.ip(), context); + context.flow_controller.template jump(AddressT(context.registers.ip() + offset)); + } else { + assert(false); + } } -template +template void call_absolute( read_t target, ContextT &context ) { push(context.registers.ip(), context); - context.flow_controller.jump(target); + context.flow_controller.template jump(AddressT(target)); } template @@ -99,10 +103,10 @@ void jump_absolute( read_t target, ContextT &context ) { - context.flow_controller.jump(target); + context.flow_controller.template jump(target); } -template +template void call_far( InstructionT &instruction, ContextT &context @@ -118,7 +122,7 @@ void call_far( case Source::Immediate: push(context.registers.cs(), context); push(context.registers.ip(), context); - context.flow_controller.jump(instruction.segment(), instruction.offset()); + context.flow_controller.template jump(instruction.segment(), instruction.offset()); return; case Source::Indirect: @@ -141,7 +145,7 @@ void call_far( push(context.registers.cs(), context); push(context.registers.ip(), context); - context.flow_controller.jump(segment, offset); + context.flow_controller.template jump(segment, offset); } template @@ -154,7 +158,7 @@ void jump_far( const auto pointer = instruction.destination(); switch(pointer.source()) { default: - case Source::Immediate: context.flow_controller.jump(instruction.segment(), instruction.offset()); return; + case Source::Immediate: context.flow_controller.template jump(instruction.segment(), instruction.offset()); return; case Source::Indirect: source_address = address(instruction, pointer, context); @@ -173,7 +177,7 @@ void jump_far( const uint16_t offset = context.memory.template access(source_segment, source_address); source_address += 2; const uint16_t segment = context.memory.template access(source_segment, source_address); - context.flow_controller.jump(segment, offset); + context.flow_controller.template jump(segment, offset); } template @@ -185,7 +189,7 @@ void iret( const auto ip = pop(context); const auto cs = pop(context); context.flags.set(pop(context)); - context.flow_controller.jump(cs, ip); + context.flow_controller.template jump(cs, ip); } template @@ -195,7 +199,7 @@ void ret_near( ) { const auto ip = pop(context); context.registers.sp() += instruction.operand(); - context.flow_controller.jump(ip); + context.flow_controller.template jump(ip); } template @@ -207,7 +211,7 @@ void ret_far( const auto ip = pop(context); const auto cs = pop(context); context.registers.sp() += instruction.operand(); - context.flow_controller.jump(cs, ip); + context.flow_controller.template jump(cs, ip); } template diff --git a/InstructionSets/x86/Implementation/PerformImplementation.hpp b/InstructionSets/x86/Implementation/PerformImplementation.hpp index d0d034801..6c65c7cae 100644 --- a/InstructionSets/x86/Implementation/PerformImplementation.hpp +++ b/InstructionSets/x86/Implementation/PerformImplementation.hpp @@ -237,8 +237,8 @@ template < case Operation::CALLrel: Primitive::call_relative(instruction.displacement(), context); return; - case Operation::CALLabs: Primitive::call_absolute(destination_r(), context); return; - case Operation::CALLfar: Primitive::call_far(instruction, context); return; + case Operation::CALLabs: Primitive::call_absolute(destination_r(), context); return; + case Operation::CALLfar: Primitive::call_far(instruction, context); return; case Operation::JMPrel: jcc(true); return; case Operation::JMPabs: Primitive::jump_absolute(destination_r(), context); return; diff --git a/Machines/PCCompatible/PCCompatible.cpp b/Machines/PCCompatible/PCCompatible.cpp index dd0cb875e..21acfd8fc 100644 --- a/Machines/PCCompatible/PCCompatible.cpp +++ b/Machines/PCCompatible/PCCompatible.cpp @@ -807,11 +807,15 @@ class FlowController { registers_(registers), segments_(segments) {} // Requirements for perform. - void jump(uint16_t address) { + template + void jump(AddressT address) { + static_assert(std::is_same_v); registers_.ip() = address; } - void jump(uint16_t segment, uint16_t address) { + template + void jump(uint16_t segment, AddressT address) { + static_assert(std::is_same_v); registers_.cs() = segment; segments_.did_update(Segments::Source::CS); registers_.ip() = address; diff --git a/OSBindings/Mac/Clock SignalTests/8088Tests.mm b/OSBindings/Mac/Clock SignalTests/8088Tests.mm index adffeecd0..ed1c4e35d 100644 --- a/OSBindings/Mac/Clock SignalTests/8088Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/8088Tests.mm @@ -371,11 +371,15 @@ class FlowController { registers_(registers), segments_(segments) {} // Requirements for perform. - void jump(uint16_t address) { + template + void jump(AddressT address) { + static_assert(std::is_same_v); registers_.ip() = address; } - void jump(uint16_t segment, uint16_t address) { + template + void jump(uint16_t segment, AddressT address) { + static_assert(std::is_same_v); registers_.cs() = segment; segments_.did_update(Segments::Source::CS); registers_.ip() = address;