*** empty log message ***
This commit is contained in:
		
							parent
							
								
									f838dd1047
								
							
						
					
					
						commit
						4ba6e7a39c
					
				
					 25 changed files with 4050 additions and 0 deletions
				
			
		
							
								
								
									
										7
									
								
								mach/proto/ncg/assert.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								mach/proto/ncg/assert.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| /* $Header$ */ | ||||
| 
 | ||||
| #ifndef NDEBUG | ||||
| #define assert(x) if(!(x)) badassertion("x",__FILE__,__LINE__) | ||||
| #else | ||||
| #define assert(x)	/* nothing */ | ||||
| #endif | ||||
							
								
								
									
										874
									
								
								mach/proto/ncg/codegen.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										874
									
								
								mach/proto/ncg/codegen.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,874 @@ | |||
| #ifndef NORCSID | ||||
| static char rcsid[] = "$Header$"; | ||||
| #endif | ||||
| 
 | ||||
| #include "assert.h" | ||||
| #include "param.h" | ||||
| #include "tables.h" | ||||
| #include "types.h" | ||||
| #include <cgg_cg.h> | ||||
| #include "data.h" | ||||
| #include "result.h" | ||||
| #include "state.h" | ||||
| #include "equiv.h" | ||||
| #include "extern.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  * Author: Hans van Staveren | ||||
|  */ | ||||
| 
 | ||||
| #define ALLOW_NEXTEM	/* code generator is allowed new try of NEXTEM | ||||
| 			   in exceptional cases */ | ||||
| 
 | ||||
| #define MAXPATTERN 5 | ||||
| #define MAXREPLLEN 5    /* Max length of EM-replacement, should come from boot */ | ||||
| 
 | ||||
| byte startupcode[] = { DO_NEXTEM }; | ||||
| 
 | ||||
| byte *nextem(); | ||||
| unsigned costcalc(); | ||||
| unsigned docoerc(); | ||||
| unsigned stackupto(); | ||||
| string tostring(); | ||||
| string ad2str(); | ||||
| 
 | ||||
| #ifdef NDEBUG | ||||
| #define DEBUG(string) | ||||
| #else | ||||
| #include <stdio.h> | ||||
| #define DEBUG(string) {if(Debug) fprintf(stderr,"%-*d%s\n",4*level,level,string);} | ||||
| #endif | ||||
| 
 | ||||
| #define BROKE() {assert(origcp!=startupcode);DEBUG("BROKE");totalcost=INFINITY;goto doreturn;} | ||||
| #define CHKCOST() {if (totalcost>=costlimit) BROKE();} | ||||
| 
 | ||||
| #ifdef TABLEDEBUG | ||||
| int tablelines[MAXTDBUG]; | ||||
| int ntableline; | ||||
| int set_fd,set_size; | ||||
| short *set_val; | ||||
| char *set_flag; | ||||
| #endif | ||||
| 
 | ||||
