1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 08:49:37 +00:00

Consider that displacements may always be signed.

Down to 1 failure.
This commit is contained in:
Thomas Harte 2023-10-08 21:41:36 -04:00
parent dbfaef632a
commit bd0b62232f
3 changed files with 46 additions and 16 deletions

View File

@ -1018,21 +1018,21 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
// TODO: whether the displacement is signed appears to depend on the opcode.
// Find an appropriate table.
if(!sign_extend_displacement_) {
switch(displacement_size_) {
case DataSize::None: displacement_ = 0; break;
case DataSize::Byte: displacement_ = decltype(displacement_)(uint8_t(inward_data_)); break;
case DataSize::Word: displacement_ = decltype(displacement_)(uint16_t(inward_data_)); break;
case DataSize::DWord: displacement_ = decltype(displacement_)(uint32_t(inward_data_)); break;
}
} else {
// if(!sign_extend_displacement_) {
// switch(displacement_size_) {
// case DataSize::None: displacement_ = 0; break;
// case DataSize::Byte: displacement_ = decltype(displacement_)(uint8_t(inward_data_)); break;
// case DataSize::Word: displacement_ = decltype(displacement_)(uint16_t(inward_data_)); break;
// case DataSize::DWord: displacement_ = decltype(displacement_)(uint32_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_);
// Use inequality of sizes as a test for necessary sign extension.

View File

@ -203,7 +203,16 @@ void add(IntT &destination, IntT source, Status &status) {
}
template <Model model, DataSize data_size, typename InstructionT, typename RegistersT, typename MemoryT>
typename DataSizeType<data_size>::type *resolve(InstructionT &instruction, Source source, DataPointer pointer, RegistersT &registers, MemoryT &memory, typename DataSizeType<data_size>::type *none = nullptr) {
typename DataSizeType<data_size>::type *
resolve(
InstructionT &instruction,
Source source,
DataPointer pointer,
RegistersT &registers,
MemoryT &memory,
typename DataSizeType<data_size>::type *none = nullptr,
typename DataSizeType<data_size>::type *immediate = nullptr
) {
// Rules:
//
// * if this is a memory access, set target_address and break;
@ -264,7 +273,9 @@ typename DataSizeType<data_size>::type *resolve(InstructionT &instruction, Sourc
case Source::FS: if constexpr (is_32bit(model) && data_size == DataSize::Word) return &registers.fs(); else return nullptr;
case Source::GS: if constexpr (is_32bit(model) && data_size == DataSize::Word) return &registers.gs(); else return nullptr;
case Source::Immediate: // TODO (here the use of a pointer falls down?)
case Source::Immediate:
*immediate = instruction.operand();
return immediate;
case Source::None: return none;
@ -319,8 +330,27 @@ template <
using AddressT = typename AddressT<is_32bit(model)>::type;
// Establish source() and destination() shorthand to fetch data if necessary.
auto source = [&]() -> IntT& { return *resolve<model, data_size>(instruction, instruction.source().template source<false>(), instruction.source(), registers, memory); };
auto destination = [&]() -> IntT& { return *resolve<model, data_size>(instruction, instruction.destination().template source<false>(), instruction.destination(), registers, memory); };
IntT immediate;
auto source = [&]() -> IntT& {
return *resolve<model, data_size>(
instruction,
instruction.source().template source<false>(),
instruction.source(),
registers,
memory,
nullptr,
&immediate);
};
auto destination = [&]() -> IntT& {
return *resolve<model, data_size>(
instruction,
instruction.destination().template source<false>(),
instruction.destination(),
registers,
memory,
nullptr,
&immediate);
};
// Guide to the below:
//

View File

@ -25,7 +25,7 @@ namespace {
// The tests themselves are not duplicated in this repository;
// provide their real path here.
constexpr char TestSuiteHome[] = "/Users/thomasharte/Projects/ProcessorTests/8088/v1";
constexpr char TestSuiteHome[] = "/Users/tharte/Projects/ProcessorTests/8088/v1";
using Status = InstructionSet::x86::Status;
struct Registers {
@ -142,7 +142,7 @@ struct Memory {
// to a selector, they're just at an absolute location.
template <typename IntT> IntT &access(uint32_t address, Tag tag) {
if(tags.find(address) == tags.end()) {
// printf("Access to unexpected RAM address");
printf("Access to unexpected RAM address");
}
tags[address] = tag;
return *reinterpret_cast<IntT *>(&memory[address]);
@ -234,7 +234,7 @@ struct FailedExecution {
NSString *path = [NSString stringWithUTF8String:TestSuiteHome];
NSSet *allowList = [NSSet setWithArray:@[
// ADC
// @"10.json.gz", @"11.json.gz", @"12.json.gz", @"13.json.gz", @"14.json.gz", @"15.json.gz",
@"10.json.gz", @"11.json.gz", @"12.json.gz", @"13.json.gz", @"14.json.gz", @"15.json.gz",
// TO add: 80/2, 81/2, 83/2
// ADD