diff options
author | Jerome Glisse <jglisse@redhat.com> | 2012-08-08 14:03:49 -0400 |
---|---|---|
committer | Jerome Glisse <jglisse@redhat.com> | 2012-08-08 14:03:49 -0400 |
commit | ba590cc8984b6e7b06f02f1e26404e4eb0e6edcd (patch) | |
tree | 96aaa434d435708dc34cbd1e2388b540e567ea4e /rdb_annotateib2.c |
rdb: register database
Diffstat (limited to 'rdb_annotateib2.c')
-rw-r--r-- | rdb_annotateib2.c | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/rdb_annotateib2.c b/rdb_annotateib2.c new file mode 100644 index 0000000..b4970df --- /dev/null +++ b/rdb_annotateib2.c @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * author: Jerome Glisse + */ +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "rdb.h" + +#define WINDOW 64 + +struct reg { + struct reg *next; + unsigned offset; + unsigned value; + unsigned after; + unsigned before; + unsigned tmp_count; + unsigned pos; +}; + +struct cmp { + struct reg *reg; + unsigned nreg; +}; + +void cmp_set_reg(struct cmp *cmp, unsigned offset, unsigned value, unsigned pos) +{ + struct reg *reg = cmp->reg; + + while (reg) { + if (reg->offset == offset) { + reg->value = value; + reg->tmp_count++; + reg->pos = pos; + return; + } + reg = reg->next; + } + + reg = malloc(sizeof(*reg)); + reg->offset = offset; + reg->value = value; + reg->next = cmp->reg; + reg->after = 0; + reg->before = 0; + reg->pos = pos; + reg->tmp_count = 1; + cmp->reg = reg; + cmp->nreg++; +} + +void cmp_commit_before(struct cmp *cmp, unsigned pos) +{ + struct reg *reg = cmp->reg; + + while (reg) { + if (reg->pos < pos && (pos - reg->pos) < WINDOW) { + reg->before += reg->tmp_count; + } + reg->tmp_count = 0; + reg = reg->next; + } +} + +void cmp_commit_after(struct cmp *cmp, unsigned pos) +{ + struct reg *reg = cmp->reg; + + while (reg) { + if (reg->pos > pos && (reg->pos - pos) < WINDOW) { + reg->after += reg->tmp_count; + } + reg->tmp_count = 0; + reg = reg->next; + } +} + +void cmp_print(struct cmp *cmp) +{ + struct reg *reg = cmp->reg; + + while (reg) { + printf("%8d %8d 0x%08x\n", reg->before, reg->after, reg->offset); + reg = reg->next; + } +} + +static void cmp_short_before(struct cmp *cmp) +{ + unsigned not_shorted = 1; + unsigned npass = 0; + +//cmp_print(cmp); + while (not_shorted) { + struct reg *reg = cmp->reg; + struct reg **preg = &cmp->reg; + + not_shorted = 0; + while (reg) { + if (reg->next && reg->next->before > reg->before) { + struct reg *nreg = reg->next; + + *preg = nreg; + reg->next = nreg->next; + nreg->next = reg; + not_shorted = 1; + } + preg = ®->next; + reg = reg->next; + } +//printf("pass %d ---------------------------------------\n", npass); +//cmp_print(cmp); + npass++; + } +} + +static void cmp_short_after(struct cmp *cmp) +{ + unsigned not_shorted = 1; + + while (not_shorted) { + struct reg *reg = cmp->reg; + struct reg **preg = &cmp->reg; + + not_shorted = 0; + while (reg) { + if (reg->next && reg->next->after > reg->after) { + struct reg *nreg = reg->next; + + *preg = nreg; + reg->next = nreg->next; + nreg->next = reg; + not_shorted = 1; + } + preg = ®->next; + reg = reg->next; + } + } +} + +char *line_skip(char *line, unsigned nspace) +{ + do { + if (*line == ' ') { + nspace--; + } + line++; + } while (nspace); + return line; +} + +void annotate(struct cmp *cmp, unsigned mreg, FILE *file) +{ + char line[128], *tmp; + unsigned offset, value, ndw = 0, pkt = 0, it; + unsigned pos = 0, rpos = 0; + + while (!feof(file)) { + if (fgets(line, sizeof(line), file) == NULL) { + continue; + } + pos++; + if (rpos && pos > rpos && (pos - rpos) >= WINDOW) { + cmp_commit_after(cmp, rpos); + rpos = 0; + } + line[strlen(line) - 1] = 0; + tmp = strstr(line, "] ["); + if (tmp == NULL) { +// printf("%s\n", line); + continue; + } + tmp = strchr(tmp + 4, ']'); + if (tmp == NULL) { +// printf("%s\n", line); + continue; + } + value = strtoul(tmp + 2, &tmp, 0); + if (tmp == NULL) { +// printf("%s\n", line); + continue; + } + if (ndw) { + switch (pkt) { + case 3: + switch (it) { + case 0x68: + if (!offset) { + offset = (value << 2) + 0x8000; + } else { + cmp_set_reg(cmp, offset, value, pos); + if (offset == mreg) { + rpos = pos; + cmp_commit_before(cmp, rpos); + } + offset += 4; + } + break; + case 0x69: + if (!offset) { + offset = (value << 2) + 0x28000; + } else { + cmp_set_reg(cmp, offset, value, pos); + if (offset == mreg) { + rpos = pos; + cmp_commit_before(cmp, rpos); + } + offset += 4; + } + break; + default: +// printf("%s\n", line); + break; + } + break; + case 0: + default: + cmp_set_reg(cmp, offset, value, pos); + if (offset == mreg) { + rpos = pos; + cmp_commit_before(cmp, rpos); + } + offset += 4; + break; + } + ndw--; + } else { + pkt = (value >> 30) & 3; + switch (pkt) { + case 0: + offset = (value & 0xffff) << 2; + if (offset == mreg) { + rpos = pos; + cmp_commit_before(cmp, rpos); + } + ndw = ((value >> 16) & 0x3fff) + 1; + break; + case 3: + offset = 0; + ndw = ((value >> 16) & 0x3fff) + 1; + it = ((value >> 8) & 0xff); + switch (it) { + case 0x29: + case 0x2b: + case 0x2d: + case 0x2e: + case 0x35: + /* DRAW */ + break; + default: + break; + } + break; + case 1: + case 2: + default: + break; + } + } + } +} + +int main(int argc, char *argv[]) +{ + struct cmp cmp; + FILE *file; + unsigned reg, i; + + cmp.reg = NULL; + cmp.nreg = 0; + if (argc < 3) { + printf("usage %s rdb reg ibfile*\n", argv[0]); + return -1; + } + + reg = strtoul(argv[1], NULL, 0); + + for (i = 2; i < argc; i++) { + file = fopen(argv[i], "r"); + if (file == NULL) { + fprintf(stderr, "failed reading %s\n", argv[i]); + return -1; + } + while (!feof(file)) { + annotate(&cmp, reg, file); + } + fclose(file); + } + printf("BEFORE REG %d -------------------------------------------------------\n", cmp.nreg); + cmp_short_before(&cmp); + cmp_print(&cmp); +#if 1 + printf("AFTER REG %d -------------------------------------------------------\n", cmp.nreg); + cmp_short_after(&cmp); + cmp_print(&cmp); +#endif +} |