| unsigned codegen(codep,ply,toplevel,costlimit,forced) byte *codep; unsigned costlimit; { | ||||
| #ifndef NDEBUG | ||||
| 	byte *origcp=codep; | ||||
| 	static int level=0; | ||||
| #endif | ||||
| 	unsigned totalcost = 0; | ||||
| 	int inscoerc=0; | ||||
| 	int procarg[2]; | ||||
| #ifdef ALLOW_NEXTEM | ||||
| 	int paniced; | ||||
| 	char *savebp; | ||||
| #endif | ||||
| 	state_t state; | ||||
| #define SAVEST	savestatus(&state) | ||||
| #define RESTST	restorestatus(&state) | ||||
| #define FREEST	/* nothing */ | ||||
| #ifdef TABLEDEBUG | ||||
| 	extern char *tablename; | ||||
| #endif | ||||
| 
 | ||||
| #ifndef NDEBUG | ||||
| 	level++; | ||||
| 	DEBUG("Entering codegen"); | ||||
| #endif | ||||
| 	for (;;) { | ||||
| 	switch( (*codep++)&037 ) { | ||||
|     default: | ||||
| 	assert(FALSE); | ||||
| 	/* NOTREACHED */ | ||||
| #ifdef TABLEDEBUG | ||||
|     case DO_DLINE: { | ||||
| 	int n; | ||||
| 
 | ||||
| 	getint(n,codep); | ||||
| 	tablelines[ntableline++] = n; | ||||
| 	if (ntableline>=MAXTDBUG) | ||||
| 		ntableline -= MAXTDBUG; | ||||
| 	if (set_fd) | ||||
| 		set_val[n>>4] &= ~(1<<(n&017)); | ||||
| #ifndef NDEBUG | ||||
| 	if (Debug) | ||||
| 		fprintf(stderr,"code from \"%s\", line %d\n",tablename,n); | ||||
| #endif | ||||
| 	break; | ||||
|     } | ||||
| #endif | ||||
|     case DO_NEXTEM: { | ||||
| 	byte *bp; | ||||
| 	int n; | ||||
| 	unsigned mindistance,dist; | ||||
| 	register i; | ||||
| 	int cindex; | ||||
| 	int npos,pos[MAXRULE]; | ||||
| 	unsigned mincost,t; | ||||
| 
 | ||||
| 	DEBUG("NEXTEM"); | ||||
| 	tokpatlen = 0; | ||||
| 	nallreg=0; | ||||
| 	if (toplevel) { | ||||
| 		garbage_collect(); | ||||
| 		totalcost=0; | ||||
| 	} else { | ||||
| 		if (--ply <= 0) | ||||
| 			goto doreturn; | ||||
| 	} | ||||
| 	if (stackheight>MAXFSTACK-7) { | ||||
| #ifndef NDEBUG | ||||
| 		if (Debug) | ||||
| 			fprintf(stderr,"Fakestack overflow threatens(%d), action ...\n",stackheight); | ||||
| #endif | ||||
| 		totalcost += stackupto(&fakestack[6],ply,toplevel); | ||||
| 	} | ||||
| #ifndef ALLOW_NEXTEM | ||||
| 	bp = nextem(toplevel); | ||||
| #else | ||||
| 	paniced=0; | ||||
| 	savebp = nextem(toplevel); | ||||
|     panic: | ||||
| 	bp = savebp; | ||||
| #endif | ||||
| 	if (bp == 0) { | ||||
| 		/*
 | ||||
| 		 * No pattern found, can be pseudo or error | ||||
| 		 * in table. | ||||
| 		 */ | ||||
| 		if (toplevel) { | ||||
| 			codep--; | ||||
| 			DEBUG("pseudo"); | ||||
| 			dopseudo(); | ||||
| 		} else | ||||
| 			goto doreturn; | ||||
| 	} else { | ||||
| #ifndef NDEBUG | ||||
| 		chkregs(); | ||||
| #endif | ||||
| 		n = *bp++; | ||||
| 		if (n==0) {	/* "procedure" */ | ||||
| 			getint(i,bp); | ||||
| 			getint(procarg[0],bp); | ||||
| 			getint(procarg[1],bp); | ||||
| 			bp= &pattern[i]; | ||||
| 			n = *bp++; | ||||
| 			DEBUG("PROC_CALL"); | ||||
| 		} | ||||
| 		assert(n>0 && n<=MAXRULE); | ||||
| 		if (n>1) { | ||||
| 			mindistance = MAXINT; npos=0; | ||||
| 			for(i=0;i<n;i++) { | ||||
| 				getint(cindex,bp); | ||||
| 				dist=distance(cindex); | ||||
| #ifndef NDEBUG | ||||
| if (Debug) | ||||
| 	fprintf(stderr,"distance of pos %d is %u\n",i,dist); | ||||
| #endif | ||||
| 				if (dist<=mindistance) { | ||||
| 					if (dist<mindistance) { | ||||
| 						if(dist==0) | ||||
| 							goto gotit; | ||||
| 						npos=0; | ||||
| 						mindistance = dist; | ||||
| 					} | ||||
| 					pos[npos++] = cindex; | ||||
| 				} | ||||
| 			} | ||||
| 			assert(mindistance<MAXINT); | ||||
| 			if (npos>1) { | ||||
| 				/*
 | ||||
| 				 * More than 1 tokenpattern is a candidate. | ||||
| 				 * Decision has to be made by lookahead. | ||||
| 				 */ | ||||
| 				SAVEST; | ||||
| 				mincost = costlimit-totalcost+1; | ||||
| 				for(i=0;i<npos;i++) { | ||||
| 					t=codegen(&coderules[pos[i]],ply,FALSE,mincost,0); | ||||
| #ifndef NDEBUG | ||||
| if (Debug) | ||||
| 	fprintf(stderr,"mincost %u,cost %u,pos %d\n",mincost,t,i); | ||||
| #endif | ||||
| 					if (t<mincost) { | ||||
| 						mincost = t; | ||||
| 						cindex = pos[i]; | ||||
| 					} | ||||
| 					RESTST; | ||||
| 				} | ||||
| 				FREEST; | ||||
| 				if (totalcost+mincost>costlimit) | ||||
| 					BROKE(); | ||||
| 			} else { | ||||
| 				cindex = pos[0]; | ||||
| 			} | ||||
| 		} else { | ||||
| 			getint(cindex,bp); | ||||
| 		} | ||||
| 
 | ||||
| 	gotit: | ||||
| 		/*
 | ||||
| 		 * Now cindex contains the code-index of the best candidate | ||||
| 		 * so proceed to use it. | ||||
| 		 */ | ||||
| 		codep = &coderules[cindex]; | ||||
| 	} | ||||
| 	break; | ||||
|     } | ||||
|     case DO_COERC: { | ||||
| 	DEBUG("COERC"); | ||||
| 	tokpatlen=1; | ||||
| 	inscoerc=1; | ||||
| 	break; | ||||
|     } | ||||
|     case DO_XXMATCH: | ||||
| 	DEBUG("XXMATCH"); | ||||
|     case DO_XMATCH: { | ||||
| 	register i; | ||||
| 	int temp; | ||||
| 
 | ||||
| 	DEBUG("XMATCH"); | ||||
| 	tokpatlen=(codep[-1]>>5)&07; | ||||
| 	for (i=0;i<tokpatlen;i++) | ||||
| 		getint(temp,codep); | ||||
| 	break;	/* match already checked by distance() */ | ||||
|     } | ||||
|     case DO_MATCH: { | ||||
| 	register i; | ||||
| 	int j; | ||||
| 	unsigned mincost,t; | ||||
| 	token_p tp; | ||||
| 	int size,lsize; | ||||
| 	int tokexp[MAXPATTERN]; | ||||
| 	int nregneeded; | ||||
| 	token_p regtp[MAXCREG]; | ||||
| 	c3_p regcp[MAXCREG]; | ||||
| 	rl_p regls[MAXCREG]; | ||||
| 	c3_p cp,findcoerc(); | ||||
| 	int sret; | ||||
| 	int stackpad; | ||||
| 	struct perm *tup,*ntup,*besttup,*tuples(); | ||||
| 
 | ||||
| 	DEBUG("MATCH"); | ||||
| 	tokpatlen=(codep[-1]>>5)&07; | ||||
| 	for(i=0;i<tokpatlen;i++) | ||||
| 		getint(tokexp[i],codep); | ||||
| 	tokexp[i] = 0; | ||||
| 	tp = &fakestack[stackheight-1]; | ||||
| 	i=0; | ||||
| 	while (i<tokpatlen && tp>=fakestack) { | ||||
| 		size=tsize(tp); | ||||
| 		while (i<tokpatlen && (lsize=ssize(tokexp[i]))<=size) { | ||||
| 			size -= lsize; | ||||
| 			i++; | ||||
| 		} | ||||
| 		if (i<tokpatlen && size!=0) { | ||||
| 			totalcost += stackupto(tp,ply,toplevel); | ||||
| 			CHKCOST(); | ||||
| 			break; | ||||
| 		} | ||||
| 		tp--; | ||||
| 	} | ||||
| 	tp = &fakestack[stackheight-1]; | ||||
| 	i=0; | ||||
| 	while (i<tokpatlen && tp >= fakestack) { | ||||
| 		size = tsize(tp); | ||||
| 		lsize= ssize(tokexp[i]); | ||||
| 		if (size != lsize) {    /* find coercion */ | ||||
| #ifdef MAXSPLIT | ||||
| 			sret = split(tp,&tokexp[i],ply,toplevel); | ||||
| 			if (sret==0) { | ||||
| #endif MAXSPLIT | ||||
| 				totalcost += stackupto(tp,ply,toplevel); | ||||
| 				CHKCOST(); | ||||
| 				break; | ||||
| #ifdef MAXSPLIT | ||||
| 			} | ||||
| 			i += sret; | ||||
| #endif MAXSPLIT | ||||
| 		} else | ||||
| 			i += 1; | ||||
| 		tp--; | ||||
| 	} | ||||
|     nextmatch: | ||||
| 	tp = &fakestack[stackheight-1]; | ||||
| 	i=0; nregneeded = 0; | ||||
| 	while (i<tokpatlen && tp>=fakestack) { | ||||
| 		if (!match(tp,&machsets[tokexp[i]],0)) { | ||||
| 			cp = findcoerc(tp, &machsets[tokexp[i]]); | ||||
| #ifndef NDEBUG | ||||
| if (Debug>1) fprintf(stderr,"findcoerc returns %d at position %d\n",cp,i); | ||||
| #endif | ||||
| 			if (cp==0) { | ||||
| 				for (j=0;j<nregneeded;j++) | ||||
| 					regtp[j] -= (tp-fakestack+1); | ||||
| 				totalcost += stackupto(tp,ply,toplevel); | ||||
| 				CHKCOST(); | ||||
| 				break; | ||||
| 			} else { | ||||
| 				if (cp->c3_prop==0) { | ||||
| 					totalcost+=docoerc(tp,cp,ply,toplevel,0); | ||||
| 					CHKCOST(); | ||||
| 				} else { | ||||
| #ifndef NDEBUG | ||||
| if(Debug>1) fprintf(stderr,"Register of type %d needed, remembering...\n",cp->c3_prop); | ||||
| #endif | ||||
| 					assert(nregneeded<MAXCREG); | ||||
| 					regtp[nregneeded] = tp; | ||||
| 					regcp[nregneeded] = cp; | ||||
| 					regls[nregneeded] = curreglist; | ||||
| 					nregneeded++; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		i++; tp--; | ||||
| 	} | ||||
| 	if (tokpatlen>stackheight) { | ||||
| #ifndef NDEBUG | ||||
| if(Debug>1) fprintf(stderr,"Pattern too long, %d with only %d items on stack\n", | ||||
| 		tokpatlen,stackheight); | ||||
| #endif | ||||
| 		stackpad = tokpatlen-stackheight; | ||||
| 		for (j=stackheight-1;j>=0;j--) | ||||
| 			fakestack[j+stackpad] = fakestack[j]; | ||||
| 		for (j=0;j<stackpad;j++) | ||||
| 			fakestack[j].t_token=0; | ||||
| 		stackheight += stackpad; | ||||
| 		for (j=0;j<nregneeded;j++) | ||||
| 			regtp[j] += stackpad; | ||||
| 		for (tp = &fakestack[stackpad-1];i<tokpatlen && tp>=fakestack;i++,tp--) { | ||||
| 			cp = findcoerc((token_p) 0, &machsets[tokexp[i]]); | ||||
| 			if (cp==0) { | ||||
| 				for (j=0;j<nregneeded;j++) | ||||
| 					myfree(regls[j]); | ||||
| #ifndef ALLOW_NEXTEM | ||||
| 				assert(!toplevel); | ||||
| 				BROKE(); | ||||
| #else | ||||
| 				assert(!(toplevel&&paniced)); | ||||
| 				goto normalfailed; | ||||
| #endif | ||||
| 			} | ||||
| 			if (cp->c3_prop==0) { | ||||
| 				totalcost+=docoerc(tp,cp,ply,toplevel,0); | ||||
| 				CHKCOST(); | ||||
| 			} else { | ||||
| 				assert(nregneeded<MAXCREG); | ||||
| 				regtp[nregneeded] = tp; | ||||
| 				regcp[nregneeded] = cp; | ||||
| 				regls[nregneeded] = curreglist; | ||||
| 				nregneeded++; | ||||
| 			} | ||||
| 		} | ||||
| 	} else | ||||
| 		stackpad=0; | ||||
| 	assert(i==tokpatlen); | ||||
| 	if (nregneeded==0) | ||||
| 		break; | ||||
| 	SAVEST; | ||||
| 	mincost=costlimit-totalcost+1; | ||||
| 	tup = tuples(regls,nregneeded); | ||||
| 	besttup=0; | ||||
| 	for (; tup != 0; tup = ntup) { | ||||
| #ifndef NDEBUG | ||||
| if(Debug>1) fprintf(stderr,"Next tuple %d,%d,%d,%d\n", | ||||
| 			tup->p_rar[0], | ||||
| 			tup->p_rar[1], | ||||
| 			tup->p_rar[2], | ||||
| 			tup->p_rar[3]); | ||||
| #endif | ||||
| 		ntup = tup->p_next; | ||||
| 		for (i=0,t=0;i<nregneeded && t<mincost; i++) | ||||
| 			t += docoerc(regtp[i],regcp[i],ply,FALSE,tup->p_rar[i]); | ||||
| 		if (t<mincost) { | ||||
| #ifndef NDEBUG | ||||
| 			if (Debug>2) | ||||
| 				fprintf(stderr,"Continuing match after coercions\n"); | ||||
| #endif | ||||
| 			t += codegen(codep,ply,FALSE,mincost-t,0); | ||||
| 		} | ||||
| 		if (t<mincost) { | ||||
| 			mincost = t; | ||||
| 			besttup = tup; | ||||
| 		} else | ||||
| 			myfree(tup); | ||||
| 		RESTST; | ||||
| 	} | ||||
| 	FREEST; | ||||
| 	for (i=0;i<nregneeded;i++) | ||||
| 		myfree(regls[i]); | ||||
| 	if (totalcost+mincost>costlimit) { | ||||
| 		if (besttup) | ||||
| 			myfree(besttup); | ||||
| normalfailed:	if (stackpad!=tokpatlen) { | ||||
| 			if (stackpad) { | ||||
| 				if (costlimit<MAXINT) | ||||
| 					BROKE(); | ||||
| 				for (i=0;i<stackheight-stackpad;i++) | ||||
| 					fakestack[i] = fakestack[i+stackpad]; | ||||
| 				stackheight -= stackpad; | ||||
| 				totalcost += stackupto(&fakestack[stackheight-1],ply,toplevel); | ||||
| 			} else | ||||
| 				totalcost += stackupto(fakestack,ply,toplevel); | ||||
| 			CHKCOST(); | ||||
| 			goto nextmatch; | ||||
| 		} | ||||
| 		totalcost += mincost; | ||||
| #ifndef ALLOW_NEXTEM | ||||
| 		BROKE(); | ||||
| #else | ||||
| 		if (toplevel && !paniced) { | ||||
| 			stackheight=0; | ||||
| 			paniced++; | ||||
| 			DEBUG("PANIC!"); | ||||
| 			goto panic; | ||||
| 		} else | ||||
| 			BROKE(); | ||||
| #endif | ||||
| 	} | ||||
| 	for (i=0;i<nregneeded;i++) | ||||
| 		totalcost += docoerc(regtp[i],regcp[i],ply,toplevel,besttup->p_rar[i]); | ||||
| 	myfree(besttup); | ||||
| 	break; | ||||
|     } | ||||
|     case DO_REMOVE: { | ||||
| 	int texpno,nodeno; | ||||
| 	token_p tp; | ||||
| 	struct reginfo *rp; | ||||
| 
 | ||||
| 	DEBUG("REMOVE"); | ||||
| 	if (codep[-1]&32) { | ||||
| 		getint(texpno,codep); | ||||
| 		getint(nodeno,codep); | ||||
| 	} else { | ||||
| 		getint(texpno,codep); | ||||
| 		nodeno=0; | ||||
| 	} | ||||
| 	for (tp= &fakestack[stackheight-tokpatlen-1];tp>=&fakestack[0];tp--) | ||||
| 		if (match(tp,&machsets[texpno],nodeno)) { | ||||
| 			/* investigate possible coercion to register */ | ||||
| 			totalcost += stackupto(tp,ply,toplevel); | ||||
| 			CHKCOST(); | ||||
| 			break; | ||||
| 		} | ||||
| 	for (rp=machregs;rp<machregs+NREGS;rp++) | ||||
| 		if (match(&rp->r_contents,&machsets[texpno],nodeno)) | ||||
| 			rp->r_contents.t_token=0; | ||||
| 	break; | ||||
|     } | ||||
|     case DO_RREMOVE: {	/* register remove */ | ||||
| 	register i; | ||||
| 	int nodeno; | ||||
| 	token_p tp; | ||||
| 	tkdef_p tdp; | ||||
| 	result_t result; | ||||
| 
 | ||||
| 	getint(nodeno,codep); | ||||
| 	result=compute(&enodes[nodeno]); | ||||
| 	assert(result.e_typ==EV_REG); | ||||
| 	for (tp= &fakestack[stackheight-tokpatlen-1];tp>=&fakestack[0];tp--) | ||||
| 		if (tp->t_token==-1) { | ||||
| 			if(tp->t_att[0].ar==result.e_v.e_reg) | ||||
| 				goto gotone; | ||||
| 		} else { | ||||
| 			tdp = &tokens[tp->t_token]; | ||||
| 			for(i=0;i<TOKENSIZE;i++) | ||||
| 				if (tdp->t_type[i]==EV_REG && | ||||
| 				    tp->t_att[i].ar==result.e_v.e_reg) | ||||
| 					goto gotone; | ||||
| 		} | ||||
| 	break; | ||||
|     gotone: | ||||
| 	/* investigate possible coercion to register */ | ||||
| 	totalcost += stackupto(tp,ply,toplevel); | ||||
| 	CHKCOST(); | ||||
| 	break; | ||||
|     } | ||||
|     case DO_DEALLOCATE: { | ||||
| 	register i; | ||||
| 	tkdef_p tdp; | ||||
| 	int tinstno; | ||||
| 	token_t token; | ||||
| 
 | ||||
| 	DEBUG("DEALLOCATE"); | ||||
| 	getint(tinstno,codep); | ||||
| 	instance(tinstno,&token); | ||||
| 	if (token.t_token==-1) | ||||
| 		chrefcount(token.t_att[0].ar,-1,TRUE); | ||||
| 	else { | ||||
| 		tdp= &tokens[token.t_token]; | ||||
| 		for (i=0;i<TOKENSIZE;i++) | ||||
| 			if (tdp->t_type[i]==EV_REG) | ||||
| 				chrefcount(token.t_att[i].ar,-1,TRUE); | ||||
| 	} | ||||
| 	break; | ||||
|     } | ||||
|     case DO_REALLOCATE: { | ||||
| 	struct reginfo *rp; | ||||
| 
 | ||||
| 	DEBUG("REALLOCATE"); | ||||
| 	for(rp=machregs+1;rp<machregs+NREGS;rp++) | ||||
| 		if(rp->r_tcount) { | ||||
| 			rp->r_refcount -= rp->r_tcount; | ||||
| 			rp->r_tcount = 0; | ||||
| 		} | ||||
| 	break; | ||||
|     } | ||||
|     case DO_ALLOCATE: { | ||||
| 	register i; | ||||
| 	int j; | ||||
| 	int tinstno; | ||||
| 	int npos,npos2,pos[NREGS],pos2[NREGS]; | ||||
| 	unsigned mincost,t; | ||||
| 	struct reginfo *rp,**rpp; | ||||
| 	token_t token,mtoken,token2; | ||||
| 	int propno; | ||||
| 	int exactmatch; | ||||
| 	int decision; | ||||
| 
 | ||||
| 	if (codep[-1]&32) { | ||||
| 		getint(propno,codep); | ||||
| 		getint(tinstno,codep); | ||||
| 		DEBUG("ALLOCATE,INIT"); | ||||
| 	} else { | ||||
| 		getint(propno,codep); | ||||
| 		tinstno=0; | ||||
| 		DEBUG("ALLOCATE,EMPTY"); | ||||
| 	} | ||||
| 	instance(tinstno,&token); | ||||
| 	if (!forced) { | ||||
| 		do { | ||||
| 			npos=exactmatch=0; | ||||
| 			for(rpp=reglist[propno];rp= *rpp; rpp++) | ||||
| 				if (getrefcount(rp-machregs)==0) { | ||||
| 					pos[npos++] = rp-machregs; | ||||
| 					if (eqtoken(&rp->r_contents,&token)) | ||||
| 						exactmatch++; | ||||
| 				} | ||||
| 			/*
 | ||||
| 			 * Now pos[] contains all free registers with desired | ||||
| 			 * property. If none then some stacking has to take place. | ||||
| 			 */ | ||||
| 			if (npos==0) { | ||||
| 				if (stackheight<=tokpatlen) { | ||||
| 					if (!toplevel) { | ||||
| 						BROKE(); | ||||
| 					} else | ||||
| 						fatal("No regs available"); | ||||
| 				} | ||||
| 				totalcost += stackupto( &fakestack[0],ply,toplevel); | ||||
| 				CHKCOST(); | ||||
| 			} | ||||
| 		} while (npos==0); | ||||
| 		if (!exactmatch) { | ||||
| 			npos2=npos; | ||||
| 			for(i=0;i<npos;i++) | ||||
| 				pos2[i]=pos[i]; | ||||
| 		} else { | ||||
| 			/*
 | ||||
| 			 * Now we are reducing the number of possible registers. | ||||
| 			 * We take only one equally likely register out of every | ||||
| 			 * equivalence class as given by set of properties. | ||||
| 			 */ | ||||
| 			mtoken = token; | ||||
| 			npos2=0; | ||||
| 			for(i=0;i<npos;i++) | ||||
| 				if (eqtoken(&machregs[pos[i]].r_contents,&mtoken)) { | ||||
| 					pos2[npos2++] = pos[i]; | ||||
| 					for(j=0;j<npos2-1;j++) | ||||
| 						if (eqregclass(pos2[j],pos[i])) { | ||||
| 							npos2--; | ||||
| 							break; | ||||
| 						} | ||||
| 				} | ||||
| 		} | ||||
| 		/*
 | ||||
| 		 * Now pos2[] contains all possibilities to try, if more than | ||||
| 		 * one, lookahead is necessary. | ||||
| 		 */ | ||||
| 		token2.t_token= -1; | ||||
| 		for (i=1;i<TOKENSIZE;i++) | ||||
| 			token2.t_att[i].aw=0; | ||||
| 		if (npos2==1) | ||||
| 			decision=pos2[0]; | ||||
| 		else { | ||||
| 			SAVEST; | ||||
| 			mincost=costlimit-totalcost+1; | ||||
| 			for(j=0;j<npos2;j++) { | ||||
| 				chrefcount(pos2[j],1,FALSE); | ||||
| 				token2.t_att[0].ar=pos2[j]; | ||||
| 				allreg[nallreg++] = pos2[j]; | ||||
| 				if (token.t_token != 0) | ||||
| 					t=move(&token,&token2,ply,FALSE,mincost); | ||||
| 				else { | ||||
| 					t = 0; | ||||
| 					erasereg(pos2[j]); | ||||
| 				} | ||||
| 				if (t<mincost) | ||||
| 					t += codegen(codep,ply,FALSE,mincost-t,0); | ||||
| 				if (t<mincost) { | ||||
| 					mincost=t; | ||||
| 					decision=pos2[j]; | ||||
| 				} | ||||
| 				RESTST; | ||||
| 			} | ||||
| 			FREEST; | ||||
| 			if (totalcost+mincost>costlimit) | ||||
| 				BROKE(); | ||||
| 		} | ||||
| 	} else { | ||||
| 		decision = forced; | ||||
| 		if (getrefcount(decision)!=0) | ||||
| 			BROKE(); | ||||
| 		token2.t_token = -1; | ||||
| 	} | ||||
| 	chrefcount(decision,1,FALSE); | ||||
| 	token2.t_att[0].ar=decision; | ||||
| 	if (token.t_token != 0) { | ||||
| 		totalcost+=move(&token,&token2,ply,toplevel,MAXINT); | ||||
| 		CHKCOST(); | ||||
| 	} else | ||||
| 		erasereg(decision); | ||||
| 	allreg[nallreg++]=decision; | ||||
| 	break; | ||||
|     } | ||||
|     case DO_INSTR: { | ||||
| 	register i; | ||||
| 	int n; | ||||
| 	int tinstno; | ||||
| 	token_t token; | ||||
| 	int stringno; | ||||
| 
 | ||||
|     	DEBUG("INSTR"); | ||||
| 	n=((codep[-1]>>5)&07); | ||||
| 	getint(stringno,codep); | ||||
| 	if (toplevel) { | ||||
| 		swtxt(); | ||||
| 		if (stringno>10000) { | ||||
| 			assert(stringno== 10001 || stringno== 10002); | ||||
| 			genstr(procarg[stringno-10001]); | ||||
| 		} else | ||||
| 			genstr(stringno); | ||||
| 	} | ||||
| 	for(i=0;i<n;i++) { | ||||
| 		getint(tinstno,codep); | ||||
| 		instance(tinstno,&token); | ||||
| 		if (toplevel) | ||||
| 			prtoken(&token,i==0 ? ' ' : ','); | ||||
| 		if (token.t_token>0) | ||||
| 			totalcost += tokens[token.t_token].t_cost.ct_space; | ||||
| 	} | ||||
| 	if (toplevel) | ||||
| 		gennl(); | ||||
| 	break;		 | ||||
|     } | ||||
|     case DO_MOVE: { | ||||
| 	int tinstno; | ||||
| 	token_t token,token2; | ||||
| 
 | ||||
| 	DEBUG("MOVE"); | ||||
| 	getint(tinstno,codep); | ||||
| 	instance(tinstno,&token); | ||||
| 	getint(tinstno,codep); | ||||
| 	instance(tinstno,&token2); | ||||
| 	totalcost += move(&token,&token2,ply,toplevel,costlimit-totalcost+1); | ||||
| 	CHKCOST(); | ||||
| 	break; | ||||
|     } | ||||
|     case DO_TEST: { | ||||
| 	int tinstno; | ||||
| 	token_t token; | ||||
| 
 | ||||
| 	DEBUG("TEST"); | ||||
| 	getint(tinstno,codep); | ||||
| 	instance(tinstno,&token); | ||||
| 	totalcost += test(&token,ply,toplevel,costlimit-totalcost+1); | ||||
| 	CHKCOST(); | ||||
| 	break; | ||||
|     } | ||||
|     case DO_SETCC: { | ||||
| 	int tinstno; | ||||
| 	token_t token; | ||||
| 
 | ||||
|     	DEBUG("SETCC"); | ||||
| 	getint(tinstno,codep); | ||||
| 	instance(tinstno,&token); | ||||
| 	setcc(&token); | ||||
| 	break; | ||||
|     } | ||||
|     case DO_ERASE: { | ||||
| 	int nodeno; | ||||
| 	result_t result; | ||||
| 
 | ||||
| 	DEBUG("ERASE"); | ||||
| 	getint(nodeno,codep); | ||||
| 	result=compute(&enodes[nodeno]); | ||||
| 	assert(result.e_typ!=EV_INT && result.e_typ!=EV_ADDR); | ||||
| 	if (result.e_typ==EV_REG) | ||||
| 		erasereg(result.e_v.e_reg); | ||||
| 	break; | ||||
|     } | ||||
|     case DO_TOKREPLACE: { | ||||
| 	register i; | ||||
| 	int tinstno; | ||||
| 	int repllen; | ||||
| 	token_t reptoken[MAXREPLLEN]; | ||||
| 
 | ||||
| 	DEBUG("TOKREPLACE"); | ||||
| 	assert(stackheight>=tokpatlen); | ||||
| 	repllen=(codep[-1]>>5)&07; | ||||
| #ifndef NDEBUG | ||||
| 	if (Debug>2) | ||||
| 		fprintf(stderr,"Stackheight=%d, tokpatlen=%d, repllen=%d %s\n", | ||||
| 			stackheight,tokpatlen,repllen,inscoerc ? "(inscoerc)":""); | ||||
| #endif | ||||
| 	for(i=0;i<repllen;i++) { | ||||
| 		getint(tinstno,codep); | ||||
| 		instance(tinstno,&reptoken[i]); | ||||
| 		tref(&reptoken[i],1); | ||||
| 	} | ||||
| 	for(i=0;i<tokpatlen;i++) { | ||||
| 		if (!inscoerc) | ||||
| 			tref(&fakestack[stackheight-1],-1); | ||||
| 		stackheight--; | ||||
| 	} | ||||
| 	for (i=0;i<repllen;i++) { | ||||
| 		assert(stackheight<MAXFSTACK); | ||||
| 		fakestack[stackheight++] = reptoken[i]; | ||||
| 	} | ||||
| 	for(i=0;i<nallreg;i++) | ||||
| 		chrefcount(allreg[i],-1,FALSE); | ||||
| 	break; | ||||
|     } | ||||
|     case DO_EMREPLACE: { | ||||
| 	register i; | ||||
| 	int j; | ||||
| 	int nodeno; | ||||
| 	result_t result; | ||||
| 	int emrepllen,eminstr; | ||||
| 
 | ||||
| 	DEBUG("EMREPLACE"); | ||||
| 	emrepllen=(codep[-1]>>5)&07; | ||||
| 	j=emp-emlines; | ||||
| 	if (emrepllen>j) { | ||||
| 		assert(nemlines+emrepllen-j<MAXEMLINES); | ||||
| 		for (i=nemlines;i>=0;i--) | ||||
| 			emlines[i+emrepllen-j] = emlines[i]; | ||||
| 		nemlines += emrepllen-j; | ||||
| 		emp += emrepllen-j; | ||||
| 	} | ||||
| 	emp -= emrepllen; | ||||
| 	for (i=0;i<emrepllen;i++) { | ||||
| 		getint(eminstr,codep); | ||||
| 		getint(nodeno,codep); | ||||
| 		emp[i].em_instr = eminstr; | ||||
| 		result = compute(&enodes[nodeno]); | ||||
| 		switch(result.e_typ) { | ||||
| 		default: | ||||
| 			assert(FALSE); | ||||
| 		case 0: | ||||
| 			emp[i].em_optyp = OPNO; | ||||
| 			emp[i].em_soper = 0; | ||||
| 			break; | ||||
| 		case EV_INT: | ||||
| 			emp[i].em_optyp = OPINT; | ||||
| 			emp[i].em_soper = tostring(result.e_v.e_con); | ||||
| 			emp[i].em_u.em_ioper = result.e_v.e_con; | ||||
| 			break; | ||||
| 		case EV_ADDR: | ||||
| 			emp[i].em_optyp = OPSYMBOL; | ||||
| 			emp[i].em_soper = ad2str(result.e_v.e_addr); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	if (!toplevel) | ||||
| 		ply += emrepllen; | ||||
| 	break; | ||||
|     } | ||||
|     case DO_COST: { | ||||
| 	cost_t cost; | ||||
| 
 | ||||
| 	DEBUG("COST"); | ||||
| 	getint(cost.ct_space,codep); | ||||
| 	getint(cost.ct_time,codep); | ||||
| 	totalcost += costcalc(cost); | ||||
| 	CHKCOST(); | ||||
| 	break; | ||||
|     } | ||||
| #ifdef REGVARS | ||||
|     case DO_PRETURN: { | ||||
| 	if (toplevel) { | ||||
| 		swtxt(); | ||||
| 		regreturn();	/* in mach.c */ | ||||
| 	} | ||||
| 	break; | ||||
|     } | ||||
| #endif | ||||
|     case DO_RETURN: | ||||
| 	DEBUG("RETURN"); | ||||
| 	assert(origcp!=startupcode); | ||||
|     doreturn: | ||||
| #ifndef NDEBUG | ||||
| 	level--; | ||||
| #endif | ||||
| 	return(totalcost); | ||||
| 	} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| readcodebytes() { | ||||
| #ifndef CODEINC | ||||
| 	register fd; | ||||
| 	extern int ncodebytes; | ||||
| 
 | ||||
| 	if ((fd=open("code",0))<0) { | ||||
| 		error("Can't open code"); | ||||
| 	} | ||||
| 	if (read(fd,coderules,ncodebytes)!=ncodebytes) { | ||||
| 		error("Short read from code"); | ||||
| 	} | ||||
| 	close(fd); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| #ifdef TABLEDEBUG | ||||
| initlset(f) char *f; { | ||||
| 	extern char *myalloc(); | ||||
| 
 | ||||
| 	set_flag = f; | ||||
| 	if ((set_fd=open(f+1,2))<0) | ||||
| 		error("Can't open %s rw",f+1); | ||||
| 	read(set_fd,&set_size,sizeof(int)); | ||||
| 	set_val=( short *) myalloc(set_size); | ||||
| 	read(set_fd,set_val,set_size); | ||||
| } | ||||
| 
 | ||||
| termlset() { | ||||
| 
 | ||||
| 	if (set_fd) { | ||||
| 		lseek(set_fd,(long) sizeof(int),0); | ||||
| 		write(set_fd,set_val,set_size); | ||||
| 		close(set_fd); | ||||
| 		if (set_flag[0]=='u') { | ||||
| 			register i; | ||||
| 			 | ||||
| 			fprintf(stderr,"Unused code rules:\n\n"); | ||||
| 			for(i=0;i<8*set_size;i++) | ||||
| 				if(set_val[i>>4]&(1<<(i&017))) | ||||
| 					fprintf(stderr,"\"%s\", line %d\n",tablename,i); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										366
									
								
								mach/proto/ncg/compute.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										366
									
								
								mach/proto/ncg/compute.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,366 @@ | |||
| #ifndef NORCSID | ||||
| static char rcsid[] = "$Header$"; | ||||
| #endif | ||||
| 
 | ||||
| #include "assert.h" | ||||
| #include "param.h" | ||||
| #include "tables.h" | ||||
| #include "types.h" | ||||
| #include <cgg_cg.h> | ||||
| #include "data.h" | ||||
| #include "result.h" | ||||
| #include "glosym.h" | ||||
| #include "extern.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  * Author: Hans van Staveren | ||||
|  */ | ||||
| 
 | ||||
| #define LLEAF 01 | ||||
| #define LDEF  02 | ||||
| #define RLEAF 04 | ||||
| #define RDEF  010 | ||||
| #define LLDEF LLEAF|LDEF | ||||
| #define RLDEF RLEAF|RDEF | ||||
| 
 | ||||
| char opdesc[] = { | ||||
| 	0,                      /* EX_TOKFIELD */ | ||||
| 	0,                      /* EX_ARG */ | ||||
| 	0,                      /* EX_CON */ | ||||
| 	0,                      /* EX_ALLREG */ | ||||
| 	LLDEF|RLDEF,            /* EX_SAMESIGN */ | ||||
| 	LLDEF|RLDEF,            /* EX_SFIT */ | ||||
| 	LLDEF|RLDEF,            /* EX_UFIT */ | ||||
| 	0,                      /* EX_ROM */ | ||||
| 	LLDEF|RLDEF,            /* EX_NCPEQ */ | ||||
| 	LLDEF|RLDEF,            /* EX_SCPEQ */ | ||||
| 	LLDEF|RLDEF,            /* EX_RCPEQ */ | ||||
| 	LLDEF|RLDEF,            /* EX_NCPNE */ | ||||
| 	LLDEF|RLDEF,            /* EX_SCPNE */ | ||||
| 	LLDEF|RLDEF,            /* EX_RCPNE */ | ||||
| 	LLDEF|RLDEF,            /* EX_NCPGT */ | ||||
| 	LLDEF|RLDEF,            /* EX_NCPGE */ | ||||
| 	LLDEF|RLDEF,            /* EX_NCPLT */ | ||||
| 	LLDEF|RLDEF,            /* EX_NCPLE */ | ||||
| 	LLDEF,                  /* EX_OR2 */ | ||||
| 	LLDEF,                  /* EX_AND2 */ | ||||
| 	LLDEF|RLDEF,            /* EX_PLUS */ | ||||
| 	LLDEF|RLDEF,            /* EX_CAT */ | ||||
| 	LLDEF|RLDEF,            /* EX_MINUS */ | ||||
| 	LLDEF|RLDEF,            /* EX_TIMES */ | ||||
| 	LLDEF|RLDEF,            /* EX_DIVIDE */ | ||||
| 	LLDEF|RLDEF,            /* EX_MOD */ | ||||
| 	LLDEF|RLDEF,            /* EX_LSHIFT */ | ||||
| 	LLDEF|RLDEF,            /* EX_RSHIFT */ | ||||
| 	LLDEF,                  /* EX_NOT */ | ||||
| 	LLDEF,                  /* EX_COMP */ | ||||
| 	0,                      /* EX_COST */ | ||||
| 	0,                      /* EX_STRING */ | ||||
| 	LLEAF,                  /* EX_DEFINED */ | ||||
| 	0,                      /* EX_SUBREG */ | ||||
| 	LLDEF,                  /* EX_TOSTRING */ | ||||
| 	LLDEF,                  /* EX_UMINUS */ | ||||
| 	0,                      /* EX_REG */ | ||||
| 	0,			/* EX_LOWW */ | ||||
| 	0,			/* EX_HIGHW */ | ||||
| 	LLDEF,			/* EX_INREG */ | ||||
| 	LLDEF,			/* EX_REGVAR */ | ||||
| }; | ||||
| 
 | ||||
| string salloc(),strcpy(),strcat(); | ||||
| 
 | ||||
| string mycat(s1,s2) register string s1,s2; { | ||||
| 	register string s; | ||||
| 
 | ||||
| 	if (s1==0) return(s2); | ||||
| 	if (s2==0) return(s1); | ||||
| 	s=salloc(strlen(s1)+strlen(s2)+1); | ||||
| 	strcpy(s,s1); | ||||
| 	strcat(s,"+"); | ||||
| 	strcat(s,s2); | ||||
| 	return(s); | ||||
| } | ||||
| 
 | ||||
| string mystrcpy(s) register string s; { | ||||
| 	register string r; | ||||
| 
 | ||||
| 	r=salloc(strlen(s)); | ||||
| 	strcpy(r,s); | ||||
| 	return(r); | ||||
| } | ||||
| 
 | ||||
| char digstr[21][15]; | ||||
| 
 | ||||
| string tostring(n) register word n; { | ||||
| 	char buf[25]; | ||||
| 
 | ||||
| 	if (n>=-20 && n<=20 && (n&1)==0) { | ||||
| 		if (digstr[(n>>1)+10][0]==0) | ||||
| 			sprintf(digstr[(n>>1)+10],WRD_FMT,n); | ||||
| 		return(digstr[(n>>1)+10]); | ||||
| 	} | ||||
| 	sprintf(buf,WRD_FMT,n); | ||||
| 	return(mystrcpy(buf)); | ||||
| } | ||||
| 
 | ||||
| result_t undefres= {EV_UNDEF}; | ||||
| 
 | ||||
| result_t compute(node) register node_p node; { | ||||
| 	result_t leaf1,leaf2,result; | ||||
| 	register token_p tp; | ||||
| 	int desc; | ||||
| 	long mask,tmp; | ||||
| 	int i,tmpreg; | ||||
| 	glosym_p gp; | ||||
| 
 | ||||
| 	desc=opdesc[node->ex_operator]; | ||||
| 	if (desc&LLEAF) { | ||||
| 		leaf1 = compute(&enodes[node->ex_lnode]); | ||||
| 		if (desc&LDEF && leaf1.e_typ==EV_UNDEF) | ||||
| 			return(undefres); | ||||
| 	} | ||||
| 	if (desc&RLEAF) { | ||||
| 		leaf2 = compute(&enodes[node->ex_rnode]); | ||||
| 		if (desc&RDEF && leaf2.e_typ==EV_UNDEF) | ||||
| 			return(undefres); | ||||
| 	} | ||||
| 	result.e_typ=EV_INT; | ||||
| 	switch(node->ex_operator) { | ||||
| 	default:        assert(FALSE); | ||||
| 	case EX_TOKFIELD: | ||||
| 		if (node->ex_lnode!=0) | ||||
| 			tp = &fakestack[stackheight-node->ex_lnode]; | ||||
| 		else | ||||
| 			tp = curtoken; | ||||
| 		switch(result.e_typ = tokens[tp->t_token].t_type[node->ex_rnode-1]) { | ||||
| 		default: | ||||
| 			assert(FALSE); | ||||
| 		case EV_INT: | ||||
| 			result.e_v.e_con = tp->t_att[node->ex_rnode-1].aw; | ||||
| 			break; | ||||
| 		case EV_ADDR: | ||||
| 			result.e_v.e_addr = tp->t_att[node->ex_rnode-1].aa; | ||||
| 			break; | ||||
| 		case EV_REG: | ||||
| 			result.e_v.e_reg = tp->t_att[node->ex_rnode-1].ar; | ||||
| 			break; | ||||
| 		} | ||||
| 		return(result); | ||||
| 	case EX_ARG: | ||||
| 		return(dollar[node->ex_lnode-1]); | ||||
| 	case EX_CON: | ||||
| 		result.e_typ = EV_INT; | ||||
| 		result.e_v.e_con = ((long) node->ex_rnode << 16) | ((long)node->ex_lnode&0xffff); | ||||
| 		return(result); | ||||
| 	case EX_REG: | ||||
| 		result.e_typ = EV_REG; | ||||
| 		result.e_v.e_reg = node->ex_lnode; | ||||
| 		return(result); | ||||
| 	case EX_ALLREG: | ||||
| 		result.e_typ = EV_REG; | ||||
| 		result.e_v.e_reg = allreg[node->ex_lnode-1]; | ||||
| #if MAXMEMBERS!=0 | ||||
| 		if (node->ex_rnode!=0) | ||||
| 			result.e_v.e_reg = machregs[result.e_v.e_reg]. | ||||
| 				r_members[node->ex_rnode-1]; | ||||
| #endif | ||||
| 		return(result); | ||||
| 	case EX_SAMESIGN: | ||||
| 	assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT); | ||||
| 		result.e_typ = EV_INT; | ||||
| 		if (leaf1.e_v.e_con>=0) | ||||
| 			result.e_v.e_con= leaf2.e_v.e_con>=0; | ||||
| 		else | ||||
| 			result.e_v.e_con= leaf2.e_v.e_con<0; | ||||
| 		return(result); | ||||
| 	case EX_SFIT: | ||||
| 	assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT); | ||||
| 		mask = 0xFFFFFFFFL; | ||||
| 		for (i=0;i<leaf2.e_v.e_con-1;i++) | ||||
| 			mask &= ~(1<<i); | ||||
| 		tmp = leaf1.e_v.e_con&mask; | ||||
| 		result.e_v.e_con = tmp==0||tmp==mask; | ||||
| 		return(result); | ||||
| 	case EX_UFIT: | ||||
| 	assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT); | ||||
| 		mask = 0xFFFFFFFFL; | ||||
| 		for (i=0;i<leaf2.e_v.e_con;i++) | ||||
| 			mask &= ~(1<<i); | ||||
| 		result.e_v.e_con = (leaf1.e_v.e_con&mask)==0; | ||||
| 		return(result); | ||||
| 	case EX_ROM: | ||||
| 		assert(node->ex_rnode>=0 &&node->ex_rnode<MAXROM); | ||||
| 		leaf2=dollar[node->ex_lnode]; | ||||
| 		if (leaf2.e_typ != EV_ADDR) | ||||
| 			return(undefres); | ||||
| 		if (leaf2.e_v.e_addr.ea_off!=0) | ||||
| 			return(undefres); | ||||
| 		gp = lookglo(leaf2.e_v.e_addr.ea_str); | ||||
| 		if (gp == (glosym_p) 0) | ||||
| 			return(undefres); | ||||
| 		if ((gp->gl_rom[MAXROM]&(1<<node->ex_rnode))==0) | ||||
| 			return(undefres); | ||||
| 		result.e_v.e_con = gp->gl_rom[node->ex_rnode]; | ||||
| 		return(result); | ||||
| 	case EX_LOWW: | ||||
| 		result.e_v.e_con = saveemp[node->ex_lnode].em_u.em_loper&0xFFFF; | ||||
| 		return(result); | ||||
| 	case EX_HIGHW: | ||||
| 		result.e_v.e_con = saveemp[node->ex_lnode].em_u.em_loper>>16; | ||||
| 		return(result); | ||||
| 	case EX_NCPEQ: | ||||
| 	assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT); | ||||
| 		result.e_v.e_con = leaf1.e_v.e_con==leaf2.e_v.e_con; | ||||
| 		return(result); | ||||
| 	case EX_SCPEQ: | ||||
| 	assert(leaf1.e_typ == EV_ADDR && leaf2.e_typ == EV_ADDR); | ||||
| 		result.e_v.e_con = | ||||
| 		    (strcmp(leaf1.e_v.e_addr.ea_str,leaf2.e_v.e_addr.ea_str)==0 && | ||||
| 		    leaf1.e_v.e_addr.ea_off==leaf2.e_v.e_addr.ea_off); | ||||
| 		return(result); | ||||
| 	case EX_RCPEQ: | ||||
| 	assert(leaf1.e_typ == EV_REG && leaf2.e_typ == EV_REG); | ||||
| 		result.e_v.e_con = leaf1.e_v.e_reg==leaf2.e_v.e_reg; | ||||
| 		return(result); | ||||
| 	case EX_NCPNE: | ||||
| 	assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT); | ||||
| 		result.e_v.e_con = leaf1.e_v.e_con!=leaf2.e_v.e_con; | ||||
| 		return(result); | ||||
| 	case EX_SCPNE: | ||||
| 	assert(leaf1.e_typ == EV_ADDR && leaf2.e_typ == EV_ADDR); | ||||
| 		result.e_v.e_con = | ||||
| 		    !(strcmp(leaf1.e_v.e_addr.ea_str,leaf2.e_v.e_addr.ea_str)==0 && | ||||
| 		    leaf1.e_v.e_addr.ea_off==leaf2.e_v.e_addr.ea_off); | ||||
| 		return(result); | ||||
| 	case EX_RCPNE: | ||||
| 	assert(leaf1.e_typ == EV_REG && leaf2.e_typ == EV_REG); | ||||
| 		result.e_v.e_con = leaf1.e_v.e_reg!=leaf2.e_v.e_reg; | ||||
| 		return(result); | ||||
| 	case EX_NCPGT: | ||||
| 	assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT); | ||||
| 		result.e_v.e_con = leaf1.e_v.e_con>leaf2.e_v.e_con; | ||||
| 		return(result); | ||||
| 	case EX_NCPGE: | ||||
| 	assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT); | ||||
| 		result.e_v.e_con = leaf1.e_v.e_con>=leaf2.e_v.e_con; | ||||
| 		return(result); | ||||
| 	case EX_NCPLT: | ||||
| 	assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT); | ||||
| 		result.e_v.e_con = leaf1.e_v.e_con<leaf2.e_v.e_con; | ||||
| 		return(result); | ||||
| 	case EX_NCPLE: | ||||
| 	assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT); | ||||
| 		result.e_v.e_con = leaf1.e_v.e_con<=leaf2.e_v.e_con; | ||||
| 		return(result); | ||||
| 	case EX_OR2: | ||||
| 	assert(leaf1.e_typ == EV_INT); | ||||
| 		if (leaf1.e_v.e_con==0) | ||||
| 			return(compute(&enodes[node->ex_rnode])); | ||||
| 		return(leaf1); | ||||
| 	case EX_AND2: | ||||
| 	assert(leaf1.e_typ == EV_INT); | ||||
| 		if (leaf1.e_v.e_con!=0) | ||||
| 			return(compute(&enodes[node->ex_rnode])); | ||||
| 		return(leaf1); | ||||
| 	case EX_PLUS: | ||||
| 	assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT); | ||||
| 		result.e_v.e_con=leaf1.e_v.e_con+leaf2.e_v.e_con; | ||||
| 		return(result); | ||||
| 	case EX_CAT: | ||||
| 	assert(leaf1.e_typ == EV_ADDR && leaf2.e_typ == EV_ADDR); | ||||
| 		result.e_typ = EV_ADDR; | ||||
| 		result.e_v.e_addr.ea_str = mycat(leaf1.e_v.e_addr.ea_str,leaf2.e_v.e_addr.ea_str); | ||||
| 		result.e_v.e_addr.ea_off = leaf1.e_v.e_addr.ea_off+leaf2.e_v.e_addr.ea_off; | ||||
| 		return(result); | ||||
| 	case EX_MINUS: | ||||
| 	assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT); | ||||
| 		result.e_v.e_con = leaf1.e_v.e_con - leaf2.e_v.e_con; | ||||
| 		return(result); | ||||
| 	case EX_TIMES: | ||||
| 	assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT); | ||||
| 		result.e_v.e_con = leaf1.e_v.e_con * leaf2.e_v.e_con; | ||||
| 		return(result); | ||||
| 	case EX_DIVIDE: | ||||
| 	assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT); | ||||
| 		result.e_v.e_con = leaf1.e_v.e_con / leaf2.e_v.e_con; | ||||
| 		return(result); | ||||
| 	case EX_MOD: | ||||
| 	assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT); | ||||
| 		result.e_v.e_con = leaf1.e_v.e_con % leaf2.e_v.e_con; | ||||
| 		return(result); | ||||
| 	case EX_LSHIFT: | ||||
| 	assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT); | ||||
| 		result.e_v.e_con = leaf1.e_v.e_con << leaf2.e_v.e_con; | ||||
| 		return(result); | ||||
| 	case EX_RSHIFT: | ||||
| 	assert(leaf1.e_typ == EV_INT && leaf2.e_typ == EV_INT); | ||||
| 		result.e_v.e_con = leaf1.e_v.e_con >> leaf2.e_v.e_con; | ||||
| 		return(result); | ||||
| 	case EX_NOT: | ||||
| 	assert(leaf1.e_typ == EV_INT); | ||||
| 		result.e_v.e_con = !leaf1.e_v.e_con; | ||||
| 		return(result); | ||||
| 	case EX_COMP: | ||||
| 	assert(leaf1.e_typ == EV_INT); | ||||
| 		result.e_v.e_con = ~leaf1.e_v.e_con; | ||||
| 		return(result); | ||||
| 	case EX_STRING: | ||||
| 		result.e_typ = EV_ADDR; | ||||
| 		result.e_v.e_addr.ea_str = codestrings[node->ex_lnode]; | ||||
| 		result.e_v.e_addr.ea_off = 0; | ||||
| 		return(result); | ||||
| 	case EX_DEFINED: | ||||
| 		result.e_v.e_con=leaf1.e_typ!=EV_UNDEF; | ||||
| 		return(result); | ||||
| 	case EX_SUBREG: | ||||
| 		result.e_typ = EV_REG; | ||||
| 		tp= &fakestack[stackheight-node->ex_lnode]; | ||||
| 		assert(tp->t_token == -1); | ||||
| 		tmpreg= tp->t_att[0].ar; | ||||
| #if MAXMEMBERS!=0 | ||||
| 		if (node->ex_rnode) | ||||
| 			tmpreg=machregs[tmpreg].r_members[node->ex_rnode-1]; | ||||
| #endif | ||||
| 		result.e_v.e_reg=tmpreg; | ||||
| 		return(result); | ||||
| 	case EX_TOSTRING: | ||||
| 	assert(leaf1.e_typ == EV_INT); | ||||
| 		result.e_typ = EV_ADDR; | ||||
| 		result.e_v.e_addr.ea_str = 0; | ||||
| 		result.e_v.e_addr.ea_off = leaf1.e_v.e_con; | ||||
| 		return(result); | ||||
| #ifdef REGVARS | ||||
| 	case EX_INREG: | ||||
| 	assert(leaf1.e_typ == EV_INT); | ||||
| 		if ((result.e_v.e_con = isregvar((long) leaf1.e_v.e_con))>0) | ||||
| 			result.e_v.e_con = machregs[result.e_v.e_con].r_size; | ||||
| 		return(result); | ||||
| 	case EX_REGVAR: | ||||
| 	assert(leaf1.e_typ == EV_INT); | ||||
| 		i = isregvar((long) leaf1.e_v.e_con); | ||||
| 		if (i<=0)  | ||||
| 			return(undefres); | ||||
| 		result.e_typ = EV_REG; | ||||
| 		result.e_v.e_reg=i; | ||||
| 		return(result); | ||||
| #endif | ||||
| 	case EX_UMINUS: | ||||
| 	assert(leaf1.e_typ == EV_INT); | ||||
| 		result.e_v.e_con = -leaf1.e_v.e_con; | ||||
| 		return(result); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										64
									
								
								mach/proto/ncg/data.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								mach/proto/ncg/data.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,64 @@ | |||
