1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-08-15 14:27:29 +00:00

Merge pull request #1284 from TomHarte/SomeWarnings

Resolve outstanding x86-related warnings.
This commit is contained in:
Thomas Harte
2023-12-24 15:48:17 -05:00
committed by GitHub
9 changed files with 52 additions and 38 deletions

View File

@@ -26,8 +26,8 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
// be back to wherever it started, so it's safe to spit out a NOP and reset parsing // be back to wherever it started, so it's safe to spit out a NOP and reset parsing
// without any loss of context. This reduces the risk of the decoder tricking a caller into // without any loss of context. This reduces the risk of the decoder tricking a caller into
// an infinite loop. // an infinite loop.
static constexpr std::size_t max_instruction_length = model >= Model::i80386 ? 15 : (model == Model::i80286 ? 10 : 65536); static constexpr int max_instruction_length = model >= Model::i80386 ? 15 : (model == Model::i80286 ? 10 : 65536);
const uint8_t *const end = source + std::min(length, max_instruction_length - consumed_); const uint8_t *const end = source + std::min(length, size_t(max_instruction_length - consumed_));
// MARK: - Prefixes (if present) and the opcode. // MARK: - Prefixes (if present) and the opcode.

View File

@@ -172,7 +172,7 @@ template <Model model> class Decoder {
// Ephemeral decoding state. // Ephemeral decoding state.
Operation operation_ = Operation::Invalid; Operation operation_ = Operation::Invalid;
uint32_t consumed_ = 0, operand_bytes_ = 0; int consumed_ = 0, operand_bytes_ = 0;
// Source and destination locations. // Source and destination locations.
Source source_ = Source::None; Source source_ = Source::None;

View File

@@ -36,7 +36,7 @@ void jump(
// TODO: proper behaviour in 32-bit. // TODO: proper behaviour in 32-bit.
if(condition) { if(condition) {
context.flow_controller.jump(uint16_t(context.registers.ip() + displacement)); context.flow_controller.template jump<uint16_t>(uint16_t(context.registers.ip() + displacement));
} }
} }
@@ -48,7 +48,7 @@ void loop(
) { ) {
--counter; --counter;
if(counter) { if(counter) {
context.flow_controller.jump(context.registers.ip() + displacement); context.flow_controller.template jump<uint16_t>(context.registers.ip() + displacement);
} }
} }
@@ -60,7 +60,7 @@ void loope(
) { ) {
--counter; --counter;
if(counter && context.flags.template flag<Flag::Zero>()) { if(counter && context.flags.template flag<Flag::Zero>()) {
context.flow_controller.jump(context.registers.ip() + displacement); context.flow_controller.template jump<uint16_t>(context.registers.ip() + displacement);
} }
} }
@@ -72,26 +72,30 @@ void loopne(
) { ) {
--counter; --counter;
if(counter && !context.flags.template flag<Flag::Zero>()) { if(counter && !context.flags.template flag<Flag::Zero>()) {
context.flow_controller.jump(context.registers.ip() + displacement); context.flow_controller.template jump<uint16_t>(context.registers.ip() + displacement);
} }
} }
template <typename IntT, typename ContextT> template <typename AddressT, typename ContextT>
void call_relative( void call_relative(
typename std::make_signed<IntT>::type offset, typename std::make_signed<AddressT>::type offset,
ContextT &context ContextT &context
) { ) {
if constexpr (std::is_same_v<AddressT, uint16_t>) {
push<uint16_t, false>(context.registers.ip(), context); push<uint16_t, false>(context.registers.ip(), context);
context.flow_controller.jump(context.registers.ip() + offset); context.flow_controller.template jump<AddressT>(AddressT(context.registers.ip() + offset));
} else {
assert(false);
}
} }
template <typename IntT, typename ContextT> template <typename IntT, typename AddressT, typename ContextT>
void call_absolute( void call_absolute(
read_t<IntT> target, read_t<IntT> target,
ContextT &context ContextT &context
) { ) {
push<uint16_t, false>(context.registers.ip(), context); push<uint16_t, false>(context.registers.ip(), context);
context.flow_controller.jump(target); context.flow_controller.template jump<AddressT>(AddressT(target));
} }
template <typename IntT, typename ContextT> template <typename IntT, typename ContextT>
@@ -99,10 +103,10 @@ void jump_absolute(
read_t<IntT> target, read_t<IntT> target,
ContextT &context ContextT &context
) { ) {
context.flow_controller.jump(target); context.flow_controller.template jump<uint16_t>(target);
} }
template <typename InstructionT, typename ContextT> template <typename AddressT, typename InstructionT, typename ContextT>
void call_far( void call_far(
InstructionT &instruction, InstructionT &instruction,
ContextT &context ContextT &context
@@ -118,17 +122,17 @@ void call_far(
case Source::Immediate: case Source::Immediate:
push<uint16_t, true>(context.registers.cs(), context); push<uint16_t, true>(context.registers.cs(), context);
push<uint16_t, true>(context.registers.ip(), context); push<uint16_t, true>(context.registers.ip(), context);
context.flow_controller.jump(instruction.segment(), instruction.offset()); context.flow_controller.template jump<uint16_t>(instruction.segment(), instruction.offset());
return; return;
case Source::Indirect: case Source::Indirect:
source_address = address<Source::Indirect, uint16_t, AccessType::Read>(instruction, pointer, context); source_address = uint16_t(address<Source::Indirect, uint16_t, AccessType::Read>(instruction, pointer, context));
break; break;
case Source::IndirectNoBase: case Source::IndirectNoBase:
source_address = address<Source::IndirectNoBase, uint16_t, AccessType::Read>(instruction, pointer, context); source_address = uint16_t(address<Source::IndirectNoBase, uint16_t, AccessType::Read>(instruction, pointer, context));
break; break;
case Source::DirectAddress: case Source::DirectAddress:
source_address = address<Source::DirectAddress, uint16_t, AccessType::Read>(instruction, pointer, context); source_address = uint16_t(address<Source::DirectAddress, uint16_t, AccessType::Read>(instruction, pointer, context));
break; break;
} }
@@ -141,7 +145,7 @@ void call_far(
push<uint16_t, true>(context.registers.cs(), context); push<uint16_t, true>(context.registers.cs(), context);
push<uint16_t, true>(context.registers.ip(), context); push<uint16_t, true>(context.registers.ip(), context);
context.flow_controller.jump(segment, offset); context.flow_controller.template jump<AddressT>(segment, offset);
} }
template <typename InstructionT, typename ContextT> template <typename InstructionT, typename ContextT>
@@ -154,16 +158,16 @@ void jump_far(
const auto pointer = instruction.destination(); const auto pointer = instruction.destination();
switch(pointer.source()) { switch(pointer.source()) {
default: default:
case Source::Immediate: context.flow_controller.jump(instruction.segment(), instruction.offset()); return; case Source::Immediate: context.flow_controller.template jump<uint16_t>(instruction.segment(), instruction.offset()); return;
case Source::Indirect: case Source::Indirect:
source_address = address<Source::Indirect, uint16_t, AccessType::Read>(instruction, pointer, context); source_address = uint16_t(address<Source::Indirect, uint16_t, AccessType::Read>(instruction, pointer, context));
break; break;
case Source::IndirectNoBase: case Source::IndirectNoBase:
source_address = address<Source::IndirectNoBase, uint16_t, AccessType::Read>(instruction, pointer, context); source_address = uint16_t(address<Source::IndirectNoBase, uint16_t, AccessType::Read>(instruction, pointer, context));
break; break;
case Source::DirectAddress: case Source::DirectAddress:
source_address = address<Source::DirectAddress, uint16_t, AccessType::Read>(instruction, pointer, context); source_address = uint16_t(address<Source::DirectAddress, uint16_t, AccessType::Read>(instruction, pointer, context));
break; break;
} }
@@ -173,7 +177,7 @@ void jump_far(
const uint16_t offset = context.memory.template access<uint16_t, AccessType::PreauthorisedRead>(source_segment, source_address); const uint16_t offset = context.memory.template access<uint16_t, AccessType::PreauthorisedRead>(source_segment, source_address);
source_address += 2; source_address += 2;
const uint16_t segment = context.memory.template access<uint16_t, AccessType::PreauthorisedRead>(source_segment, source_address); const uint16_t segment = context.memory.template access<uint16_t, AccessType::PreauthorisedRead>(source_segment, source_address);
context.flow_controller.jump(segment, offset); context.flow_controller.template jump<uint16_t>(segment, offset);
} }
template <typename ContextT> template <typename ContextT>
@@ -185,7 +189,7 @@ void iret(
const auto ip = pop<uint16_t, true>(context); const auto ip = pop<uint16_t, true>(context);
const auto cs = pop<uint16_t, true>(context); const auto cs = pop<uint16_t, true>(context);
context.flags.set(pop<uint16_t, true>(context)); context.flags.set(pop<uint16_t, true>(context));
context.flow_controller.jump(cs, ip); context.flow_controller.template jump<uint16_t>(cs, ip);
} }
template <typename InstructionT, typename ContextT> template <typename InstructionT, typename ContextT>
@@ -195,7 +199,7 @@ void ret_near(
) { ) {
const auto ip = pop<uint16_t, false>(context); const auto ip = pop<uint16_t, false>(context);
context.registers.sp() += instruction.operand(); context.registers.sp() += instruction.operand();
context.flow_controller.jump(ip); context.flow_controller.template jump<uint16_t>(ip);
} }
template <typename InstructionT, typename ContextT> template <typename InstructionT, typename ContextT>
@@ -207,7 +211,7 @@ void ret_far(
const auto ip = pop<uint16_t, true>(context); const auto ip = pop<uint16_t, true>(context);
const auto cs = pop<uint16_t, true>(context); const auto cs = pop<uint16_t, true>(context);
context.registers.sp() += instruction.operand(); context.registers.sp() += instruction.operand();
context.flow_controller.jump(cs, ip); context.flow_controller.template jump<uint16_t>(cs, ip);
} }
template <typename ContextT> template <typename ContextT>

