200 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			200 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
 | 
						|
 * See the copyright notice in the ACK home directory, in the file "Copyright".
 | 
						|
 */
 | 
						|
#ifndef NORCSID
 | 
						|
static char rcsid[]= "$Header$";
 | 
						|
#endif
 | 
						|
 | 
						|
#include "param.h"
 | 
						|
#include "instruct.h"
 | 
						|
#include "pseudo.h"
 | 
						|
#include "varinfo.h"
 | 
						|
#include "set.h"
 | 
						|
#include "expr.h"
 | 
						|
#include "iocc.h"
 | 
						|
#include <cgg_cg.h>
 | 
						|
#include "extern.h"
 | 
						|
 | 
						|
extern int niops;
 | 
						|
extern iocc_t iops[];
 | 
						|
extern inproc;
 | 
						|
 | 
						|
extern set_t l_sets[];
 | 
						|
extern inst_t l_instances[];
 | 
						|
 | 
						|
extern expr_t subreg_expr(),regno_expr();
 | 
						|
 | 
						|
struct varinfo * setcoco(n) {
 | 
						|
	struct varinfo *vi;
 | 
						|
	
 | 
						|
	NEW(vi,struct varinfo);
 | 
						|
	vi->vi_next = VI_NULL;
 | 
						|
	vi->vi_int[0] = INSSETCC;
 | 
						|
	vi->vi_int[1] = n;
 | 
						|
	return(vi);
 | 
						|
}
 | 
						|
 | 
						|
struct varinfo * generase(n) {
 | 
						|
	struct varinfo *vi;
 | 
						|
 | 
						|
	NEW(vi,struct varinfo);
 | 
						|
	vi->vi_next = VI_NULL;
 | 
						|
	vi->vi_int[0] = INSERASE;
 | 
						|
	vi->vi_int[1] = n;
 | 
						|
	return(vi);
 | 
						|
}
 | 
						|
 | 
						|
struct varinfo * genremove(n) {
 | 
						|
	struct varinfo *vi;
 | 
						|
 | 
						|
	NEW(vi,struct varinfo);
 | 
						|
	vi->vi_next = VI_NULL;
 | 
						|
	vi->vi_int[0] = INSREMOVE;
 | 
						|
	vi->vi_int[1] = n;
 | 
						|
	return(vi);
 | 
						|
}
 | 
						|
 | 
						|
onlyreg(argno) {
 | 
						|
	register bitno;
 | 
						|
	register short *sp;
 | 
						|
	
 | 
						|
	if (! argno) argno++;
 | 
						|
	sp = l_sets[tokpatset[argno-1]].set_val;
 | 
						|
	for(bitno=nregs;bitno<nregs+ntokens;bitno++)
 | 
						|
		if (BIT(sp,bitno))
 | 
						|
			return(0);
 | 
						|
	return(1);
 | 
						|
}
 | 
						|
 | 
						|
makescratch(argno) {
 | 
						|
	set_t s;
 | 
						|
 | 
						|
	if (! argno) argno++;
 | 
						|
	if (tokpatro[argno-1])
 | 
						|
		error("Instruction destroys %%%d, not allowed here",argno);
 | 
						|
	s = l_sets[tokpatset[argno-1]];
 | 
						|
	BIC(s.set_val,0);
 | 
						|
	tokpatset[argno-1] = setlookup(s);
 | 
						|
}
 | 
						|
 | 
						|
struct varinfo *gen_inst(ident,star) char *ident; {
 | 
						|
	register struct varinfo *vi,*retval,*eravi;
 | 
						|
	register instr_p ip;
 | 
						|
	register struct operand *op;
 | 
						|
	register i;
 | 
						|
	register inst_p insta;
 | 
						|
	
