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

Retain baseless addresses correctly.

This commit is contained in:
Thomas Harte 2023-09-22 17:27:27 -04:00
parent c8c0c3ca6d
commit 787e9e770e
3 changed files with 43 additions and 21 deletions

View File

@ -651,7 +651,6 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
data_size(address_size_)
};
displacement_size_ = sizes[mod];
memreg = Source::Indirect;
if(address_size_ == AddressSize::b32) {
// 32-bit decoding: the range of potential indirections is expanded,
@ -659,21 +658,26 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
sib_ = ScaleIndexBase(0, Source::None, reg_table[rm]);
expects_sib = rm == 4; // Indirect via eSP isn't directly supported; it's the
// escape indicator for reading a SIB.
memreg = Source::Indirect;
} else {
// Classic 16-bit decoding: mode picks a displacement size,
// and a few fixed index+base pairs are defined.
//
// A base of eAX is meaningless, with the source type being the indicator
// that it should be ignored. ScaleIndexBase can't store a base of Source::None.
constexpr ScaleIndexBase rm_table[8] = {
ScaleIndexBase(0, Source::eSI, Source::eBX),
ScaleIndexBase(0, Source::eDI, Source::eBX),
ScaleIndexBase(0, Source::eSI, Source::eBP),
ScaleIndexBase(0, Source::eDI, Source::eBP),
ScaleIndexBase(0, Source::eSI, Source::None),
ScaleIndexBase(0, Source::eDI, Source::None),
ScaleIndexBase(0, Source::eBP, Source::None),
ScaleIndexBase(0, Source::eBX, Source::None),
ScaleIndexBase(0, Source::eSI, Source::eAX),
ScaleIndexBase(0, Source::eDI, Source::eAX),
ScaleIndexBase(0, Source::eBP, Source::eAX),
ScaleIndexBase(0, Source::eBX, Source::eAX),
};
sib_ = rm_table[rm];
memreg = rm >= 4 ? Source::IndirectNoBase : Source::Indirect;
}
}

View File

@ -521,7 +521,7 @@ class ScaleIndexBase {
constexpr ScaleIndexBase(int scale, Source index, Source base) noexcept :
sib_(uint8_t(
scale << 6 |
(int(index != Source::None ? index : Source::eSI) << 3) |
(int(index != Source::None ? index : Source::eSP) << 3) |
int(base)
)) {}
constexpr ScaleIndexBase(Source index, Source base) noexcept : ScaleIndexBase(0, index, base) {}

View File

@ -120,7 +120,7 @@ constexpr char TestSuiteHome[] = "/Users/tharte/Projects/ProcessorTests/8088/v1"
std::string operand;
using Source = InstructionSet::x86::Source;
const Source source = pointer.source();
const Source source = pointer.source<false>();
switch(source) {
// to_string handles all direct register names correctly.
default: return InstructionSet::x86::to_string(source, instruction.operation_size());
@ -132,7 +132,8 @@ constexpr char TestSuiteHome[] = "/Users/tharte/Projects/ProcessorTests/8088/v1"
);
case Source::DirectAddress:
case Source::Indirect: {
case Source::Indirect:
case Source::IndirectNoBase: {
std::stringstream stream;
if(!InstructionSet::x86::mnemonic_implies_data_size(instruction.operation)) {
@ -149,14 +150,24 @@ constexpr char TestSuiteHome[] = "/Users/tharte/Projects/ProcessorTests/8088/v1"
stream << InstructionSet::x86::to_string(segment, InstructionSet::x86::DataSize::None) << ':';
stream << '[';
if(source == Source::Indirect) {
stream << InstructionSet::x86::to_string(pointer.base(), data_size(instruction.address_size()));
stream << '+' << InstructionSet::x86::to_string(pointer.index(), data_size(instruction.address_size()));
if(instruction.offset()) {
stream << '+' << to_hex(instruction.offset(), 4);
}
} else {
stream << to_hex(instruction.offset(), 4);
switch(source) {
default: break;
case Source::Indirect:
stream << InstructionSet::x86::to_string(pointer.base(), data_size(instruction.address_size()));
stream << '+' << InstructionSet::x86::to_string(pointer.index(), data_size(instruction.address_size()));
if(instruction.offset()) {
stream << '+' << to_hex(instruction.offset(), 4);
}
break;
case Source::IndirectNoBase:
stream << InstructionSet::x86::to_string(pointer.index(), data_size(instruction.address_size()));
if(instruction.offset()) {
stream << '+' << to_hex(instruction.offset(), 4);
}
break;
case Source::DirectAddress:
stream << to_hex(instruction.offset(), 4);
break;
}
stream << ']';
return stream.str();
@ -187,11 +198,18 @@ constexpr char TestSuiteHome[] = "/Users/tharte/Projects/ProcessorTests/8088/v1"
log_hex();
// Repeat operand conversions, for debugging.
Decoder().decode(data.data(), data.size());
const auto destination = decoded.second.destination();
to_string(destination, decoded.second);
const auto source = decoded.second.source();
to_string(source, decoded.second);
Decoder decoder;
const auto instruction = decoder.decode(data.data(), data.size());
const InstructionSet::x86::Source sources[] = {
instruction.second.source().source<false>(),
instruction.second.destination().source<false>(),
};
(void)sources;
const auto destination = instruction.second.destination();
to_string(destination, instruction.second);
const auto source = instruction.second.source();
to_string(source, instruction.second);
return false;
}