V10/cmd/lcomp/5bb.c

Compare this file to the similar file:
Show the results in this format:

#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, "0 %s: %d\n", 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, "0 %s: %d\n", 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
}