mirror of
https://github.com/TomHarte/CLK.git
synced 2025-04-09 15:39:08 +00:00
Float out data resolution.
This commit is contained in:
parent
a5523c9feb
commit
a4b1d2b00a
@ -200,6 +200,88 @@ 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, DataPointer source, RegistersT ®isters, MemoryT &memory) {
|
||||
// Rules:
|
||||
//
|
||||
// * if this is a memory access, set target_address and break;
|
||||
// * otherwise return the appropriate value.
|
||||
uint32_t address;
|
||||
switch(source.source<false>()) {
|
||||
case Source::eAX:
|
||||
// Slightly contorted if chain here and below:
|
||||
//
|
||||
// (i) does the `constexpr` version of a `switch`; and
|
||||
// (i) ensures .eax() etc aren't called on @c registers for 16-bit processors, so they need not implement 32-bit storage.
|
||||
if constexpr (is_32bit(model) && data_size == DataSize::DWord) { return ®isters.eax(); }
|
||||
else if constexpr (data_size == DataSize::Word) { return ®isters.ax(); }
|
||||
else if constexpr (data_size == DataSize::Byte) { return ®isters.al(); }
|
||||
else { return nullptr; }
|
||||
case Source::eCX:
|
||||
if constexpr (is_32bit(model) && data_size == DataSize::DWord) { return ®isters.ecx(); }
|
||||
else if constexpr (data_size == DataSize::Word) { return ®isters.cx(); }
|
||||
else if constexpr (data_size == DataSize::Byte) { return ®isters.cl(); }
|
||||
else { return nullptr; }
|
||||
case Source::eDX:
|
||||
if constexpr (is_32bit(model) && data_size == DataSize::DWord) { return ®isters.edx(); }
|
||||
else if constexpr (data_size == DataSize::Word) { return ®isters.dx(); }
|
||||
else if constexpr (data_size == DataSize::Byte) { return ®isters.dl(); }
|
||||
else if constexpr (data_size == DataSize::DWord) { return nullptr; }
|
||||
case Source::eBX:
|
||||
if constexpr (is_32bit(model) && data_size == DataSize::DWord) { return ®isters.ebx(); }
|
||||
else if constexpr (data_size == DataSize::Word) { return ®isters.bx(); }
|
||||
else if constexpr (data_size == DataSize::Byte) { return ®isters.bl(); }
|
||||
else if constexpr (data_size == DataSize::DWord) { return nullptr; }
|
||||
case Source::eSPorAH:
|
||||
if constexpr (is_32bit(model) && data_size == DataSize::DWord) { return ®isters.esp(); }
|
||||
else if constexpr (data_size == DataSize::Word) { return ®isters.sp(); }
|
||||
else if constexpr (data_size == DataSize::Byte) { return ®isters.ah(); }
|
||||
else { return nullptr; }
|
||||
case Source::eBPorCH:
|
||||
if constexpr (is_32bit(model) && data_size == DataSize::DWord) { return ®isters.ebp(); }
|
||||
else if constexpr (data_size == DataSize::Word) { return ®isters.bp(); }
|
||||
else if constexpr (data_size == DataSize::Byte) { return ®isters.ch(); }
|
||||
else { return nullptr; }
|
||||
case Source::eSIorDH:
|
||||
if constexpr (is_32bit(model) && data_size == DataSize::DWord) { return ®isters.esi(); }
|
||||
else if constexpr (data_size == DataSize::Word) { return ®isters.si(); }
|
||||
else if constexpr (data_size == DataSize::Byte) { return ®isters.dh(); }
|
||||
else { return nullptr; }
|
||||
case Source::eDIorBH:
|
||||
if constexpr (is_32bit(model) && data_size == DataSize::DWord) { return ®isters.edi(); }
|
||||
else if constexpr (data_size == DataSize::Word) { return ®isters.di(); }
|
||||
else if constexpr (data_size == DataSize::Byte) { return ®isters.bh(); }
|
||||
else { return nullptr; }
|
||||
|
||||
case Source::ES: if constexpr (data_size == DataSize::Word) return ®isters.es(); else return nullptr;
|
||||
case Source::CS: if constexpr (data_size == DataSize::Word) return ®isters.cs(); else return nullptr;
|
||||
case Source::SS: if constexpr (data_size == DataSize::Word) return ®isters.ss(); else return nullptr;
|
||||
case Source::DS: if constexpr (data_size == DataSize::Word) return ®isters.ds(); else return nullptr;
|
||||
|
||||
// 16-bit models don't have FS and GS.
|
||||
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::None: return nullptr;
|
||||
|
||||
case Source::Indirect: // TODO
|
||||
|
||||
case Source::IndirectNoBase: // TODO
|
||||
|
||||
case Source::DirectAddress:
|
||||
address = instruction.offset();
|
||||
break;
|
||||
}
|
||||
|
||||
// If execution has reached here then a memory fetch is required.
|
||||
// Do it and exit.
|
||||
const Source segment = source.segment(instruction.segment_override());
|
||||
using IntT = typename DataSizeType<data_size>::type;
|
||||
return &memory.template access<IntT>(segment, address);
|
||||
};
|
||||
|
||||
template <
|
||||
Model model,
|
||||
DataSize data_size,
|
||||
@ -219,85 +301,9 @@ template <
|
||||
using IntT = typename DataSizeType<data_size>::type;
|
||||
using AddressT = typename AddressT<is_32bit(model)>::type;
|
||||
|
||||
IntT zero = 0;
|
||||
auto data = [&](DataPointer source) -> IntT& {
|
||||
// Rules:
|
||||
//
|
||||
// * if this is a memory access, set target_address and break;
|
||||
// * otherwise return the appropriate value.
|
||||
AddressT address;
|
||||
switch(source.source<false>()) {
|
||||
case Source::eAX:
|
||||
if constexpr (is_32bit(model) && data_size == DataSize::DWord) { return registers.eax(); }
|
||||
else if constexpr (data_size == DataSize::DWord) { return zero; }
|
||||
else if constexpr (data_size == DataSize::Word) { return registers.ax(); }
|
||||
else { return registers.al(); }
|
||||
case Source::eCX:
|
||||
if constexpr (is_32bit(model) && data_size == DataSize::DWord) { return registers.ecx(); }
|
||||
else if constexpr (data_size == DataSize::DWord) { return zero; }
|
||||
else if constexpr (data_size == DataSize::Word) { return registers.cx(); }
|
||||
else { return registers.cl(); }
|
||||
case Source::eDX:
|
||||
if constexpr (is_32bit(model) && data_size == DataSize::DWord) { return registers.edx(); }
|
||||
else if constexpr (data_size == DataSize::DWord) { return zero; }
|
||||
else if constexpr (data_size == DataSize::Word) { return registers.dx(); }
|
||||
else { return registers.dl(); }
|
||||
case Source::eBX:
|
||||
if constexpr (is_32bit(model) && data_size == DataSize::DWord) { return registers.ebx(); }
|
||||
else if constexpr (data_size == DataSize::DWord) { return zero; }
|
||||
else if constexpr (data_size == DataSize::Word) { return registers.bx(); }
|
||||
else { return registers.bl(); }
|
||||
case Source::eSPorAH:
|
||||
if constexpr (is_32bit(model) && data_size == DataSize::DWord) { return registers.esp(); }
|
||||
else if constexpr (data_size == DataSize::DWord) { return zero; }
|
||||
else if constexpr (data_size == DataSize::Word) { return registers.sp(); }
|
||||
else { return registers.ah(); }
|
||||
case Source::eBPorCH:
|
||||
if constexpr (is_32bit(model) && data_size == DataSize::DWord) { return registers.ebp(); }
|
||||
else if constexpr (data_size == DataSize::DWord) { return zero; }
|
||||
else if constexpr (data_size == DataSize::Word) { return registers.bp(); }
|
||||
else { return registers.ch(); }
|
||||
case Source::eSIorDH:
|
||||
if constexpr (is_32bit(model) && data_size == DataSize::DWord) { return registers.esi(); }
|
||||
else if constexpr (data_size == DataSize::DWord) { return zero; }
|
||||
else if constexpr (data_size == DataSize::Word) { return registers.si(); }
|
||||
else { return registers.dh(); }
|
||||
case Source::eDIorBH:
|
||||
if constexpr (is_32bit(model) && data_size == DataSize::DWord) { return registers.edi(); }
|
||||
else if constexpr (data_size == DataSize::DWord) { return zero; }
|
||||
else if constexpr (data_size == DataSize::Word) { return registers.di(); }
|
||||
else { return registers.bh(); }
|
||||
|
||||
// TODO: the below.
|
||||
default:
|
||||
// case Source::ES: return registers.es();
|
||||
// case Source::CS: return registers.cs();
|
||||
// case Source::SS: return registers.ss();
|
||||
// case Source::DS: return registers.ds();
|
||||
// case Source::FS: return registers.fs();
|
||||
// case Source::GS: return registers.gs();
|
||||
|
||||
case Source::Immediate: // TODO (here the use of a reference falls down?)
|
||||
|
||||
case Source::None: return zero;
|
||||
|
||||
case Source::Indirect: // TODO
|
||||
case Source::IndirectNoBase: // TODO
|
||||
|
||||
case Source::DirectAddress:
|
||||
address = instruction.offset();
|
||||
break;
|
||||
}
|
||||
|
||||
// If execution has reached here then a memory fetch is required.
|
||||
// Do it and exit.
|
||||
const Source segment = source.segment(instruction.segment_override());
|
||||
return memory.template access<IntT>(segment, address);
|
||||
};
|
||||
|
||||
// Establish source() and destination() shorthand to fetch data if necessary.
|
||||
auto source = [&]() -> IntT& { return data(instruction.source()); };
|
||||
auto destination = [&]() -> IntT& { return data(instruction.destination()); };
|
||||
auto source = [&]() -> IntT& { return *resolve<model, data_size>(instruction, instruction.source(), registers, memory); };
|
||||
auto destination = [&]() -> IntT& { return *resolve<model, data_size>(instruction, instruction.destination(), registers, memory); };
|
||||
|
||||
// Guide to the below:
|
||||
//
|
||||
|
@ -66,6 +66,16 @@ struct Registers {
|
||||
uint16_t es_, cs_, ds_, ss_;
|
||||
uint16_t ip_;
|
||||
|
||||
uint16_t &es() { return es_; }
|
||||
uint16_t &cs() { return cs_; }
|
||||
uint16_t &ds() { return ds_; }
|
||||
uint16_t &ss() { return ss_; }
|
||||
|
||||
// uint32_t zero_ = 0;
|
||||
// template <typename IntT> IntT &zero() {
|
||||
// return static_cast<IntT>(zero);
|
||||
// }
|
||||
|
||||
bool operator ==(const Registers &rhs) const {
|
||||
return
|
||||
ax_.full == rhs.ax_.full &&
|
||||
@ -210,17 +220,17 @@ 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
|
||||
@"00.json.gz", @"01.json.gz", @"02.json.gz", @"03.json.gz", @"04.json.gz", @"05.json.gz",
|
||||
@"00.json.gz", //@"01.json.gz", @"02.json.gz", @"03.json.gz", @"04.json.gz", @"05.json.gz",
|
||||
// TO add: 80/0, 81/0, 83/0
|
||||
|
||||
@"37.json.gz", // AAA
|
||||
@"3F.json.gz", // AAS
|
||||
@"D4.json.gz", // AAM
|
||||
@"D5.json.gz", // AAD
|
||||
// @"37.json.gz", // AAA
|
||||
// @"3F.json.gz", // AAS
|
||||
// @"D4.json.gz", // AAM
|
||||
// @"D5.json.gz", // AAD
|
||||
]];
|
||||
|
||||
NSSet *ignoreList = nil;
|
||||
|
Loading…
x
Reference in New Issue
Block a user