|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * cpuopti.c - Small optimizer for cpu*.s files ! 5: * Based on work by Tauno Taipaleenmaki ! 6: * ! 7: * Copyright 1996 Bernd Schmidt ! 8: */ ! 9: ! 10: #include "sysconfig.h" ! 11: #include "sysdeps.h" ! 12: #include <ctype.h> ! 13: ! 14: #include "options.h" ! 15: ! 16: struct line { ! 17: struct line *next, *prev; ! 18: int delete; ! 19: char *data; ! 20: }; ! 21: ! 22: struct func { ! 23: struct line *first_line, *last_line; ! 24: int initial_offset; ! 25: }; ! 26: ! 27: static void oops(void) ! 28: { ! 29: fprintf(stderr, "Corrupted assembly file!\n"); ! 30: abort(); ! 31: } ! 32: ! 33: static char * match(struct line *l, const char *m) ! 34: { ! 35: char *str = l->data; ! 36: int len = strlen(m); ! 37: while (isspace(*str)) ! 38: str++; ! 39: ! 40: if (strncmp(str, m, strlen(m)) != 0) ! 41: return NULL; ! 42: return str + len; ! 43: } ! 44: ! 45: static void do_function(struct func *f) ! 46: { ! 47: int pops_at_end = 0; ! 48: struct line *l, *fl; ! 49: char *s, *s2; ! 50: int in_pop_area = 1; ! 51: ! 52: f->initial_offset = 0; ! 53: ! 54: l = f->last_line; ! 55: fl = f->first_line; ! 56: ! 57: if (!match(l,"ret")) ! 58: oops(); ! 59: l = l->prev; ! 60: ! 61: while (!match(fl, "op_")) ! 62: fl = fl->next; ! 63: fl = fl->next; ! 64: ! 65: s = match(l, "addl $"); ! 66: s2 = match(fl, "subl $"); ! 67: if (s && s2 && strcmp(s,s2) == 0) { ! 68: int v = 0; ! 69: while (isdigit(*s)) { ! 70: v = v * 10 + (*s) - '0'; ! 71: s++; ! 72: } ! 73: if (strcmp(s, ",%esp") == 0) { ! 74: f->initial_offset = v; ! 75: l->delete = 2; ! 76: fl->delete = 3; ! 77: l = l->prev; ! 78: fl = fl->next; ! 79: } else ! 80: in_pop_area = 0; ! 81: } ! 82: while (in_pop_area) { ! 83: char *popm, *pushm; ! 84: popm = match(l, "popl %"); ! 85: pushm = match(fl, "pushl %"); ! 86: if (popm && pushm && strcmp(pushm, popm) == 0) { ! 87: pops_at_end++; ! 88: fl->delete = l->delete = 1; ! 89: } else ! 90: in_pop_area = 0; ! 91: l = l->prev; ! 92: fl = fl->next; ! 93: } ! 94: if (f->initial_offset) ! 95: f->initial_offset += 4 * pops_at_end; ! 96: } ! 97: ! 98: static void output_function(struct func *f) ! 99: { ! 100: struct line *l = f->first_line; ! 101: ! 102: while (l) { ! 103: switch (l->delete) { ! 104: case 1: ! 105: break; ! 106: case 0: ! 107: printf("%s\n", l->data); ! 108: break; ! 109: case 2: ! 110: if (f->initial_offset) ! 111: printf("\taddl $%d,%%esp\n", f->initial_offset); ! 112: break; ! 113: case 3: ! 114: if (f->initial_offset) ! 115: printf("\tsubl $%d,%%esp\n", f->initial_offset); ! 116: break; ! 117: } ! 118: l = l->next; ! 119: } ! 120: } ! 121: ! 122: int main(int argc, char **argv) ! 123: { ! 124: char tmp[4096]; ! 125: ! 126: for(;;) { ! 127: char *s; ! 128: ! 129: if ((fgets(tmp, 4095, stdin)) == NULL) ! 130: break; ! 131: ! 132: s = strchr (tmp, '\n'); ! 133: if (s != NULL) ! 134: *s = 0; ! 135: ! 136: if (strncmp(tmp, ".globl op_", 10) == 0) { ! 137: struct line *first_line = NULL, *prev = NULL; ! 138: struct line **nextp = &first_line; ! 139: struct func f; ! 140: ! 141: do { ! 142: struct line *current; ! 143: ! 144: if (strcmp (tmp, "#APP") != 0 && strcmp (tmp, "#NO_APP") != 0) { ! 145: current = *nextp = (struct line *)malloc(sizeof (struct line)); ! 146: nextp = ¤t->next; ! 147: current->prev = prev; prev = current; ! 148: current->next = NULL; ! 149: current->delete = 0; ! 150: current->data = my_strdup (tmp); ! 151: } ! 152: if ((fgets(tmp, 4095, stdin)) == NULL) ! 153: oops(); ! 154: s = strchr (tmp, '\n'); ! 155: if (s != NULL) ! 156: *s = 0; ! 157: } while (strncmp (tmp,".Lfe", 4) != 0); ! 158: ! 159: f.first_line = first_line; ! 160: f.last_line = prev; ! 161: ! 162: do_function(&f); ! 163: output_function(&f); ! 164: } ! 165: printf("%s\n", tmp); ! 166: } ! 167: return 0; ! 168: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.