mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Take a swing at LEA r16, r16.
This commit is contained in:
parent
599c123b36
commit
817a30332c
@ -55,36 +55,8 @@ uint32_t address(
|
|||||||
return address + *resolve<model, uint16_t>(instruction, pointer.base(), pointer, registers, memory);
|
return address + *resolve<model, uint16_t>(instruction, pointer.base(), pointer, registers, memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <Model model, typename IntT, typename InstructionT, typename RegistersT, typename MemoryT>
|
template <Model model, typename IntT, Source source, typename RegistersT>
|
||||||
uint32_t address(
|
IntT *register_(RegistersT ®isters) {
|
||||||
InstructionT &instruction,
|
|
||||||
DataPointer pointer,
|
|
||||||
RegistersT ®isters,
|
|
||||||
MemoryT &memory
|
|
||||||
) {
|
|
||||||
switch(pointer.source<false>()) {
|
|
||||||
default: return 0;
|
|
||||||
case Source::Indirect: return address<model, Source::Indirect, IntT>(instruction, pointer, registers, memory);
|
|
||||||
case Source::IndirectNoBase: return address<model, Source::IndirectNoBase, IntT>(instruction, pointer, registers, memory);
|
|
||||||
case Source::DirectAddress: return address<model, Source::DirectAddress, IntT>(instruction, pointer, registers, memory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <Model model, typename IntT, typename InstructionT, typename RegistersT, typename MemoryT>
|
|
||||||
IntT *resolve(
|
|
||||||
InstructionT &instruction,
|
|
||||||
Source source,
|
|
||||||
DataPointer pointer,
|
|
||||||
RegistersT ®isters,
|
|
||||||
MemoryT &memory,
|
|
||||||
IntT *none,
|
|
||||||
IntT *immediate
|
|
||||||
) {
|
|
||||||
// Rules:
|
|
||||||
//
|
|
||||||
// * if this is a memory access, set target_address and break;
|
|
||||||
// * otherwise return the appropriate value.
|
|
||||||
uint32_t target_address;
|
|
||||||
switch(source) {
|
switch(source) {
|
||||||
case Source::eAX:
|
case Source::eAX:
|
||||||
// Slightly contorted if chain here and below:
|
// Slightly contorted if chain here and below:
|
||||||
@ -131,10 +103,63 @@ IntT *resolve(
|
|||||||
else if constexpr (std::is_same_v<IntT, uint8_t>) { return ®isters.bh(); }
|
else if constexpr (std::is_same_v<IntT, uint8_t>) { return ®isters.bh(); }
|
||||||
else { return nullptr; }
|
else { return nullptr; }
|
||||||
|
|
||||||
case Source::ES: if constexpr (std::is_same_v<IntT, uint16_t>) return ®isters.es(); else return nullptr;
|
default: return nullptr;
|
||||||
case Source::CS: if constexpr (std::is_same_v<IntT, uint16_t>) return ®isters.cs(); else return nullptr;
|
}
|
||||||
case Source::SS: if constexpr (std::is_same_v<IntT, uint16_t>) return ®isters.ss(); else return nullptr;
|
}
|
||||||
case Source::DS: if constexpr (std::is_same_v<IntT, uint16_t>) return ®isters.ds(); else return nullptr;
|
|
||||||
|
template <Model model, typename IntT, typename InstructionT, typename RegistersT, typename MemoryT>
|
||||||
|
uint32_t address(
|
||||||
|
InstructionT &instruction,
|
||||||
|
DataPointer pointer,
|
||||||
|
RegistersT ®isters,
|
||||||
|
MemoryT &memory
|
||||||
|
) {
|
||||||
|
switch(pointer.source<false>()) {
|
||||||
|
default: return 0;
|
||||||
|
case Source::eAX: return *register_<model, IntT, Source::eAX>(registers);
|
||||||
|
case Source::eCX: return *register_<model, IntT, Source::eCX>(registers);
|
||||||
|
case Source::eDX: return *register_<model, IntT, Source::eDX>(registers);
|
||||||
|
case Source::eBX: return *register_<model, IntT, Source::eBX>(registers);
|
||||||
|
case Source::eSPorAH: return *register_<model, IntT, Source::eSPorAH>(registers);
|
||||||
|
case Source::eBPorCH: return *register_<model, IntT, Source::eBPorCH>(registers);
|
||||||
|
case Source::eSIorDH: return *register_<model, IntT, Source::eSIorDH>(registers);
|
||||||
|
case Source::eDIorBH: return *register_<model, IntT, Source::eDIorBH>(registers);
|
||||||
|
case Source::Indirect: return address<model, Source::Indirect, IntT>(instruction, pointer, registers, memory);
|
||||||
|
case Source::IndirectNoBase: return address<model, Source::IndirectNoBase, IntT>(instruction, pointer, registers, memory);
|
||||||
|
case Source::DirectAddress: return address<model, Source::DirectAddress, IntT>(instruction, pointer, registers, memory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <Model model, typename IntT, typename InstructionT, typename RegistersT, typename MemoryT>
|
||||||
|
IntT *resolve(
|
||||||
|
InstructionT &instruction,
|
||||||
|
Source source,
|
||||||
|
DataPointer pointer,
|
||||||
|
RegistersT ®isters,
|
||||||
|
MemoryT &memory,
|
||||||
|
IntT *none,
|
||||||
|
IntT *immediate
|
||||||
|
) {
|
||||||
|
// Rules:
|
||||||
|
//
|
||||||
|
// * if this is a memory access, set target_address and break;
|
||||||
|
// * otherwise return the appropriate value.
|
||||||
|
uint32_t target_address;
|
||||||
|
switch(source) {
|
||||||
|
case Source::eAX: return register_<model, IntT, Source::eAX>(registers);
|
||||||
|
case Source::eCX: return register_<model, IntT, Source::eCX>(registers);
|
||||||
|
case Source::eDX: return register_<model, IntT, Source::eDX>(registers);
|
||||||
|
case Source::eBX: return register_<model, IntT, Source::eBX>(registers);
|
||||||
|
case Source::eSPorAH: return register_<model, IntT, Source::eSPorAH>(registers);
|
||||||
|
case Source::eBPorCH: return register_<model, IntT, Source::eBPorCH>(registers);
|
||||||
|
case Source::eSIorDH: return register_<model, IntT, Source::eSIorDH>(registers);
|
||||||
|
case Source::eDIorBH: return register_<model, IntT, Source::eDIorBH>(registers);
|
||||||
|
|
||||||
|
// Segment registers are always 16-bit.
|
||||||
|
case Source::ES: if constexpr (std::is_same_v<IntT, uint16_t>) return ®isters.es(); else return nullptr;
|
||||||
|
case Source::CS: if constexpr (std::is_same_v<IntT, uint16_t>) return ®isters.cs(); else return nullptr;
|
||||||
|
case Source::SS: if constexpr (std::is_same_v<IntT, uint16_t>) return ®isters.ss(); else return nullptr;
|
||||||
|
case Source::DS: if constexpr (std::is_same_v<IntT, uint16_t>) return ®isters.ds(); else return nullptr;
|
||||||
|
|
||||||
// 16-bit models don't have FS and GS.
|
// 16-bit models don't have FS and GS.
|
||||||
case Source::FS: if constexpr (is_32bit(model) && std::is_same_v<IntT, uint16_t>) return ®isters.fs(); else return nullptr;
|
case Source::FS: if constexpr (is_32bit(model) && std::is_same_v<IntT, uint16_t>) return ®isters.fs(); else return nullptr;
|
||||||
|
@ -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/tharte/Projects/ProcessorTests/8088/v1";
|
constexpr char TestSuiteHome[] = "/Users/thomasharte/Projects/ProcessorTests/8088/v1";
|
||||||
|
|
||||||
using Status = InstructionSet::x86::Status;
|
using Status = InstructionSet::x86::Status;
|
||||||
struct Registers {
|
struct Registers {
|
||||||
@ -497,6 +497,10 @@ struct FailedExecution {
|
|||||||
execution_support.status = initial_status;
|
execution_support.status = initial_status;
|
||||||
execution_support.registers = initial_registers;
|
execution_support.registers = initial_registers;
|
||||||
|
|
||||||
|
if(decoded.second.operation != InstructionSet::x86::Operation::LEA) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Execute instruction.
|
// Execute instruction.
|
||||||
//
|
//
|
||||||
// TODO: enquire of the actual mechanism of repetition; if it were stateful as below then
|
// TODO: enquire of the actual mechanism of repetition; if it were stateful as below then
|
||||||
|
Loading…
Reference in New Issue
Block a user