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