1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-23 03:32:32 +00:00

Add 8086 length limit test.

This commit is contained in:
Thomas Harte 2022-03-11 11:55:41 -05:00
parent c744a97e3c
commit 727342134c

View File

@ -64,8 +64,28 @@ template <typename InstructionT> void test_far(
// MARK: - Decoder // MARK: - Decoder
template <Model model, typename CollectionT>
std::vector<typename InstructionSet::x86::Decoder<model>::InstructionT>
decode(const CollectionT &stream, bool set_32_bit = false) {
// Build instructions list with a byte-by-byte decoding.
std::vector<typename InstructionSet::x86::Decoder<model>::InstructionT> instructions;
InstructionSet::x86::Decoder<model> decoder;
decoder.set_32bit_protected_mode(set_32_bit);
for(uint8_t item: stream) {
const auto [size, next] = decoder.decode(&item, 1);
if(size > 0) {
instructions.push_back(next);
}
}
return instructions;
}
template <Model model> template <Model model>
std::vector<typename InstructionSet::x86::Decoder<model>::InstructionT> decode(const std::initializer_list<uint8_t> &stream, bool set_32_bit = false) { std::vector<typename InstructionSet::x86::Decoder<model>::InstructionT>
decode(const std::initializer_list<uint8_t> &stream, bool set_32_bit = false) {
// Decode by offering up all data at once. // Decode by offering up all data at once.
std::vector<typename InstructionSet::x86::Decoder<model>::InstructionT> instructions; std::vector<typename InstructionSet::x86::Decoder<model>::InstructionT> instructions;
InstructionSet::x86::Decoder<model> decoder; InstructionSet::x86::Decoder<model> decoder;
@ -80,18 +100,17 @@ std::vector<typename InstructionSet::x86::Decoder<model>::InstructionT> decode(c
} }
// Grab a byte-at-a-time decoding and check that it matches the previous. // Grab a byte-at-a-time decoding and check that it matches the previous.
{ const auto byte_instructions = decode<model>(std::vector<uint8_t>{stream}, set_32_bit);
InstructionSet::x86::Decoder<model> decoder;
decoder.set_32bit_protected_mode(set_32_bit); XCTAssertEqual(byte_instructions.size(), instructions.size());
auto previous_instruction = instructions.begin(); auto previous_instruction = instructions.begin();
for(auto item: stream) { auto byte_instruction = byte_instructions.begin();
const auto [size, next] = decoder.decode(&item, 1); while(previous_instruction != instructions.end()) {
if(size > 0) { XCTAssert(*previous_instruction == *byte_instruction);
XCTAssert(next == *previous_instruction);
++previous_instruction; ++previous_instruction;
} ++byte_instruction;
}
} }
return instructions; return instructions;
@ -557,6 +576,13 @@ std::vector<typename InstructionSet::x86::Decoder<model>::InstructionT> decode(c
test(instructions[0], DataSize::DWord, Operation::ADD, Source::Immediate, ScaleIndexBase(Source::eDI), 0x9f683aa9, -0x42); test(instructions[0], DataSize::DWord, Operation::ADD, Source::Immediate, ScaleIndexBase(Source::eDI), 0x9f683aa9, -0x42);
} }
- (void)test8086LengthLimit {
const std::vector<uint8_t> all_prefix(65536, 0x26);
const auto instructions = decode<Model::i8086>(all_prefix);
XCTAssertEqual(instructions.size(), 1);
test(instructions[0], Operation::NOP);
}
- (void)test286LengthLimit { - (void)test286LengthLimit {
const auto instructions = decode<Model::i80286>({ const auto instructions = decode<Model::i80286>({
0x90, 0x90,