View File

@@ -35,7 +35,7 @@ void ld(
ContextT &context ContextT &context
) { ) {
const auto pointer = instruction.source(); const auto pointer = instruction.source();
auto source_address = address<uint16_t, AccessType::Read>(instruction, pointer, context); uint16_t source_address = uint16_t(address<uint16_t, AccessType::Read>(instruction, pointer, context));
const Source source_segment = instruction.data_segment(); const Source source_segment = instruction.data_segment();
context.memory.preauthorise_read(source_segment, source_address, 4); context.memory.preauthorise_read(source_segment, source_address, 4);

View File

@@ -136,7 +136,7 @@ void setmo(
write_t<IntT> destination, write_t<IntT> destination,
ContextT &context ContextT &context
) { ) {
const auto result = destination = ~0; const auto result = destination = IntT(~0);
context.flags.template set_from<Flag::Carry, Flag::AuxiliaryCarry, Flag::Overflow>(0); context.flags.template set_from<Flag::Carry, Flag::AuxiliaryCarry, Flag::Overflow>(0);
context.flags.template set_from<IntT, Flag::Sign, Flag::Zero, Flag::ParityOdd>(result); context.flags.template set_from<IntT, Flag::Sign, Flag::Zero, Flag::ParityOdd>(result);
} }

