|
|
researchv10 Norman
#define unsafe 1 /* pretend killing all but C is as good as killing
* all condition codes */
#ifdef unsafe
#define E (C|K)
#else
#define E K
#endif
#include "stdio.h"
#include "instr.c"
#include "ctype.h"
struct inst *index[128];
#define SBBLK 1 /* looking for the start of a basic block */
#define SINST 2 /* thinking about generating a tally */
#define SPRO 3 /* thinking about generating prolog code */
#define SMAYBE 4 /* seen _, thinking about SPRO */
FILE *outs, *fd, *outl; /* outs goes to assembler, outl is for listing */
extern FILE *popen();
char line[256], fname[256]; /* file names must fit in fname */
char curfunc[256];
int lineno, lastline;
int cnt;
int state = SBBLK;
char *ptr, *curarg;
char curdir[256];
main(argc, argv)
char **argv;
{ int i;
if(argc <= 1) {
fprintf(stderr, "no files given\n");
exit(1);
}
for(i = 0; insts[i].iname; i++)
;
for(; i >= 0; i--)
index[insts[i].iname[0]] = insts + i;
fd = popen("pwd", "r");
for(i = 0; i < sizeof(curdir) && !feof(fd); i++)
curdir[i] = getc(fd);
curdir[i-2] = 0; /* thisdir\n */
fclose(fd);
for(i = 1; i < argc; i++) {
if(setfd(argv[i])) /* fix fd, outs, outl */
doarg(); /* do the work */
}
exit(0);
}
setfd(s)
char *s;
{ char outnams[24], outnaml[24];
fname[0] = 0;
cnt = 3;
if(fd != NULL)
fclose(fd);
if(outs != NULL)
fclose(outs);
if(outl != NULL)
fclose(outl);
sprintf(outnams, "X%s", s);
sprintf(outnaml, "%sL", s);
lastline = lineno = 0;
fd = fopen(s, "r");
if(fd == NULL) {
perror(s);
return(0);
}
outs = fopen(outnams, "w");
if(outs == NULL) {
perror(outnams);
return(0);
}
outl = fopen(outnaml, "w");
if(outl == NULL) {
perror(outnaml);
return(0);
}
curarg = s;
return(1);
}
doarg()
{ struct inst *x, *firstword();
state = SBBLK;
for(;;) {
(void) fgets(line, sizeof(line), fd);
if(feof(fd))
break;
for(ptr = line; isspace(*ptr); *ptr++)
;
if(*ptr == 0 || *ptr == '#')
continue;
testlabel();
/* deal with symbol table info */
if(*ptr == '.') {
stab();
fprintf(outs, "%s", ptr);
continue;
}
if(*ptr == 0 || *ptr == '\n')
continue;
x = firstword();
if(x == 0)
continue;
if(state == SPRO)
prolog(x);
if(state == SINST)
tally(x);
if(state == SBBLK && (x->type & JUMP))
state = SINST;
outinstr();
if(x->type & BYTE)
fixinstr(x);
fprintf(outs, "%s", ptr);
}
finish();
}
/* unbelievable variability in sdb info */
stab()
{ char buf[128];
int i, j, k;
if(state == SMAYBE && strncmp(ptr, ".word", 5) == 0) {
state = SPRO;
return;
}
if((i = *(ptr + 1)) != 's' && i != 'f' && i != 'l')
return;
/* real compiler output */
if(sscanf(ptr, ".stabs \"%[^\"]\", %o", buf, &i) == 2 && i == 0144)
strcat(fname, buf);
else if(sscanf(ptr, ".stabs \"%[^\"]\", 0x%x", buf, &i) == 2 && i == 0x64)
strcat(fname, buf);
else if(sscanf(ptr, ".stabd %o,%o,%o", &i, &j, &k) == 3 && i == 0104)
lineno = k;
else if(sscanf(ptr, ".stabd 0x%x,0,%d", &i, &k) == 2 && i == 0x44)
lineno = k;
/* pwb 3.0 */
else if(sscanf(ptr, ".stab %[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%d",
buf, buf+2, buf+4, buf+6, buf+8, buf+10, buf+12, buf+14, &i)
== 9 && i == 144) {
for(i = k = 0; buf[i] ; i++)
if(buf[i] == '\'')
buf[k++] = buf[++i];
buf[k] = 0;
strcat(fname, buf);
}
else if(sscanf(ptr, ".stab %[0,]%d,%d,%d", buf,&i, &j, &k) == 4
&& i == 104)
lineno = k;
/* pwb 5.0 */
else if(sscanf(ptr," .file \"%[^\"]\"", buf) == 1)
strcat(fname, buf);
else if(sscanf(ptr, " .ln %d",&k) == 1)
lineno = k;
}
testlabel()
{ char *p;
again:
for(p = ptr; *p; p++) {
if(*p == ':')
break;
if(isalnum(*p) || *p == '_')
continue;
if(p > ptr && *p == '.') /* f77 */
continue;
return;
}
if(*p == 0)
return;
*p++ = 0; /* that is overwriting the : */
fprintf(outs, "%s:\n", ptr);
if(*ptr == '_') {
state = SMAYBE;
strcpy(curfunc, ptr);
}
else
if(state != SPRO)
state = SINST;
for(ptr = p; isspace(*ptr); ptr++)
;
goto again; /* L68:L70: ... */
}
struct inst *
firstword()
{ char buf[sizeof(line)], *p, *q;
struct inst *x;
for(p = buf, q = ptr; isalnum(*q); )
*p++ = *q++;
if(p == buf)
return((struct inst *)0);
*p = 0;
for(x = index[buf[0]]; x && x->iname[0] == buf[0]; x++)
if(strcmp(buf, x->iname) == 0)
return(x);
return(0);
}
tally(x)
struct inst *x;
{
if(x->type & E)
fprintf(outs, "incl locprof+%d\n", 4*cnt++);
else {
fprintf(outs, "movpsl -(sp)\n");
fprintf(outs, "incl locprof+%d\n", 4*cnt++);
fprintf(outs, "movw (sp)+,(sp)\n");
fprintf(outs, "bicpsw $0xff\n");
fprintf(outs, "bispsw (sp)+\n");
/* thanks to kirk mckusick */
}
state = SBBLK;
}
outinstr()
{ int i;
for(i = lastline + 1; i <= lineno; i++)
fprintf(outl, "%d %s: %d\n", 4*(cnt - 1), fname, i);
lastline = lineno;
fprintf(outl, "%d %s", 4*(cnt - 1), ptr);
}
prolog(x) /* no liveness test, presumes can't get here by jump */
struct inst *x;
{ int i;
fprintf(outs, ".data\n");
fprintf(outs, ".comm _proFptr,4\n"); /* the global chain */
fprintf(outs, ".text\n");
fprintf(outs, "tstl locprof+4\n");
fprintf(outs, "bneq L%da\n", i = cnt);
fprintf(outs, "movl _proFptr,locprof+4\n");
fprintf(outs, "moval locprof,_proFptr\n");
fprintf(outs, "L%da: incl locprof+%d\n", i, 4*cnt++);
state = SBBLK;
fprintf(outl, "%d %s: %s\n", 4*(cnt-1), fname, curfunc);
}
finish()
{ int i;
fprintf(outs, ".data\n");
fprintf(outs, "locprof: .long %d\n", cnt);
fprintf(outs, ".long 0\n");
fprintf(outs, ".long L%db\n", cnt);
fprintf(outs, ".space %d\n", 4 * cnt);
fprintf(outs, "L%db: .byte ", cnt);
for(i = 0; curdir[i]; i++)
fprintf(outs, "0x%x,", curdir[i]);
fprintf(outs, "0x%x\n", '/');
fprintf(outs, ".byte ");
if(fname[0])
for(i = 0; fname[i]; i++)
fprintf(outs, "0x%x,", fname[i]);
else
for(i = 0; curarg[i]; i++)
fprintf(outs, "0x%x,", curarg[i]);
fprintf(outs, "0\n");
}
fixinstr(x)
struct inst *x;
{
if(x->iname[0] == 'b')
*ptr = 'j'; /* let assembler worry about branches */
/* this is where the code for aob and sob goes */
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.