summaryrefslogtreecommitdiff
path: root/rdb_annotateib2.c
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2012-08-08 14:03:49 -0400
committerJerome Glisse <jglisse@redhat.com>2012-08-08 14:03:49 -0400
commitba590cc8984b6e7b06f02f1e26404e4eb0e6edcd (patch)
tree96aaa434d435708dc34cbd1e2388b540e567ea4e /rdb_annotateib2.c
rdb: register database
Diffstat (limited to 'rdb_annotateib2.c')
-rw-r--r--rdb_annotateib2.c322
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 = &reg->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 = &reg->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
+}