View File

@@ -237,8 +237,8 @@ template <
case Operation::CALLrel: case Operation::CALLrel:
Primitive::call_relative<AddressT>(instruction.displacement(), context); Primitive::call_relative<AddressT>(instruction.displacement(), context);
return; return;
case Operation::CALLabs: Primitive::call_absolute<IntT>(destination_r(), context); return; case Operation::CALLabs: Primitive::call_absolute<IntT, AddressT>(destination_r(), context); return;
case Operation::CALLfar: Primitive::call_far(instruction, context); return; case Operation::CALLfar: Primitive::call_far<AddressT>(instruction, context); return;
case Operation::JMPrel: jcc(true); return; case Operation::JMPrel: jcc(true); return;
case Operation::JMPabs: Primitive::jump_absolute<IntT>(destination_r(), context); return; case Operation::JMPabs: Primitive::jump_absolute<IntT>(destination_r(), context); return;

View File

@@ -199,7 +199,9 @@ typename Accessor<IntT, access>::type resolve(
// If execution has reached here then a memory fetch is required. // If execution has reached here then a memory fetch is required.
// Do it and exit. // Do it and exit.
return context.memory.template access<IntT, access>(instruction.data_segment(), target_address); //
// TODO: support 32-bit addresses.
return context.memory.template access<IntT, access>(instruction.data_segment(), uint16_t(target_address));
} }
} }

View File

@@ -807,11 +807,15 @@ class FlowController {
registers_(registers), segments_(segments) {} registers_(registers), segments_(segments) {}
// Requirements for perform. // Requirements for perform.
void jump(uint16_t address) { template <typename AddressT>
void jump(AddressT address) {
static_assert(std::is_same_v<AddressT, uint16_t>);
registers_.ip() = address; registers_.ip() = address;
} }
void jump(uint16_t segment, uint16_t address) { template <typename AddressT>
void jump(uint16_t segment, AddressT address) {
static_assert(std::is_same_v<AddressT, uint16_t>);
registers_.cs() = segment; registers_.cs() = segment;
segments_.did_update(Segments::Source::CS); segments_.did_update(Segments::Source::CS);
registers_.ip() = address; registers_.ip() = address;
@@ -916,7 +920,7 @@ class ConcreteMachine:
// MARK: - TimedMachine. // MARK: - TimedMachine.
void run_for(const Cycles duration) override { void run_for(const Cycles duration) override {
const auto pit_ticks = duration.as_integral(); const auto pit_ticks = duration.as<int>();
int ticks; int ticks;
if constexpr (!turbo) { if constexpr (!turbo) {

View File

@@ -371,11 +371,15 @@ class FlowController {
registers_(registers), segments_(segments) {} registers_(registers), segments_(segments) {}
// Requirements for perform. // Requirements for perform.
void jump(uint16_t address) { template <typename AddressT>
void jump(AddressT address) {
static_assert(std::is_same_v<AddressT, uint16_t>);
registers_.ip() = address; registers_.ip() = address;
} }
void jump(uint16_t segment, uint16_t address) { template <typename AddressT>
void jump(uint16_t segment, AddressT address) {
static_assert(std::is_same_v<AddressT, uint16_t>);
registers_.cs() = segment; registers_.cs() = segment;
segments_.did_update(Segments::Source::CS); segments_.did_update(Segments::Source::CS);
registers_.ip() = address; registers_.ip() = address;