1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-11 08:30:55 +00:00

Don't sign-extend ports (!).

This commit is contained in:
Thomas Harte 2023-11-16 11:17:12 -05:00
parent 233ec7b818
commit 25f0a373f3
3 changed files with 21 additions and 8 deletions

View File

@ -58,14 +58,16 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
#define RegAddr(op, dest, op_size, addr_size) \
SetOpSrcDestSize(op, DirectAddress, dest, op_size); \
displacement_size_ = addr_size; \
phase_ = Phase::DisplacementOrOperand
phase_ = Phase::DisplacementOrOperand; \
sign_extend_displacement_ = false
/// Handles instructions of the form jjkk, Ax where the former is implicitly an address.
#define AddrReg(op, source, op_size, addr_size) \
SetOpSrcDestSize(op, source, DirectAddress, op_size); \
displacement_size_ = addr_size; \
destination_ = Source::DirectAddress; \
phase_ = Phase::DisplacementOrOperand
phase_ = Phase::DisplacementOrOperand; \
sign_extend_displacement_ = false
/// Covers both `mem/reg, reg` and `reg, mem/reg`.
#define MemRegReg(op, format, size) \
@ -1017,11 +1019,20 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
if(bytes_to_consume == outstanding_bytes) {
phase_ = Phase::ReadyToPost;
switch(displacement_size_) {
case DataSize::None: displacement_ = 0; break;
case DataSize::Byte: displacement_ = int8_t(inward_data_); break;
case DataSize::Word: displacement_ = int16_t(inward_data_); break;
case DataSize::DWord: displacement_ = int32_t(inward_data_); break;
if(!sign_extend_displacement_) {
switch(displacement_size_) {
case DataSize::None: displacement_ = 0; break;
case DataSize::Byte: displacement_ = uint8_t(inward_data_); break;
case DataSize::Word: displacement_ = uint16_t(inward_data_); break;
case DataSize::DWord: displacement_ = int32_t(inward_data_); break;
}
} else {
switch(displacement_size_) {
case DataSize::None: displacement_ = 0; break;
case DataSize::Byte: displacement_ = int8_t(inward_data_); break;
case DataSize::Word: displacement_ = int16_t(inward_data_); break;
case DataSize::DWord: displacement_ = int32_t(inward_data_); break;
}
}
inward_data_ >>= bit_size(displacement_size_);

View File

@ -193,6 +193,8 @@ template <Model model> class Decoder {
DataSize operand_size_ = DataSize::None; // i.e. size of in-stream operand, if any.
DataSize operation_size_ = DataSize::None; // i.e. size of data manipulated by the operation.
bool sign_extend_displacement_ = true; // If set then sign extend any displacement up to the address
// size; otherwise it'll be zero-padded.
bool sign_extend_operand_ = false; // If set then sign extend the operand up to the operation size;
// otherwise it'll be zero-padded.
@ -223,6 +225,7 @@ template <Model model> class Decoder {
next_inward_data_shift_ = 0;
inward_data_ = 0;
sign_extend_operand_ = false;
sign_extend_displacement_ = true;
}
};

View File

@ -267,7 +267,6 @@ struct Memory {
uint16_t write_back_value_;
};
// TODO: the decoder is clearly sign-extending 8-bit port addresses. That's incorrect. Fix.
struct IO {
template <typename IntT> void out([[maybe_unused]] uint16_t port, [[maybe_unused]] IntT value) {
if constexpr (std::is_same_v<IntT, uint8_t>) {