| /* $Header$ */ | ||||
| 
 | ||||
| typedef struct cost { | ||||
| 	short ct_space; | ||||
| 	short ct_time; | ||||
| } cost_t,*cost_p; | ||||
| 
 | ||||
| typedef struct { | ||||
| 	string ea_str; | ||||
| 	word ea_off; | ||||
| } addr_t; | ||||
| 
 | ||||
| typedef struct { | ||||
| 	int     t_token;        /* kind of token, -1 for register */ | ||||
| 	union { | ||||
| 		word aw;	/* integer type */ | ||||
| 		addr_t aa;	/* address type */ | ||||
| 		int ar;		/* register type */ | ||||
| 	} t_att[TOKENSIZE]; | ||||
| } token_t,*token_p; | ||||
| 
 | ||||
| struct reginfo { | ||||
| 	int     r_repr;                 /* index in string table */ | ||||
| 	int     r_size;                 /* size in bytes */ | ||||
| #if MAXMEMBERS!=0 | ||||
| 	int     r_members[MAXMEMBERS];  /* register contained within this reg */ | ||||
| 	short	r_clash[REGSETSIZE];	/* set of clashing registers */ | ||||
| #endif | ||||
| 	int     r_refcount;             /* Times in use */ | ||||
| 	token_t r_contents;             /* Current contents */ | ||||
| 	int     r_tcount;               /* Temporary count difference */ | ||||
| }; | ||||
| 
 | ||||
| #if MAXMEMBERS!=0 | ||||
| #define clash(a,b) ((machregs[a].r_clash[(b)>>4]&(1<<((b)&017)))!=0) | ||||
| #else | ||||
| #define clash(a,b) ((a)==(b)) | ||||
| #endif | ||||
| 
 | ||||
| typedef struct { | ||||
| 	int     t_size;                 /* size in bytes */ | ||||
| 	cost_t  t_cost;                 /* cost in bytes and time */  | ||||
| 	byte    t_type[TOKENSIZE];      /* types of attributes, TT_??? */ | ||||
| 	int     t_format;               /* index of formatstring */ | ||||
| } tkdef_t,*tkdef_p; | ||||
| 
 | ||||
| struct emline { | ||||
| 	int     em_instr; | ||||
| 	int     em_optyp; | ||||
| 	string  em_soper; | ||||
| 	union { | ||||
| 		word    em_ioper; | ||||
| 		long	em_loper; | ||||
| 	} em_u; | ||||
| }; | ||||
| 
 | ||||
| #define OPNO 0 | ||||
| #define OPINT 1 | ||||
| #define OPSYMBOL 2 | ||||
| 
 | ||||
| typedef struct { | ||||
| 	int rl_n;       /* number in list */ | ||||
| 	int rl_list[NREGS]; | ||||
| } rl_t,*rl_p; | ||||
							
								
								
									
										105
									
								
								mach/proto/ncg/equiv.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								mach/proto/ncg/equiv.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,105 @@ | |||
| #ifndef NORCSID | ||||
| static char rcsid[] = "$Header$"; | ||||
| #endif | ||||
| 
 | ||||
| #include "assert.h" | ||||
| #include "equiv.h" | ||||
| #include "param.h" | ||||
| #include "tables.h" | ||||
| #include "types.h" | ||||
| #include <cgg_cg.h> | ||||
| #include "data.h" | ||||
| #include "result.h" | ||||
| #include "extern.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  * Author: Hans van Staveren | ||||
|  */ | ||||
| 
 | ||||
| extern string myalloc(); | ||||
| 
 | ||||
| int rar[MAXCREG]; | ||||
| rl_p *lar; | ||||
| int maxindex; | ||||
| int regclass[NREGS]; | ||||
| struct perm *perms; | ||||
| 
 | ||||
