|
|
1.1 root 1: #define unsafe 1 /* pretend killing all but C is as good as killing
2: * all condition codes */
3: #ifdef unsafe
4: #define E (C|K)
5: #else
6: #define E K
7: #endif
8: #include "stdio.h"
9: #include "instr.c"
10: #include "ctype.h"
11: struct inst *index[128];
12:
13: #define SBBLK 1 /* looking for the start of a basic block */
14: #define SINST 2 /* thinking about generating a tally */
15: #define SPRO 3 /* thinking about generating prolog code */
16: #define SMAYBE 4 /* seen _, thinking about SPRO */
17:
18: FILE *outs, *fd, *outl; /* outs goes to assembler, outl is for listing */
19: extern FILE *popen();
20: char line[256], fname[256]; /* file names must fit in fname */
21: char curfunc[256];
22: int lineno, lastline;
23: int cnt;
24: int state = SBBLK;
25: char *ptr, *curarg;
26: char curdir[256];
27:
28: main(argc, argv)
29: char **argv;
30: { int i;
31: if(argc <= 1) {
32: fprintf(stderr, "no files given\n");
33: exit(1);
34: }
35: for(i = 0; insts[i].iname; i++)
36: ;
37: for(; i >= 0; i--)
38: index[insts[i].iname[0]] = insts + i;
39: fd = popen("pwd", "r");
40: for(i = 0; i < sizeof(curdir) && !feof(fd); i++)
41: curdir[i] = getc(fd);
42: curdir[i-2] = 0; /* thisdir\n */
43: fclose(fd);
44: for(i = 1; i < argc; i++) {
45: if(setfd(argv[i])) /* fix fd, outs, outl */
46: doarg(); /* do the work */
47: }
48: exit(0);
49: }
50:
51: setfd(s)
52: char *s;
53: { char outnams[24], outnaml[24];
54: fname[0] = 0;
55: cnt = 3;
56: if(fd != NULL)
57: fclose(fd);
58: if(outs != NULL)
59: fclose(outs);
60: if(outl != NULL)
61: fclose(outl);
62: sprintf(outnams, "X%s", s);
63: sprintf(outnaml, "%sL", s);
64: lastline = lineno = 0;
65: fd = fopen(s, "r");
66: if(fd == NULL) {
67: perror(s);
68: return(0);
69: }
70: outs = fopen(outnams, "w");
71: if(outs == NULL) {
72: perror(outnams);
73: return(0);
74: }
75: outl = fopen(outnaml, "w");
76: if(outl == NULL) {
77: perror(outnaml);
78: return(0);
79: }
80: curarg = s;
81: return(1);
82: }
83:
84: doarg()
85: { struct inst *x, *firstword();
86: state = SBBLK;
87: for(;;) {
88: (void) fgets(line, sizeof(line), fd);
89: if(feof(fd))
90: break;
91: for(ptr = line; isspace(*ptr); *ptr++)
92: ;
93: if(*ptr == 0 || *ptr == '#')
94: continue;
95: testlabel();
96: /* deal with symbol table info */
97: if(*ptr == '.') {
98: stab();
99: fprintf(outs, "%s", ptr);
100: continue;
101: }
102: if(*ptr == 0 || *ptr == '\n')
103: continue;
104: x = firstword();
105: if(x == 0)
106: continue;
107: if(state == SPRO)
108: prolog(x);
109: if(state == SINST)
110: tally(x);
111: if(state == SBBLK && (x->type & JUMP))
112: state = SINST;
113: outinstr();
114: if(x->type & BYTE)
115: fixinstr(x);
116: fprintf(outs, "%s", ptr);
117: }
118: finish();
119: }
120: /* unbelievable variability in sdb info */
121: stab()
122: { char buf[128];
123: int i, j, k;
124: if(state == SMAYBE && strncmp(ptr, ".word", 5) == 0) {
125: state = SPRO;
126: return;
127: }
128: if((i = *(ptr + 1)) != 's' && i != 'f' && i != 'l')
129: return;
130: /* real compiler output */
131: if(sscanf(ptr, ".stabs \"%[^\"]\", %o", buf, &i) == 2 && i == 0144)
132: strcat(fname, buf);
133: else if(sscanf(ptr, ".stabs \"%[^\"]\", 0x%x", buf, &i) == 2 && i == 0x64)
134: strcat(fname, buf);
135: else if(sscanf(ptr, ".stabd %o,%o,%o", &i, &j, &k) == 3 && i == 0104)
136: lineno = k;
137: else if(sscanf(ptr, ".stabd 0x%x,0,%d", &i, &k) == 2 && i == 0x44)
138: lineno = k;
139: /* pwb 3.0 */
140: else if(sscanf(ptr, ".stab %[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%d",
141: buf, buf+2, buf+4, buf+6, buf+8, buf+10, buf+12, buf+14, &i)
142: == 9 && i == 144) {
143: for(i = k = 0; buf[i] ; i++)
144: if(buf[i] == '\'')
145: buf[k++] = buf[++i];
146: buf[k] = 0;
147: strcat(fname, buf);
148: }
149: else if(sscanf(ptr, ".stab %[0,]%d,%d,%d", buf,&i, &j, &k) == 4
150: && i == 104)
151: lineno = k;
152: /* pwb 5.0 */
153: else if(sscanf(ptr," .file \"%[^\"]\"", buf) == 1)
154: strcat(fname, buf);
155: else if(sscanf(ptr, " .ln %d",&k) == 1)
156: lineno = k;
157: }
158:
159: testlabel()
160: { char *p;
161: again:
162: for(p = ptr; *p; p++) {
163: if(*p == ':')
164: break;
165: if(isalnum(*p) || *p == '_')
166: continue;
167: if(p > ptr && *p == '.') /* f77 */
168: continue;
169: return;
170: }
171: if(*p == 0)
172: return;
173: *p++ = 0; /* that is overwriting the : */
174: fprintf(outs, "%s:\n", ptr);
175: if(*ptr == '_') {
176: state = SMAYBE;
177: strcpy(curfunc, ptr);
178: }
179: else
180: if(state != SPRO)
181: state = SINST;
182: for(ptr = p; isspace(*ptr); ptr++)
183: ;
184: goto again; /* L68:L70: ... */
185: }
186:
187: struct inst *
188: firstword()
189: { char buf[sizeof(line)], *p, *q;
190: struct inst *x;
191: for(p = buf, q = ptr; isalnum(*q); )
192: *p++ = *q++;
193: if(p == buf)
194: return((struct inst *)0);
195: *p = 0;
196: for(x = index[buf[0]]; x && x->iname[0] == buf[0]; x++)
197: if(strcmp(buf, x->iname) == 0)
198: return(x);
199: return(0);
200: }
201:
202: tally(x)
203: struct inst *x;
204: {
205: if(x->type & E)
206: fprintf(outs, "incl locprof+%d\n", 4*cnt++);
207: else {
208: fprintf(outs, "movpsl -(sp)\n");
209: fprintf(outs, "incl locprof+%d\n", 4*cnt++);
210: fprintf(outs, "movw (sp)+,(sp)\n");
211: fprintf(outs, "bicpsw $0xff\n");
212: fprintf(outs, "bispsw (sp)+\n");
213: /* thanks to kirk mckusick */
214: }
215: state = SBBLK;
216: }
217:
218: outinstr()
219: { int i;
220: for(i = lastline + 1; i <= lineno; i++)
221: fprintf(outl, "%d %s: %d\n", 4*(cnt - 1), fname, i);
222: lastline = lineno;
223: fprintf(outl, "%d %s", 4*(cnt - 1), ptr);
224: }
225:
226: prolog(x) /* no liveness test, presumes can't get here by jump */
227: struct inst *x;
228: { int i;
229: fprintf(outs, ".data\n");
230: fprintf(outs, ".comm _proFptr,4\n"); /* the global chain */
231: fprintf(outs, ".text\n");
232: fprintf(outs, "tstl locprof+4\n");
233: fprintf(outs, "bneq L%da\n", i = cnt);
234: fprintf(outs, "movl _proFptr,locprof+4\n");
235: fprintf(outs, "moval locprof,_proFptr\n");
236: fprintf(outs, "L%da: incl locprof+%d\n", i, 4*cnt++);
237: state = SBBLK;
238: fprintf(outl, "%d %s: %s\n", 4*(cnt-1), fname, curfunc);
239: }
240:
241: finish()
242: { int i;
243: fprintf(outs, ".data\n");
244: fprintf(outs, "locprof: .long %d\n", cnt);
245: fprintf(outs, ".long 0\n");
246: fprintf(outs, ".long L%db\n", cnt);
247: fprintf(outs, ".space %d\n", 4 * cnt);
248: fprintf(outs, "L%db: .byte ", cnt);
249: for(i = 0; curdir[i]; i++)
250: fprintf(outs, "0x%x,", curdir[i]);
251: fprintf(outs, "0x%x\n", '/');
252: fprintf(outs, ".byte ");
253: if(fname[0])
254: for(i = 0; fname[i]; i++)
255: fprintf(outs, "0x%x,", fname[i]);
256: else
257: for(i = 0; curarg[i]; i++)
258: fprintf(outs, "0x%x,", curarg[i]);
259: fprintf(outs, "0\n");
260: }
261:
262: fixinstr(x)
263: struct inst *x;
264: {
265: if(x->iname[0] == 'b')
266: *ptr = 'j'; /* let assembler worry about branches */
267: /* this is where the code for aob and sob goes */
268: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.