V8/usr/src/cmd/PDP11/11as/as27.c

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

/*  a7 -- pdp-11 assembler pass 2 */
#include "as2.h"

#define M -1
#define X -2
char reltp2[6][6] = {
	T_UNDEF, T_UNDEF, T_UNDEF, T_UNDEF, T_UNDEF, T_UNDEF,
	T_UNDEF, M,       T_TEXT,  T_DATA,  T_BSS,   T_EXTERN,
	T_UNDEF, T_TEXT,  X,       X,       X,       X,
	T_UNDEF, T_DATA,  X,       X,       X,       X,
	T_UNDEF, T_BSS,   X,       X,       X,       X,
	T_UNDEF, T_EXTERN,X,       X,       X,       X,
};
char reltm2[6][6] = {
	T_UNDEF, T_UNDEF, T_UNDEF, T_UNDEF, T_UNDEF, T_UNDEF,
	T_UNDEF, M,       T_TEXT,  T_DATA,  T_BSS,   T_EXTERN,
	T_UNDEF, X,       T_ABS,   X,       X,       X,
	T_UNDEF, X,       X,       T_ABS,   X,       X,
	T_UNDEF, X,       X,       X,       T_ABS,   X,
	T_UNDEF, X,       X,       X,       X,       X,
};
char relte2[6][6] = {
	T_UNDEF, T_UNDEF, T_UNDEF, T_UNDEF, T_UNDEF, T_UNDEF,
	T_UNDEF, M,       X,       X,       X,       X,
	T_UNDEF, X,       X,       X,       X,       X,
	T_UNDEF, X,       X,       X,       X,       X,
	T_UNDEF, X,       X,       X,       X,       X,
	T_UNDEF, X,       X,       X,       X,       X,
};
	
struct expr
expres(op)
OP op;
{
	register int ltyp,rtyp;
	register short lval,rval;
	int opprev = '+';	/* previous operator */
	struct expr x;
	struct expr *savxsym;

	xsymbol=0;
	lval=0; ltyp=T_ABS;
	for (;;) {
		if (!ISCHAR(op)) {
			if ((rtyp=op.xp->typ)==T_UNDEF && passno) error('u');
			if (rtyp==T_EXTERN) {xsymbol=op.xp; rval=0;}
			else rval=op.xp->val;
		} else if (op.v>='a') {
			rtyp=curfb[op.v-'a']->typ;
			rval=curfb[op.v-'a']->val;
		} else switch (op.v) {
			default:
				x.typ=ltyp; x.val=lval;
				return(x);
			case T_ABS:
				rval=getw(); rtyp=T_ABS; break;
			case 2:
				rval=numval; rtyp=T_ABS; break;
			case '+': case '-': case '*': case '/':
			case '&': case 037: case 035: case 036:
			case '%': case '^': case '!':
				if (opprev!='+') errore();
				opprev=op.v;
				goto advanc;
			case '[':
				savxsym=xsymbol; x=expres(readop()); if (xsymbol==0) xsymbol=savxsym;
				if (!LAST(']')) error(']');
				rtyp=x.typ; rval=x.val;
		}
		switch (opprev) {
			case '+': ltyp=combin(reltp2,rtyp,ltyp); lval+=rval; break;
			case '-': ltyp=combin(reltm2,rtyp,ltyp); lval-=rval; break;
			case '*': ltyp=combin(relte2,rtyp,ltyp); lval*=rval; break;
			case '/': ltyp=combin(relte2,rtyp,ltyp); lval/=rval; break;
			case 037: ltyp=combin(relte2,rtyp,ltyp); lval|=rval; break;
			case '&': ltyp=combin(relte2,rtyp,ltyp); lval&=rval; break;
			case 035: ltyp=combin(relte2,rtyp,ltyp); lval<<=rval; break;
			case 036: ltyp=combin(relte2,rtyp,ltyp); lval>>=rval; break;
			case '%': ltyp=combin(relte2,rtyp,ltyp); lval%=rval; break;
			case '!': ltyp=combin(relte2,rtyp,ltyp); lval= ~rval; break;
			case '^': ltyp=rtyp; break;
		}
		opprev='+';
	  advanc:
		op=readop();
	}
}

int maxtyp;

combin(tab,rtyp,ltyp)
register int rtyp,ltyp;
char tab[6][6];
{
	register int t;

	if (passno==0) {
		t=(ltyp|rtyp)&T_EXTERN;
		rtyp&=037; ltyp&=037;
		if (rtyp>ltyp) {register int x=rtyp; rtyp=ltyp; ltyp=x;}
		if (rtyp!=T_UNDEF) {
			if (tab==reltm2) {
				if (rtyp!=ltyp) return(t|ltyp);
				return(T_ABS|t);
			} else return(t|ltyp);
		} else return(t);
	} else {
		maxtyp=0;
		if ((ltyp=tab[maprel(rtyp)][maprel(ltyp)])>=0) return(ltyp);
		if (ltyp!=M) error('r');
		return(maxtyp);
	}
}

maprel(t)
register int t;
{
	if (t==T_EXTERN) return(R_EXTERN);
	if ((t&=037)>maxtyp) maxtyp=t;
	if (t<R_EXTERN) return(t);
	return(T_ABS);
}