1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-29 00:29:34 +00:00

Summarise failures.

This commit is contained in:
Thomas Harte 2024-03-10 16:56:39 -04:00
parent e17700b495
commit 06a5df029d

View File

@ -12,6 +12,7 @@
#include "CSROMFetcher.hpp" #include "CSROMFetcher.hpp"
#include "NSData+dataWithContentsOfGZippedFile.h" #include "NSData+dataWithContentsOfGZippedFile.h"
#include <map>
#include <sstream> #include <sstream>
using namespace InstructionSet::ARM; using namespace InstructionSet::ARM;
@ -65,7 +66,7 @@ struct MemoryLedger {
template <typename IntT> template <typename IntT>
bool write(uint32_t address, IntT source, Mode, bool) { bool write(uint32_t address, IntT source, Mode, bool) {
if(write_pointer == writes.size() || writes[write_pointer].size != sizeof(IntT) || writes[write_pointer].address != address || writes[write_pointer].value != source) { if(write_pointer == writes.size() || writes[write_pointer].size != sizeof(IntT) || writes[write_pointer].address != address || writes[write_pointer].value != source) {
throw 0; return false;
} }
++write_pointer; ++write_pointer;
return true; return true;
@ -74,7 +75,7 @@ struct MemoryLedger {
template <typename IntT> template <typename IntT>
bool read(uint32_t address, IntT &source, Mode, bool) { bool read(uint32_t address, IntT &source, Mode, bool) {
if(read_pointer == reads.size() || reads[read_pointer].size != sizeof(IntT) || reads[read_pointer].address != address) { if(read_pointer == reads.size() || reads[read_pointer].size != sizeof(IntT) || reads[read_pointer].address != address) {
throw 0; return false;
} }
source = reads[read_pointer].value; source = reads[read_pointer].value;
++read_pointer; ++read_pointer;
@ -336,6 +337,13 @@ struct MemoryLedger {
using Exec = Executor<Model::ARMv2, MemoryLedger>; using Exec = Executor<Model::ARMv2, MemoryLedger>;
std::unique_ptr<Exec> test; std::unique_ptr<Exec> test;
struct FailureRecord {
int count = 0;
int first = 0;
NSString *sample;
};
std::map<uint32_t, FailureRecord> failures;
uint32_t instruction = 0; uint32_t instruction = 0;
int test_count = 0; int test_count = 0;
while(!input.eof()) { while(!input.eof()) {
@ -345,7 +353,6 @@ struct MemoryLedger {
if(label == "**") { if(label == "**") {
input >> instruction; input >> instruction;
test_count = 0; test_count = 0;
test = std::make_unique<Exec>();
continue; continue;
} }
@ -356,6 +363,7 @@ struct MemoryLedger {
input >> regs[c]; input >> regs[c];
} }
if(!test) test = std::make_unique<Exec>();
auto &registers = test->registers(); auto &registers = test->registers();
if(label == "Before:") { if(label == "Before:") {
// This is the start of a new test. // This is the start of a new test.
@ -382,20 +390,30 @@ struct MemoryLedger {
} }
execute<Model::ARMv2>(instruction, *test); execute<Model::ARMv2>(instruction, *test);
NSMutableString *error = nil;
for(uint32_t c = 0; c < 15; c++) { for(uint32_t c = 0; c < 15; c++) {
XCTAssertEqual( if(regs[c] != registers[c]) {
regs[c], if(!error) error = [[NSMutableString alloc] init]; else [error appendString:@"; "];
registers[c], [error appendFormat:@"R%d %08x v %08x", c, regs[c], registers[c]];
@"R%d doesn't match during instruction %08x, test %d", c, instruction, test_count); }
} }
XCTAssertEqual( if((regs[15] & r15_mask) != (registers.pc_status(8) & r15_mask)) {
regs[15] & r15_mask, if(!error) error = [[NSMutableString alloc] init]; else [error appendString:@"; "];
registers.pc_status(8) & r15_mask, [error appendFormat:@"; PC/PSR %08x/%08x v %08x/%08x",
@"PC or PSR doesn't match during instruction %08x, test %d; PC: %08x v %08x; PSR: %08x v %08x", regs[15] & 0x3fffffc, regs[15] & ~0x3fffffc,
instruction, test_count, registers.pc(8), registers.status()];
regs[15] & 0x3fffffc, registers.pc(8), }
regs[15] & ~0x3fffffc, registers.status());
if(error) {
++failures[instruction].count;
if(failures[instruction].count == 1) {
failures[instruction].first = test_count;
failures[instruction].sample = error;
}
}
test.reset();
} }
continue; continue;
} }
@ -431,7 +449,14 @@ struct MemoryLedger {
} }
} }
XCTAssertNotNil(tests); XCTAssertTrue(failures.empty());
if(!failures.empty()) {
NSLog(@"Failed %zu instructions; examples below", failures.size());
for(const auto &pair: failures) {
NSLog(@"%08x, %d total, test %d: %@", pair.first, pair.second.count, pair.second.first, pair.second.sample);
}
}
} }
// TODO: turn the below into a trace-driven test case. // TODO: turn the below into a trace-driven test case.