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:
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.
|
||||
// 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.
|
||||
|
@ -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 ®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:
|
||||
//
|
||||
// * 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::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;
|
||||
|
||||
@ -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:
|
||||
//
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user