xref: /csrg-svn/usr.bin/pascal/src/tmps.c (revision 15940)
13219Smckusick /* Copyright (c) 1979 Regents of the University of California */
23219Smckusick 
315939Smckusick #ifndef lint
4*15940Smckusick static char sccsid[] = "@(#)tmps.c 1.13 02/04/84";
515939Smckusick #endif
63219Smckusick 
73219Smckusick #include "whoami.h"
83219Smckusick #include "0.h"
910657Speter #include "objfmt.h"
103280Smckusic #ifdef PC
113280Smckusic #   include "pc.h"
123280Smckusic #endif PC
1311853Speter #include "align.h"
1411332Speter #include "tmps.h"
153219Smckusick 
163219Smckusick /*
173280Smckusic  * This routine defines the register allocation strategy
183280Smckusic  * All temporaries are allocated here, and this routines decides
193280Smckusic  * where they are to be put.
203280Smckusic  */
213281Smckusic #ifdef PC
2211332Speter     /*
23*15940Smckusick      *	register temporaries
24*15940Smckusick      *	- are allocated from highreg towards lowreg.
25*15940Smckusick      *	- are of size regsize.
26*15940Smckusick      *	- register numbers from the various register types are mapped to
27*15940Smckusick      *	  integer register numbers using the offsets.  (cf. pcc/mac2defs)
28*15940Smckusick      *
29*15940Smckusick      *	stack temporaries
30*15940Smckusick      *	- are allocated on a downward growing stack.
3111332Speter      */
3211332Speter 
3310657Speter #ifdef vax
3411332Speter     /*
3511332Speter      *	first pass register declaration constants
3611332Speter      */
3711332Speter struct	regtype {
3811332Speter     long	lowreg;
3911332Speter     long	highreg;
4011332Speter     long	regsize;
4111332Speter } regtypes[NUMREGTYPES] = {
42*15940Smckusick 	{ 6, 11, 4 },		/* r6..r11 */
4311332Speter };
4410657Speter #endif vax
4511332Speter 
4611332Speter #ifdef mc68000
4711332Speter     /*
4811332Speter      *	first pass register declaration constants
4911332Speter      */
5011332Speter struct	regtype {
5111332Speter     long	lowreg;
5211332Speter     long	highreg;
5311332Speter     long	regsize;
5411332Speter } regtypes[NUMREGTYPES] = {
55*15940Smckusick 	{ 2, 7, 4 },		/* d2..d7 */
56*15940Smckusick 	{ 2, 5, 4 },		/* a2..a5 */
5711332Speter };
5811332Speter #endif mc68000
593281Smckusic #endif PC
603280Smckusic 
6111332Speter tmpinit(cbn)
6211332Speter 	int	cbn;
6311332Speter {
6411332Speter 	struct om	*sizesp = &sizes[cbn];
6515939Smckusick #	ifdef PC
6611332Speter 	int	i;
6715939Smckusick #	endif PC
6811332Speter 
6911332Speter 	sizesp->om_max = -DPOFF1;
7011332Speter 	sizesp->curtmps.om_off = -DPOFF1;
7111332Speter #	ifdef PC
7211332Speter 		for (i = 0; i < NUMREGTYPES; i++) {
7311332Speter 			sizesp->low_water[i] = regtypes[i].highreg + 1;
7411332Speter 			sizesp->curtmps.next_avail[i] = regtypes[i].highreg;
7511332Speter 		}
7611332Speter #	endif PC
7711332Speter }
7811332Speter 
793280Smckusic /*
803219Smckusick  * allocate runtime temporary variables
813219Smckusick  */
8215939Smckusick /*ARGSUSED*/
833839Speter struct nl *
843280Smckusic tmpalloc(size, type, mode)
853219Smckusick 	long size;
863219Smckusick 	struct nl *type;
873280Smckusic 	int mode;
883219Smckusick {
8911332Speter 	register struct om	*op = &sizes[ cbn ];
9011332Speter 	register int		offset;
913839Speter 	register struct nl	*nlp;
9211853Speter 	long			alignment;
933219Smckusick 
943280Smckusic #	ifdef PC
9511332Speter #	    ifdef vax
9611332Speter 		if (  mode == REGOK
9711332Speter 		   && size == regtypes[REG_GENERAL].regsize
9811332Speter 		   && op->curtmps.next_avail[REG_GENERAL]
9911332Speter 			    >= regtypes[REG_GENERAL].lowreg) {
10011332Speter 			offset = op->curtmps.next_avail[REG_GENERAL]--;
10111332Speter 			if (offset < op->low_water[REG_GENERAL]) {
10211332Speter 				op->low_water[REG_GENERAL] = offset;
10311332Speter 			}
10415939Smckusick 			nlp = defnl( (char *) 0 , VAR , type , offset );
10511332Speter 			nlp -> extra_flags = NLOCAL | NREGVAR;
10611332Speter 			putlbracket(ftnno, op);
10711332Speter 			return nlp;
10811332Speter 		}
10911332Speter #	    endif vax
110*15940Smckusick #	    ifdef mc68000
111*15940Smckusick 		if (  mode == REGOK
112*15940Smckusick 		   && type != nl + TPTR
113*15940Smckusick 		   && size == regtypes[REG_DATA].regsize
114*15940Smckusick 		   && op->curtmps.next_avail[REG_DATA]
115*15940Smckusick 			    >= regtypes[REG_DATA].lowreg) {
116*15940Smckusick 			offset = op->curtmps.next_avail[REG_DATA]--;
117*15940Smckusick 			if (offset < op->low_water[REG_DATA]) {
118*15940Smckusick 				op->low_water[REG_DATA] = offset;
119*15940Smckusick 			}
120*15940Smckusick 			nlp = defnl(0, VAR, type, offset + DATA_REG_OFFSET );
121*15940Smckusick 			nlp -> extra_flags = NLOCAL | NREGVAR;
122*15940Smckusick 			putlbracket(ftnno, op);
123*15940Smckusick 			return nlp;
124*15940Smckusick 		}
125*15940Smckusick 		if (  mode == REGOK
126*15940Smckusick 		   && type == nl + TPTR
127*15940Smckusick 		   && size == regtypes[REG_ADDR].regsize
128*15940Smckusick 		   && op->curtmps.next_avail[REG_ADDR]
129*15940Smckusick 			    >= regtypes[REG_ADDR].lowreg) {
130*15940Smckusick 			offset = op->curtmps.next_avail[REG_ADDR]--;
131*15940Smckusick 			if (offset < op->low_water[REG_ADDR]) {
132*15940Smckusick 				op->low_water[REG_ADDR] = offset;
133*15940Smckusick 			}
134*15940Smckusick 			nlp = defnl(0, VAR, type, offset + ADDR_REG_OFFSET );
135*15940Smckusick 			nlp -> extra_flags = NLOCAL | NREGVAR;
136*15940Smckusick 			putlbracket(ftnno, op);
137*15940Smckusick 			return nlp;
138*15940Smckusick 		}
139*15940Smckusick #	    endif mc68000
1403280Smckusic #	endif PC
14111853Speter 	if (type == NIL) {
14211853Speter 	    alignment = A_STACK;
143*15940Smckusick 	} else if (type == nl+TPTR) {
144*15940Smckusick 	    alignment = A_POINT;
14511853Speter 	} else {
14611853Speter 	    alignment = align(type);
14711853Speter 	}
14811332Speter         op->curtmps.om_off =
14911853Speter 	    roundup((int)(op->curtmps.om_off - size), alignment);
15011332Speter 	offset = op->curtmps.om_off;
1513280Smckusic 	if ( offset < op->om_max ) {
1523280Smckusic 	        op->om_max = offset;
1533219Smckusick 	}
15415939Smckusick 	nlp = defnl( (char *) 0 , VAR , type , offset );
1553219Smckusick #	ifdef PC
1563839Speter 	    nlp -> extra_flags = NLOCAL;
15711332Speter 	    putlbracket(ftnno, op);
1583219Smckusick #	endif PC
1593839Speter 	return nlp;
1603219Smckusick }
16111332Speter 
1623219Smckusick /*
1633219Smckusick  * deallocate runtime temporary variables
1643219Smckusick  */
16515939Smckusick /*ARGSUSED*/
1663219Smckusick tmpfree(restore)
16711332Speter     register struct tmps	*restore;
1683219Smckusick {
16915939Smckusick #   ifdef PC
17011332Speter     register struct om		*op = &sizes[ cbn ];
17111332Speter     bool			change = FALSE;
1723219Smckusick 
17311332Speter #	ifdef vax
17411332Speter 	    if (restore->next_avail[REG_GENERAL]
17511332Speter 		> op->curtmps.next_avail[REG_GENERAL]) {
17611332Speter 		    op->curtmps.next_avail[REG_GENERAL]
17711332Speter 			= restore->next_avail[REG_GENERAL];
17811332Speter 		    change = TRUE;
1793280Smckusic 	    }
18011332Speter #	endif vax
181*15940Smckusick #	ifdef mc68000
182*15940Smckusick 	    if (restore->next_avail[REG_DATA]
183*15940Smckusick 		> op->curtmps.next_avail[REG_DATA]) {
184*15940Smckusick 		    op->curtmps.next_avail[REG_DATA]
185*15940Smckusick 			= restore->next_avail[REG_DATA];
186*15940Smckusick 		    change = TRUE;
187*15940Smckusick 	    }
188*15940Smckusick 	    if (restore->next_avail[REG_ADDR]
189*15940Smckusick 		> op->curtmps.next_avail[REG_ADDR]) {
190*15940Smckusick 		    op->curtmps.next_avail[REG_ADDR]
191*15940Smckusick 			= restore->next_avail[REG_ADDR];
192*15940Smckusick 		    change = TRUE;
193*15940Smckusick 	    }
194*15940Smckusick #	endif mc68000
19511332Speter     if (restore->om_off > op->curtmps.om_off) {
19611332Speter 	    op->curtmps.om_off = restore->om_off;
19711332Speter 	    change = TRUE;
19811332Speter     }
19911332Speter 	if (change) {
20011332Speter 	    putlbracket(ftnno, op);
2013219Smckusick 	}
20215939Smckusick #endif PC
2033219Smckusick }
20411332Speter 
2053281Smckusic #ifdef PC
20610657Speter #ifdef vax
2073280Smckusic /*
2083280Smckusic  * create a save mask for registers which have been used
2093280Smckusic  * in this level
2103280Smckusic  */
2113280Smckusic savmask()
2123280Smckusic {
2133839Speter 	int mask;
2143280Smckusic 	int i;
2153280Smckusic 
2163280Smckusic 	mask = RSAVEMASK;
2173280Smckusic 	if (opt('t'))
2183280Smckusic 	        mask |= RUNCHECK;
21911332Speter 	for (i = 0; i <= regtypes[REG_GENERAL].highreg; i++) {
22011332Speter 	    if (i >= sizes[cbn].low_water[REG_GENERAL]) {
22111332Speter 		mask |= 1 << i;
22211332Speter 	    }
22311332Speter 	}
2243280Smckusic 	return mask;
2253280Smckusic }
22610657Speter #endif vax
2273281Smckusic #endif PC
228