xref: /csrg-svn/usr.bin/pascal/src/tmps.c (revision 22197)
1*22197Sdist /*
2*22197Sdist  * Copyright (c) 1980 Regents of the University of California.
3*22197Sdist  * All rights reserved.  The Berkeley software License Agreement
4*22197Sdist  * specifies the terms and conditions for redistribution.
5*22197Sdist  */
63219Smckusick 
715939Smckusick #ifndef lint
8*22197Sdist static char sccsid[] = "@(#)tmps.c	5.1 (Berkeley) 06/05/85";
9*22197Sdist #endif not lint
103219Smckusick 
113219Smckusick #include "whoami.h"
123219Smckusick #include "0.h"
1310657Speter #include "objfmt.h"
143280Smckusic #ifdef PC
153280Smckusic #   include "pc.h"
163280Smckusic #endif PC
1711853Speter #include "align.h"
1811332Speter #include "tmps.h"
193219Smckusick 
203219Smckusick /*
213280Smckusic  * This routine defines the register allocation strategy
223280Smckusic  * All temporaries are allocated here, and this routines decides
233280Smckusic  * where they are to be put.
243280Smckusic  */
253281Smckusic #ifdef PC
2611332Speter     /*
2715940Smckusick      *	register temporaries
2815940Smckusick      *	- are allocated from highreg towards lowreg.
2915940Smckusick      *	- are of size regsize.
3015940Smckusick      *	- register numbers from the various register types are mapped to
3115940Smckusick      *	  integer register numbers using the offsets.  (cf. pcc/mac2defs)
3215940Smckusick      *
3315940Smckusick      *	stack temporaries
3415940Smckusick      *	- are allocated on a downward growing stack.
3511332Speter      */
3611332Speter 
3710657Speter #ifdef vax
3811332Speter     /*
3911332Speter      *	first pass register declaration constants
4011332Speter      */
4111332Speter struct	regtype {
4211332Speter     long	lowreg;
4311332Speter     long	highreg;
4411332Speter     long	regsize;
4511332Speter } regtypes[NUMREGTYPES] = {
4615940Smckusick 	{ 6, 11, 4 },		/* r6..r11 */
4711332Speter };
4810657Speter #endif vax
4911332Speter 
5011332Speter #ifdef mc68000
5111332Speter     /*
5211332Speter      *	first pass register declaration constants
5311332Speter      */
5411332Speter struct	regtype {
5511332Speter     long	lowreg;
5611332Speter     long	highreg;
5711332Speter     long	regsize;
5811332Speter } regtypes[NUMREGTYPES] = {
5915940Smckusick 	{ 2, 7, 4 },		/* d2..d7 */
6015940Smckusick 	{ 2, 5, 4 },		/* a2..a5 */
6111332Speter };
6211332Speter #endif mc68000
633281Smckusic #endif PC
643280Smckusic 
6511332Speter tmpinit(cbn)
6611332Speter 	int	cbn;
6711332Speter {
6811332Speter 	struct om	*sizesp = &sizes[cbn];
6915939Smckusick #	ifdef PC
7011332Speter 	int	i;
7115939Smckusick #	endif PC
7211332Speter 
7311332Speter 	sizesp->om_max = -DPOFF1;
7411332Speter 	sizesp->curtmps.om_off = -DPOFF1;
7511332Speter #	ifdef PC
7611332Speter 		for (i = 0; i < NUMREGTYPES; i++) {
7711332Speter 			sizesp->low_water[i] = regtypes[i].highreg + 1;
7811332Speter 			sizesp->curtmps.next_avail[i] = regtypes[i].highreg;
7911332Speter 		}
8011332Speter #	endif PC
8111332Speter }
8211332Speter 
833280Smckusic /*
843219Smckusick  * allocate runtime temporary variables
853219Smckusick  */
8615939Smckusick /*ARGSUSED*/
873839Speter struct nl *
883280Smckusic tmpalloc(size, type, mode)
893219Smckusick 	long size;
903219Smckusick 	struct nl *type;
913280Smckusic 	int mode;
923219Smckusick {
9311332Speter 	register struct om	*op = &sizes[ cbn ];
9411332Speter 	register int		offset;
953839Speter 	register struct nl	*nlp;
9611853Speter 	long			alignment;
973219Smckusick 
983280Smckusic #	ifdef PC
9911332Speter #	    ifdef vax
10011332Speter 		if (  mode == REGOK
10111332Speter 		   && size == regtypes[REG_GENERAL].regsize
10211332Speter 		   && op->curtmps.next_avail[REG_GENERAL]
10311332Speter 			    >= regtypes[REG_GENERAL].lowreg) {
10411332Speter 			offset = op->curtmps.next_avail[REG_GENERAL]--;
10511332Speter 			if (offset < op->low_water[REG_GENERAL]) {
10611332Speter 				op->low_water[REG_GENERAL] = offset;
10711332Speter 			}
10815939Smckusick 			nlp = defnl( (char *) 0 , VAR , type , offset );
10911332Speter 			nlp -> extra_flags = NLOCAL | NREGVAR;
11011332Speter 			putlbracket(ftnno, op);
11111332Speter 			return nlp;
11211332Speter 		}
11311332Speter #	    endif vax
11415940Smckusick #	    ifdef mc68000
11515940Smckusick 		if (  mode == REGOK
11615940Smckusick 		   && type != nl + TPTR
11715940Smckusick 		   && size == regtypes[REG_DATA].regsize
11815940Smckusick 		   && op->curtmps.next_avail[REG_DATA]
11915940Smckusick 			    >= regtypes[REG_DATA].lowreg) {
12015940Smckusick 			offset = op->curtmps.next_avail[REG_DATA]--;
12115940Smckusick 			if (offset < op->low_water[REG_DATA]) {
12215940Smckusick 				op->low_water[REG_DATA] = offset;
12315940Smckusick 			}
12415940Smckusick 			nlp = defnl(0, VAR, type, offset + DATA_REG_OFFSET );
12515940Smckusick 			nlp -> extra_flags = NLOCAL | NREGVAR;
12615940Smckusick 			putlbracket(ftnno, op);
12715940Smckusick 			return nlp;
12815940Smckusick 		}
12915940Smckusick 		if (  mode == REGOK
13015940Smckusick 		   && type == nl + TPTR
13115940Smckusick 		   && size == regtypes[REG_ADDR].regsize
13215940Smckusick 		   && op->curtmps.next_avail[REG_ADDR]
13315940Smckusick 			    >= regtypes[REG_ADDR].lowreg) {
13415940Smckusick 			offset = op->curtmps.next_avail[REG_ADDR]--;
13515940Smckusick 			if (offset < op->low_water[REG_ADDR]) {
13615940Smckusick 				op->low_water[REG_ADDR] = offset;
13715940Smckusick 			}
13815940Smckusick 			nlp = defnl(0, VAR, type, offset + ADDR_REG_OFFSET );
13915940Smckusick 			nlp -> extra_flags = NLOCAL | NREGVAR;
14015940Smckusick 			putlbracket(ftnno, op);
14115940Smckusick 			return nlp;
14215940Smckusick 		}
14315940Smckusick #	    endif mc68000
1443280Smckusic #	endif PC
14511853Speter 	if (type == NIL) {
14611853Speter 	    alignment = A_STACK;
14715940Smckusick 	} else if (type == nl+TPTR) {
14815940Smckusick 	    alignment = A_POINT;
14911853Speter 	} else {
15011853Speter 	    alignment = align(type);
15111853Speter 	}
15211332Speter         op->curtmps.om_off =
15311853Speter 	    roundup((int)(op->curtmps.om_off - size), alignment);
15411332Speter 	offset = op->curtmps.om_off;
1553280Smckusic 	if ( offset < op->om_max ) {
1563280Smckusic 	        op->om_max = offset;
1573219Smckusick 	}
15815939Smckusick 	nlp = defnl( (char *) 0 , VAR , type , offset );
1593219Smckusick #	ifdef PC
1603839Speter 	    nlp -> extra_flags = NLOCAL;
16111332Speter 	    putlbracket(ftnno, op);
1623219Smckusick #	endif PC
1633839Speter 	return nlp;
1643219Smckusick }
16511332Speter 
1663219Smckusick /*
1673219Smckusick  * deallocate runtime temporary variables
1683219Smckusick  */
16915939Smckusick /*ARGSUSED*/
1703219Smckusick tmpfree(restore)
17111332Speter     register struct tmps	*restore;
1723219Smckusick {
17315939Smckusick #   ifdef PC
17411332Speter     register struct om		*op = &sizes[ cbn ];
17511332Speter     bool			change = FALSE;
1763219Smckusick 
17711332Speter #	ifdef vax
17811332Speter 	    if (restore->next_avail[REG_GENERAL]
17911332Speter 		> op->curtmps.next_avail[REG_GENERAL]) {
18011332Speter 		    op->curtmps.next_avail[REG_GENERAL]
18111332Speter 			= restore->next_avail[REG_GENERAL];
18211332Speter 		    change = TRUE;
1833280Smckusic 	    }
18411332Speter #	endif vax
18515940Smckusick #	ifdef mc68000
18615940Smckusick 	    if (restore->next_avail[REG_DATA]
18715940Smckusick 		> op->curtmps.next_avail[REG_DATA]) {
18815940Smckusick 		    op->curtmps.next_avail[REG_DATA]
18915940Smckusick 			= restore->next_avail[REG_DATA];
19015940Smckusick 		    change = TRUE;
19115940Smckusick 	    }
19215940Smckusick 	    if (restore->next_avail[REG_ADDR]
19315940Smckusick 		> op->curtmps.next_avail[REG_ADDR]) {
19415940Smckusick 		    op->curtmps.next_avail[REG_ADDR]
19515940Smckusick 			= restore->next_avail[REG_ADDR];
19615940Smckusick 		    change = TRUE;
19715940Smckusick 	    }
19815940Smckusick #	endif mc68000
19911332Speter     if (restore->om_off > op->curtmps.om_off) {
20011332Speter 	    op->curtmps.om_off = restore->om_off;
20111332Speter 	    change = TRUE;
20211332Speter     }
20311332Speter 	if (change) {
20411332Speter 	    putlbracket(ftnno, op);
2053219Smckusick 	}
20615939Smckusick #endif PC
2073219Smckusick }
20811332Speter 
2093281Smckusic #ifdef PC
21010657Speter #ifdef vax
2113280Smckusic /*
2123280Smckusic  * create a save mask for registers which have been used
2133280Smckusic  * in this level
2143280Smckusic  */
2153280Smckusic savmask()
2163280Smckusic {
2173839Speter 	int mask;
2183280Smckusic 	int i;
2193280Smckusic 
2203280Smckusic 	mask = RSAVEMASK;
2213280Smckusic 	if (opt('t'))
2223280Smckusic 	        mask |= RUNCHECK;
22311332Speter 	for (i = 0; i <= regtypes[REG_GENERAL].highreg; i++) {
22411332Speter 	    if (i >= sizes[cbn].low_water[REG_GENERAL]) {
22511332Speter 		mask |= 1 << i;
22611332Speter 	    }
22711332Speter 	}
2283280Smckusic 	return mask;
2293280Smckusic }
23010657Speter #endif vax
2313281Smckusic #endif PC
232