blob: 7c2450b87a572358462fd350ddb46b11d8e9e60f [file]
/*
* Copyright (C) 2021 Collabora, Ltd.
* SPDX-License-Identifier: MIT
*/
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "asahi/isa/disasm.h"
#include "util/macros.h"
static inline uint8_t
parse_nibble(const char c)
{
return (c >= 'a') ? 10 + (c - 'a') : (c - '0');
}
/* Given a little endian 8 byte hexdump, parse out the 64-bit value */
static uint64_t
parse_hex(const char *in)
{
uint64_t v = 0;
for (unsigned i = 0; i < 8; ++i) {
uint8_t byte = (parse_nibble(in[0]) << 4) | parse_nibble(in[1]);
v |= ((uint64_t)byte) << (8 * i);
/* Skip the space after the byte */
in += 3;
}
return v;
}
int
main(int argc, const char **argv)
{
if (argc < 2) {
fprintf(stderr, "Expected case list\n");
return 1;
}
FILE *fp = fopen(argv[1], "r");
if (fp == NULL) {
fprintf(stderr, "Could not open the case list");
return 1;
}
char line[128];
unsigned nr_fail = 0, nr_pass = 0;
while (fgets(line, sizeof(line), fp) != NULL) {
char *output = NULL;
size_t sz = 0;
size_t len = strlen(line);
/* Skip empty lines */
if (len <= 1)
continue;
/* Parse the hex */
uint8_t code[16];
const char *cursor = line;
const char *end = line + len;
uint32_t i = 0;
while ((cursor + 2) <= end && cursor[0] != ' ') {
assert(i < ARRAY_SIZE(code));
code[i] = (parse_nibble(cursor[0]) << 4) | parse_nibble(cursor[1]);
cursor += 2;
++i;
}
/* Skip spacing */
while (cursor < end && (*cursor) == ' ')
++cursor;
FILE *outputp = open_memstream(&output, &sz);
signed ret = agx2_disassemble_instr((void *)code, outputp, 0, false);
unsigned instr_len = abs(ret);
fclose(outputp);
/* Rest of the line is the reference assembly */
bool fail = strcmp(cursor, output);
fail |= (instr_len != i);
fail |= (ret < 0);
if (fail) {
/* Extra spaces after Got to align with Expected */
printf("Got %sExpected %s\n", output, cursor);
if (instr_len != i) {
printf("Got length %d, expected length %u\n", instr_len, i);
}
if (ret < 0) {
printf("Got an error.\n");
}
nr_fail++;
} else {
nr_pass++;
}
free(output);
}
printf("Passed %u/%u tests.\n", nr_pass, nr_pass + nr_fail);
fclose(fp);
return nr_fail ? 1 : 0;
}