mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Agree that JZ/JNZ are clearer (for me) of the synonyms.
This commit is contained in:
parent
2d928199d6
commit
e5dfc882cb
@ -261,8 +261,8 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
|
||||
case 0x71: Displacement(JNO, DataSize::Byte); break;
|
||||
case 0x72: Displacement(JB, DataSize::Byte); break;
|
||||
case 0x73: Displacement(JNB, DataSize::Byte); break;
|
||||
case 0x74: Displacement(JE, DataSize::Byte); break;
|
||||
case 0x75: Displacement(JNE, DataSize::Byte); break;
|
||||
case 0x74: Displacement(JZ, DataSize::Byte); break;
|
||||
case 0x75: Displacement(JNZ, DataSize::Byte); break;
|
||||
case 0x76: Displacement(JBE, DataSize::Byte); break;
|
||||
case 0x77: Displacement(JNBE, DataSize::Byte); break;
|
||||
case 0x78: Displacement(JS, DataSize::Byte); break;
|
||||
@ -497,8 +497,8 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
|
||||
case 0x71: RequiresMin(i80386); Displacement(JNO, data_size_); break;
|
||||
case 0x72: RequiresMin(i80386); Displacement(JB, data_size_); break;
|
||||
case 0x73: RequiresMin(i80386); Displacement(JNB, data_size_); break;
|
||||
case 0x74: RequiresMin(i80386); Displacement(JE, data_size_); break;
|
||||
case 0x75: RequiresMin(i80386); Displacement(JNE, data_size_); break;
|
||||
case 0x74: RequiresMin(i80386); Displacement(JZ, data_size_); break;
|
||||
case 0x75: RequiresMin(i80386); Displacement(JNZ, data_size_); break;
|
||||
case 0x76: RequiresMin(i80386); Displacement(JBE, data_size_); break;
|
||||
case 0x77: RequiresMin(i80386); Displacement(JNBE, data_size_); break;
|
||||
case 0x78: RequiresMin(i80386); Displacement(JS, data_size_); break;
|
||||
|
@ -45,8 +45,8 @@ std::string InstructionSet::x86::to_string(Operation operation, DataSize size) {
|
||||
case Operation::JNO: return "jno";
|
||||
case Operation::JB: return "jb";
|
||||
case Operation::JNB: return "jnb";
|
||||
case Operation::JE: return "jo";
|
||||
case Operation::JNE: return "jne";
|
||||
case Operation::JZ: return "jz";
|
||||
case Operation::JNZ: return "jnz";
|
||||
case Operation::JBE: return "jbe";
|
||||
case Operation::JNBE: return "jnbe";
|
||||
case Operation::JS: return "js";
|
||||
|
@ -87,7 +87,7 @@ enum class Operation: uint8_t {
|
||||
OUT,
|
||||
|
||||
// Various jumps; see the displacement to calculate targets.
|
||||
JO, JNO, JB, JNB, JE, JNE, JBE, JNBE,
|
||||
JO, JNO, JB, JNB, JZ, JNZ, JBE, JNBE,
|
||||
JS, JNS, JP, JNP, JL, JNL, JLE, JNLE,
|
||||
|
||||
/// Near call.
|
||||
@ -340,18 +340,26 @@ enum class Operation: uint8_t {
|
||||
MOVtoTr, MOVfromTr,
|
||||
};
|
||||
|
||||
constexpr int num_operands(Operation operation) {
|
||||
constexpr bool has_displacement(Operation operation) {
|
||||
switch(operation) {
|
||||
default: return 2;
|
||||
default: return false;
|
||||
|
||||
case Operation::JO: case Operation::JNO:
|
||||
case Operation::JB: case Operation::JNB:
|
||||
case Operation::JE: case Operation::JNE:
|
||||
case Operation::JZ: case Operation::JNZ:
|
||||
case Operation::JBE: case Operation::JNBE:
|
||||
case Operation::JS: case Operation::JNS:
|
||||
case Operation::JP: case Operation::JNP:
|
||||
case Operation::JL: case Operation::JNL:
|
||||
case Operation::JLE: case Operation::JNLE:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr int num_operands(Operation operation) {
|
||||
switch(operation) {
|
||||
default: return 2;
|
||||
|
||||
case Operation::INC: case Operation::DEC:
|
||||
case Operation::POP: case Operation::PUSH:
|
||||
case Operation::MUL:
|
||||
@ -360,6 +368,16 @@ constexpr int num_operands(Operation operation) {
|
||||
case Operation::ESC:
|
||||
return 1;
|
||||
|
||||
// Pedantically, these have an displacement rather than an operand.
|
||||
case Operation::JO: case Operation::JNO:
|
||||
case Operation::JB: case Operation::JNB:
|
||||
case Operation::JZ: case Operation::JNZ:
|
||||
case Operation::JBE: case Operation::JNBE:
|
||||
case Operation::JS: case Operation::JNS:
|
||||
case Operation::JP: case Operation::JNP:
|
||||
case Operation::JL: case Operation::JNL:
|
||||
case Operation::JLE: case Operation::JNLE:
|
||||
// Genuine zero-operand instructions:
|
||||
case Operation::CMPS: case Operation::LODS:
|
||||
case Operation::MOVS: case Operation::SCAS:
|
||||
case Operation::STOS:
|
||||
|
@ -104,7 +104,19 @@ constexpr char TestSuiteHome[] = "/Users/tharte/Projects/ProcessorTests/8088/v1"
|
||||
|
||||
operation += to_string(decoded.second.operation, decoded.second.operation_size());
|
||||
|
||||
auto to_string = [] (InstructionSet::x86::DataPointer pointer, const auto &instruction) -> std::string {
|
||||
auto to_hex = [] (int value, int digits) -> std::string {
|
||||
auto stream = std::stringstream();
|
||||
stream << std::setfill('0') << std::uppercase << std::hex << std::setw(digits);
|
||||
switch(digits) {
|
||||
case 2: stream << +uint8_t(value); break;
|
||||
case 4: stream << +uint16_t(value); break;
|
||||
default: stream << value; break;
|
||||
}
|
||||
stream << 'h';
|
||||
return stream.str();
|
||||
};
|
||||
|
||||
auto to_string = [&to_hex] (InstructionSet::x86::DataPointer pointer, const auto &instruction) -> std::string {
|
||||
std::string operand;
|
||||
|
||||
using Source = InstructionSet::x86::Source;
|
||||
@ -113,17 +125,11 @@ constexpr char TestSuiteHome[] = "/Users/tharte/Projects/ProcessorTests/8088/v1"
|
||||
// to_string handles all direct register names correctly.
|
||||
default: return InstructionSet::x86::to_string(source, instruction.operation_size());
|
||||
|
||||
case Source::Immediate: {
|
||||
auto stream = std::stringstream();
|
||||
stream << std::setfill('0') << std::uppercase << std::hex;
|
||||
if(instruction.operation_size() == InstructionSet::x86::DataSize::Byte) {
|
||||
stream << std::setw(2) << uint8_t(instruction.operand());
|
||||
} else {
|
||||
stream << std::setw(4) << instruction.operand();
|
||||
}
|
||||
stream << 'h';
|
||||
return stream.str();
|
||||
}
|
||||
case Source::Immediate:
|
||||
return to_hex(
|
||||
instruction.operand(),
|
||||
instruction.operation_size() == InstructionSet::x86::DataSize::Byte ? 2 : 4
|
||||
);
|
||||
|
||||
case Source::Indirect:
|
||||
return (std::stringstream() <<
|
||||
@ -139,18 +145,17 @@ constexpr char TestSuiteHome[] = "/Users/tharte/Projects/ProcessorTests/8088/v1"
|
||||
};
|
||||
|
||||
const int operands = num_operands(decoded.second.operation);
|
||||
const bool displacement = has_displacement(decoded.second.operation);
|
||||
operation += " ";
|
||||
if(operands > 1) {
|
||||
operation += " ";
|
||||
operation += to_string(decoded.second.destination(), decoded.second);
|
||||
operation += ",";
|
||||
operation += ", ";
|
||||
}
|
||||
if(operands > 0) {
|
||||
operation += " ";
|
||||
operation += to_string(decoded.second.source(), decoded.second);
|
||||
}
|
||||
if(!operands) {
|
||||
// These tests always leave a space after the operation.
|
||||
operation += " ";
|
||||
if(displacement) {
|
||||
operation += to_hex(decoded.second.displacement(), 2);
|
||||
}
|
||||
|
||||
const NSString *objcOperation = [NSString stringWithUTF8String:operation.c_str()];
|
||||
|
@ -533,11 +533,11 @@ decode(const std::initializer_list<uint8_t> &stream, bool set_32_bit = false) {
|
||||
// cmp ecx,DWORD PTR [ebp+0x2c87445f]
|
||||
// jecxz 0x00000084 (from 0x82)
|
||||
// sahf
|
||||
// je 0x000000f3 (from 0x85)
|
||||
// jz 0x000000f3 (from 0x85)
|
||||
test(instructions[52], DataSize::DWord, Operation::CMP, ScaleIndexBase(Source::eBP), Source::eCX, 0, 0x2c87445f);
|
||||
test(instructions[53], Operation::JPCX, 0, 0x02);
|
||||
test(instructions[54], Operation::SAHF);
|
||||
test(instructions[55], Operation::JE, 0, 0x6e);
|
||||
test(instructions[55], Operation::JZ, 0, 0x6e);
|
||||
|
||||
// sbb ecx,DWORD PTR [edi+0x433c54d]
|
||||
// lahf
|
||||
|
Loading…
Reference in New Issue
Block a user