xref: /csrg-svn/usr.bin/pascal/src/tmps.c (revision 62219)
148116Sbostic /*-
2*62219Sbostic  * Copyright (c) 1980, 1993
3*62219Sbostic  *	The Regents of the University of California.  All rights reserved.
448116Sbostic  *
548116Sbostic  * %sccs.include.redist.c%
622197Sdist  */
73219Smckusick 
815939Smckusick #ifndef lint
9*62219Sbostic static char sccsid[] = "@(#)tmps.c	8.1 (Berkeley) 06/06/93";
1048116Sbostic #endif /* not lint */
113219Smckusick 
123219Smckusick #include "whoami.h"
133219Smckusick #include "0.h"
1410657Speter #include "objfmt.h"
153280Smckusic #ifdef PC
163280Smckusic #   include "pc.h"
173280Smckusic #endif PC
1811853Speter #include "align.h"
1911332Speter #include "tmps.h"
203219Smckusick 
213219Smckusick /*
223280Smckusic  * This routine defines the register allocation strategy
233280Smckusic  * All temporaries are allocated here, and this routines decides
243280Smckusic  * where they are to be put.
253280Smckusic  */
263281Smckusic #ifdef PC
2711332Speter     /*
2815940Smckusick      *	register temporaries
2915940Smckusick      *	- are allocated from highreg towards lowreg.
3015940Smckusick      *	- are of size regsize.
3115940Smckusick      *	- register numbers from the various register types are mapped to
3215940Smckusick      *	  integer register numbers using the offsets.  (cf. pcc/mac2defs)
3315940Smckusick      *
3415940Smckusick      *	stack temporaries
3515940Smckusick      *	- are allocated on a downward growing stack.
3611332Speter      */
3711332Speter 
3810657Speter #ifdef vax
3911332Speter     /*
4011332Speter      *	first pass register declaration constants
4111332Speter      */
4211332Speter struct	regtype {
4311332Speter     long	lowreg;
4411332Speter     long	highreg;
4511332Speter     long	regsize;
4611332Speter } regtypes[NUMREGTYPES] = {
4715940Smckusick 	{ 6, 11, 4 },		/* r6..r11 */
4811332Speter };
4910657Speter #endif vax
5011332Speter 
5130033Smckusick #ifdef tahoe
5230033Smckusick     /*
5330033Smckusick      *	first pass register declaration constants
5430033Smckusick      */
5530033Smckusick struct	regtype {
5630033Smckusick     long	lowreg;
5730033Smckusick     long	highreg;
5830033Smckusick     long	regsize;
5930033Smckusick } regtypes[NUMREGTYPES] = {
6030033Smckusick 	{ 6, 12, 4 },		/* r6..r12 */
6130033Smckusick };
6230033Smckusick #endif tahoe
6330033Smckusick 
6411332Speter #ifdef mc68000
6511332Speter     /*
6611332Speter      *	first pass register declaration constants
6711332Speter      */
6811332Speter struct	regtype {
6911332Speter     long	lowreg;
7011332Speter     long	highreg;
7111332Speter     long	regsize;
7211332Speter } regtypes[NUMREGTYPES] = {
7315940Smckusick 	{ 2, 7, 4 },		/* d2..d7 */
7415940Smckusick 	{ 2, 5, 4 },		/* a2..a5 */
7511332Speter };
7611332Speter #endif mc68000
773281Smckusic #endif PC
783280Smckusic 
tmpinit(cbn)7911332Speter tmpinit(cbn)
8011332Speter 	int	cbn;
8111332Speter {
8211332Speter 	struct om	*sizesp = &sizes[cbn];
8315939Smckusick #	ifdef PC
8411332Speter 	int	i;
8515939Smckusick #	endif PC
8611332Speter 
8711332Speter 	sizesp->om_max = -DPOFF1;
8811332Speter 	sizesp->curtmps.om_off = -DPOFF1;
8911332Speter #	ifdef PC
9011332Speter 		for (i = 0; i < NUMREGTYPES; i++) {
9111332Speter 			sizesp->low_water[i] = regtypes[i].highreg + 1;
9211332Speter 			sizesp->curtmps.next_avail[i] = regtypes[i].highreg;
9311332Speter 		}
9411332Speter #	endif PC
9511332Speter }
9611332Speter 
973280Smckusic /*
983219Smckusick  * allocate runtime temporary variables
993219Smckusick  */
10015939Smckusick /*ARGSUSED*/
1013839Speter struct nl *
tmpalloc(size,type,mode)1023280Smckusic tmpalloc(size, type, mode)
1033219Smckusick 	long size;
1043219Smckusick 	struct nl *type;
1053280Smckusic 	int mode;
1063219Smckusick {
10711332Speter 	register struct om	*op = &sizes[ cbn ];
10811332Speter 	register int		offset;
1093839Speter 	register struct nl	*nlp;
11011853Speter 	long			alignment;
1113219Smckusick 
1123280Smckusic #	ifdef PC
11330033Smckusick #	    if defined(vax) || defined(tahoe)
11411332Speter 		if (  mode == REGOK
11511332Speter 		   && size == regtypes[REG_GENERAL].regsize
11611332Speter 		   && op->curtmps.next_avail[REG_GENERAL]
11711332Speter 			    >= regtypes[REG_GENERAL].lowreg) {
11811332Speter 			offset = op->curtmps.next_avail[REG_GENERAL]--;
11911332Speter 			if (offset < op->low_water[REG_GENERAL]) {
12011332Speter 				op->low_water[REG_GENERAL] = offset;
12111332Speter 			}
12215939Smckusick 			nlp = defnl( (char *) 0 , VAR , type , offset );
12311332Speter 			nlp -> extra_flags = NLOCAL | NREGVAR;
12411332Speter 			putlbracket(ftnno, op);
12511332Speter 			return nlp;
12611332Speter 		}
12730033Smckusick #	    endif vax || tahoe
12815940Smckusick #	    ifdef mc68000
12915940Smckusick 		if (  mode == REGOK
13015940Smckusick 		   && type != nl + TPTR
13115940Smckusick 		   && size == regtypes[REG_DATA].regsize
13215940Smckusick 		   && op->curtmps.next_avail[REG_DATA]
13315940Smckusick 			    >= regtypes[REG_DATA].lowreg) {
13415940Smckusick 			offset = op->curtmps.next_avail[REG_DATA]--;
13515940Smckusick 			if (offset < op->low_water[REG_DATA]) {
13615940Smckusick 				op->low_water[REG_DATA] = offset;
13715940Smckusick 			}
13815940Smckusick 			nlp = defnl(0, VAR, type, offset + DATA_REG_OFFSET );
13915940Smckusick 			nlp -> extra_flags = NLOCAL | NREGVAR;
14015940Smckusick 			putlbracket(ftnno, op);
14115940Smckusick 			return nlp;
14215940Smckusick 		}
14315940Smckusick 		if (  mode == REGOK
14415940Smckusick 		   && type == nl + TPTR
14515940Smckusick 		   && size == regtypes[REG_ADDR].regsize
14615940Smckusick 		   && op->curtmps.next_avail[REG_ADDR]
14715940Smckusick 			    >= regtypes[REG_ADDR].lowreg) {
14815940Smckusick 			offset = op->curtmps.next_avail[REG_ADDR]--;
14915940Smckusick 			if (offset < op->low_water[REG_ADDR]) {
15015940Smckusick 				op->low_water[REG_ADDR] = offset;
15115940Smckusick 			}
15215940Smckusick 			nlp = defnl(0, VAR, type, offset + ADDR_REG_OFFSET );
15315940Smckusick 			nlp -> extra_flags = NLOCAL | NREGVAR;
15415940Smckusick 			putlbracket(ftnno, op);
15515940Smckusick 			return nlp;
15615940Smckusick 		}
15715940Smckusick #	    endif mc68000
1583280Smckusic #	endif PC
15911853Speter 	if (type == NIL) {
16011853Speter 	    alignment = A_STACK;
16115940Smckusick 	} else if (type == nl+TPTR) {
16215940Smckusick 	    alignment = A_POINT;
16311853Speter 	} else {
16411853Speter 	    alignment = align(type);
16511853Speter 	}
16611332Speter         op->curtmps.om_off =
16711853Speter 	    roundup((int)(op->curtmps.om_off - size), alignment);
16811332Speter 	offset = op->curtmps.om_off;
1693280Smckusic 	if ( offset < op->om_max ) {
1703280Smckusic 	        op->om_max = offset;
1713219Smckusick 	}
17215939Smckusick 	nlp = defnl( (char *) 0 , VAR , type , offset );
1733219Smckusick #	ifdef PC
1743839Speter 	    nlp -> extra_flags = NLOCAL;
17511332Speter 	    putlbracket(ftnno, op);
1763219Smckusick #	endif PC
1773839Speter 	return nlp;
1783219Smckusick }
17911332Speter 
1803219Smckusick /*
1813219Smckusick  * deallocate runtime temporary variables
1823219Smckusick  */
18315939Smckusick /*ARGSUSED*/
tmpfree(restore)1843219Smckusick tmpfree(restore)
18511332Speter     register struct tmps	*restore;
1863219Smckusick {
18715939Smckusick #   ifdef PC
18811332Speter     register struct om		*op = &sizes[ cbn ];
18911332Speter     bool			change = FALSE;
1903219Smckusick 
19130033Smckusick #	if defined(vax) || defined(tahoe)
19211332Speter 	    if (restore->next_avail[REG_GENERAL]
19311332Speter 		> op->curtmps.next_avail[REG_GENERAL]) {
19411332Speter 		    op->curtmps.next_avail[REG_GENERAL]
19511332Speter 			= restore->next_avail[REG_GENERAL];
19611332Speter 		    change = TRUE;
1973280Smckusic 	    }
19830033Smckusick #	endif vax || tahoe
19915940Smckusick #	ifdef mc68000
20015940Smckusick 	    if (restore->next_avail[REG_DATA]
20115940Smckusick 		> op->curtmps.next_avail[REG_DATA]) {
20215940Smckusick 		    op->curtmps.next_avail[REG_DATA]
20315940Smckusick 			= restore->next_avail[REG_DATA];
20415940Smckusick 		    change = TRUE;
20515940Smckusick 	    }
20615940Smckusick 	    if (restore->next_avail[REG_ADDR]
20715940Smckusick 		> op->curtmps.next_avail[REG_ADDR]) {
20815940Smckusick 		    op->curtmps.next_avail[REG_ADDR]
20915940Smckusick 			= restore->next_avail[REG_ADDR];
21015940Smckusick 		    change = TRUE;
21115940Smckusick 	    }
21215940Smckusick #	endif mc68000
21311332Speter     if (restore->om_off > op->curtmps.om_off) {
21411332Speter 	    op->curtmps.om_off = restore->om_off;
21511332Speter 	    change = TRUE;
21611332Speter     }
21711332Speter 	if (change) {
21811332Speter 	    putlbracket(ftnno, op);
2193219Smckusick 	}
22015939Smckusick #endif PC
2213219Smckusick }
22211332Speter 
2233281Smckusic #ifdef PC
22430033Smckusick #if defined(vax) || defined(tahoe)
2253280Smckusic /*
2263280Smckusic  * create a save mask for registers which have been used
2273280Smckusic  * in this level
2283280Smckusic  */
savmask()2293280Smckusic savmask()
2303280Smckusic {
2313839Speter 	int mask;
2323280Smckusic 	int i;
2333280Smckusic 
2343280Smckusic 	mask = RSAVEMASK;
2353280Smckusic 	if (opt('t'))
2363280Smckusic 	        mask |= RUNCHECK;
23711332Speter 	for (i = 0; i <= regtypes[REG_GENERAL].highreg; i++) {
23811332Speter 	    if (i >= sizes[cbn].low_water[REG_GENERAL]) {
23911332Speter 		mask |= 1 << i;
24011332Speter 	    }
24111332Speter 	}
2423280Smckusic 	return mask;
2433280Smckusic }
24430033Smckusick #endif vax || tahoe
2453281Smckusic #endif PC
246