mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-01 11:49:58 +00:00
Summarise failures.
This commit is contained in:
parent
e17700b495
commit
06a5df029d
@ -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 ®isters = test->registers();
|
auto ®isters = 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.
|
||||||
|
Loading…
Reference in New Issue
Block a user