File:  [Research Unix] / researchv10no / cmd / ccom / vax / tests / 8.i
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:21:35 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv10, HEAD
researchv10 Norman

/* gencode.c */
extern	struct	_iobuf {
	int	_cnt;
	unsigned char	*_ptr;
	unsigned char	*_base;
	short	_flag;
	char	_file;
} _iob[20];
struct _iobuf	*fopen();
struct _iobuf	*fdopen();
struct _iobuf	*freopen();
long	ftell();
char	*fgets();
	char		*hash();
	char		*savestr();
	char		*tstr();
	extern int	tstrused;
	extern char	*tstrbuf[];
	extern char	**curtstr;
extern int nerrors;  
typedef union ndu NODE;
typedef unsigned int TWORD;
typedef long CONSZ;  
extern int dope[];  
extern char *opst[];  
union ndu {
	struct {
		int op;
		int goal;
		TWORD type;
		int cst[(6+4)];
		char * name;
		char pad[8  -sizeof(char *)];	
		NODE *left;
		NODE *right;
	}in;	
	
	struct {
		int op;
		int goal;
		TWORD type;
		int cst[(6+4)];
		char * name;
		char pad[8  -sizeof(char *)];	
		CONSZ lval;
		int rval;
	}tn;	
	
	struct {
		int op;
		int goal;
		TWORD type;
		int cst[(6+4)];
		int label;  
		int lop;  
	}bn;	
	struct {
		int op;
		int goal;
		TWORD type;
		int cst[(6+4)];
		int stsize;  
		short stalign;  
		short argsize;  
	}stn;	
	struct {
		int op;
		int goal;
		TWORD type;
		int cdim;
		int csiz;
	}fn;	
	
	struct {
		
		int op;
		int goal;
		TWORD type;
		int cdim;
		int csiz;
		double dval;
	}fpn;	
};
extern int busy[];
extern NODE node[];
typedef struct shape SHAPE;
	
extern struct shape {
	int	op;	
	SHAPE	*sl;	
	SHAPE	*sr;
	int	sh;	
	int	sc;	
} shapes[];
extern SHAPE	*pshape[];
typedef struct optab OPTAB;
struct optab {
	int	op;	
	int	tyop;	
	OPTAB	*nextop;
	SHAPE	**lshape;	
	int	ltype;		
	SHAPE	**rshape;	
	int	rtype;
	int	needs;
	int	rewrite;
	char	*cstring;
	int	cost;
	int	lcount;		
	int	rcount;		
	int	stinline;	
};
extern OPTAB
	*match(),
	*ophead[],
	table[];
extern NODE resc[];
extern int tmpoff;
extern int maxboff;
extern int maxtemp;
extern int maxarg;
extern int ftnno;
extern int sideff;
extern NODE
	*talloc(),
	*ind2type(),
	*tcopy(),
	*getadr(),
	*getlr();
