mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-18 16:30:29 +00:00
Consider that displacements may always be signed.
Down to 1 failure.
This commit is contained in:
parent
dbfaef632a
commit
bd0b62232f
@ -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.
|
// TODO: whether the displacement is signed appears to depend on the opcode.
|
||||||
// Find an appropriate table.
|
// Find an appropriate table.
|
||||||
|
|
||||||
if(!sign_extend_displacement_) {
|
// if(!sign_extend_displacement_) {
|
||||||
switch(displacement_size_) {
|
// switch(displacement_size_) {
|
||||||
case DataSize::None: displacement_ = 0; break;
|
// case DataSize::None: displacement_ = 0; break;
|
||||||
case DataSize::Byte: displacement_ = decltype(displacement_)(uint8_t(inward_data_)); 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::Word: displacement_ = decltype(displacement_)(uint16_t(inward_data_)); break;
|
||||||
case DataSize::DWord: displacement_ = decltype(displacement_)(uint32_t(inward_data_)); break;
|
// case DataSize::DWord: displacement_ = decltype(displacement_)(uint32_t(inward_data_)); break;
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
switch(displacement_size_) {
|
switch(displacement_size_) {
|
||||||
case DataSize::None: displacement_ = 0; break;
|
case DataSize::None: displacement_ = 0; break;
|
||||||
case DataSize::Byte: displacement_ = int8_t(inward_data_); break;
|
case DataSize::Byte: displacement_ = int8_t(inward_data_); break;
|
||||||
case DataSize::Word: displacement_ = int16_t(inward_data_); break;
|
case DataSize::Word: displacement_ = int16_t(inward_data_); break;
|
||||||
case DataSize::DWord: displacement_ = int32_t(inward_data_); break;
|
case DataSize::DWord: displacement_ = int32_t(inward_data_); break;
|
||||||
}
|
}
|
||||||
}
|
// }
|
||||||
inward_data_ >>= bit_size(displacement_size_);
|
inward_data_ >>= bit_size(displacement_size_);
|
||||||
|
|
||||||
// Use inequality of sizes as a test for necessary sign extension.
|
// Use inequality of sizes as a test for necessary sign extension.
|
||||||
|
@ -203,7 +203,16 @@ void add(IntT &destination, IntT source, Status &status) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <Model model, DataSize data_size, typename InstructionT, typename RegistersT, typename MemoryT>
|
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 ®isters, MemoryT &memory, typename DataSizeType<data_size>::type *none = nullptr) {
|
typename DataSizeType<data_size>::type *
|
||||||
|
resolve(
|
||||||
|
InstructionT &instruction,
|
||||||
|
Source source,
|
||||||
|
DataPointer pointer,
|
||||||
|
RegistersT ®isters,
|
||||||
|
MemoryT &memory,
|
||||||
|
typename DataSizeType<data_size>::type *none = nullptr,
|
||||||
|
typename DataSizeType<data_size>::type *immediate = nullptr
|
||||||
|
) {
|
||||||
// Rules:
|
// Rules:
|
||||||
//
|
//
|
||||||
// * if this is a memory access, set target_address and break;
|
// * 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 ®isters.fs(); else return nullptr;
|
case Source::FS: if constexpr (is_32bit(model) && data_size == DataSize::Word) return ®isters.fs(); else return nullptr;
|
||||||
case Source::GS: if constexpr (is_32bit(model) && data_size == DataSize::Word) return ®isters.gs(); else return nullptr;
|
case Source::GS: if constexpr (is_32bit(model) && data_size == DataSize::Word) return ®isters.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;
|
case Source::None: return none;
|
||||||
|
|
||||||
@ -319,8 +330,27 @@ template <
|
|||||||
using AddressT = typename AddressT<is_32bit(model)>::type;
|
using AddressT = typename AddressT<is_32bit(model)>::type;
|
||||||
|
|
||||||
// Establish source() and destination() shorthand to fetch data if necessary.
|
// 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); };
|
IntT immediate;
|
||||||
auto destination = [&]() -> IntT& { return *resolve<model, data_size>(instruction, instruction.destination().template source<false>(), instruction.destination(), registers, memory); };
|
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:
|
// Guide to the below:
|
||||||
//
|
//
|
||||||
|
@ -25,7 +25,7 @@ namespace {
|
|||||||
|
|
||||||
// The tests themselves are not duplicated in this repository;
|
// The tests themselves are not duplicated in this repository;
|
||||||
// provide their real path here.
|
// 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;
|
using Status = InstructionSet::x86::Status;
|
||||||
struct Registers {
|
struct Registers {
|
||||||
@ -142,7 +142,7 @@ struct Memory {
|
|||||||
// to a selector, they're just at an absolute location.
|
// to a selector, they're just at an absolute location.
|
||||||
template <typename IntT> IntT &access(uint32_t address, Tag tag) {
|
template <typename IntT> IntT &access(uint32_t address, Tag tag) {
|
||||||
if(tags.find(address) == tags.end()) {
|
if(tags.find(address) == tags.end()) {
|
||||||
// printf("Access to unexpected RAM address");
|
printf("Access to unexpected RAM address");
|
||||||
}
|
}
|
||||||
tags[address] = tag;
|
tags[address] = tag;
|
||||||
return *reinterpret_cast<IntT *>(&memory[address]);
|
return *reinterpret_cast<IntT *>(&memory[address]);
|
||||||
@ -234,7 +234,7 @@ struct FailedExecution {
|
|||||||
NSString *path = [NSString stringWithUTF8String:TestSuiteHome];
|
NSString *path = [NSString stringWithUTF8String:TestSuiteHome];
|
||||||
NSSet *allowList = [NSSet setWithArray:@[
|
NSSet *allowList = [NSSet setWithArray:@[
|
||||||
// ADC
|
// 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
|
// TO add: 80/2, 81/2, 83/2
|
||||||
|
|
||||||
// ADD
|
// ADD
|
||||||
|
Loading…
x
Reference in New Issue
Block a user