|
|
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:
1.1.1.2 ! root 40: if (strncmp(str, m, len) != 0)
1.1 root 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;
1.1.1.2 ! root 64:
1.1 root 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:
1.1.1.2 ! root 126: #ifdef AMIGA
! 127: char *cmd="machdep/cpuopti";
! 128: if(execl(cmd,cmd,NULL)==-1) perror(cmd);
! 129: return 10;
! 130: #endif
! 131:
1.1 root 132: for(;;) {
133: char *s;
134:
135: if ((fgets(tmp, 4095, stdin)) == NULL)
136: break;
137:
138: s = strchr (tmp, '\n');
139: if (s != NULL)
140: *s = 0;
141:
142: if (strncmp(tmp, ".globl op_", 10) == 0) {
143: struct line *first_line = NULL, *prev = NULL;
144: struct line **nextp = &first_line;
145: struct func f;
146:
147: do {
148: struct line *current;
149:
150: if (strcmp (tmp, "#APP") != 0 && strcmp (tmp, "#NO_APP") != 0) {
151: current = *nextp = (struct line *)malloc(sizeof (struct line));
152: nextp = ¤t->next;
153: current->prev = prev; prev = current;
154: current->next = NULL;
155: current->delete = 0;
156: current->data = my_strdup (tmp);
157: }
158: if ((fgets(tmp, 4095, stdin)) == NULL)
159: oops();
160: s = strchr (tmp, '\n');
161: if (s != NULL)
162: *s = 0;
163: } while (strncmp (tmp,".Lfe", 4) != 0);
164:
165: f.first_line = first_line;
166: f.last_line = prev;
167:
168: do_function(&f);
169: output_function(&f);
170: }
171: printf("%s\n", tmp);
172: }
173: return 0;
174: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.