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[]= "$Id$";
 | |
| #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);
 | |
| }
 |