 | 
						|
	if (star && !inproc)
 | 
						|
		error("Variable instruction only allowed inside proc");
 | 
						|
	for (ip=l_instr;ip<l_instr+ninstr;ip++) {
 | 
						|
		if(strcmp(ident,ip->i_name))
 | 
						|
			continue;
 | 
						|
		if (ip->i_nops!=niops)
 | 
						|
			continue;
 | 
						|
		for(i=0,op=ip->i_oplist;i<niops;i++,op=op->o_next) {
 | 
						|
			if (!subset(iops[i].in_set,l_sets[op->o_setno].set_val,SETSIZE))
 | 
						|
				goto cont;
 | 
						|
		}
 | 
						|
		goto found;		/* oh well, one more won't hurt */
 | 
						|
	    cont:;
 | 
						|
	}
 | 
						|
	error("Such an \"%s\" does not exist",ident);
 | 
						|
	return(0);
 | 
						|
found:
 | 
						|
	NEW(vi,struct varinfo);
 | 
						|
	vi->vi_int[0] = ip-l_instr;
 | 
						|
	vi->vi_int[1] = star;
 | 
						|
	vi->vi_next=0;
 | 
						|
	retval = vi;
 | 
						|
	for(i=0;i<niops;i++) {
 | 
						|
		NEW(vi->vi_vi,struct varinfo);
 | 
						|
		vi=vi->vi_vi;
 | 
						|
		vi->vi_int[0] = iops[i].in_index;
 | 
						|
	}
 | 
						|
	vi->vi_vi = 0;
 | 
						|
	vi = retval;
 | 
						|
	for(i=0,op=ip->i_oplist;i<niops;i++,op=op->o_next) {
 | 
						|
	    if(op->o_adorn&AD_CC) {
 | 
						|
		vi->vi_next = setcoco(iops[i].in_index);
 | 
						|
		vi=vi->vi_next;
 | 
						|
	    }
 | 
						|
	    switch(op->o_adorn&AD_RWMASK) {
 | 
						|
	    default:
 | 
						|
		/* Nothing possible to do */
 | 
						|
		break;
 | 
						|
	    case AD_RO:
 | 
						|
		/* It might be possible to do something
 | 
						|
		 * here but not now.
 | 
						|
		 */
 | 
						|
		break;
 | 
						|
	    case AD_RW:
 | 
						|
	    case AD_WO:
 | 
						|
		/* Treated the same for now */
 | 
						|
		insta = &l_instances[iops[i].in_index];
 | 
						|
		switch(insta->in_which) {
 | 
						|
		case IN_COPY:
 | 
						|
			if(insta->in_info[1]==0 && !onlyreg(insta->in_info[0]))
 | 
						|
				break;
 | 
						|
			makescratch(insta->in_info[0]);
 | 
						|
			vi->vi_next = generase(
 | 
						|
			               ex_lookup(
 | 
						|
				        EX_SUBREG,insta->in_info[0],
 | 
						|
					          insta->in_info[1]
 | 
						|
				       )
 | 
						|
				      );
 | 
						|
			vi = vi->vi_next;
 | 
						|
			break;
 | 
						|
		case IN_MEMB:
 | 
						|
			vi->vi_next = generase(
 | 
						|
				       ex_lookup(
 | 
						|
				        EX_TOKFIELD,insta->in_info[0],
 | 
						|
					            insta->in_info[1]
 | 
						|
				       )
 | 
						|
				      );
 | 
						|
			vi=vi->vi_next;
 | 
						|
			break;
 | 
						|
		case IN_RIDENT:
 | 
						|
			vi->vi_next = generase(
 | 
						|
				       ex_lookup(
 | 
						|
				        EX_REG,insta->in_info[0],0
 | 
						|
				       )
 | 
						|
				      );
 | 
						|
			vi = vi->vi_next;
 | 
						|
			break;
 | 
						|
		case IN_ALLOC:
 | 
						|
			vi->vi_next = generase(
 | 
						|
				       ex_lookup(
 | 
						|
				        EX_ALLREG,insta->in_info[0]+1,
 | 
						|
						  insta->in_info[1]
 | 
						|
				       )
 | 
						|
				      );
 | 
						|
			vi = vi->vi_next;
 | 
						|
			break;
 | 
						|
		case IN_S_DESCR:
 | 
						|
		case IN_D_DESCR:
 | 
						|
			{ int temp;
 | 
						|
 | 
						|
			temp=ex_lookup(EX_REGVAR,insta->in_info[1],0);
 | 
						|
			vi->vi_next = generase(temp);
 | 
						|
			vi = vi->vi_next;
 | 
						|
			vi->vi_next = genremove(temp);
 | 
						|
			vi = vi->vi_next;
 | 
						|
			break;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
	for (eravi=ip->i_erases;eravi != VI_NULL;eravi=eravi->vi_next) {
 | 
						|
		if (eravi->vi_int[0] < 0)
 | 
						|
			vi->vi_next = setcoco(0);
 | 
						|
		else {
 | 
						|
			vi->vi_next = generase(eravi->vi_int[0]);
 | 
						|
			vi=vi->vi_next;
 | 
						|
			vi->vi_next = genremove(eravi->vi_int[0]);
 | 
						|
		}
 | 
						|
		vi=vi->vi_next;
 | 
						|
	}
 | 
						|
	return(retval);
 | 
						|
}
 |