| struct perm * | ||||
| tuples(regls,nregneeded) rl_p *regls; { | ||||
| 	int class=0; | ||||
| 	register i,j; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * First compute equivalence classes of registers. | ||||
| 	 */ | ||||
| 
 | ||||
| 	for (i=0;i<NREGS;i++) { | ||||
| 		regclass[i] = class++; | ||||
| 		if (getrefcount(i) == 0) { | ||||
| 			for (j=0;j<i;j++) { | ||||
| 				if (eqregclass(i,j) && | ||||
| 				    eqtoken(&machregs[i].r_contents, | ||||
| 					    &machregs[j].r_contents)) { | ||||
| 					regclass[i] = regclass[j]; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Now create tuples through a recursive function | ||||
| 	 */ | ||||
| 
 | ||||
| 	maxindex = nregneeded; | ||||
| 	lar = regls; | ||||
| 	perms = 0; | ||||
| 	permute(0); | ||||
| 	return(perms); | ||||
| } | ||||
| 
 | ||||
| permute(index) { | ||||
| 	register struct perm *pp; | ||||
| 	register rl_p rlp; | ||||
| 	register i,j; | ||||
| 
 | ||||
| 	if (index == maxindex) { | ||||
| 		for (pp=perms; pp != 0; pp=pp->p_next) { | ||||
| 			for (i=0; i<maxindex; i++) | ||||
| 				if (regclass[rar[i]] != regclass[pp->p_rar[i]]) | ||||
| 					goto diff; | ||||
| 			for (i=0; i<maxindex; i++) | ||||
| 				for (j=0; j<i; j++) | ||||
| 					if (clash(rar[i],rar[j]) != | ||||
| 					    clash(pp->p_rar[i],pp->p_rar[j])) | ||||
| 						goto diff; | ||||
| 			return; | ||||
| 		    diff: ; | ||||
| 		} | ||||
| 		pp = (struct perm *) myalloc(sizeof ( *pp )); | ||||
| 		pp->p_next = perms; | ||||
| 		for (i=0; i<maxindex; i++) | ||||
| 			pp->p_rar[i] = rar[i]; | ||||
| 		perms = pp; | ||||
| 	} else { | ||||
| 		rlp=lar[index]; | ||||
| 		for (i=rlp->rl_n-1; i>=0; i--) { | ||||
| 			rar[index] = rlp->rl_list[i]; | ||||
| 			permute(index+1); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										8
									
								
								mach/proto/ncg/equiv.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								mach/proto/ncg/equiv.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| /* $Header$ */ | ||||
| 
 | ||||
| #define MAXCREG 4 | ||||
| 
 | ||||
| struct perm { | ||||
| 	struct perm *p_next; | ||||
| 	int p_rar[MAXCREG]; | ||||
| }; | ||||
							
								
								
									
										50
									
								
								mach/proto/ncg/extern.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								mach/proto/ncg/extern.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,50 @@ | |||
| /* $Header$ */ | ||||
| 
 | ||||
| extern int maxply;                      /* amount of lookahead allowed */ | ||||
| extern int stackheight;                 /* # of tokens on fakestack */ | ||||
| extern token_t fakestack[];             /* fakestack itself */ | ||||
| extern int nallreg;                     /* number of allocated registers */ | ||||
| extern int allreg[];                    /* array of allocated registers */ | ||||
| extern token_p curtoken;                /* pointer to current token */ | ||||
| extern result_t dollar[];               /* Values of $1,$2 etc.. */ | ||||
| extern int nemlines;                    /* # of EM instructions in core */ | ||||
| extern struct emline emlines[];         /* EM instructions itself */ | ||||
| extern struct emline *emp;              /* pointer to current instr */ | ||||
| extern struct emline *saveemp;		/* pointer to start of pattern */ | ||||
| extern int tokpatlen;                   /* length of current stackpattern */ | ||||
| extern rl_p curreglist;                 /* side effect of findcoerc() */ | ||||
| #ifndef NDEBUG | ||||
| extern int Debug;                       /* on/off debug printout */ | ||||
| #endif | ||||
| 
 | ||||
| /*
 | ||||
|  * Next descriptions are external declarations for tables created | ||||
|  * by bootgram. | ||||
|  * All definitions are to be found in tables.c (Not for humans) | ||||
|  */ | ||||
| 
 | ||||
| extern byte coderules[];                /* pseudo code for cg itself */ | ||||
| extern char stregclass[];               /* static register class */ | ||||
| extern struct reginfo machregs[];       /* register info */ | ||||
| extern tkdef_t tokens[];                /* token info */ | ||||
| extern node_t enodes[];                 /* expression nodes */ | ||||
| extern string codestrings[];            /* table of strings */ | ||||
| extern set_t machsets[];                /* token expression table */ | ||||
| extern inst_t tokeninstances[];         /* token instance description table */ | ||||
| extern move_t moves[];                  /* move descriptors */ | ||||
| extern test_t tests[];                  /* test descriptors */ | ||||
| extern byte pattern[];                  /* EM patterns */ | ||||
| extern int pathash[256];                /* Indices into previous */ | ||||
| extern c1_t c1coercs[];                 /* coercions type 1 */ | ||||
| #ifdef MAXSPLIT | ||||
| extern c2_t c2coercs[];                 /* coercions type 2 */ | ||||
| #endif MAXSPLIT | ||||
| extern c3_t c3coercs[];                 /* coercions type 3 */ | ||||
| extern struct reginfo **reglist[];	/* lists of registers per property */ | ||||
| 
 | ||||
| #define eqregclass(r1,r2) (stregclass[r1]==stregclass[r2]) | ||||
| 
 | ||||
| #ifdef REGVARS | ||||
| extern int nregvar[];			/* # of register variables per type */ | ||||
| extern int *rvnumbers[];		/* lists of numbers */ | ||||
| #endif | ||||
							
								
								
									
										676
									
								
								mach/proto/ncg/fillem.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										676
									
								
								mach/proto/ncg/fillem.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,676 @@ | |||
| #ifndef NORCSID | ||||
| static char rcsid2[] = "$Header$"; | ||||
| #endif | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include "assert.h" | ||||
| #include <em_spec.h> | ||||
| #include <em_pseu.h> | ||||
| #include <em_flag.h> | ||||
| #include <em_ptyp.h> | ||||
| #include <em_mes.h> | ||||
| #include "mach.h" | ||||
| #include "param.h" | ||||
| #include "tables.h" | ||||
| #include "types.h" | ||||
| #include <cgg_cg.h> | ||||
| #include "data.h" | ||||
| #include "result.h" | ||||
| #ifdef REGVARS | ||||
| #include "regvar.h" | ||||
| #include <em_reg.h> | ||||
| #endif | ||||
| #include "extern.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  * Author: Hans van Staveren | ||||
|  */ | ||||
| 
 | ||||
| #ifndef newplb			/* retrofit for older mach.h */ | ||||
| #define newplb newilb | ||||
| #endif | ||||
| 
 | ||||
| #ifdef fmt_id | ||||
| #ifdef id_first | ||||
| It is an error to define both fmt_id and id_first. | ||||
| Read the documentation. | ||||
| #endif | ||||
| #endif | ||||
| 
 | ||||
| #ifdef fmt_ilb | ||||
| #ifdef ilb_fmt | ||||
| It is an error to define both fmt_ilb and ilb_fmt. | ||||
| Read the documentation. | ||||
| #endif | ||||
| #endif | ||||
| 
 | ||||
| /* segment types for switchseg() */ | ||||
| #define SEGTXT          0 | ||||
| #define SEGCON          1 | ||||
| #define SEGROM          2 | ||||
| #define SEGBSS          3 | ||||
| 
 | ||||
| long con(); | ||||
| 
 | ||||
| #define get8()  getc(emfile) | ||||
| 
 | ||||
| #define MAXSTR 256 | ||||
| 
 | ||||
| FILE *emfile; | ||||
| extern FILE *codefile; | ||||
| 
 | ||||
| int nextispseu,savetab1; | ||||
| int opcode; | ||||
| int offtyp; | ||||
| long argval; | ||||
| int dlbval; | ||||
| char str[MAXSTR],argstr[32],labstr[32]; | ||||
| int strsiz; | ||||
| int holno=0; | ||||
| int procno=0; | ||||
| int curseg= -1; | ||||
| int part_size=0; | ||||
| word part_word=0; | ||||
| int endofprog=0; | ||||
| #ifdef REGVARS | ||||
| int regallowed=0; | ||||
| #endif | ||||
| 
 | ||||
| extern char em_flag[]; | ||||
| extern short em_ptyp[]; | ||||
| extern long atol(); | ||||
| extern double atof(); | ||||
| 
 | ||||
| #define sp_cstx sp_cst2 | ||||
| 
 | ||||
| string tostring(); | ||||
| string holstr(); | ||||
| string strarg(); | ||||
| string mystrcpy(); | ||||
| long get32(); | ||||
| 
 | ||||
| in_init(filename) char *filename; { | ||||
| 
 | ||||
| 	if ((emfile=freopen(filename,"r",stdin))==NULL) | ||||
| 		error("Can't open %s",filename); | ||||
| 	if (get16()!=sp_magic) | ||||
| 		error("Bad format %s",filename); | ||||
| } | ||||
| 
 | ||||
| in_finish() { | ||||
| } | ||||
| 
 | ||||
| fillemlines() { | ||||
| 	register int t,i; | ||||
| 	register struct emline *lp; | ||||
| 
 | ||||
| 	while ((emlines+nemlines)-emp<MAXEMLINES-5) { | ||||
| 		assert(nemlines<MAXEMLINES); | ||||
| 		if (nextispseu) { | ||||
| 			emlines[nemlines].em_instr=0; | ||||
| 			return; | ||||
| 		} | ||||
| 		lp = &emlines[nemlines++]; | ||||
| 
 | ||||
| 		switch(t=table1()) { | ||||
| 		default: | ||||
| 			error("unknown instruction byte"); | ||||
| 		case sp_ilb1: | ||||
| 		case sp_ilb2: | ||||
| 		case sp_fpseu: | ||||
| 		case sp_dlb1: | ||||
| 		case sp_dlb2: | ||||
| 		case sp_dnam: | ||||
| 			nextispseu=1; savetab1=t; | ||||
| 			nemlines--; | ||||
| 			lp->em_instr = 0; | ||||
| 			return; | ||||
| 		case EOF: | ||||
| 			nextispseu=1; savetab1=t; | ||||
| 			endofprog=1; | ||||
| 			nemlines--; | ||||
| 			lp->em_instr = 0; | ||||
| 			return; | ||||
| 		case sp_fmnem: | ||||
| 			lp->em_instr = opcode; | ||||
| 			break; | ||||
| 		} | ||||
| 		i=em_flag[lp->em_instr-sp_fmnem] & EM_PAR; | ||||
| 		if ( i == PAR_NO ) { | ||||
| 			lp->em_optyp = OPNO; | ||||
| 			lp->em_soper = 0; | ||||
| 			continue; | ||||
| 		} | ||||
| 		t= em_ptyp[i]; | ||||
| 		t= getarg(t); | ||||
| 		switch(i) { | ||||
| 		case PAR_L: | ||||
| 			assert(t == sp_cstx); | ||||
| 			if (argval >= 0) | ||||
| 				argval += TEM_BSIZE; | ||||
| 			lp->em_optyp = OPINT; | ||||
| 			lp->em_u.em_ioper = argval; | ||||
| 			lp->em_soper = tostring((word) argval); | ||||
| 			continue; | ||||
| 		case PAR_G: | ||||
| 			if (t != sp_cstx) | ||||
| 				break; | ||||
| 			lp->em_optyp = OPSYMBOL; | ||||
| 			lp->em_soper = holstr((word) argval); | ||||
| 			continue; | ||||
| 		case PAR_B: | ||||
| 			t = sp_ilb2; | ||||
| 			break; | ||||
| 		case PAR_D: | ||||
| 			assert(t == sp_cstx); | ||||
| 			lp->em_optyp = OPSYMBOL; | ||||
| 			lp->em_soper = strarg(t); | ||||
| 			lp->em_u.em_loper = argval; | ||||
| 			continue; | ||||
| 		} | ||||
| 		lp->em_soper = strarg(t); | ||||
| 		if (t==sp_cend) | ||||
| 			lp->em_optyp = OPNO; | ||||
| 		else if (t==sp_cstx) { | ||||
| 			lp->em_optyp = OPINT; | ||||
| 			lp->em_u.em_ioper = argval; | ||||
| 		} else | ||||
| 			lp->em_optyp = OPSYMBOL; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| dopseudo() { | ||||
| 	register b,t; | ||||
| 	register full n; | ||||
| 	register long save; | ||||
| 	word romcont[MAXROM+1]; | ||||
| 	int nromwords; | ||||
| 	int rombit,rommask; | ||||
| 	unsigned dummy,stackupto(); | ||||
| 
 | ||||
| 	if (nextispseu==0 || nemlines>0) | ||||
| 		error("No table entry for %d",emlines[0].em_instr); | ||||
| 	nextispseu=0; | ||||
| 	switch(savetab1) { | ||||
| 	case sp_ilb1: | ||||
| 	case sp_ilb2: | ||||
| 		swtxt(); | ||||
| 		dummy = stackupto(&fakestack[stackheight-1],maxply,TRUE); | ||||
| 		cleanregs(); | ||||
| 		strarg(savetab1); | ||||
| 		newilb(argstr); | ||||
| #ifndef NDEBUG | ||||
| 		{ extern int Debug; extern char * strtdebug; | ||||
| 		if (strcmp(strtdebug,argstr)==0) | ||||
| 			Debug = strtdebug[-2]-'0'; | ||||
| 		} | ||||
| #endif | ||||
| 		return; | ||||
| 	case sp_dlb1: | ||||
| 	case sp_dlb2: | ||||
| 	case sp_dnam: | ||||
| 		strarg(savetab1); | ||||
| 		savelab(); | ||||
| 		return; | ||||
| 	case sp_fpseu: | ||||
| 		break; | ||||
| 	case EOF: | ||||
| 		swtxt(); | ||||
| 		in_finish(); | ||||
| 		out_finish(); | ||||
| 		popstr(0); | ||||
| 		tstoutput(); | ||||
| 		exit(0); | ||||
| 	default: | ||||
| 		error("Unknown opcode %d",savetab1); | ||||
| 	} | ||||
| 	switch (opcode) { | ||||
| 	case ps_hol: | ||||
| 		sprintf(labstr,hol_fmt,++holno); | ||||
| 	case ps_bss: | ||||
| 		getarg(cst_ptyp); | ||||
| 		n = (full) argval; | ||||
| 		t = getarg(val_ptyp); | ||||
| 		save = argval; | ||||
| 		getarg(cst_ptyp); | ||||
| 		b = (int) argval; | ||||
| 		argval = save; | ||||
| 		bss(n,t,b); | ||||
| 		break; | ||||
| 	case ps_con: | ||||
| 		switchseg(SEGCON); | ||||
| 		dumplab(); | ||||
| 		con(getarg(val_ptyp)); | ||||
| 		while ((t = getarg(any_ptyp)) != sp_cend) | ||||
| 			con(t); | ||||
| 		break; | ||||
| 	case ps_rom: | ||||
| 		switchseg(SEGROM); | ||||
| 		xdumplab(); | ||||
| 		nromwords=0; | ||||
| 		rommask=0; | ||||
| 		rombit=1; | ||||
| 		t=getarg(val_ptyp); | ||||
| 		while (t!=sp_cend) { | ||||
| 			if (t==sp_cstx && nromwords<MAXROM) { | ||||
| 				romcont[nromwords] = (word) argval; | ||||
| 				rommask |= rombit; | ||||
| 			} | ||||
| 			nromwords++; | ||||
| 			rombit <<= 1; | ||||
| 			con(t); | ||||
| 			t=getarg(any_ptyp); | ||||
| 		} | ||||
| 		if (rommask != 0) { | ||||
| 			romcont[MAXROM]=rommask; | ||||
| 			enterglo(labstr,romcont); | ||||
| 		} | ||||
| 		labstr[0]=0; | ||||
| 		break; | ||||
| 	case ps_mes: | ||||
| 		getarg(ptyp(sp_cst2)); | ||||
| 		if (argval == ms_emx) { | ||||
| 			getarg(ptyp(sp_cst2)); | ||||
| 			if (argval != TEM_WSIZE) | ||||
| 				fatal("bad word size"); | ||||
| 			getarg(ptyp(sp_cst2)); | ||||
| 			if (argval != TEM_PSIZE) | ||||
| 				fatal("bad pointer size"); | ||||
| 			if ( getarg(any_ptyp)!=sp_cend ) | ||||
| 				fatal("too many parameters"); | ||||
| #ifdef REGVARS | ||||
| 		} else if (argval == ms_gto) { | ||||
| 			getarg(ptyp(sp_cend)); | ||||
| 			if (!regallowed) | ||||
| 				error("mes 3 not allowed here"); | ||||
| 			fixregvars(TRUE); | ||||
| 			regallowed=0; | ||||
| 		} else if (argval == ms_reg) { | ||||
| 			long r_off; | ||||
| 			int r_size,r_type,r_score; | ||||
| 			struct regvar *linkreg(); | ||||
| 
 | ||||
| 			if (!regallowed) | ||||
| 				error("mes 3 not allowed here"); | ||||
| 			if(getarg(ptyp(sp_cst2)|ptyp(sp_cend)) == sp_cend) { | ||||
| 				fixregvars(FALSE); | ||||
| 				regallowed=0; | ||||
| 			} else { | ||||
| 				r_off = argval; | ||||
|   				if (r_off >= 0) | ||||
|   					r_off += TEM_BSIZE; | ||||
| 				getarg(ptyp(sp_cst2)); | ||||
| 				r_size = argval; | ||||
| 				getarg(ptyp(sp_cst2)); | ||||
| 				r_type = argval; | ||||
| 				if (r_type<reg_any || r_type>reg_float) | ||||
| 					fatal("Bad type in register message"); | ||||
| 				if(getarg(ptyp(sp_cst2)|ptyp(sp_cend)) == sp_cend) | ||||
| 					r_score = 0; | ||||
| 				else { | ||||
| 					r_score = argval; | ||||
| 					if ( getarg(any_ptyp)!=sp_cend ) | ||||
| 						fatal("too many parameters"); | ||||
| 				} | ||||
| 				tryreg(linkreg(r_off,r_size,r_type,r_score),r_type); | ||||
| 			} | ||||
| #endif | ||||
| 		} else | ||||
| 			mes((word)argval); | ||||
| 		break; | ||||
| 	case ps_exa: | ||||
| 		strarg(getarg(sym_ptyp)); | ||||
| 		ex_ap(argstr); | ||||
| 		break; | ||||
| 	case ps_ina: | ||||
| 		strarg(getarg(sym_ptyp)); | ||||
| 		in_ap(argstr); | ||||
| 		break; | ||||
| 	case ps_exp: | ||||
| 		strarg(getarg(ptyp(sp_pnam))); | ||||
| 		ex_ap(argstr); | ||||
| 		break; | ||||
| 	case ps_inp: | ||||
| 		strarg(getarg(ptyp(sp_pnam))); | ||||
| 		in_ap(argstr); | ||||
| 		break; | ||||
| 	case ps_pro: | ||||
| 		switchseg(SEGTXT); | ||||
| 		procno++; | ||||
| 		strarg(getarg(ptyp(sp_pnam))); | ||||
| 		newplb(argstr); | ||||
| 		getarg(cst_ptyp); | ||||
| 		prolog((full)argval); | ||||
| #ifdef REGVARS | ||||
| 		regallowed++; | ||||
| #endif | ||||
| 		break; | ||||
| 	case ps_end: | ||||
| 		getarg(cst_ptyp | ptyp(sp_cend)); | ||||
| 		cleanregs(); | ||||
| #ifdef REGVARS | ||||
| 		unlinkregs(); | ||||
| #endif | ||||
| 		tstoutput(); | ||||
| 		break; | ||||
| 	default: | ||||
| 		error("No table entry for %d",savetab1); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /* ----- input ----- */ | ||||
| 
 | ||||
| int getarg(typset) { | ||||
| 	register t,argtyp; | ||||
| 
 | ||||
| 	argtyp = t = table2(); | ||||
| 	if (t == EOF) | ||||
| 		fatal("unexpected EOF"); | ||||
| 	t -= sp_fspec; | ||||
| 	t = 1 << t; | ||||
| 	if ((typset & t) == 0) | ||||
| 		error("bad argument type %d",argtyp); | ||||
| 	return(argtyp); | ||||
| } | ||||
| 
 | ||||
| int table1() { | ||||
| 	register i; | ||||
| 
 | ||||
| 	i = get8(); | ||||
| 	if (i < sp_fmnem+sp_nmnem && i >= sp_fmnem) { | ||||
| 		opcode = i; | ||||
| 		return(sp_fmnem); | ||||
| 	} | ||||
| 	if (i < sp_fpseu+sp_npseu && i >= sp_fpseu) { | ||||
| 		opcode = i; | ||||
| 		return(sp_fpseu); | ||||
| 	} | ||||
| 	if (i < sp_filb0+sp_nilb0 && i >= sp_filb0) { | ||||
| 		argval = i - sp_filb0; | ||||
| 		return(sp_ilb2); | ||||
| 	} | ||||
| 	return(table3(i)); | ||||
| } | ||||
| 
 | ||||
| int table2() { | ||||
| 	register i; | ||||
| 
 | ||||
| 	i = get8(); | ||||
| 	if (i < sp_fcst0+sp_ncst0 && i >= sp_fcst0) { | ||||
| 		argval = i - sp_zcst0; | ||||
| 		return(sp_cstx); | ||||
| 	} | ||||
| 	return(table3(i)); | ||||
| } | ||||
| 
 | ||||
| int table3(i) { | ||||
| 	word consiz; | ||||
| 
 | ||||
| 	switch(i) { | ||||
| 	case sp_ilb1: | ||||
| 		argval = get8(); | ||||
| 		break; | ||||
| 	case sp_dlb1: | ||||
| 		dlbval = get8(); | ||||
| 		break; | ||||
| 	case sp_dlb2: | ||||
| 		dlbval = get16(); | ||||
| 		break; | ||||
| 	case sp_cst2: | ||||
| 		i = sp_cstx; | ||||
| 	case sp_ilb2: | ||||
| 		argval = get16(); | ||||
| 		break; | ||||
| 	case sp_cst4: | ||||
| 		i = sp_cstx; | ||||
| 		argval = get32(); | ||||
| 		break; | ||||
| 	case sp_dnam: | ||||
| 	case sp_pnam: | ||||
| 	case sp_scon: | ||||
| 		getstring(); | ||||
| 		break; | ||||
| 	case sp_doff: | ||||
| 		offtyp = getarg(sym_ptyp); | ||||
| 		getarg(cst_ptyp); | ||||
| 		break; | ||||
| 	case sp_icon: | ||||
| 	case sp_ucon: | ||||
| 	case sp_fcon: | ||||
| 		getarg(cst_ptyp); | ||||
| 		consiz = (word) argval; | ||||
| 		getstring(); | ||||
| 		argval = consiz; | ||||
| 		break; | ||||
| 	} | ||||
| 	return(i); | ||||
| } | ||||
| 
 | ||||
| int get16() { | ||||
| 	register int l_byte, h_byte; | ||||
| 
 | ||||
| 	l_byte = get8(); | ||||
| 	h_byte = get8(); | ||||
| 	if ( h_byte>=128 ) h_byte -= 256 ; | ||||
| 	return l_byte | (h_byte*256) ; | ||||
| } | ||||
| 
 | ||||
| long get32() { | ||||
| 	register long l; | ||||
| 	register int h_byte; | ||||
| 
 | ||||
| 	l = get8(); | ||||
| 	l |= ((unsigned) get8())*256 ; | ||||
| 	l |= get8()*256L*256L ; | ||||
| 	h_byte = get8() ; | ||||
| 	if ( h_byte>=128 ) h_byte -= 256 ; | ||||
| 	return l | (h_byte*256L*256*256L) ; | ||||
| } | ||||
| 
 | ||||
| getstring() { | ||||
| 	register char *p; | ||||
| 	register n; | ||||
| 
 | ||||
| 	getarg(cst_ptyp); | ||||
| 	if (argval < 0 || argval > MAXSTR-1) | ||||
| 		fatal("string/identifier too long"); | ||||
| 	strsiz = n = (int) argval; | ||||
| 	p = str; | ||||
| 	while (--n >= 0) | ||||
| 		*p++ = get8(); | ||||
| 	*p++ = '\0'; | ||||
| } | ||||
| 
 | ||||
| char *strarg(t) { | ||||
| 	register char *p; | ||||
| 
 | ||||
| 	switch (t) { | ||||
| 	case sp_ilb1: | ||||
| 	case sp_ilb2: | ||||
| #ifdef fmt_ilb | ||||
| 		fmt_ilb(procno,((int) argval),argstr); | ||||
| #else | ||||
| 		sprintf(argstr,ilb_fmt,procno,(int)argval); | ||||
| #endif | ||||
| 		break; | ||||
| 	case sp_dlb1: | ||||
| 	case sp_dlb2: | ||||
| 		sprintf(argstr,dlb_fmt,dlbval); | ||||
| 		break; | ||||
| 	case sp_cstx: | ||||
| 		sprintf(argstr,cst_fmt,(full)argval); | ||||
| 		break; | ||||
| 	case sp_dnam: | ||||
| 	case sp_pnam: | ||||
| #ifdef fmt_id | ||||
| 		fmt_id(str,argstr); | ||||
| #else | ||||
| 		p = argstr; | ||||
| 		if (strsiz < 8 || str[0] == id_first) | ||||
| 			*p++ = id_first; | ||||
| 		sprintf(p,"%.*s",strsiz,str); | ||||
| #endif | ||||
| 		break; | ||||
| 	case sp_doff: | ||||
| 		strarg(offtyp); | ||||
| 		for (p = argstr; *p; p++) | ||||
| 			; | ||||
| 		if (argval >= 0) | ||||
| 			*p++ = '+'; | ||||
| 		sprintf(p,off_fmt,(full)argval); | ||||
| 		break; | ||||
| 	case sp_cend: | ||||
| 		return(""); | ||||
| 	} | ||||
| 	return(mystrcpy(argstr)); | ||||
| } | ||||
| 
 | ||||
| bss(n,t,b) full n; { | ||||
| 	register long s; | ||||
| 
 | ||||
| 	if (n % TEM_WSIZE) | ||||
| 		fatal("bad BSS size"); | ||||
| 	if (b==0 | ||||
| #ifdef BSS_INIT | ||||
| 	    || (t==sp_cstx && argval==BSS_INIT) | ||||
| #endif BSS_INIT | ||||
| 		) { | ||||
| 		switchseg(SEGBSS); | ||||
| 		newlbss(labstr,n); | ||||
| 		labstr[0]=0; | ||||
| 		return; | ||||
| 	} | ||||
| 	switchseg(SEGCON); | ||||
| 	dumplab(); | ||||
| 	while (n > 0) | ||||
| 		n -= (s = con(t)); | ||||
| 	if (s % TEM_WSIZE) | ||||
| 		fatal("bad BSS initializer"); | ||||
| } | ||||
| 
 | ||||
| long con(t) { | ||||
| 	register i; | ||||
| 
 | ||||
| 	strarg(t); | ||||
| 	switch (t) { | ||||
| 	case sp_ilb1: | ||||
| 	case sp_ilb2: | ||||
| 	case sp_pnam: | ||||
| 		part_flush(); | ||||
| 		con_ilb(argstr); | ||||
| 		return((long)TEM_PSIZE); | ||||
| 	case sp_dlb1: | ||||
| 	case sp_dlb2: | ||||
| 	case sp_dnam: | ||||
| 	case sp_doff: | ||||
| 		part_flush(); | ||||
| 		con_dlb(argstr); | ||||
| 		return((long)TEM_PSIZE); | ||||
| 	case sp_cstx: | ||||
| 		con_part(TEM_WSIZE,(word)argval); | ||||
| 		return((long)TEM_WSIZE); | ||||
| 	case sp_scon: | ||||
| 		for (i = 0; i < strsiz; i++) | ||||
| 			con_part(1,(word) str[i]); | ||||
| 		return((long)strsiz); | ||||
| 	case sp_icon: | ||||
| 	case sp_ucon: | ||||
| 		if (argval > TEM_WSIZE) { | ||||
| 			part_flush(); | ||||
| 			con_mult((word)argval); | ||||
| 		} else { | ||||
| 			con_part((int)argval,(word)atol(str)); | ||||
| 		} | ||||
| 		return(argval); | ||||
| 	case sp_fcon: | ||||
| 		part_flush(); | ||||
| 		con_float(); | ||||
| 		return(argval); | ||||
| 	} | ||||
| 	assert(FALSE); | ||||
| 	/* NOTREACHED */ | ||||
| } | ||||
| 
 | ||||
| extern char *segname[]; | ||||
| 
 | ||||
| swtxt() { | ||||
| 	switchseg(SEGTXT); | ||||
| } | ||||
| 
 | ||||
| switchseg(s) { | ||||
| 
 | ||||
| 	if (s == curseg) | ||||
| 		return; | ||||
| 	part_flush(); | ||||
| 	if ((curseg = s) >= 0) | ||||
| 		fprintf(codefile,"%s\n",segname[s]); | ||||
| } | ||||
| 
 | ||||
| savelab() { | ||||
| 	register char *p,*q; | ||||
| 
 | ||||
| 	part_flush(); | ||||
| 	if (labstr[0]) { | ||||
| 		dlbdlb(argstr,labstr); | ||||
| 		return; | ||||
| 	} | ||||
| 	p = argstr; | ||||
| 	q = labstr; | ||||
| 	while (*q++ = *p++) | ||||
| 		; | ||||
| } | ||||
| 
 | ||||
| dumplab() { | ||||
| 
 | ||||
| 	if (labstr[0] == 0) | ||||
| 		return; | ||||
| 	assert(part_size == 0); | ||||
| 	newdlb(labstr); | ||||
| 	labstr[0] = 0; | ||||
| } | ||||
| 
 | ||||
| xdumplab() { | ||||
| 
 | ||||
| 	if (labstr[0] == 0) | ||||
| 		return; | ||||
| 	assert(part_size == 0); | ||||
| 	newdlb(labstr); | ||||
| } | ||||
| 
 | ||||
| part_flush() { | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Each new data fragment and each data label starts at | ||||
| 	 * a new target machine word | ||||
| 	 */ | ||||
| 	if (part_size == 0) | ||||
| 		return; | ||||
| 	con_cst(part_word); | ||||
| 	part_size = 0; | ||||
| 	part_word = 0; | ||||
| } | ||||
| 
 | ||||
| string holstr(n) word n; { | ||||
| 
 | ||||
| 	sprintf(str,hol_off,n,holno); | ||||
| 	return(mystrcpy(str)); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* ----- machine dependent routines ----- */ | ||||
| 
 | ||||
| #include        "mach.c" | ||||
							
								
								
									
										143
									
								
								mach/proto/ncg/gencode.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								mach/proto/ncg/gencode.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,143 @@ | |||
| #ifndef NORCSID | ||||
| static char rcsid[] = "$Header$"; | ||||
| #endif | ||||
| 
 | ||||
| #include "assert.h" | ||||
| #include <stdio.h> | ||||
| #include "param.h" | ||||
| #include "tables.h" | ||||
| #include "types.h" | ||||
| #include <cgg_cg.h> | ||||
| #include "data.h" | ||||
| #include "result.h" | ||||
| #include "extern.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  * Author: Hans van Staveren | ||||
|  */ | ||||
| 
 | ||||
| string mystrcpy(); | ||||
| 
 | ||||
| FILE *codefile; | ||||
| 
 | ||||
| out_init(filename) char *filename; { | ||||
| 
 | ||||
| #ifndef NDEBUG | ||||
| 	static char stderrbuff[BUFSIZ]; | ||||
| 
 | ||||
|     if (Debug) { | ||||
| 	codefile = stderr; | ||||
| 	if (!isatty(2)) | ||||
| 		setbuf(stderr,stderrbuff); | ||||
|     } else { | ||||
| #endif | ||||
| 	if (filename == (char *) 0) | ||||
| 		codefile = stdout; | ||||
| 	else | ||||
| 		if ((codefile=freopen(filename,"w",stdout))==NULL) | ||||
| 			error("Can't create %s",filename); | ||||
| #ifndef NDEBUG | ||||
|     } | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| out_finish() { | ||||
| 
 | ||||
| #ifndef NDEBUG | ||||
| 	if (Debug) | ||||
| 		fflush(stderr); | ||||
| 	else | ||||
| #endif | ||||
| 		fclose(codefile); | ||||
| #ifdef TABLEDEBUG | ||||
| 	termlset(); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| tstoutput() { | ||||
| 
 | ||||
| 	if (ferror(codefile)) | ||||
| 		error("Write error on output"); | ||||
| } | ||||
| 
 | ||||
| genstr(stringno) { | ||||
| 
 | ||||
| 	fputs(codestrings[stringno],codefile); | ||||
| } | ||||
| 
 | ||||
| string ad2str(ad) addr_t ad; { | ||||
| 	static char buf[100]; | ||||
| 
 | ||||
| 	if (ad.ea_str==0) | ||||
| 		ad.ea_str=""; | ||||
| 	sprintf(buf,"%s%c%ld",ad.ea_str,ad.ea_off>=0 ? '+' : ' ',(long)ad.ea_off); | ||||
| 	return(mystrcpy(buf)); | ||||
| } | ||||
| 
 | ||||
| praddr(ad) addr_t ad; { | ||||
| 
 | ||||
| 	if (ad.ea_str==0) | ||||
| 		fprintf(codefile,WRD_FMT,ad.ea_off); | ||||
| 	else { | ||||
| 		fprintf(codefile,"%s",ad.ea_str); | ||||
| 		if (ad.ea_off<0) | ||||
| 			fprintf(codefile,WRD_FMT,ad.ea_off);		 | ||||
| 		else if(ad.ea_off>0) { | ||||
| 			fputc('+',codefile); | ||||
| 			fprintf(codefile,WRD_FMT,ad.ea_off); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| gennl() { | ||||
| 	fputc('\n',codefile); | ||||
| } | ||||
| 
 | ||||
| prtoken(tp,leadingchar) token_p tp; { | ||||
| 	register c; | ||||
| 	register char *code; | ||||
| 	register tkdef_p tdp; | ||||
| 
 | ||||
| 	fputc(leadingchar,codefile); | ||||
| 	if (tp->t_token == -1) { | ||||
| 		fprintf(codefile,"%s",codestrings[machregs[tp->t_att[0].ar].r_repr]); | ||||
| 		return; | ||||
| 	} | ||||
| 	tdp = &tokens[tp->t_token]; | ||||
| 	assert(tdp->t_format != -1); | ||||
| 	code = codestrings[tdp->t_format]; | ||||
| 	while ((c = *code++) != 0) { | ||||
| 		if (c>=' ' && c<='~') | ||||
| 			fputc(c,codefile); | ||||
| 		else { | ||||
| 			assert(c>0 && c<=TOKENSIZE); | ||||
| 			switch(tdp->t_type[c-1]) { | ||||
| 			default: | ||||
| 				assert(FALSE); | ||||
| 			case EV_INT: | ||||
| 				fprintf(codefile,WRD_FMT,tp->t_att[c-1].aw); | ||||
| 				break; | ||||
| 			case EV_ADDR: | ||||
| 				praddr(tp->t_att[c-1].aa); | ||||
| 				break; | ||||
| 			case EV_REG: | ||||
| 				fprintf(codefile,"%s",codestrings[machregs[tp->t_att[c-1].ar].r_repr]); | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										52
									
								
								mach/proto/ncg/glosym.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								mach/proto/ncg/glosym.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,52 @@ | |||
| #ifndef NORCSID | ||||
| static char rcsid[] = "$Header$"; | ||||
| #endif | ||||
| 
 | ||||
| #include "param.h" | ||||
| #include "tables.h" | ||||
| #include "types.h" | ||||
| #include "glosym.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  * Author: Hans van Staveren | ||||
|  */ | ||||
| 
 | ||||
| extern string myalloc(); | ||||
| 
 | ||||
| glosym_p glolist= (glosym_p) 0; | ||||
| 
 | ||||
| enterglo(name,romp) string name; word *romp; { | ||||
| 	register glosym_p gp; | ||||
| 	register i; | ||||
| 
 | ||||
| 	gp = (glosym_p) myalloc(sizeof *gp); | ||||
| 	gp->gl_next = glolist; | ||||
| 	gp->gl_name = (string) myalloc(strlen(name)+1); | ||||
| 	strcpy(gp->gl_name,name); | ||||
| 	for (i=0;i<=MAXROM;i++) | ||||
| 		gp->gl_rom[i] = romp[i]; | ||||
| 	glolist = gp; | ||||
| } | ||||
| 
 | ||||
| glosym_p lookglo(name) string name; { | ||||
| 	register glosym_p gp; | ||||
| 
 | ||||
| 	for (gp=glolist;gp != (glosym_p) 0; gp=gp->gl_next) | ||||
| 		if (strcmp(gp->gl_name,name)==0) | ||||
| 			return(gp); | ||||
| 	return((glosym_p) 0); | ||||
| } | ||||
							
								
								
									
										9
									
								
								mach/proto/ncg/glosym.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								mach/proto/ncg/glosym.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | |||
| /* $Header$ */ | ||||
| 
 | ||||
| typedef struct glosym { | ||||
| 	struct glosym *gl_next; | ||||
| 	string	       gl_name; | ||||
| 	word	       gl_rom[MAXROM+1]; | ||||
| } glosym_t,*glosym_p; | ||||
| 
 | ||||
| glosym_p lookglo(); | ||||
							
								
								
									
										99
									
								
								mach/proto/ncg/main.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								mach/proto/ncg/main.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,99 @@ | |||
| #ifndef NORCSID | ||||
| static char rcsid[] = "$Header$"; | ||||
| #endif | ||||
| 
 | ||||
| #include "param.h" | ||||
| #include "tables.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  * Author: Hans van Staveren | ||||
|  */ | ||||
| 
 | ||||
| char *progname; | ||||
| extern char startupcode[]; | ||||
| int maxply=1; | ||||
| #ifndef NDEBUG | ||||
| int Debug=0; | ||||
| char *strtdebug=""; | ||||
| #endif | ||||
| 
 | ||||
| extern int endofprog; | ||||
| 
 | ||||
| main(argc,argv) char **argv; { | ||||
| 	register unsigned n; | ||||
| 	extern unsigned cc1,cc2,cc3,cc4; | ||||
| 	unsigned ggd(); | ||||
| 
 | ||||
| 	progname = argv[0]; | ||||
| 	while (--argc && **++argv == '-') { | ||||
| 		switch(argv[0][1]) { | ||||
| #ifndef NDEBUG | ||||
| 		case 'd': | ||||
| 			if ((Debug = argv[0][2]) != 0) { | ||||
| 				Debug -= '0'; | ||||
| 				if (argv[0][3] == '@') { | ||||
| 					Debug = 0; | ||||
| 					strtdebug = &argv[0][4]; | ||||
| 				} | ||||
| 			} else | ||||
| 				Debug++; | ||||
| 			break; | ||||
| #endif | ||||
| #ifdef TABLEDEBUG | ||||
| 		case 'u': | ||||
| 		case 'U': | ||||
| 			initlset(argv[0]+1); | ||||
| 			break; | ||||
| #endif | ||||
| 		case 'p': | ||||
| 			maxply = atoi(argv[0]+2); | ||||
| 			break; | ||||
| 		case 'w':	/* weight percentage for size */ | ||||
| 			n=atoi(argv[0]+2); | ||||
| 			cc1 *= n; | ||||
| 			cc2 *= 50; | ||||
| 			cc3 *= (100-n); | ||||
| 			cc4 *= 50; | ||||
| 			n=ggd(cc1,cc2); | ||||
| 			cc1 /= n; | ||||
| 			cc2 /= n; | ||||
| 			n=ggd(cc3,cc4); | ||||
| 			cc3 /= n; | ||||
| 			cc4 /= n; | ||||
| 			break; | ||||
| 		default: | ||||
| 			error("Unknown flag %c",argv[0][1]); | ||||
| 		} | ||||
| 	} | ||||
| 	if (argc < 1 || argc > 2) | ||||
| 		error("Usage: %s EMfile [ asfile ]",progname); | ||||
| 	in_init(argv[0]); | ||||
| 	out_init(argv[1]); | ||||
| 	readcodebytes(); | ||||
| 	itokcost(); | ||||
| 	codegen(startupcode,maxply,TRUE,MAXINT,0); | ||||
| 	error("Bombed out of codegen"); | ||||
| } | ||||
| 
 | ||||
| unsigned ggd(a,b) register unsigned a,b; { | ||||
| 	register unsigned c; | ||||
| 
 | ||||
| 	do { | ||||
| 		c = a%b; a=b; b=c; | ||||
| 	} while (c!=0); | ||||
| 	return(a); | ||||
| } | ||||
							
								
								
									
										149
									
								
								mach/proto/ncg/move.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								mach/proto/ncg/move.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,149 @@ | |||
| #ifndef NORCSID | ||||
| static char rcsid[] = "$Header$"; | ||||
| #endif | ||||
| 
 | ||||
| #include "assert.h" | ||||
| #include "param.h" | ||||
| #include "tables.h" | ||||
| #include "types.h" | ||||
| #include <cgg_cg.h> | ||||
| #include "data.h" | ||||
| #include "result.h" | ||||
| #include "extern.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  * Author: Hans van Staveren | ||||
|  */ | ||||
| 
 | ||||
| unsigned costcalc(); | ||||
| 
 | ||||
| move(tp1,tp2,ply,toplevel,maxcost) token_p tp1,tp2; unsigned maxcost; { | ||||
| 	register move_p mp; | ||||
| 	register unsigned t; | ||||
| 	register struct reginfo *rp; | ||||
| 	tkdef_p tdp; | ||||
| 	int i; | ||||
| 	unsigned codegen(); | ||||
| 
 | ||||
| 	if (eqtoken(tp1,tp2)) | ||||
| 		return(0); | ||||
| 	if (tp2->t_token == -1) { | ||||
| 		if (tp1->t_token == -1) { | ||||
| 			if (eqtoken(&machregs[tp1->t_att[0].ar].r_contents, | ||||
| 				    &machregs[tp2->t_att[0].ar].r_contents) && | ||||
| 			      machregs[tp1->t_att[0].ar].r_contents.t_token!=0) | ||||
| 				return(0); | ||||
| 			erasereg(tp2->t_att[0].ar); | ||||
| 			machregs[tp2->t_att[0].ar].r_contents = | ||||
| 			  machregs[tp1->t_att[0].ar].r_contents ; | ||||
| 
 | ||||
| 		} else { | ||||
| 			if (eqtoken(&machregs[tp2->t_att[0].ar].r_contents,tp1)) | ||||
| 				return(0); | ||||
| 			erasereg(tp2->t_att[0].ar); | ||||
| 			machregs[tp2->t_att[0].ar].r_contents = *tp1; | ||||
| 		} | ||||
| 		for (rp=machregs+1;rp<machregs+NREGS;rp++) { | ||||
| 			if (rp->r_contents.t_token == 0) | ||||
| 				continue; | ||||
| 			assert(rp->r_contents.t_token > 0); | ||||
| 			tdp = &tokens[rp->r_contents.t_token]; | ||||
| 			for (i=0;i<TOKENSIZE;i++) | ||||
| 				if (tdp->t_type[i] == EV_REG && | ||||
| 				    clash(rp->r_contents.t_att[i].ar,tp2->t_att[0].ar)) { | ||||
| 					erasereg(rp-machregs); | ||||
| 					break; | ||||
| 				} | ||||
| 		} | ||||
| 	} else if (tp1->t_token == -1) { | ||||
| 		if (eqtoken(tp2,&machregs[tp1->t_att[0].ar].r_contents)) | ||||
| 			return(0); | ||||
| 		machregs[tp1->t_att[0].ar].r_contents = *tp2; | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * If we arrive here the move must really be executed | ||||
| 	 */ | ||||
| 	for (mp=moves;mp->m_set1>=0;mp++) { | ||||
| 		if (!match(tp1,&machsets[mp->m_set1],mp->m_expr1)) | ||||
| 			continue; | ||||
| 		if (match(tp2,&machsets[mp->m_set2],mp->m_expr2)) | ||||
| 			break; | ||||
| 		/*
 | ||||
| 		 * Correct move rule is found | ||||
| 		 */ | ||||
| 	} | ||||
| 	assert(mp->m_set1>=0); | ||||
| 	/*
 | ||||
| 	 * To get correct interpretation of things like %[1] | ||||
| 	 * in move code we stack tp2 and tp1. This little trick | ||||
| 	 * saves a lot of testing in other places. | ||||
| 	 */ | ||||
| 
 | ||||
| 	fakestack[stackheight] = *tp2; | ||||
| 	fakestack[stackheight+1] = *tp1; | ||||
| 	stackheight += 2; | ||||
| 	t = codegen(&coderules[mp->m_cindex],ply,toplevel,maxcost,0); | ||||
| 	stackheight -= 2; | ||||
| 	return(t); | ||||
| } | ||||
| 
 | ||||
| #define cocoreg machregs[0].r_contents | ||||
| 
 | ||||
| setcc(tp) token_p tp; { | ||||
| 
 | ||||
| 	cocoreg = *tp; | ||||
| } | ||||
| 
 | ||||
| test(tp,ply,toplevel,maxcost) token_p tp; unsigned maxcost; { | ||||
| 	register test_p mp; | ||||
| 	register unsigned t; | ||||
| 	register struct reginfo *rp; | ||||
| 	tkdef_p tdp; | ||||
| 	int i; | ||||
| 	unsigned codegen(); | ||||
| 
 | ||||
| 	if (cocoreg.t_token!=0) { | ||||
| 		if (eqtoken(tp,&cocoreg)) | ||||
| 			return(0); | ||||
| 		if (tp->t_token == -1) { | ||||
| 			if (eqtoken(&machregs[tp->t_att[0].ar].r_contents,&cocoreg)) | ||||
| 				return(0); | ||||
| 		} | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * If we arrive here the test must really be executed | ||||
| 	 */ | ||||
| 	for (mp=tests;mp->t_set>=0;mp++) { | ||||
| 		if (match(tp,&machsets[mp->t_set],mp->t_expr)) | ||||
| 			break; | ||||
| 		/*
 | ||||
| 		 * Correct move rule is found | ||||
| 		 */ | ||||
| 	} | ||||
| 	assert(mp->t_set>=0); | ||||
| 	/*
 | ||||
| 	 * To get correct interpretation of things like %[1] | ||||
| 	 * in test code we stack tp. This little trick | ||||
| 	 * saves a lot of testing in other places. | ||||
| 	 */ | ||||
| 
 | ||||
| 	fakestack[stackheight] = *tp; | ||||
| 	stackheight++; | ||||
| 	t = codegen(&coderules[mp->t_cindex],ply,toplevel,maxcost,0); | ||||
| 	stackheight--; | ||||
| 	return(t); | ||||
| } | ||||
							
								
								
									
										133
									
								
								mach/proto/ncg/nextem.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								mach/proto/ncg/nextem.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,133 @@ | |||
| #ifndef NORCSID | ||||
| static char rcsid[] = "$Header$"; | ||||
| #endif | ||||
| 
 | ||||
| #include <em_spec.h> | ||||
| #include <em_flag.h> | ||||
| #include "assert.h" | ||||
| #include "param.h" | ||||
| #include "tables.h" | ||||
| #include "types.h" | ||||
| #include <cgg_cg.h> | ||||
| #include "data.h" | ||||
| #include "result.h" | ||||
| #include "extern.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  * Author: Hans van Staveren | ||||
|  */ | ||||
| 
 | ||||
| #ifndef NDEBUG | ||||
| #include <stdio.h> | ||||
| extern char em_mnem[][4]; | ||||
| #endif | ||||
| 
 | ||||
| byte *trypat(bp,len) register byte *bp; { | ||||
| 	register patlen,i; | ||||
| 	result_t result; | ||||
| 
 | ||||
| 	getint(patlen,bp); | ||||
| 	if (len == 3) { | ||||
| 		if (patlen < 3) | ||||
| 			return(0); | ||||
| 	} else { | ||||
| 		if (patlen != len) | ||||
| 			return(0); | ||||
| 	} | ||||
| 	for(i=0;i<patlen;i++) | ||||
| 		if (emp[i].em_instr != (*bp++&BMASK)) | ||||
| 			return(0); | ||||
| 	for (i=0;i<patlen;i++) | ||||
| 		if (emp[i].em_optyp==OPNO) | ||||
| 			dollar[i].e_typ=EV_UNDEF; | ||||
| 		else if ((dollar[i].e_typ=argtyp(emp[i].em_instr))==EV_INT) | ||||
| 			dollar[i].e_v.e_con=emp[i].em_u.em_ioper; | ||||
| 		else { | ||||
| 			dollar[i].e_v.e_addr.ea_str=emp[i].em_soper; | ||||
| 			dollar[i].e_v.e_addr.ea_off=0; | ||||
| 		} | ||||
| 	getint(i,bp); | ||||
| 	if (i!=0) { | ||||
| 		result = compute(&enodes[i]); | ||||
| 		if (result.e_typ != EV_INT || result.e_v.e_con == 0) | ||||
| 			return(0); | ||||
| 	} | ||||
| #ifndef NDEBUG | ||||
| 	if (Debug) { | ||||
| 		fprintf(stderr,"Matched:"); | ||||
| 		for (i=0;i<patlen;i++) | ||||
| 			fprintf(stderr," %3.3s",em_mnem[emp[i].em_instr-sp_fmnem]); | ||||
| 		fprintf(stderr,"\n"); | ||||
| 	} | ||||
| #endif | ||||
| 	saveemp = emp; | ||||
| 	emp += patlen; | ||||
| 	return(bp); | ||||
| } | ||||
| 
 | ||||
| extern char em_flag[]; | ||||
| 
 | ||||
| argtyp(mn) { | ||||
| 
 | ||||
| 	switch(em_flag[mn-sp_fmnem]&EM_PAR) { | ||||
| 	case PAR_W: | ||||
| 	case PAR_S: | ||||
| 	case PAR_Z: | ||||
| 	case PAR_O: | ||||
| 	case PAR_N: | ||||
| 	case PAR_L: | ||||
| 	case PAR_F: | ||||
| 	case PAR_R: | ||||
| 	case PAR_C: | ||||
| 		return(EV_INT); | ||||
| 	default: | ||||
| 		return(EV_ADDR); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| byte *nextem(toplevel) { | ||||
| 	register i; | ||||
| 	short hash[3]; | ||||
| 	register byte *bp; | ||||
| 	byte *cp; | ||||
| 	int index; | ||||
| 	register struct emline *ep; | ||||
| 
 | ||||
| 	if (toplevel) { | ||||
| 		if (nemlines && emp>emlines) { | ||||
| 			nemlines -= emp-emlines; | ||||
| 			for (i=0,ep=emlines;i<nemlines;i++) | ||||
| 				*ep++ = *emp++; | ||||
| 			emp=emlines; | ||||
| 		} | ||||
| 		fillemlines(); | ||||
| 	} | ||||
| 	hash[0] = emp[0].em_instr; | ||||
| 	hash[1] = (hash[0]<<4) ^ emp[1].em_instr; | ||||
| 	hash[2] = (hash[1]<<4) ^ emp[2].em_instr; | ||||
| 	for (i=2;i>=0;i--) { | ||||
| 		index = pathash[hash[i]&BMASK]; | ||||
| 		while (index != 0) { | ||||
| 			bp = &pattern[index]; | ||||
| 			if ( bp[PO_HASH] == (hash[i]>>8)) | ||||
| 				if ((cp=trypat(&bp[PO_MATCH],i+1)) != 0) | ||||
| 					return(cp); | ||||
| 			index = (bp[PO_NEXT]&BMASK) | (bp[PO_NEXT+1]<<8); | ||||
| 		} | ||||
| 	} | ||||
| 	return(0); | ||||
| } | ||||
							
								
								
									
										20
									
								
								mach/proto/ncg/param.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								mach/proto/ncg/param.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | |||
| /* $Header$ */ | ||||
| 
 | ||||
| #define BMASK 0377 | ||||
| #define BSHIFT 8 | ||||
| 
 | ||||
| #define TRUE    1 | ||||
| #define FALSE   0 | ||||
| 
 | ||||
| #define MAXINT 32767 | ||||
| #define INFINITY (MAXINT+100) | ||||
| 
 | ||||
| #define MAXROM 3 | ||||
| 
 | ||||
| /*
 | ||||
|  * Tunable constants | ||||
|  */ | ||||
| 
 | ||||
| #define MAXEMLINES 20 | ||||
| #define MAXFSTACK 20 | ||||
| #define MAXTDBUG 32 | ||||
							
								
								
									
										175
									
								
								mach/proto/ncg/reg.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								mach/proto/ncg/reg.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,175 @@ | |||
| #ifndef NORCSID | ||||
| static char rcsid[] = "$Header$"; | ||||
| #endif | ||||
| 
 | ||||
| #include "assert.h" | ||||
| #include "param.h" | ||||
| #include "tables.h" | ||||
| #include "types.h" | ||||
| #include <cgg_cg.h> | ||||
| #include "data.h" | ||||
| #include "result.h" | ||||
| #include "extern.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  * Author: Hans van Staveren | ||||
|  */ | ||||
| 
 | ||||
| chrefcount(regno,amount,tflag) { | ||||
| 	register struct reginfo *rp; | ||||
| 	register i; | ||||
| 
 | ||||
| 	rp= &machregs[regno]; | ||||
| #if MAXMEMBERS!=0 | ||||
| 	if (rp->r_members[0]==0) { | ||||
| #endif | ||||
| 		rp->r_refcount += amount; | ||||
| 		if (tflag) | ||||
| 			rp->r_tcount += amount; | ||||
| 		assert(rp->r_refcount >= 0); | ||||
| #if MAXMEMBERS!=0 | ||||
| 	} else | ||||
| 		for (i=0;i<MAXMEMBERS;i++) | ||||
| 			if (rp->r_members[i]!=0) | ||||
| 				chrefcount(rp->r_members[i],amount,tflag); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| getrefcount(regno) { | ||||
| 	register struct reginfo *rp; | ||||
| 	register i,maxcount; | ||||
| 
 | ||||
| 	rp= &machregs[regno]; | ||||
| #if MAXMEMBERS!=0 | ||||
| 	if (rp->r_members[0]==0) | ||||
| #endif | ||||
| 		return(rp->r_refcount); | ||||
| #if MAXMEMBERS!=0 | ||||
| 	else { | ||||
| 		maxcount=0; | ||||
| 		for (i=0;i<MAXMEMBERS;i++) | ||||
| 			if (rp->r_members[i]!=0) | ||||
| 				maxcount=max(maxcount,getrefcount(rp->r_members[i])); | ||||
| 		return(maxcount); | ||||
| 	} | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| erasereg(regno) { | ||||
| 	register struct reginfo *rp; | ||||
| 
 | ||||
| #if MAXMEMBERS==0 | ||||
| 	awayreg(regno); | ||||
| #else | ||||
| 	for (rp=machregs+1;rp<machregs+NREGS;rp++) | ||||
| 		if (rp->r_clash[regno>>4]&(1<<(regno&017))) | ||||
| 			awayreg(rp-machregs); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| awayreg(regno) { | ||||
| 	register struct reginfo *rp; | ||||
| 	register tkdef_p tdp; | ||||
| 	register i; | ||||
| 
 | ||||
| 	rp = &machregs[regno]; | ||||
| 	rp->r_contents.t_token = 0; | ||||
| 	for (i=0;i<TOKENSIZE;i++) | ||||
| 		rp->r_contents.t_att[i].aw = 0; | ||||
| 
 | ||||
| 	/* Now erase recursively all registers containing
 | ||||
| 	 * something using this one | ||||
| 	 */ | ||||
| 	for (rp=machregs;rp<machregs+NREGS;rp++) { | ||||
| 		if (rp->r_contents.t_token == -1) { | ||||
| 			if (rp->r_contents.t_att[0].ar == regno) | ||||
| 				erasereg(rp-machregs); | ||||
| 		} else { | ||||
| 			tdp= & tokens[rp->r_contents.t_token]; | ||||
| 			for (i=0;i<TOKENSIZE;i++) | ||||
| 				if (tdp->t_type[i] == EV_REG &&  | ||||
| 				    rp->r_contents.t_att[i].ar == regno) { | ||||
| 					erasereg(rp-machregs); | ||||
| 					break; | ||||
| 				} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| cleanregs() { | ||||
| 	register struct reginfo *rp; | ||||
| 	register i; | ||||
| 
 | ||||
| 	for (rp=machregs;rp<machregs+NREGS;rp++) { | ||||
| 		rp->r_contents.t_token = 0; | ||||
| 		for (i=0;i<TOKENSIZE;i++) | ||||
| 			rp->r_contents.t_att[i].aw = 0; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| #ifndef NDEBUG | ||||
| inctcount(regno) { | ||||
| 	register struct reginfo *rp; | ||||
| 	register i; | ||||
| 
 | ||||
| 	rp = &machregs[regno]; | ||||
| #if MAXMEMBERS!=0 | ||||
| 	if (rp->r_members[0] == 0) { | ||||
| #endif | ||||
| 		rp->r_tcount++; | ||||
| #if MAXMEMBERS!=0 | ||||
| 	} else  { | ||||
| 		for (i=0;i<MAXMEMBERS;i++) | ||||
| 			if (rp->r_members[i] != 0) | ||||
| 				inctcount(rp->r_members[i]); | ||||
| 	} | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| chkregs() { | ||||
| 	register struct reginfo *rp; | ||||
| 	register token_p tp; | ||||
| 	register tkdef_p tdp; | ||||
| 	int i; | ||||
| 
 | ||||
| 	for (rp=machregs+1;rp<machregs+NREGS;rp++) { | ||||
| 		assert(rp->r_tcount==0); | ||||
| 	} | ||||
| 	for (tp=fakestack;tp<fakestack+stackheight;tp++) { | ||||
| 		if (tp->t_token == -1) | ||||
| 			inctcount(tp->t_att[0].ar); | ||||
| 		else { | ||||
| 			tdp = &tokens[tp->t_token]; | ||||
| 			for (i=0;i<TOKENSIZE;i++) | ||||
| 				if (tdp->t_type[i]==EV_REG) | ||||
| 					inctcount(tp->t_att[i].ar); | ||||
| 		} | ||||
| 	} | ||||
| #ifdef REGVARS | ||||
| #include <em_reg.h> | ||||
| 	for(i=reg_any;i<=reg_float;i++) { | ||||
| 		int j; | ||||
| 		for(j=0;j<nregvar[i];j++) | ||||
| 			inctcount(rvnumbers[i][j]); | ||||
| 	} | ||||
| #endif REGVARS | ||||
| 	for (rp=machregs+1;rp<machregs+NREGS;rp++) { | ||||
| 		assert(rp->r_refcount==rp->r_tcount); | ||||
| 		rp->r_tcount=0; | ||||
| 	} | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										151
									
								
								mach/proto/ncg/regvar.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								mach/proto/ncg/regvar.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,151 @@ | |||
| #include "assert.h" | ||||
| #include "param.h" | ||||
| #include "tables.h" | ||||
| 
 | ||||
| #ifdef REGVARS | ||||
| 
 | ||||
| #ifndef NORCSID | ||||
| static char rcsid[] = "$Header$"; | ||||
| #endif | ||||
| 
 | ||||
| #include "types.h" | ||||
| #include <cgg_cg.h> | ||||
| #include "data.h" | ||||
| #include "regvar.h" | ||||
| #include <em_reg.h> | ||||
| #include "result.h" | ||||
| #include "extern.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  * Author: Hans van Staveren | ||||
|  */ | ||||
| extern string myalloc(); | ||||
| struct regvar *rvlist; | ||||
| 
 | ||||
| struct regvar * | ||||
| linkreg(of,sz,tp,sc) long of; { | ||||
| 	register struct regvar *rvlp; | ||||
| 
 | ||||
| 	rvlp= (struct regvar *) myalloc(sizeof *rvlp); | ||||
| 	rvlp->rv_next = rvlist; | ||||
| 	rvlist=rvlp; | ||||
| 	rvlp->rv_off	= of; | ||||
| 	rvlp->rv_size	= sz; | ||||
| 	rvlp->rv_type	= tp; | ||||
| 	rvlp->rv_score	= sc; | ||||
| 	rvlp->rv_reg	= 0;	/* no register assigned yet */ | ||||
| 	return(rvlp); | ||||
| } | ||||
| 
 | ||||
| tryreg(rvlp,typ) register struct regvar *rvlp; { | ||||
| 	int score; | ||||
| 	register i; | ||||
| 	register struct regassigned *ra; | ||||
| 	struct regvar *save; | ||||
| 
 | ||||
| 	if (typ != reg_any && nregvar[typ]!=0) { | ||||
| 		if (machregs[rvnumbers[typ][0]].r_size!=rvlp->rv_size) | ||||
| 			score = -1; | ||||
| 		else | ||||
| 			score = regscore(rvlp->rv_off, | ||||
| 					 rvlp->rv_size, | ||||
| 					 rvlp->rv_type, | ||||
| 					 rvlp->rv_score, | ||||
| 					 typ);	/* machine dependent */ | ||||
| 		ra = regassigned[typ]; | ||||
| 		if (score>ra[nregvar[typ]-1].ra_score) { | ||||
| 			save = ra[nregvar[typ]-1].ra_rv; | ||||
| 			for (i=nregvar[typ]-1;i>0 && ra[i-1].ra_score<score;i--) | ||||
| 				ra[i] = ra[i-1]; | ||||
| 			ra[i].ra_rv = rvlp; | ||||
| 			ra[i].ra_score = score; | ||||
| 			if((rvlp=save)==0) | ||||
| 				return; | ||||
| 		} | ||||
| 	} | ||||
| 	if (nregvar[reg_any]==0) | ||||
| 		return; | ||||
| 	if (machregs[rvnumbers[reg_any][0]].r_size!=rvlp->rv_size) | ||||
| 		score = -1; | ||||
| 	else | ||||
| 		score = regscore(rvlp->rv_off, | ||||
| 				 rvlp->rv_size, | ||||
| 				 rvlp->rv_type, | ||||
| 				 rvlp->rv_score, | ||||
| 				 reg_any);	/* machine dependent */ | ||||
| 	ra = regassigned[reg_any]; | ||||
| 	if (score>ra[nregvar[reg_any]-1].ra_score) { | ||||
| 		for (i=nregvar[reg_any]-1;i>0 && ra[i-1].ra_score<score;i--) | ||||
| 			ra[i] = ra[i-1]; | ||||
| 		ra[i].ra_rv = rvlp; | ||||
| 		ra[i].ra_score = score; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fixregvars(saveall) { | ||||
| 	register struct regvar *rv; | ||||
| 	register rvtyp,i; | ||||
| 	 | ||||
| 	swtxt(); | ||||
| 	i_regsave();	/* machine dependent initialization */ | ||||
| 	for (rvtyp=reg_any;rvtyp<=reg_float;rvtyp++) { | ||||
| 	    for(i=0;i<nregvar[rvtyp];i++) | ||||
| 		if (saveall) { | ||||
| 			struct reginfo *rp; | ||||
| 			rp= &machregs[rvnumbers[rvtyp][i]]; | ||||
| 			regsave(codestrings[rp->r_repr],(long)-TEM_WSIZE,rp->r_size); | ||||
| 		} else if(regassigned[rvtyp][i].ra_score>0) { | ||||
| 			rv=regassigned[rvtyp][i].ra_rv; | ||||
| 			rv->rv_reg=rvnumbers[rvtyp][i]; | ||||
| 			regsave(codestrings[machregs[rv->rv_reg].r_repr], | ||||
| 				    rv->rv_off,rv->rv_size); | ||||
| 		} | ||||
| 	} | ||||
| 	f_regsave(); | ||||
| } | ||||
| 
 | ||||
| isregvar(off) long off; { | ||||
| 	register struct regvar *rvlp; | ||||
| 
 | ||||
| 	for(rvlp=rvlist;rvlp!=0;rvlp=rvlp->rv_next) | ||||
| 		if(rvlp->rv_off == off) | ||||
| 			return(rvlp->rv_reg); | ||||
| 	return(-1); | ||||
| } | ||||
| 
 | ||||
| unlinkregs() { | ||||
| 	register struct regvar *rvlp,*t; | ||||
| 	register struct regassigned *ra; | ||||
| 	int rvtyp,i; | ||||
| 
 | ||||
| 	for(rvlp=rvlist;rvlp!=0;rvlp=t) { | ||||
| 		t=rvlp->rv_next; | ||||
| 		myfree(rvlp); | ||||
| 	} | ||||
| 	rvlist=0; | ||||
| 	for (rvtyp=reg_any;rvtyp<=reg_float;rvtyp++) { | ||||
| 	    for(i=0;i<nregvar[rvtyp];i++) { | ||||
| 		ra= ®assigned[rvtyp][i]; | ||||
| 		ra->ra_rv = 0; | ||||
| 		ra->ra_score = 0; | ||||
| 	    } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| #endif REGVARS | ||||
| 
 | ||||
| /* nothing after this */ | ||||
							
								
								
									
										19
									
								
								mach/proto/ncg/regvar.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								mach/proto/ncg/regvar.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | |||
| /* $Header$ */ | ||||
| 
 | ||||
| struct regvar { | ||||
| 	struct regvar  *rv_next; | ||||
| 	long		rv_off; | ||||
| 	int		rv_size; | ||||
| 	int		rv_type; | ||||
| 	int		rv_score; | ||||
| 	int		rv_reg; | ||||
| }; | ||||
| 
 | ||||
| struct regassigned { | ||||
| 	struct regvar  *ra_rv; | ||||
| 	int		ra_score; | ||||
| }; | ||||
| 
 | ||||
| extern struct regvar *rvlist; | ||||
| extern int nregvar[]; | ||||
| extern struct regassigned *regassigned[]; | ||||
							
								
								
									
										19
									
								
								mach/proto/ncg/result.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								mach/proto/ncg/result.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | |||
| /* $Header$ */ | ||||
| 
 | ||||
| struct result { | ||||
| 	int	e_typ;		/* EV_INT,EV_REG,EV_STR */ | ||||
| 	union { | ||||
| 		word e_con; | ||||
| 		int e_reg; | ||||
| 		addr_t e_addr; | ||||
| 	} e_v;			/* value */ | ||||
| }; | ||||
| 
 | ||||
| #define EV_UNDEF 0 | ||||
| #define EV_INT	1 | ||||
| #define EV_REG	2 | ||||
| #define EV_ADDR	3 | ||||
| 
 | ||||
| typedef struct result result_t; | ||||
| 
 | ||||
| extern result_t compute(); | ||||
							
								
								
									
										150
									
								
								mach/proto/ncg/salloc.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								mach/proto/ncg/salloc.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,150 @@ | |||
| #ifndef NORCSID | ||||
| static char rcsid[] = "$Header$"; | ||||
| #endif | ||||
| 
 | ||||
| #include "assert.h" | ||||
| #include "param.h" | ||||
| #include "tables.h" | ||||
| #include "types.h" | ||||
| #include <cgg_cg.h> | ||||
| #include "data.h" | ||||
| #include "result.h" | ||||
| #include "extern.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  * Author: Hans van Staveren | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Package for string allocation and garbage collection. | ||||
|  * Call salloc(size) to get room for string. | ||||
|  * Every now and then call garbage_collect() from toplevel. | ||||
|  */ | ||||
| 
 | ||||
| #define MAXSTAB         500 | ||||
| #define THRESHOLD       200 | ||||
| 
 | ||||
| char *stab[MAXSTAB]; | ||||
| int nstab=0; | ||||
| string malloc(); | ||||
| 
 | ||||
| string myalloc(size) { | ||||
| 	register string p; | ||||
| 
 | ||||
| 	p = (string) malloc(size); | ||||
| 	if (p==0) | ||||
| 		fatal("Out of memory"); | ||||
| 	return(p); | ||||
| } | ||||
| 
 | ||||
| myfree(p) string p; { | ||||
| 
 | ||||
| 	free(p); | ||||
| } | ||||
| 
 | ||||
| popstr(nnstab) { | ||||
| 	register i; | ||||
| 
 | ||||
| 	for (i=nnstab;i<nstab;i++) | ||||
| 		myfree(stab[i]); | ||||
| 	nstab = nnstab; | ||||
| } | ||||
| 
 | ||||
| char *salloc(size) { | ||||
| 	register char *p; | ||||
| 
 | ||||
| 	if (nstab==MAXSTAB) | ||||
| 		fatal("String table overflow"); | ||||
| 	p = myalloc(size+1);    /* extra room for terminating zero */ | ||||
| 	stab[nstab++] = p; | ||||
| 	return(p); | ||||
| } | ||||
| 
 | ||||
| compar(p1,p2) char **p1,**p2; { | ||||
| 
 | ||||
| 	assert(*p1 != *p2); | ||||
| 	if (*p1 < *p2) | ||||
| 		return(-1); | ||||
| 	return(1); | ||||
| } | ||||
| 
 | ||||
| garbage_collect() { | ||||
| 	register i; | ||||
| 	struct emline *emlp; | ||||
| 	token_p tp; | ||||
| 	tkdef_p tdp; | ||||
| 	struct reginfo *rp; | ||||
| 	register char **fillp,**scanp; | ||||
| 	char used[MAXSTAB];     /* could be bitarray */ | ||||
| 
 | ||||
| 	if (nstab<THRESHOLD) | ||||
| 		return; | ||||
| 	qsort(stab,nstab,sizeof (char *),compar); | ||||
| 	for (i=0;i<nstab;i++) | ||||
| 		used[i]= FALSE; | ||||
| 	for(emlp=emlines;emlp<emlines+nemlines;emlp++) | ||||
| 		chkstr(emlp->em_soper,used); | ||||
| 	for (tp= fakestack;tp<&fakestack[stackheight];tp++) { | ||||
| 		if (tp->t_token== -1) | ||||
| 			continue; | ||||
| 		tdp = &tokens[tp->t_token]; | ||||
| 		for (i=0;i<TOKENSIZE;i++) | ||||
| 			if (tdp->t_type[i] == EV_ADDR) | ||||
| 				chkstr(tp->t_att[i].aa.ea_str,used); | ||||
| 	} | ||||
| 	for (rp= machregs+1; rp<machregs+NREGS; rp++) { | ||||
| 		tp = &rp->r_contents; | ||||
| 		assert(tp->t_token != -1); | ||||
| 		tdp= &tokens[tp->t_token]; | ||||
| 		for (i=0;i<TOKENSIZE;i++) | ||||
| 			if (tdp->t_type[i] == EV_ADDR) | ||||
| 				chkstr(tp->t_att[i].aa.ea_str,used); | ||||
| 	} | ||||
| 	for (i=0;i<nstab;i++) | ||||
| 		if (!used[i]) { | ||||
| 			myfree(stab[i]); | ||||
| 			stab[i]=0; | ||||
| 		} | ||||
| 	fillp=stab; | ||||
| 	for (scanp=stab;scanp<stab+nstab;scanp++) | ||||
| 		if (*scanp != 0) | ||||
| 			*fillp++ = *scanp; | ||||
| 	nstab = fillp-stab; | ||||
| } | ||||
| 
 | ||||
| chkstr(str,used) string str; char used[]; { | ||||
| 	register low,middle,high; | ||||
| 
 | ||||
| 	low=0; high=nstab-1; | ||||
| 	while (high>low) { | ||||
| 		middle= (low+high)>>1; | ||||
| 		if (str==stab[middle]) { | ||||
| 			used[middle]=1; | ||||
| 			return; | ||||
| 		} | ||||
| 		if (str<stab[middle]) | ||||
| 			high = middle-1; | ||||
| 		else | ||||
| 			low = middle+1; | ||||
| 	} | ||||
| 	if (low==high) { | ||||
| 		if (str==stab[low]) { | ||||
| 			used[low]=1; | ||||
| 		} | ||||
| 		return; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										78
									
								
								mach/proto/ncg/state.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								mach/proto/ncg/state.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,78 @@ | |||
| #ifndef NORCSID | ||||
| static char rcsid[] = "$Header$"; | ||||
| #endif | ||||
| 
 | ||||
| #include "assert.h" | ||||
| #include "param.h" | ||||
| #include "tables.h" | ||||
| #include "types.h" | ||||
| #include <cgg_cg.h> | ||||
| #include "data.h" | ||||
| #include "result.h" | ||||
| #include "state.h" | ||||
| #include "extern.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  * Author: Hans van Staveren | ||||
|  */ | ||||
| 
 | ||||
| extern int nstab;	/* salloc.c */ | ||||
| 
 | ||||
| savestatus(sp) register state_p sp; { | ||||
| 
 | ||||
| 	sp->st_sh = stackheight; | ||||
| 	bmove((short *)fakestack,(short *)sp->st_fs,stackheight*sizeof(token_t)); | ||||
| 	sp->st_na = nallreg; | ||||
| 	bmove((short *)allreg,(short *)sp->st_ar,nallreg*sizeof(int)); | ||||
| 	sp->st_ct = curtoken; | ||||
| 	bmove((short *)dollar,(short *)sp->st_do,LONGESTPATTERN*sizeof(result_t)); | ||||
| 	bmove((short *)machregs,(short *)sp->st_mr,NREGS*sizeof(struct reginfo)); | ||||
| 	sp->st_ne = nemlines; | ||||
| 	bmove((short *)emlines,(short *)sp->st_el,nemlines*sizeof(struct emline)); | ||||
| 	sp->st_em = emp; | ||||
| 	sp->st_se = saveemp; | ||||
| 	sp->st_tl = tokpatlen; | ||||
| 	sp->st_ns = nstab; | ||||
| } | ||||
| 
 | ||||
| restorestatus(sp) register state_p sp; { | ||||
| 
 | ||||
| 	stackheight = sp->st_sh; | ||||
| 	bmove((short *)sp->st_fs,(short *)fakestack,stackheight*sizeof(token_t)); | ||||
| 	nallreg = sp->st_na; | ||||
| 	bmove((short *)sp->st_ar,(short *)allreg,nallreg*sizeof(int)); | ||||
| 	curtoken = sp->st_ct; | ||||
| 	bmove((short *)sp->st_do,(short *)dollar,LONGESTPATTERN*sizeof(result_t)); | ||||
| 	bmove((short *)sp->st_mr,(short *)machregs,NREGS*sizeof(struct reginfo)); | ||||
| 	nemlines = sp->st_ne; | ||||
| 	bmove((short *)sp->st_el,(short *)emlines,nemlines*sizeof(struct emline)); | ||||
| 	emp = sp->st_em; | ||||
| 	saveemp = sp->st_se; | ||||
| 	tokpatlen = sp->st_tl; | ||||
| 	popstr(sp->st_ns); | ||||
| } | ||||
| 
 | ||||
| bmove(from,to,nbytes) register short *from,*to; register nbytes; { | ||||
| 
 | ||||
| 	if (nbytes<=0) | ||||
| 		return; | ||||
| 	assert(sizeof(short)==2 && (nbytes&1)==0); | ||||
| 	nbytes>>=1; | ||||
| 	do | ||||
| 		*to++ = *from++; | ||||
| 	while (--nbytes); | ||||
| } | ||||
							
								
								
									
										18
									
								
								mach/proto/ncg/state.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								mach/proto/ncg/state.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | |||
| /* $Header$ */ | ||||
| 
 | ||||
| typedef struct state { | ||||
| 	struct state *st_next;                  /* for linked list */ | ||||
| 	int st_sh;                              /* stackheight */ | ||||
| 	token_t st_fs[MAXFSTACK];               /* fakestack */ | ||||
| 	int st_na;                              /* nallreg */ | ||||
| 	int st_ar[MAXALLREG];                   /* allreg[] */ | ||||
| 	token_p st_ct;                          /* curtoken */ | ||||
| 	result_t st_do[LONGESTPATTERN];         /* dollar[] */ | ||||
| 	struct reginfo st_mr[NREGS];            /* machregs[] */ | ||||
| 	int st_ne;                              /* nemlines */ | ||||
| 	struct emline st_el[MAXEMLINES];        /* emlines[] */ | ||||
| 	struct emline *st_em;                   /* emp */ | ||||
| 	struct emline *st_se;			/* saveemp */ | ||||
| 	int st_tl;				/* tokpatlen */ | ||||
| 	int st_ns;				/* nstab */ | ||||
| } state_t,*state_p; | ||||
							
								
								
									
										617
									
								
								mach/proto/ncg/subr.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										617
									
								
								mach/proto/ncg/subr.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,617 @@ | |||
| #ifndef NORCSID | ||||
| static char rcsid[] = "$Header$"; | ||||
| #endif | ||||
| 
 | ||||
| #include "assert.h" | ||||
| #include <stdio.h> | ||||
| #include "param.h" | ||||
| #include "tables.h" | ||||
| #include "types.h" | ||||
| #include <cgg_cg.h> | ||||
| #include "data.h" | ||||
| #include "result.h" | ||||
| #include "extern.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  * Author: Hans van Staveren | ||||
|  */ | ||||
| 
 | ||||
| string myalloc(); | ||||
| unsigned codegen(); | ||||
| 
 | ||||
| match(tp,tep,optexp) register token_p tp; register set_p tep; { | ||||
| 	register bitno; | ||||
| 	token_p ct; | ||||
| 	result_t result; | ||||
| 
 | ||||
| 	if (tp->t_token == -1) {        /* register frame */ | ||||
| 		bitno = tp->t_att[0].ar; | ||||
| 		if (tep->set_val[bitno>>4]&(1<<(bitno&017))) | ||||
| 			if (tep->set_val[0]&1 || getrefcount(tp->t_att[0].ar)<=1) | ||||
| 				goto oklabel; | ||||
| 		return(0); | ||||
| 	} else {                /* token frame */ | ||||
| 		bitno = tp->t_token+NREGS; | ||||
| 		if ((tep->set_val[bitno>>4]&(1<<(bitno&017)))==0) | ||||
| 			return(0); | ||||
| 	} | ||||
|     oklabel: | ||||
| 	if (optexp==0) | ||||
| 		return(1); | ||||
| 	ct=curtoken; | ||||
| 	curtoken=tp; | ||||
| 	result=compute(&enodes[optexp]); | ||||
| 	curtoken=ct; | ||||
| 	return(result.e_v.e_con); | ||||
| } | ||||
| 
 | ||||
| instance(instno,token) register token_p token; { | ||||
| 	register inst_p inp; | ||||
| 	int i; | ||||
| 	register token_p tp; | ||||
| 	struct reginfo *rp; | ||||
| 	int regno; | ||||
| 	result_t result; | ||||
| 
 | ||||
| 	if (instno==0) { | ||||
| 		token->t_token = 0; | ||||
| 		for(i=0;i<TOKENSIZE;i++) | ||||
| 			token->t_att[i].aw=0; | ||||
| 		return; | ||||
| 	} | ||||
| 	inp= &tokeninstances[instno]; | ||||
| 	switch(inp->in_which) { | ||||
| 	default: | ||||
| 		assert(FALSE); | ||||
| 	case IN_COPY: | ||||
| 		tp= &fakestack[stackheight-inp->in_info[0]]; | ||||
| 		if (inp->in_info[1]==0) { | ||||
| 			*token = *tp; | ||||
| 		} else { | ||||
| 			token->t_token= -1; | ||||
| #if MAXMEMBERS!=0 | ||||
| 			assert(tp->t_token == -1); | ||||
| 			rp = &machregs[tp->t_att[0].ar]; | ||||
| 			token->t_att[0].ar=rp->r_members[inp->in_info[1]-1]; | ||||
| #else | ||||
| 			assert(FALSE); | ||||
| #endif | ||||
| 		} | ||||
| 		return; | ||||
| 	case IN_MEMB: | ||||
| 		tp= &fakestack[stackheight-inp->in_info[0]]; | ||||
| 		assert(inp->in_info[1]!=0); | ||||
| 		assert(tp->t_token>0); | ||||
| 		token->t_token= -1; | ||||
| 		assert(tokens[tp->t_token].t_type[inp->in_info[1]-1] == EV_REG); | ||||
| 		token->t_att[0].ar=tp->t_att[inp->in_info[1]-1].ar; | ||||
| 		return; | ||||
| 	case IN_RIDENT: | ||||
| 		token->t_token= -1; | ||||
| 		token->t_att[0].ar= inp->in_info[0]; | ||||
| 		return; | ||||
| 	case IN_ALLOC: | ||||
| 		token->t_token= -1; | ||||
| 		regno=allreg[inp->in_info[0]]; | ||||
| #if MAXMEMBERS!=0 | ||||
| 		if (inp->in_info[1]) | ||||
| 			regno=machregs[regno].r_members[inp->in_info[1]-1]; | ||||
| #endif | ||||
| 		token->t_att[0].ar = regno; | ||||
| 		return; | ||||
| #ifdef REGVARS | ||||
| 	case IN_S_DESCR: | ||||
| 	case IN_D_DESCR: | ||||
| 		result=compute(&enodes[inp->in_info[1]]); | ||||
| 		assert(result.e_typ==EV_INT); | ||||
| 		if ((regno=isregvar(result.e_v.e_con)) > 0) { | ||||
| 			token->t_token = -1; | ||||
| 			token->t_att[0].ar = regno; | ||||
| 			for(i=1;i<TOKENSIZE;i++) | ||||
| 				token->t_att[i].aw = 0; | ||||
| 			return; | ||||
| 		} | ||||
| 		/* fall through */ | ||||
| #endif | ||||
| 	case IN_DESCR: | ||||
| 		token->t_token=inp->in_info[0]; | ||||
| 		for (i=0;i<TOKENSIZE;i++) | ||||
| 			if (inp->in_info[i+1]==0) { | ||||
| 				assert(tokens[token->t_token].t_type[i]==0); | ||||
| 				token->t_att[i].aw=0; | ||||
| 			} else { | ||||
| 				result=compute(&enodes[inp->in_info[i+1]]); | ||||
| 				assert(tokens[token->t_token].t_type[i]==result.e_typ); | ||||
| 				if (result.e_typ==EV_INT) | ||||
| 					token->t_att[i].aw=result.e_v.e_con; | ||||
| 				else if (result.e_typ==EV_ADDR) | ||||
| 					token->t_att[i].aa= result.e_v.e_addr; | ||||
| 				else | ||||
| 					token->t_att[i].ar=result.e_v.e_reg; | ||||
| 			} | ||||
| 		return; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| cinstance(instno,token,tp,regno) register token_p token,tp; { | ||||
| 	register inst_p inp; | ||||
| 	int i; | ||||
| 	struct reginfo *rp; | ||||
| 	result_t result; | ||||
| 	int sh; /* saved stackheight */ | ||||
| 
 | ||||
| 	assert(instno!=0); | ||||
| 	inp= &tokeninstances[instno]; | ||||
| 	switch(inp->in_which) { | ||||
| 	default: | ||||
| 		assert(FALSE); | ||||
| 	case IN_COPY: | ||||
| 		assert(inp->in_info[0] == 1); | ||||
| 		if (inp->in_info[1]==0) { | ||||
| 			*token = *tp; | ||||
| 		} else { | ||||
| 			token->t_token= -1; | ||||
| #if MAXMEMBERS!=0 | ||||
| 			assert(tp->t_token == -1); | ||||
| 			rp = &machregs[tp->t_att[0].ar]; | ||||
| 			token->t_att[0].ar=rp->r_members[inp->in_info[1]-1]; | ||||
| #else | ||||
| 			assert(FALSE); | ||||
| #endif | ||||
| 		} | ||||
| 		return; | ||||
| 	case IN_MEMB: | ||||
| 		assert(inp->in_info[0] == 1); | ||||
| 		token->t_token= -1; | ||||
| 		assert(tp->t_token>0); | ||||
| 		assert(tokens[tp->t_token].t_type[inp->in_info[1]-1] == EV_REG); | ||||
| 		token->t_att[0].ar=tp->t_att[inp->in_info[1]-1].ar; | ||||
| 		return; | ||||
| 	case IN_RIDENT: | ||||
| 		token->t_token= -1; | ||||
| 		token->t_att[0].ar= inp->in_info[0]; | ||||
| 		return; | ||||
| 	case IN_ALLOC: | ||||
| 		token->t_token= -1; | ||||
| 		assert(inp->in_info[0]==0); | ||||
| #if MAXMEMBERS!=0 | ||||
| 		if (inp->in_info[1]) | ||||
| 			regno=machregs[regno].r_members[inp->in_info[1]-1]; | ||||
| #endif | ||||
| 		token->t_att[0].ar = regno; | ||||
| 		return; | ||||
| #ifdef REGVARS | ||||
| 	case IN_S_DESCR: | ||||
| 	case IN_D_DESCR: | ||||
| 		result=compute(&enodes[inp->in_info[1]]); | ||||
| 		assert(result.e_typ==EV_INT); | ||||
| 		if ((regno=isregvar(result.e_v.e_con)) > 0) { | ||||
| 			token->t_token = -1; | ||||
| 			token->t_att[0].ar = regno; | ||||
| 			for(i=1;i<TOKENSIZE;i++) | ||||
| 				token->t_att[i].aw = 0; | ||||
| 			return; | ||||
| 		} | ||||
| 		/* fall through */ | ||||
| #endif | ||||
| 	case IN_DESCR: | ||||
| 		sh = stackheight; | ||||
| 		stackheight = tp - fakestack + 1; | ||||
| 		token->t_token=inp->in_info[0]; | ||||
| 		for (i=0;i<TOKENSIZE;i++) | ||||
| 			if (inp->in_info[i+1]==0) { | ||||
| 				assert(tokens[token->t_token].t_type[i]==0); | ||||
| 				token->t_att[i].aw=0; | ||||
| 			} else { | ||||
| 				result=compute(&enodes[inp->in_info[i+1]]); | ||||
| 				assert(tokens[token->t_token].t_type[i]==result.e_typ); | ||||
| 				if (result.e_typ==EV_INT) | ||||
| 					token->t_att[i].aw=result.e_v.e_con; | ||||
| 				else if (result.e_typ==EV_ADDR) | ||||
| 					token->t_att[i].aa= result.e_v.e_addr; | ||||
| 				else | ||||
| 					token->t_att[i].ar=result.e_v.e_reg; | ||||
| 			} | ||||
| 		stackheight = sh; | ||||
| 		return; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| eqtoken(tp1,tp2) token_p tp1,tp2; { | ||||
| 	register i; | ||||
| 	register tkdef_p tdp; | ||||
| 
 | ||||
| 	if (tp1->t_token!=tp2->t_token) | ||||
| 		return(0); | ||||
| 	if (tp1->t_token==0) | ||||
| 		return(1); | ||||
| 	if (tp1->t_token==-1) { | ||||
| 		if (tp1->t_att[0].ar!=tp2->t_att[0].ar) | ||||
| 			return(0); | ||||
| 		return(1); | ||||
| 	} | ||||
| 	tdp = &tokens[tp1->t_token]; | ||||
| 	for (i=0;i<TOKENSIZE;i++) | ||||
| 		switch(tdp->t_type[i]) { | ||||
| 		default: | ||||
| 			return(1); | ||||
| 		case EV_INT: | ||||
| 			if (tp1->t_att[i].aw != tp2->t_att[i].aw) | ||||
| 				return(0); | ||||
| 			break; | ||||
| 		case EV_REG: | ||||
| 			if (tp1->t_att[i].ar != tp2->t_att[i].ar) | ||||
| 				return(0); | ||||
| 			break; | ||||
| 		case EV_ADDR: | ||||
| 			if (strcmp(tp1->t_att[i].aa.ea_str, tp2->t_att[i].aa.ea_str)) | ||||
| 				return(0); | ||||
| 			if (tp1->t_att[i].aa.ea_off!=tp2->t_att[i].aa.ea_off) | ||||
| 				return(0); | ||||
| 			break; | ||||
| 		} | ||||
| 	return(1); | ||||
| } | ||||
| 
 | ||||
| distance(cindex) { | ||||
| 	register char *bp; | ||||
| 	register i; | ||||
| 	register token_p tp; | ||||
| 	int tokexp,tpl; | ||||
| 	int expsize,toksize,exact; | ||||
| 	int xsekt=0; | ||||
| 
 | ||||
| 	bp = &coderules[cindex]; | ||||
| #ifndef NDEBUG | ||||
| 	if (*bp==DO_DLINE) { | ||||
| 		++bp; | ||||
| 		getint(i,bp); | ||||
| 	} | ||||
| #endif | ||||
| 	switch( (*bp)&037 ) { | ||||
| 	default: | ||||
| 		return(stackheight==0 ? 0 : 100); | ||||
| 	case DO_MATCH: | ||||
| 		break; | ||||
| 	case DO_XXMATCH: | ||||
| 		xsekt++; | ||||
| 	case DO_XMATCH: | ||||
| 		xsekt++; | ||||
| 		break; | ||||
| 	} | ||||
| 	tpl= ((*bp++)>>5)&07; | ||||
| 	if (stackheight < tpl) { | ||||
| 		if (xsekt) | ||||
| 			return(MAXINT); | ||||
| 		tpl = stackheight; | ||||
| 	} else | ||||
| 		if (stackheight != tpl && xsekt==2) | ||||
| 			return(MAXINT); | ||||
| 	exact=0; | ||||
| 	tp= &fakestack[stackheight-1]; | ||||
| 	for (i=0;i<tpl;i++,tp--) { | ||||
| 		getint(tokexp,bp); | ||||
| 		if (!match(tp, &machsets[tokexp], 0)) { | ||||
| 			if (xsekt) | ||||
| 				return(MAXINT); | ||||
| 			expsize = ssize(tokexp); | ||||
| 			toksize = tsize(tp); | ||||
| 			if (expsize>toksize) | ||||
| 				return(100); | ||||
| 			if (expsize<toksize) | ||||
| 				return(99-i); | ||||
| 		} else | ||||
| 			exact++; | ||||
| 	} | ||||
| 	if (exact==tpl) { | ||||
| 		if (xsekt) | ||||
| 			return(0); | ||||
| 		return(10-exact); | ||||
| 	} | ||||
| 	return(20-exact); | ||||
| } | ||||
| 
 | ||||
| unsigned costcalc(cost) cost_t cost; { | ||||
| 	extern unsigned cc1,cc2,cc3,cc4; | ||||
| 
 | ||||
| 	return(cost.ct_space*cc1/cc2 + cost.ct_time*cc3/cc4); | ||||
| } | ||||
| 
 | ||||
| ssize(tokexpno) { | ||||
| 
 | ||||
| 	return(machsets[tokexpno].set_size); | ||||
| } | ||||
| 
 | ||||
| tsize(tp) register token_p tp; { | ||||
| 
 | ||||
| 	if (tp->t_token==-1) | ||||
| 		return(machregs[tp->t_att[0].ar].r_size); | ||||
| 	return(tokens[tp->t_token].t_size); | ||||
| } | ||||
| 
 | ||||
| #ifdef MAXSPLIT | ||||
| instsize(tinstno,tp) token_p tp; { | ||||
| 	inst_p inp; | ||||
| 	struct reginfo *rp; | ||||
| 
 | ||||
| 	inp = &tokeninstances[tinstno]; | ||||
| 	switch(inp->in_which) { | ||||
| 	default: | ||||
| 		assert(FALSE); | ||||
| 	case IN_COPY: | ||||
| 		assert(inp->in_info[0]==1); | ||||
| #if MAXMEMBERS!=0 | ||||
| 		if (inp->in_info[1]==0) | ||||
| #endif | ||||
| 			return(tsize(tp)); | ||||
| #if MAXMEMBERS!=0 | ||||
| 		else { | ||||
| 			assert(tp->t_token == -1); | ||||
| 			rp = &machregs[tp->t_att[0].ar]; | ||||
| 			return(machregs[rp->r_members[inp->in_info[1]-1]].r_size); | ||||
| 		} | ||||
| #endif | ||||
| 	case IN_RIDENT: | ||||
| 		return(machregs[inp->in_info[0]].r_size); | ||||
| 	case IN_ALLOC: | ||||
| 		assert(FALSE);  /* cannot occur in splitting coercion */ | ||||
| 	case IN_DESCR: | ||||
| 	case IN_S_DESCR: | ||||
| 	case IN_D_DESCR: | ||||
| 		return(tokens[inp->in_info[0]].t_size); | ||||
| 	} | ||||
| } | ||||
| #endif MAXSPLIT | ||||
| 
 | ||||
| tref(tp,amount) register token_p tp; { | ||||
| 	register i; | ||||
| 	register tkdef_p tdp; | ||||
| 
 | ||||
| 	if (tp->t_token==-1) | ||||
| 		chrefcount(tp->t_att[0].ar,amount,FALSE); | ||||
| 	else { | ||||
| 		tdp= &tokens[tp->t_token]; | ||||
| 		for(i=0;i<TOKENSIZE;i++) | ||||
| 			if (tdp->t_type[i]==EV_REG) | ||||
| 				chrefcount(tp->t_att[i].ar,amount,FALSE); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| #define MAXSAVE 10 | ||||
| 
 | ||||
| #ifdef MAXSPLIT | ||||
| split(tp,ip,ply,toplevel) token_p tp; register int *ip; { | ||||
| 	register c2_p cp; | ||||
| 	token_t savestack[MAXSAVE]; | ||||
| 	int ok; | ||||
| 	register i; | ||||
| 	int diff; | ||||
| 	token_p stp; | ||||
| 	int tpl; | ||||
| 
 | ||||
| 	for (cp=c2coercs;cp->c2_texpno>=0; cp++) { | ||||
| 		if (!match(tp,&machsets[cp->c2_texpno],0)) | ||||
| 			continue; | ||||
| 		ok=1; | ||||
| 		for (i=0; ok && i<cp->c2_nsplit;i++) { | ||||
| 			if (ip[i]==0) | ||||
| 				goto found; | ||||
| 			if (instsize(cp->c2_repl[i],tp) != ssize(ip[i])) | ||||
| 				ok=0; | ||||
| 		} | ||||
| 		goto found; | ||||
| 	} | ||||
| 	return(0); | ||||
| found: | ||||
| 	assert(stackheight+cp->c2_nsplit-1<MAXFSTACK); | ||||
| 	stp = &fakestack[stackheight-1]; | ||||
| 	diff = stp - tp; | ||||
| 	assert(diff<=MAXSAVE); | ||||
| 	for (i=1;i<=diff;i++) | ||||
| 		savestack[i-1] = tp[i];         /* save top of stack */ | ||||
| 	stackheight -= diff; | ||||
| 	tpl = tokpatlen; | ||||
| 	tokpatlen = 1; | ||||
| 	codegen(&coderules[cp->c2_codep],ply,toplevel,MAXINT,0); | ||||
| 	tokpatlen = tpl; | ||||
| 	for (i=0;i<diff;i++)            /* restore top of stack */ | ||||
| 		fakestack[stackheight++] = savestack[i]; | ||||
| 	return(cp->c2_nsplit); | ||||
| } | ||||
| #endif MAXSPLIT | ||||
| 
 | ||||
| unsigned docoerc(tp,cp,ply,toplevel,forced) token_p tp; register c3_p cp; { | ||||
| 	token_t savestack[MAXSAVE]; | ||||
| 	token_p stp; | ||||
| 	register int i,diff; | ||||
| 	unsigned cost; | ||||
| 	int tpl;        /* saved tokpatlen */ | ||||
| 
 | ||||
| 	stp = &fakestack[stackheight-1]; | ||||
| 	diff = stp -tp; | ||||
| 	assert(diff<=MAXSAVE); | ||||
| #ifndef NDEBUG | ||||
| 	if (diff!=0 && Debug>1) | ||||
| 		fprintf(stderr,"Saving %d items from fakestack\n",diff); | ||||
| #endif | ||||
| 	for (i=1;i<=diff;i++) | ||||
| 		savestack[i-1] = tp[i]; | ||||
| 	stackheight -= diff; | ||||
| 	tpl = tokpatlen; | ||||
| 	tokpatlen = 1; | ||||
| 	cost = codegen(&coderules[cp->c3_codep],ply,toplevel,MAXINT,forced); | ||||
| 	tokpatlen = tpl; | ||||
| #ifndef NDEBUG | ||||
| 	if (diff!=0 && Debug>1) | ||||
| 		fprintf(stderr,"Restoring %d items to fakestack(%d)\n",diff,stackheight); | ||||
| #endif | ||||
| 	for (i=0;i<diff;i++) | ||||
| 		fakestack[stackheight++] = savestack[i]; | ||||
| 	nallreg = 0; | ||||
| 	return(cost); | ||||
| } | ||||
| 
 | ||||
| unsigned stackupto(limit,ply,toplevel) token_p limit; { | ||||
| 	token_t savestack[MAXFSTACK]; | ||||
| 	token_p stp; | ||||
| 	int i,diff; | ||||
| 	int tpl;        /* saved tokpatlen */ | ||||
| 	int nareg;	/* saved nareg */ | ||||
| 	int areg[MAXALLREG]; | ||||
| 	register c1_p cp; | ||||
| 	register token_p tp; | ||||
| 	unsigned totalcost=0; | ||||
| 	struct reginfo *rp,**rpp; | ||||
| 
 | ||||
| 	for (tp=fakestack;tp<=limit;limit--) { | ||||
| 		for (cp=c1coercs;cp->c1_texpno>=0; cp++) { | ||||
| 			if (match(tp,&machsets[cp->c1_texpno],cp->c1_expr)) { | ||||
| 				if (cp->c1_prop>=0) { | ||||
| 					for (rpp=reglist[cp->c1_prop]; | ||||
| 					       (rp = *rpp)!=0 && | ||||
| 					       getrefcount(rp-machregs)!=0; | ||||
| 						  rpp++) | ||||
| 						; | ||||
| 					if (rp==0) | ||||
| 						continue; | ||||
| 						/* look for other possibility */ | ||||
| 				} | ||||
| 				stp = &fakestack[stackheight-1]; | ||||
| 				diff = stp -tp; | ||||
| 				assert(diff<=MAXFSTACK); | ||||
| 				for (i=1;i<=diff;i++) | ||||
| 					savestack[i-1] = tp[i]; | ||||
| 				stackheight -= diff; | ||||
| 				tpl = tokpatlen; | ||||
| 				tokpatlen = 1; | ||||
| 				nareg = nallreg; | ||||
| 				for (i=0;i<nareg;i++) | ||||
| 					areg[i] = allreg[i]; | ||||
| 				if (cp->c1_prop>=0) { | ||||
| 					nallreg=1; allreg[0] = rp-machregs; | ||||
| 					chrefcount(allreg[0],1,FALSE); | ||||
| 				} else  | ||||
| 					nallreg=0; | ||||
| 				totalcost+= codegen(&coderules[cp->c1_codep],ply,toplevel,MAXINT,0); | ||||
| 				tokpatlen = tpl; | ||||
| 				for (i=0;i<diff;i++) | ||||
| 					fakestack[stackheight++] = savestack[i]; | ||||
| 				nallreg=nareg; | ||||
| 				for (i=0;i<nareg;i++) | ||||
| 					allreg[i] = areg[i]; | ||||
| 				goto contin; | ||||
| 			} | ||||
| 		} | ||||
| 		assert(FALSE); | ||||
| 	contin: ; | ||||
| 	} | ||||
| 	return(totalcost); | ||||
| } | ||||
| 
 | ||||
| c3_p findcoerc(tp,tep) token_p tp; set_p tep; { | ||||
| 	register c3_p cp; | ||||
| 	token_t rtoken; | ||||
| 	register i; | ||||
| 	register struct reginfo **rpp; | ||||
| 
 | ||||
| 	for (cp=c3coercs;cp->c3_texpno>=0; cp++) { | ||||
| 		if (tp!=(token_p) 0) { | ||||
| 			if (cp->c3_texpno==0) | ||||
| 				continue; | ||||
| 			if (!match(tp,&machsets[cp->c3_texpno],cp->c3_expr)) | ||||
| 				continue; | ||||
| 		} else { | ||||
| 			if (cp->c3_texpno!=0) | ||||
| 				continue; | ||||
| 		} | ||||
| 		if (cp->c3_prop==0) {   /* no reg needed */ | ||||
| 			cinstance(cp->c3_repl,&rtoken,tp,0); | ||||
| 			if (match(&rtoken,tep,0)) | ||||
| 				return(cp); | ||||
| 		} else { | ||||
| 			curreglist = (rl_p) myalloc(sizeof (rl_t)); | ||||
| 			curreglist->rl_n = 0; | ||||
| 			for (rpp=reglist[cp->c3_prop];*rpp;rpp++) { | ||||
| 				i = *rpp - machregs; | ||||
| 				cinstance(cp->c3_repl,&rtoken,tp,i); | ||||
| 				if (match(&rtoken,tep,0)) | ||||
| 					curreglist->rl_list[curreglist->rl_n++] = i; | ||||
| 			} | ||||
| 			if (curreglist->rl_n != 0) | ||||
| 				return(cp); | ||||
| 			myfree(curreglist); | ||||
| 		} | ||||
| 	} | ||||
| 	return(0);      /* nothing found */ | ||||
| } | ||||
| 
 | ||||
| itokcost() { | ||||
| 	register tkdef_p tdp; | ||||
| 
 | ||||
| 	for(tdp=tokens+1;tdp->t_size!=0;tdp++) | ||||
| 		tdp->t_cost.ct_space = costcalc(tdp->t_cost); | ||||
| } | ||||
| 
 | ||||
| error(s,a1,a2,a3,a4,a5,a6,a7,a8) char *s; { | ||||
| 
 | ||||
| 	fatal(s,a1,a2,a3,a4,a5,a6,a7,a8); | ||||
| } | ||||
| 
 | ||||
| fatal(s,a1,a2,a3,a4,a5,a6,a7,a8) char *s; { | ||||
| 
 | ||||
| 	fprintf(stderr,"Error: "); | ||||
| 	fprintf(stderr,s,a1,a2,a3,a4,a5,a6,a7,a8); | ||||
| 	fprintf(stderr,"\n"); | ||||
| #ifdef TABLEDEBUG | ||||
| 	ruletrace(); | ||||
| #endif | ||||
| 	out_finish(); | ||||
| 	abort(); | ||||
| 	exit(-1); | ||||
| } | ||||
| 
 | ||||
| #ifdef TABLEDEBUG | ||||
| 
 | ||||
| ruletrace() { | ||||
| 	register i; | ||||
| 	extern int tablelines[MAXTDBUG]; | ||||
| 	extern int ntableline; | ||||
| 	extern char *tablename; | ||||
| 
 | ||||
| 	fprintf(stderr,"Last code rules used\n"); | ||||
| 	i=ntableline-1; | ||||
| 	while(i!=ntableline) { | ||||
| 		if (i<0) | ||||
| 			i += MAXTDBUG; | ||||
| 		if (tablelines[i]!=0) | ||||
| 			fprintf(stderr,"\%d: \"%s\", line %d\n",i,tablename,tablelines[i]); | ||||
| 		i--; | ||||
| 	} | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #ifndef NDEBUG | ||||
| badassertion(asstr,file,line) char *asstr, *file; { | ||||
| 
 | ||||
| 	fatal("\"%s\", line %d:Assertion \"%s\" failed",file,line,asstr); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| max(a,b) { | ||||
| 
 | ||||
| 	return(a>b ? a : b); | ||||
| } | ||||
							
								
								
									
										27
									
								
								mach/proto/ncg/types.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								mach/proto/ncg/types.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | |||
| /* $Header$ */ | ||||
| 
 | ||||
| #ifndef TEM_WSIZE | ||||
| TEM_WSIZE should be defined at this point | ||||
| #endif | ||||
| #ifndef TEM_PSIZE | ||||
| TEM_PSIZE should be defined at this point | ||||
| #endif | ||||
| #if TEM_WSIZE>4 || TEM_PSIZE>4 | ||||
| Implementation will not be correct unless a long integer | ||||
| has more then 4 bytes of precision. | ||||
| #endif | ||||
| 
 | ||||
| typedef char byte; | ||||
| typedef char * string; | ||||
| 
 | ||||
| #if TEM_WSIZE>2 || TEM_PSIZE>2 | ||||
| #define full            long | ||||
| #else | ||||
| #define full		int | ||||
| #endif | ||||
| 
 | ||||
| #if TEM_WSIZE>2 | ||||
| #define word long | ||||
| #else | ||||
| #define word int | ||||
| #endif | ||||
							
								
								
									
										41
									
								
								mach/proto/ncg/var.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								mach/proto/ncg/var.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,41 @@ | |||
| #ifndef NORCSID | ||||
| static char rcsid[] = "$Header$"; | ||||
| #endif | ||||
| 
 | ||||
| #include "param.h" | ||||
| #include "tables.h" | ||||
| #include "types.h" | ||||
| #include <cgg_cg.h> | ||||
| #include "data.h" | ||||
| #include "result.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. | ||||
|  * | ||||
|  *          This product is part of the Amsterdam Compiler Kit. | ||||
|  * | ||||
|  * Permission to use, sell, duplicate or disclose this software must be | ||||
|  * obtained in writing. Requests for such permissions may be sent to | ||||
|  * | ||||
|  *      Dr. Andrew S. Tanenbaum | ||||
|  *      Wiskundig Seminarium | ||||
|  *      Vrije Universiteit | ||||
|  *      Postbox 7161 | ||||
|  *      1007 MC Amsterdam | ||||
|  *      The Netherlands | ||||
|  * | ||||
|  * Author: Hans van Staveren | ||||
|  */ | ||||
| 
 | ||||
| int stackheight = 0; | ||||
| token_t fakestack[MAXFSTACK]; | ||||
| int nallreg = 0; | ||||
| int allreg[MAXALLREG]; | ||||
| token_p curtoken = (token_p) 0; | ||||
| result_t dollar[LONGESTPATTERN]; | ||||
| int nemlines =0; | ||||
| struct emline emlines[MAXEMLINES]; | ||||
| struct emline *emp=emlines; | ||||
| struct emline *saveemp; | ||||
| int tokpatlen; | ||||
| rl_p curreglist; | ||||
		Loading…
	
	Add table
		
		Reference in a new issue