1 /* Copyright (c) 1979 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)tmps.c 1.9 04/06/83"; 4 5 #include "whoami.h" 6 #include "0.h" 7 #include "objfmt.h" 8 #ifdef PC 9 # include "pc.h" 10 #endif PC 11 #include "align.h" 12 #include "tmps.h" 13 14 /* 15 * This routine defines the register allocation strategy 16 * All temporaries are allocated here, and this routines decides 17 * where they are to be put. 18 */ 19 #ifdef PC 20 /* 21 * registers are allocated from highreg towards lowreg. 22 * registers are of size regsize. 23 * stack variables are allocated on a downward growing stack. 24 */ 25 26 #ifdef vax 27 /* 28 * first pass register declaration constants 29 */ 30 # define LONGREGTYPE 0 31 struct regtype { 32 long lowreg; 33 long highreg; 34 long regsize; 35 } regtypes[NUMREGTYPES] = { 36 { 6, 11, 4 }, 37 }; 38 #endif vax 39 40 #ifdef mc68000 41 /* 42 * first pass register declaration constants 43 */ 44 # define DATAREGTYPE 0 45 # define ADDRREGTYPE 1 46 struct regtype { 47 long lowreg; 48 long highreg; 49 long regsize; 50 } regtypes[NUMREGTYPES] = { 51 { 2, 7, 0 }, /* off for now */ 52 { 2, 5, 0 }, /* off for now */ 53 }; 54 #endif mc68000 55 #endif PC 56 57 tmpinit(cbn) 58 int cbn; 59 { 60 struct om *sizesp = &sizes[cbn]; 61 int i; 62 63 sizesp->om_max = -DPOFF1; 64 sizesp->curtmps.om_off = -DPOFF1; 65 # ifdef PC 66 for (i = 0; i < NUMREGTYPES; i++) { 67 sizesp->low_water[i] = regtypes[i].highreg + 1; 68 sizesp->curtmps.next_avail[i] = regtypes[i].highreg; 69 } 70 # endif PC 71 } 72 73 /* 74 * allocate runtime temporary variables 75 */ 76 struct nl * 77 tmpalloc(size, type, mode) 78 long size; 79 struct nl *type; 80 int mode; 81 { 82 register struct om *op = &sizes[ cbn ]; 83 register int offset; 84 register struct nl *nlp; 85 long alignment; 86 87 # ifdef PC 88 # ifdef vax 89 if ( mode == REGOK 90 && size == regtypes[REG_GENERAL].regsize 91 && op->curtmps.next_avail[REG_GENERAL] 92 >= regtypes[REG_GENERAL].lowreg) { 93 offset = op->curtmps.next_avail[REG_GENERAL]--; 94 if (offset < op->low_water[REG_GENERAL]) { 95 op->low_water[REG_GENERAL] = offset; 96 } 97 nlp = defnl( 0 , VAR , type , offset ); 98 nlp -> extra_flags = NLOCAL | NREGVAR; 99 putlbracket(ftnno, op); 100 return nlp; 101 } 102 # endif vax 103 # endif PC 104 if (type == NIL) { 105 alignment = A_STACK; 106 } else { 107 alignment = align(type); 108 } 109 op->curtmps.om_off = 110 roundup((int)(op->curtmps.om_off - size), alignment); 111 offset = op->curtmps.om_off; 112 if ( offset < op->om_max ) { 113 op->om_max = offset; 114 } 115 nlp = defnl( 0 , VAR , type , offset ); 116 # ifdef PC 117 nlp -> extra_flags = NLOCAL; 118 putlbracket(ftnno, op); 119 # endif PC 120 return nlp; 121 } 122 123 /* 124 * deallocate runtime temporary variables 125 */ 126 tmpfree(restore) 127 register struct tmps *restore; 128 { 129 register struct om *op = &sizes[ cbn ]; 130 bool change = FALSE; 131 132 # ifdef PC 133 /* i think this never gives back storage! ... peter */ 134 # ifdef vax 135 if (restore->next_avail[REG_GENERAL] 136 > op->curtmps.next_avail[REG_GENERAL]) { 137 op->curtmps.next_avail[REG_GENERAL] 138 = restore->next_avail[REG_GENERAL]; 139 change = TRUE; 140 } 141 # endif vax 142 # endif PC 143 if (restore->om_off > op->curtmps.om_off) { 144 op->curtmps.om_off = restore->om_off; 145 change = TRUE; 146 } 147 # ifdef PC 148 if (change) { 149 putlbracket(ftnno, op); 150 } 151 # endif PC 152 } 153 154 #ifdef PC 155 #ifdef vax 156 /* 157 * create a save mask for registers which have been used 158 * in this level 159 */ 160 savmask() 161 { 162 int mask; 163 int i; 164 165 mask = RSAVEMASK; 166 if (opt('t')) 167 mask |= RUNCHECK; 168 for (i = 0; i <= regtypes[REG_GENERAL].highreg; i++) { 169 if (i >= sizes[cbn].low_water[REG_GENERAL]) { 170 mask |= 1 << i; 171 } 172 } 173 return mask; 174 } 175 #endif vax 176 #endif PC 177