1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-02-07 05:30:30 +00:00

Defer worrying about immediate sign extensions.

This commit is contained in:
Thomas Harte 2023-09-27 22:18:05 -04:00
parent 02aeec0173
commit 11c747e3c4

View File

@ -38,7 +38,7 @@ std::string to_hex(int value, int digits, bool with_suffix = true) {
};
template <typename InstructionT>
std::string to_string(InstructionSet::x86::DataPointer pointer, const InstructionT &instruction, int offset_length) {
std::string to_string(InstructionSet::x86::DataPointer pointer, const InstructionT &instruction, int offset_length, int immediate_length) {
std::string operand;
auto append = [](std::stringstream &stream, auto value, int length, const char *prefix) {
@ -76,7 +76,7 @@ std::string to_string(InstructionSet::x86::DataPointer pointer, const Instructio
case Source::Immediate: {
std::stringstream stream;
append(stream, instruction.operand(), instruction.operation_size() == InstructionSet::x86::DataSize::Byte ? 2 : 4, "");
append(stream, instruction.operand(), immediate_length, "");
return stream.str();
}
@ -181,7 +181,7 @@ std::string to_string(InstructionSet::x86::DataPointer pointer, const Instructio
return [fullPaths sortedArrayUsingSelector:@selector(compare:)];
}
- (NSString *)toString:(const InstructionSet::x86::Instruction<false> &)instruction offsetLength:(int)offsetLength {
- (NSString *)toString:(const InstructionSet::x86::Instruction<false> &)instruction offsetLength:(int)offsetLength immediateLength:(int)immediateLength {
// Form string version, compare.
std::string operation;
using Operation = InstructionSet::x86::Operation;
@ -213,11 +213,11 @@ std::string to_string(InstructionSet::x86::DataPointer pointer, const Instructio
const bool displacement = has_displacement(instruction.operation);
operation += " ";
if(operands > 1) {
operation += to_string(instruction.destination(), instruction, offsetLength);
operation += to_string(instruction.destination(), instruction, offsetLength, immediateLength);
operation += ", ";
}
if(operands > 0) {
operation += to_string(instruction.source(), instruction, offsetLength);
operation += to_string(instruction.source(), instruction, offsetLength, immediateLength);
}
if(displacement) {
operation += to_hex(instruction.displacement(), 2);
@ -242,7 +242,7 @@ std::string to_string(InstructionSet::x86::DataPointer pointer, const Instructio
const bool displacement = has_displacement(instruction.operation);
operation += " ";
if(operands > 1) {
operation += to_string(instruction.destination(), instruction, offsetLength);
operation += to_string(instruction.destination(), instruction, offsetLength, immediateLength);
}
if(operands > 0) {
switch(instruction.source().source()) {
@ -255,7 +255,7 @@ std::string to_string(InstructionSet::x86::DataPointer pointer, const Instructio
[[fallthrough]];
default:
operation += ", ";
operation += to_string(instruction.source(), instruction, offsetLength);
operation += to_string(instruction.source(), instruction, offsetLength, immediateLength);
break;
}
}
@ -300,12 +300,17 @@ std::string to_string(InstructionSet::x86::DataPointer pointer, const Instructio
// The decoder doesn't preserve the original offset length, which makes no functional difference but
// does affect the way that offsets are printed in the test set.
NSString *const fullOffset = [self toString:decoded.second offsetLength:4];
NSString *const shortOffset = [self toString:decoded.second offsetLength:2];
NSString *const noOffset = [self toString:decoded.second offsetLength:0];
NSSet<NSString *> *decodings = [NSSet setWithObjects:
[self toString:decoded.second offsetLength:4 immediateLength:4],
[self toString:decoded.second offsetLength:2 immediateLength:4],
[self toString:decoded.second offsetLength:0 immediateLength:4],
[self toString:decoded.second offsetLength:4 immediateLength:2],
[self toString:decoded.second offsetLength:2 immediateLength:2],
[self toString:decoded.second offsetLength:0 immediateLength:2],
nil];
auto compare_decoding = [&](NSString *name) -> bool {
return [fullOffset isEqualToString:name] || [shortOffset isEqualToString:name] || [noOffset isEqualToString:name];
return [decodings containsObject:name];
};
@ -319,7 +324,7 @@ std::string to_string(InstructionSet::x86::DataPointer pointer, const Instructio
isEqual = compare_decoding(alteredName);
}
XCTAssert(isEqual, "%@ doesn't match %@ or similar, was %@ within %@", test[@"name"], fullOffset, hex_instruction(), file);
XCTAssert(isEqual, "%@ doesn't match %@ or similar, was %@ within %@", test[@"name"], [decodings anyObject], hex_instruction(), file);
// Repetition, to allow for easy breakpoint placement.
if(!isEqual) {
@ -333,9 +338,9 @@ std::string to_string(InstructionSet::x86::DataPointer pointer, const Instructio
(void)sources;
const auto destination = instruction.second.destination();
std::cout << to_string(destination, instruction.second, false);
std::cout << to_string(destination, instruction.second, 4, 2);
const auto source = instruction.second.source();
std::cout << to_string(source, instruction.second, false);
std::cout << to_string(source, instruction.second, 4, 2);
return false;
}