V10/cmd/lcomp/prof.mail
From rabbit!groucho!dcb Tue Sep 4 15:59 EDT 1984
#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 */
#define MAXLA 5 /* max no. of lines that can be read for lookahead */
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 labuf[5][256]; /* look ahead needed for 5.0 stab entries */
int lastla, lookahead;
char begfcn[] = " .def .bf"; /* 5.0 stab entry */
int lineno, lastline;
int base=0;
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;
lookahead = 0; /* empty buffer */
lastla = 0;
for(;;) {
if (lookahead != lastla){
strcpy(line,labuf[ (lookahead++) % MAXLA ] );
if (lookahead == lastla) lookahead = lastla = 0;
}
else
(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){
printf("unknown inst: %s\n",ptr);
continue;
}
#ifdef u3b
if ((state == SMAYBE) && !strncmp(ptr,"save",4)){
state = SPRO;
getlnum(); /* 5.0 true line # */
}
#endif
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();
}
getlnum(){ /* get true line number from 5.0 sdb info */
char *la;
int l;
/* get true line number by looking ahead */
/* this is necessary for 5.0 sdb output */
do
(void) fgets(labuf[l = ((lastla++)%MAXLA)], sizeof(line), fd);
while (!feof(fd) && strncmp(begfcn, labuf[l],
9) && (lookahead != (lastla)%MAXLA ));
if ( strncmp(begfcn, labuf[l], 9) )
return; /* bad input or not 5.0 */
la = labuf[l];
while ( *la != '\0' ){
while ( *la != ';' && *la != '\0') la++;
if ( *la == ';' ) la++;
while ( isspace(*la) ) la++;
if ( !strncmp(la, ".line" , 5) ){
lineno = base = atoi( la + 5 );
return;
}
}
}
/* unbelievable variability in sdb info */
stab()
{ char buf[128];
int i, j, k;
#ifndef u3b
if(state == SMAYBE && strncmp(ptr, ".word", 5) == 0) {
state = SPRO;
getlnum();
return;
}
#endif
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, ".stabd %o,%o,%o", &i, &j, &k) == 3 && i == 0104)
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 + base - 1;
}
testlabel()
{ char *p;
int i;
for(;;){
for(p = ptr; *p; p++) {
if(*p == ':')
break;
if(!isalnum(*p) && *p != '_' && *p != '.')
return;
}
if(*p == 0)
return;
*p++ = 0; /* that is overwriting the : */
fprintf(outs, "%s:\n", ptr);
if (lineno != lastline){
for (i=lastline+1; i < lineno ; i++) /* allign label with right inst */
fprintf(outl, "%d %s: %d\n", 4*(cnt-1), fname, i);
lastline = lineno - 1;
}
fprintf(outl, "%d %s:\n", 4*(cnt - 1), ptr);
#ifdef u3b
if(*ptr != '.')
#else
if(*ptr == '_' )
#endif
state = SMAYBE;
else
if(state != SPRO)
state = SINST;
for(ptr = p; isspace(*ptr); ptr++)
;
} /* 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);
}
outinstr()
{ int i;
for(i = lastline + 1; i < lineno; i++)
fprintf(outl, "%d %s: %d\n", 4*(cnt - 1), fname, i);
if (lastline != lineno){
fprintf(outl, "%d %s: %d\n", 4*(cnt - 1), fname, lineno);
lastline = lineno;
}
fprintf(outl, "%d %s", 4*(cnt - 1), ptr);
}
#ifdef u3b
/* 3b code ***********************************/
tally(x)
struct inst *x;
{
if(x->type & E)
fprintf(outs, " addw2 &1,locprof+%d\n", 4*cnt++);
else {
fprintf(outs, " stsm &1,savecc\n");
fprintf(outs, " gcc %%r0\n");
fprintf(outs, " addw2 &1,locprof+%d\n", 4*cnt++);
fprintf(outs, " scc %%r0\n");
fprintf(outs, " lsm &1,savecc\n");
}
state = SBBLK;
}
prolog(x) /* no liveness test, presumes can't get here by jump */
struct inst *x;
{ int i;
fprintf(outs, " .data\n");
fprintf(outs, " .globl proFptr\n"); /* the global chain */
fprintf(outs, " .globl savecc\n");
fprintf(outs, " .text\n");
fprintf(outs, " cmpw &0,locprof+4\n");
fprintf(outs, " jne .L%da\n", i = cnt);
fprintf(outs, " movw proFptr,locprof+4\n");
fprintf(outs, " movaw locprof,proFptr\n");
fprintf(outs, ".L%da: addw2 &1,locprof+%d\n", i, 4*cnt++);
state = SBBLK;
}
finish()
{ int i;
fprintf(outs, " .data\n");
fprintf(outs, " .align 4\n");
fprintf(outs, "locprof:\n");
fprintf(outs, " .word %d\n", cnt);
fprintf(outs, " .word 0\n");
fprintf(outs, " .word .L%db\n", cnt);
fprintf(outs, " .zero %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");
}
#else
/* Vax code **************************/
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;
}
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");
/*if(!(x->type & E))
fprintf(outs, " movpsl -(sp)\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++);
/*if(!(x->type & E)) {
fprintf(outs, " movw (sp)+,(sp)\n");
fprintf(outs, " bicpsw $0xff\n");
fprintf(outs, " bispsw (sp)+\n");
}*/
state = SBBLK;
}
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");
}
#endif
fixinstr(x)
struct inst *x;
{
#ifndef u3b
if(x->iname[0] == 'b')
*ptr = 'j'; /* let assembler worry about branches */
/* this is where the code for aob and sob goes */
#endif
}