1*48116Sbostic /*- 2*48116Sbostic * Copyright (c) 1980 The Regents of the University of California. 3*48116Sbostic * All rights reserved. 4*48116Sbostic * 5*48116Sbostic * %sccs.include.redist.c% 622197Sdist */ 73219Smckusick 815939Smckusick #ifndef lint 9*48116Sbostic static char sccsid[] = "@(#)tmps.c 5.3 (Berkeley) 04/16/91"; 10*48116Sbostic #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 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 * 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*/ 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 */ 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