extern CONSZ rdin();
extern char *rnames[];
extern int lineno;
extern char ftitle[];
extern int fldshf, fldsz;
extern int lflag, udebug, e2debug, odebug, rdebug, radebug, sdebug;
extern int fast;  
typedef struct inst INST;
struct inst {
	NODE	*p;
	OPTAB	*q;
	int	goal;
};
extern INST inst[300];
extern nins;
typedef SHAPE	*SHTABLE[2][20];
extern SHTABLE	sha;
typedef struct {
	unsigned char ans;
	unsigned char regmask;
	unsigned short flag;
} ret;
ret doit(), allocreg(), reg0(), indir(), tostack();
char *genjmp();
char bufs[128][64];
char *buf;
char prbuf[10240];
char *prptr;
NODE *copytree(), *gimmenode();
extern int ntree;
typedef int jmp_buf[10];
jmp_buf back;
int acnt;
gencode(p)
NODE *p;
{	NODE *q;
	if(setjmp(back)) {
		pr("#\treg\t%d\n", ++acnt);
		if(acnt > 20) {
			prtree(q);
			outpr();
			return;
		}
	}
	else
		q = copytree(p);
	buf = bufs[1];
	prptr = prbuf;
	(void) doit(q, 0, 0, 0x3f);
	acnt = ntree = 0;
	outpr();
}
ret
doit(p, flag, dest, regmask)
NODE *p;
ret dest;
{	ret s, t, x;
	char *pp;
	NODE snode, *q;
	int i, j;
	switch(p->in.op) {
	default:
		pr("#\tweird??? %d\n", p->in.op);
		return(dest);
	case 1+ 14:
		flag |= 256;
		flag &= ~1;
	case 14:
		
		t = doit(p->in.left, 2, 0, regmask);
		regmask &= ~t.regmask;
		s = doit(p->in.right, 2, 0, regmask);
		if(s.flag & 1024) {
			totemp(p, 0);
			longjmp(back, 1);
		}
		regmask &= ~s.regmask;
		if(flag & 1) {
			pr("#\tbit%c\t%s,%s\n", childtype(p), 	bufs[s.ans], 	bufs[t.ans]);
			dest.ans = 0;
			dest.flag = 1;
			dest.regmask = 0;
			return(dest);
		}
		if(flag & 256)
			dest = x = t;
		if(dest.ans == 0)
			if(s.flag & 16)
				dest = x = s;
			else if(t.flag & 16)
				dest = x = t;
			else
				dest = x = allocreg(p, regmask);
		else
			x = allocreg(p, regmask);
		if(p->in.right->in.op == 4) {
			x = tostack();	
			sprintf(	bufs[x.ans], "$%d", -p->in.right->tn.lval - 1);
		}
		else
			pr("#\tmcom%c\t%s,%s\n", childtype(p), 	bufs[s.ans], 	bufs[x.ans]);
		if(strcmp(	bufs[t.ans], 	bufs[dest.ans]) == 0)
			pr("#\tbic%c2\t%s,%s\n", childtype(p), 	bufs[x.ans], 	bufs[dest.ans]);
		else
			pr("#\tbic%c3\t%s,%s,%s\n", childtype(p), 	bufs[x.ans],
					bufs[t.ans], 	bufs[dest.ans]);
		dest.flag |= 1;
		return(dest);
	case 70:
call:
		funargs(p->in.right, regmask);
		i = p->stn.argsize/32;
called:
		s = doit(p->in.left, 2|8, 0, regmask & ~3);
		pp = 	bufs[s.ans];
aftercall:
		if(regmask != 0x3f) {
			s.flag = 1024;
			return(s);
		}
		x = reg0(p, regmask);
		pr("#\tcalls\t$%d,%s\n", i, pp);
		if(p->in.op == 100 || p->in.op == 2+ 100 || (flag & 8)) {
			strcat(	bufs[x.ans], ")");
			strshift(	bufs[x.ans], 1);
				bufs[x.ans][0] = '(';
		}
		if(dest.ans == 0)
			if(flag & 256)
				dest = doit(p->in.left->in.op == 104?
					p->in.left->in.left:
					p->in.left, 0, 0, regmask & ~x.regmask);
			else
				return(x);
movexdest:	
		if(strcmp(	bufs[x.ans], 	bufs[dest.ans]) == 0)
			return(x);
		if(flag & 4)
			pr("#\tpush%c\t%s\n", type(p), 	bufs[x.ans]);
		else
			pr("#\tmov%c\t%s,%s\n", type(p), 	bufs[x.ans], 	bufs[dest.ans]);
		dest.flag |= 1;
		return(dest);
	case 111:
		s = doit(p->in.left, 2, 0, regmask);
		regmask &= ~s.regmask;
		t = doit(p->in.right, 2, 0, regmask);
		if(t.flag & 1024) {
			totemp(p, 0);
			longjmp(back, 1);
		}
		pr("#\tcmp%c\t%s,%s\n", childtype(p), 	bufs[s.ans], 	bufs[t.ans]);
		dest.ans = dest.regmask = 0;
		dest.flag = 1;
		return(dest);
	case 59:	
		if(p->in.left->in.op == 108) {
			if(dest.ans == 0) {
				dest = allocreg(p, regmask);
			}
			(void) doit(p->in.left, 2, dest, regmask);
		}
		else
			(void) doit(p->in.left, 0, 0, regmask);
		s = doit(p->in.right, 2, dest, regmask);
		if(flag & 8) {
			dest.ans = 0;
			i = (s.flag & (128|512|16));
			j = s.regmask;
			buf = 	bufs[s.ans];
			goto convbuf;
		}
		return(s);
	case 77:
		s = doit(p->in.left, 2, 0, regmask);
		if(dest.ans == 0)
			if(s.flag & 16)
				dest = s;
			else
				dest = allocreg(p, regmask & ~s.regmask);
		pr("#\tmcom%c\t%s,%s\n", childtype(p), 	bufs[s.ans], 	bufs[dest.ans]);
		dest.flag |= 1;
		return(dest);
	case 104:
		if(p->in.left->in.op == 58 && p->in.left->in.left->in.op == (2+ 11)) {
			if(dest.ans == 0) {
				dest = allocreg(p, regmask);
				s = doit(p->in.left, 2, dest, regmask);
			}
			else {
				x = allocreg(p, regmask);
				s = doit(p->in.left, 2, x, regmask & ~x.regmask);
			}
		}
		else
			s = doit(p->in.left, 2, 0, regmask);
		regmask &= ~s.regmask;
		if(childtype(p) == type(p))
			return(s);
		if(dest.ans == 0)
			if(s.flag & 16)
				dest = s;
			else
				dest = allocreg(p, regmask);
		if(isunsigned(p->in.left) && incrsize(p) > incrsize(p->in.left)
			&& type(p) != 'f' && type(p) != 'd')
			pp = "movz";	
		else
			pp = "cvt";
		pr("#\t%s%c%c\t%s,%s\n", pp, childtype(p), type(p), 	bufs[s.ans], 	bufs[dest.ans]);
		dest.flag |= 1;
		return(dest);
	case 79:
		i = -1;
		pp = "sub";
incrop:
		if(p->in.right->in.op != 4)
			fflush((&_iob[1])), cerror("codegen! incrop not with ICON");
		s = doit(p->in.left, 0, 0, regmask);
		t = doit(p->in.right, 0, 0, 0);
		if(flag & 2) {
			if(dest.ans == 0)
				dest = allocreg(p, regmask & ~s.regmask);
			pr("#\tmov%c\t%s,%s\n", childtype(p), 	bufs[s.ans], 	bufs[dest.ans]);
			if(t.flag & 64) {
				if(i == 1)
					pp = "inc";
				else
					pp = "dec";
				pr("#\t%s%c\t%s\n", pp, childtype(p), 	bufs[s.ans]);
			}
			else
				pr("#\t%s%c2\t%s,%s\n", pp, childtype(p),
						bufs[t.ans], 	bufs[s.ans]);
			if(flag & 8) {
				s = dest;
				goto inreg;
			}
			dest.flag &= ~1;
			return(dest);
		}
		if(t.flag & 64) {
			if(i == 1)
				pp = "inc";
			else
				pp = "dec";
			pr("#\t%s%c\t%s\n", pp, childtype(p), 	bufs[s.ans]);
		}
		else
			pr("#\t%s%c2\t%s,%s\n", pp, childtype(p), 	bufs[t.ans], 	bufs[s.ans]);
		if(dest.ans) {
			x = s;
			goto movexdest;
		}
		s.flag |= 1;
		return(s);
	case 1+ 60:
		flag |= 256;
	case 60:
		
		if(!isunsigned(p->in.left)) {
			if(p->in.left->in.op == 104 && type(p) == childtype(p->in.left)) {
				p->in.left = p->in.left->in.left;
			}
			if(p->in.right->in.op == 104 && type(p) == childtype(p->in.right)) {
				p->in.right = p->in.right->in.left;
			}
			pp = "div";
			goto binop;
		}
		pp = "udiv";
unsdiv:
		if(incrsize(p->in.right) != 4) {
			snode.in.op = 104;
			snode.in.left = p->in.right;
			snode.in.type = 	01000;
			s = doit(&snode, 2|4, tostack(), regmask);
		}
		else
			s = doit(p->in.right, 4, tostack(), regmask);
		regmask &= ~s.regmask;
		if(incrsize(p->in.left) != 4) {		
			snode.in.op = 104;
			snode.in.left = p->in.left;
			snode.in.type = 	01000;
			t = doit(&snode, 2|4, tostack(), regmask);
		}
		else
			t = doit(p->in.left, 4, tostack(), regmask);
		if(t.flag & 1024) {
			totemp(p, 1);
			longjmp(back, 1);
		}
		i = 2;
		goto aftercall;
	case 1+ 19:
		flag |= 256;
	case 19:
		pp = "xor";
binop:
		t = doit(p->in.left, 2, 0, regmask);
		regmask &= ~t.regmask;
		s = doit(p->in.right, 2, 0, regmask);
		if(s.flag & 1024) {
			totemp(p, 0);
			longjmp(back, 1);
		}
		regmask &= ~s.regmask;
		if(type(p) != childtype(p)) {
			x = allocreg(p, regmask);
			pr("#\t%s%c3\t%s,%s,%s\n", pp, childtype(p), 	bufs[s.ans],
					bufs[t.ans], 	bufs[x.ans]);
			if(dest.ans == 0)
				dest = x;
			pr("#\tcvt%c%c\t%s,%s\n", childtype(p), type(p),
					bufs[x.ans], 	bufs[dest.ans]);
			dest.flag |= 1;
			return(dest);
		}	
		if(dest.ans == 0)	
			if((t.flag & 16) || (flag & 256)) {
twoop:
				dest = t;
				if(*pp == 'a' && (s.flag & 64))
					pr("#\tinc%c\t%s\n", childtype(p), 	bufs[t.ans]);
				else if(*pp == 's' && (s.flag & 64))
					pr("#\tdec%c\t%s\n", childtype(p), 	bufs[t.ans]);
				else
					pr("#\t%s%c2\t%s,%s\n", pp, childtype(p),
							bufs[s.ans], 	bufs[t.ans]);
				if(flag & 8)
					goto binopaddr;
				dest.flag |= 1;
				return(dest);
			}
			else if(s.flag & 16)
				dest = s;
			else
				dest = allocreg(p, regmask);
		if((*pp == 'a' || *pp == 'm' || *pp == 'x' || *pp == 'b')
			&& strcmp(	bufs[s.ans], 	bufs[dest.ans]) == 0) {
			dest = s;
			s = t;
			t = dest;
			goto twoop;
		}
		pr("#\t%s%c3\t%s,%s,%s\n", pp, childtype(p), 	bufs[s.ans], 	bufs[t.ans], 	bufs[dest.ans]);
binopaddr:
		if(flag & 8) {
			if(dest.flag & 128) {
				strcat(	bufs[dest.ans], ")");
				strshift(	bufs[dest.ans], 1);
					bufs[dest.ans][0] = '(';
				return(dest);
			}
			if(dest.flag & 512) {
				strshift(	bufs[dest.ans], 1);
					bufs[dest.ans][0] = '*';
				dest.flag &= ~512;
				return(dest);
			}
			dest.flag = 1024;	
			return(dest);
		}
		dest.flag |= 1;
		return(dest);	
	case 103:
		
		s = doit(p->in.left, 0, 0, regmask);
		if(dest.ans == 0)
			dest = allocreg(p, regmask & ~s.regmask);
		pr("#\text%sv\t$%d,$%d,%s,%s\n", isunsigned(p->in.left)? "z": "",
			p->tn.rval/64, p->tn.rval%64, 	bufs[s.ans], 	bufs[dest.ans]);
		dest.flag |= 1;
		return(dest);
	case 110:
		s = doit(p->in.left, 1|2, 0, regmask);
		pp = genjmp(p->bn.lop);
		if(s.flag & 1)
			pr("#\t%s\tL%d\n", pp, p->bn.label);
		else
			pr("#\ttst%c\t%s\n#\t%s\tL%d\n", childtype(p), 	bufs[s.ans],
				pp, p->bn.label);
		s.flag |= 1;
		return(s);
	case 108:
		s = doit(p->in.left, flag, dest, regmask);
		pr("#L%d:\n", p->bn.label);
		return(s);
	case 112:
		(void) doit(p->in.left, 0, dest, regmask);
		pr("#\tjbr\tL%d\n", p->bn.label);
		s.ans = s.regmask = s.flag = 0;
		return(s);
	case 4:
		if(p->tn.name)
			if(p->tn.lval)
				sprintf(buf, "%s+%d", p->tn.name, p->tn.lval);
			else
				sprintf(buf, "%s", p->tn.name);
		else
			sprintf(buf, "%d", p->tn.lval);
		if(!(flag & 8)) {
			strshift(buf, 1);;
			buf[0] = '$';
		}
		i = 0;
		if(p->tn.name == 0)
			if(p->tn.lval == 0)
				i = 32;
			else if(p->tn.lval == 1)
				i = 64;
		j = 0;
convbuf:	
		if(dest.ans == 0) {
			if(p->in.op == 4 || !(flag & 8)) {
				 s.ans = (buf - bufs[0])/64; buf += 64; s.flag =  i; s.regmask =  j; return(s);
			}
			if(i & 512) {
				strshift(buf, 1);
				buf[0] = '*';
				 s.ans = (buf - bufs[0])/64; buf += 64; s.flag =  i & ~512; s.regmask =  j; return(s);
			}
			if(i & 128) {
				strcat(buf, ")");
				strshift(buf, 1);
				buf[0] = '(';
				 s.ans = (buf - bufs[0])/64; buf += 64; s.flag =  i; s.regmask =  j; return(s);
			}
			pp = buf;
			buf += 64;
			s = allocreg(p, regmask);
			pr("#\tmov%c\t%s,%s\n", type(p), pp, 	bufs[s.ans]);
			flag &= ~8;
			goto inreg;
		}
		if(flag & 4)
			if(p->in.type != 040)
				pr("#\tpushl\t%s\n", buf);
			else
				pr("#\tmovd\t%s,%s\n", buf, 	bufs[dest.ans]);
		else if(i & 32)
			pr("#\tclr%c\t%s\n", type(p), 	bufs[dest.ans]);
		else	
			pr("#\tmov%c\t%s,%s\n", type(p), buf, 	bufs[dest.ans]);
		dest.flag |= 1;
		return(dest);
	case 78:
		i = 1;
		pp = "add";
		goto incrop;
	case 113:	
		s = doit(p->in.left, 8, 0, 0);
		pr("#\t.long\t%s\n", 	bufs[s.ans]);
		return(dest);
	case 1+ 64:
		flag |= 256;
	case 64:
		s = doit(p->in.left, 2, 0, regmask);
		regmask &= ~s.flag;
		t = doit(p->in.right, 2, 0, regmask);
		if(t.flag & 1024) {
			totemp(p, 0);
			longjmp(back, 1);
		}
		regmask &= ~t.regmask;
		if(dest.ans == 0)
			if((s.flag & 16) || (flag & 256))
				dest = s;
			else
				dest = allocreg(p, regmask);
		pr("#\tashl\t%s,%s,%s\n", 	bufs[t.ans], 	bufs[s.ans], 	bufs[dest.ans]);
		dest.flag |= 1;
		return(dest);
	case 1+ 8:
		if(p->in.right->in.op == 4) {
			i = -1;
			pp = "sub";
			flag &= ~2;
			goto incrop;
		}
		flag |= 256;
	case 8:
		pp = "sub";
		goto binop;
	case 1+ 62:
		flag |= 256;
		if(p->in.left->in.op == 104 && !isunsigned(p)) {
			snode = *p;
			snode.in.left = p->in.left->in.left;
			p = &snode;
		}
	case 62:
		if(isunsigned(p)) {
			pp = "urem";
			goto unsdiv;
		}
		s = doit(p->in.left, 2, 0, regmask);
		regmask &= ~s.regmask;
		t = doit(p->in.right, 2, 0, regmask);
		regmask &= ~t.regmask;
		x = allocreg(p, regmask);
		pr("#\tdiv%c3\t%s,%s,%s\n", childtype(p), 	bufs[t.ans], 	bufs[s.ans], 	bufs[x.ans]);
		pr("#\tmul%c2\t%s,%s\n", childtype(p), 	bufs[t.ans], 	bufs[x.ans]);
		pr("#\tsub%c3\t%s,%s,%s\n", childtype(p), 	bufs[x.ans], 	bufs[s.ans], 	bufs[x.ans]);
		if(dest.ans)
			goto movexdest;
		if(flag & 256) {
			dest = s;
			goto movexdest;
		}
		x.flag |= 1;
		return(x);
	case 1+ 11:
		flag |= 256;
	case 11:
		pp = "mul";
		goto binop;
	case 2:	
		if(p->tn.lval)
			sprintf(buf, "%s+%d", p->tn.name, p->tn.lval);
		else if(p->tn.name)
			sprintf(buf, "%s", p->tn.name);
		else
			sprintf(buf, "0");
		j = 0;
		i = 512;
		goto convbuf;
	case 1+ 17:
		flag |= 256;
	case 17:
		pp = "bis";
		goto binop;
	case 1+ 6:
		if(p->in.right->in.op == 4) {
			i = 1;
			pp = "add";
			flag &= ~2;
			goto incrop;
		}
		flag |= 256;
	case 6:
		pp = "add";
		goto binop;
	case 94:
		sprintf(buf, "r%d", p->tn.rval);
		j = 0;
		i = 128;
		goto convbuf;
	case 118: case 119:
		x = reg0(p, 3);
		x.regmask = 0;
		if(dest.ans)
			goto movexdest;
		return(x);
	case 120:
		return(reg0(p, regmask));
	case 1+ 66:
		flag |= 256;
	case 66:
		s = doit(p->in.left, 2, 0, regmask);
		regmask &= ~s.regmask;
		if(dest.ans == 0)
			if((flag & 256) || (s.flag & 16))
				dest = s;
			else
				dest = allocreg(p, regmask);
		dest.flag |= 1;
		regmask &= ~dest.regmask;
		if(p->in.right->in.op == 4 && (i = p->in.right->tn.lval) >= 0) {
			pr("#\textv\t$%d,$%d,%s,%s\n", i, 32 - i, 	bufs[s.ans], 	bufs[dest.ans]);
			return(dest);
		}
		t = doit(p->in.right, 2, 0, regmask);
		regmask &= ~t.regmask;
		x = allocreg(p, regmask);
		pr("#\tmnegl\t%s,%s\n", 	bufs[t.ans], 	bufs[x.ans]);
		pr("#\tashl\t%s,%s,%s\n", 	bufs[x.ans], 	bufs[s.ans], 	bufs[dest.ans]);
		return(dest);
	case (2+ 11):
		switch(p->in.left->in.op) {
		case 116:
		case 117:
		case 2:
			s = doit(p->in.left, 2, 0, regmask);
			sprintf(buf, "*%s", 	bufs[s.ans]);
			j = i = 0;
			goto convbuf;
		case 94:
			s = doit(p->in.left, 2, 0, regmask);
inreg:
			if(s.flag & 128) {
				sprintf(buf, "(%s)", 	bufs[s.ans]);
				j = 0;
				i = 512;
				goto convbuf;
			}
			else if(s.flag & 512) {
				sprintf(buf, "*%s", 	bufs[s.ans]);
				j = 0;
				i = 0;
				goto convbuf;
			}
			else {
				s.flag = 1024;
				return(s);
			}
		}
		q = p->in.left;
		if(q->in.op == 78
			&& q->in.right->in.op == 4 && q->in.left->in.op == 94
			&& incrsize(p) == (int) q->in.right->tn.lval) {
			s = doit(q->in.left, 2, 0, regmask);
			sprintf(buf, "(%s)+", 	bufs[s.ans]);
			i = 0;
			j = s.regmask;
			goto convbuf;
		}
		if(q->in.op == 6 && q->in.left->in.op == 64
			&& q->in.left->in.right->in.op == 4
			&& shiftsize(p) == (int) q->in.left->in.right->tn.lval) {
			s = doit(q->in.left->in.left, 2, 0, regmask);
			regmask &= ~s.regmask;
			if(!(s.flag & 128)) {
				x = allocreg(p, regmask);
				pr("#\tmov%c\t%s,%s\n", childtype(q), 	bufs[s.ans], 	bufs[x.ans]);
				regmask |= s.regmask;
				regmask &= ~x.regmask;
				s = x;
			}
			t = doit(q->in.right, 8, 0, regmask);
			sprintf(buf, "%s[%s]", 	bufs[t.ans], 	bufs[s.ans]);
			i = 0;
			j = s.regmask;
			goto convbuf;
		}
		if(q->in.op == 6
			&& (q->in.right->in.op == 4 || q->in.right->in.op == 2)) {
			s = doit(q->in.left, 2, 0, regmask);
			regmask &= ~s.regmask;
			if(!(s.flag & 128)) {
				x = allocreg(p, regmask);
				pr("#\tmov%c\t%s,%s\n", childtype(q), 	bufs[s.ans], 	bufs[x.ans]);
				regmask |= s.regmask;
				regmask &= ~x.regmask;
				s = x;
			}
			t = doit(q->in.right, 8, 0, regmask);
			sprintf(buf, "%s(%s)", 	bufs[t.ans], 	bufs[s.ans]);
			i = 512;
			j = s.regmask;
			goto convbuf;
		}
		if(q->in.op == 8 && q->in.right->in.op == 4) {
			s = doit(q->in.left, 2, 0, regmask);
			regmask &= ~s.regmask;
			if(!(s.flag & 128)) {
				x = allocreg(p, regmask);
				pr("#\tmov%c\t%s,%s\n", childtype(q), 	bufs[s.ans], 	bufs[x.ans]);
				regmask |= s.regmask;
				regmask &= ~x.regmask;
				s = x;
				if(!(s.flag & 128)) {
					s.flag = 1024;
					return(s);
				}
			}
			sprintf(buf, "%d(%s)", -q->in.right->tn.lval, 	bufs[s.ans]);
			i = 512;
			j = s.regmask;
			goto convbuf;
		}
		if(q->in.op == 1+ 8
			&& q->in.right->in.op == 4 && q->in.left->in.op == 94
			&& incrsize(p) == (int) q->in.right->tn.lval) {
			s = doit(q->in.left, 2, 0, regmask);
			sprintf(buf, "-(%s)", 	bufs[s.ans]);
			i = 0;
			j = s.regmask;
			goto convbuf;
		}
		if(q->in.op == 6 && q->in.left->in.op == 94
			&& q->in.right->in.op == 94) {
			sprintf(buf, "(r%d)[r%d]", q->in.right->tn.rval,
				q->in.left->tn.rval);
			i = 0;
			j = 0;
			goto convbuf;
		}
		s = doit(p->in.left, 2, 0, regmask);
		if(s.flag & 1024)
			return(s);
		regmask &= ~s.regmask;
		if(s.flag & 512) {
			sprintf(buf, "*%s", 	bufs[s.ans]);
			i = 0;
			j = s.regmask;
			goto convbuf;
		}
		if(!(s.flag & 128)) {
			x = allocreg(p, regmask);
			pr("#\tmov%c\t%s,%s\n", childtype(q), 	bufs[s.ans], 	bufs[x.ans]);
			regmask |= s.regmask;
			regmask &= ~x.regmask;
			s = x;
		}
		if(!(s.flag & 128)) {
			s.flag = 1024;
			return(s);
		}
		sprintf(buf, "(%s)", 	bufs[s.ans]);
		i = 0;
		j = s.regmask;
		goto convbuf;
	case 98:
		if(p->stn.stsize/8 == 4) {
			i = 'l';
stasg:
			s = doit(p->in.right, 2|8, 0, regmask);
			regmask &= ~s.regmask;
			t = doit(p->in.left, 2|8, 0, regmask);
			pr("#\tmov%c\t%s,%s\n", i, 	bufs[s.ans], 	bufs[t.ans]);
			s.regmask = s.flag = 0;
			return(s);
		}
		else if(p->stn.stsize/8 == 8) {
			i = 'q';
			goto stasg;
		}
		if(regmask != 0x3f) {
			s.flag = 1024;
			return(s);
		}
		s = doit(p->in.right, 2|8, 0, regmask);
		regmask &= ~s.regmask;
		t = doit(p->in.left, 2|8, 0, regmask);
		pr("#\tmovc3\t$%d,%s,%s\n", p->stn.stsize/8, 	bufs[s.ans], 	bufs[t.ans]);
		s.regmask = s.flag = 0;
		return(s);
	case 100:
		goto call;
	case 116:
		sprintf(buf, "%d(fp)", p->tn.lval);
		j = 0;
		i = 512;
		goto convbuf;
	case 117:
		sprintf(buf, "%d(ap)", p->tn.lval);
		j = 0;
		i = 512;
		goto convbuf;
	case 2+ 14:
		s = doit(p->in.left, 0, 0, regmask);
		regmask &= ~s.regmask;
		if(dest.ans == 0) {
			dest = allocreg(p, regmask);
		}
		if(flag & 4)
			pr("#\tpushal\t%s\n", 	bufs[s.ans]);
		else {
			pr("#\tmova%c\t%s,%s\n", childtype(p), 	bufs[s.ans], 	bufs[dest.ans]);
		}
		if(flag & 8) {
			if(dest.flag & 128) {
				strcat(	bufs[dest.ans], ")");
				strshift(	bufs[dest.ans], 1);
					bufs[dest.ans][0] = '(';
			}
			else {
				strshift(	bufs[dest.ans], 1);
					bufs[dest.ans][0] = '*';
			}
		}
		return(dest);
	case 2+ 70:
		i = 0;
		goto called;
	case 2+ 8:
		s = doit(p->in.left, 2, 0, regmask);
		if(dest.ans == 0)
			if(s.flag & 16)
				dest = s;
			else
				dest = allocreg(p, regmask & ~s.regmask);
		pr("#\tmneg%c\t%s,%s\n", childtype(p), 	bufs[s.ans], 	bufs[dest.ans]);
		dest.flag |= 1;
		return(dest);
	case 2+ 100:
		i = 0;
		goto called;
	case 58:
		if(p->in.left->in.op == 120 && dest.ans) {
			s = doit(p->in.right, 2, dest, regmask);
			return(s);
		}
		if(p->in.left->in.op == 103) {
			s = doit(p->in.left->in.left, 0, 0, regmask);
			regmask &= ~s.regmask;
			if(p->in.right->in.op == 58) {
				x = allocreg(p->in.right, regmask);
				t = doit(p->in.right, 2, x, regmask & ~x.regmask);
			}
			else
				t = doit(p->in.right, 2, 0, regmask);
			if(t.flag & 1024) {
				totemp(p->in.left, 0);
				longjmp(back, 1);
			}
			pr("#\tinsv\t%s,$%d,$%d,%s\n", 	bufs[t.ans], p->in.left->tn.rval/64,
				p->in.left->tn.rval % 64, 	bufs[s.ans]);
			t.flag |= 1;
			return(t);
		}
		if(dest.ans && p->in.left->in.op == (2+ 11)) {
			if(dest.flag & 16)
				x = dest;
			else
				x = allocreg(p, regmask);
			s = doit(p->in.right, 2, x, regmask);
			regmask &= ~s.regmask;
assignit:
			t = doit(p->in.left, 0, 0, regmask);
			pr("#\tmov%c\t%s,%s\n", type(p), 	bufs[x.ans], 	bufs[t.ans]);
			if(strcmp(	bufs[x.ans], 	bufs[dest.ans]) == 0) {
				dest.flag |= 1;
				return(dest);
			}
			goto movexdest;
		}
		if(p->in.right->in.op == 119)
			t = doit(p->in.left, 0, 0, regmask & ~3);
		else
			t = doit(p->in.left, 0, 0, regmask);
		regmask &= ~t.regmask;
		s = doit(p->in.right, 2, t, regmask);
		if(s.flag & 1024) {
		
			if(dest.ans) {
				regmask |= t.regmask;
				s = doit(p->in.right, 2, t, regmask);
				if(s.flag & 1024)
					return(s);
			}
			asgwrite(p);
			longjmp(back, 1);
		}
		if(dest.ans) {
			x = s;
			goto movexdest;
		}
		else if(flag & 8) {
			i = (s.flag & (128|512|16));
			j = s.regmask;
			buf = 	bufs[s.ans];
			goto convbuf;
		}
		s.flag |= 1;
		return(s);
	}
}
char *
genjmp(n)
{
	switch(n) {
	default:
		return("jweird");
	case 80:
		return("jeql");
	case 81:
		return("jneq");
	case 85:
		return("jgtr");
	case 84:
		return("jgeq");
	case 83:
		return("jlss");
	case 82:
		return("jleq");
	case 89:
		return("jgtru");
	case 88:
		return("jgequ");
	case 87:
		return("jlssu");
	case 86:
		return("jlequ");
	}
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.