1 /*- 2 * Copyright (c) 1980, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)tmps.c 8.1 (Berkeley) 06/06/93"; 10 #endif /* not lint */ 11 12 #include "whoami.h" 13 #include "0.h" 14 #include "objfmt.h" 15 #ifdef PC 16 # include "pc.h" 17 #endif PC 18 #include "align.h" 19 #include "tmps.h" 20 21 /* 22 * This routine defines the register allocation strategy 23 * All temporaries are allocated here, and this routines decides 24 * where they are to be put. 25 */ 26 #ifdef PC 27 /* 28 * register temporaries 29 * - are allocated from highreg towards lowreg. 30 * - are of size regsize. 31 * - register numbers from the various register types are mapped to 32 * integer register numbers using the offsets. (cf. pcc/mac2defs) 33 * 34 * stack temporaries 35 * - are allocated on a downward growing stack. 36 */ 37 38 #ifdef vax 39 /* 40 * first pass register declaration constants 41 */ 42 struct regtype { 43 long lowreg; 44 long highreg; 45 long regsize; 46 } regtypes[NUMREGTYPES] = { 47 { 6, 11, 4 }, /* r6..r11 */ 48 }; 49 #endif vax 50 51 #ifdef tahoe 52 /* 53 * first pass register declaration constants 54 */ 55 struct regtype { 56 long lowreg; 57 long highreg; 58 long regsize; 59 } regtypes[NUMREGTYPES] = { 60 { 6, 12, 4 }, /* r6..r12 */ 61 }; 62 #endif tahoe 63 64 #ifdef mc68000 65 /* 66 * first pass register declaration constants 67 */ 68 struct regtype { 69 long lowreg; 70 long highreg; 71 long regsize; 72 } regtypes[NUMREGTYPES] = { 73 { 2, 7, 4 }, /* d2..d7 */ 74 { 2, 5, 4 }, /* a2..a5 */ 75 }; 76 #endif mc68000 77 #endif PC 78 79 tmpinit(cbn) 80 int cbn; 81 { 82 struct om *sizesp = &sizes[cbn]; 83 # ifdef PC 84 int i; 85 # endif PC 86 87 sizesp->om_max = -DPOFF1; 88 sizesp->curtmps.om_off = -DPOFF1; 89 # ifdef PC 90 for (i = 0; i < NUMREGTYPES; i++) { 91 sizesp->low_water[i] = regtypes[i].highreg + 1; 92 sizesp->curtmps.next_avail[i] = regtypes[i].highreg; 93 } 94 # endif PC 95 } 96 97 /* 98 * allocate runtime temporary variables 99 */ 100 /*ARGSUSED*/ 101 struct nl * 102 tmpalloc(size, type, mode) 103 long size; 104 struct nl *type; 105 int mode; 106 { 107 register struct om *op = &sizes[ cbn ]; 108 register int offset; 109 register struct nl *nlp; 110 long alignment; 111 112 # ifdef PC 113 # if defined(vax) || defined(tahoe) 114 if ( mode == REGOK 115 && size == regtypes[REG_GENERAL].regsize 116 && op->curtmps.next_avail[REG_GENERAL] 117 >= regtypes[REG_GENERAL].lowreg) { 118 offset = op->curtmps.next_avail[REG_GENERAL]--; 119 if (offset < op->low_water[REG_GENERAL]) { 120 op->low_water[REG_GENERAL] = offset; 121 } 122 nlp = defnl( (char *) 0 , VAR , type , offset ); 123 nlp -> extra_flags = NLOCAL | NREGVAR; 124 putlbracket(ftnno, op); 125 return nlp; 126 } 127 # endif vax || tahoe 128 # ifdef mc68000 129 if ( mode == REGOK 130 && type != nl + TPTR 131 && size == regtypes[REG_DATA].regsize 132 && op->curtmps.next_avail[REG_DATA] 133 >= regtypes[REG_DATA].lowreg) { 134 offset = op->curtmps.next_avail[REG_DATA]--; 135 if (offset < op->low_water[REG_DATA]) { 136 op->low_water[REG_DATA] = offset; 137 } 138 nlp = defnl(0, VAR, type, offset + DATA_REG_OFFSET ); 139 nlp -> extra_flags = NLOCAL | NREGVAR; 140 putlbracket(ftnno, op); 141 return nlp; 142 } 143 if ( mode == REGOK 144 && type == nl + TPTR 145 && size == regtypes[REG_ADDR].regsize 146 && op->curtmps.next_avail[REG_ADDR] 147 >= regtypes[REG_ADDR].lowreg) { 148 offset = op->curtmps.next_avail[REG_ADDR]--; 149 if (offset < op->low_water[REG_ADDR]) { 150 op->low_water[REG_ADDR] = offset; 151 } 152 nlp = defnl(0, VAR, type, offset + ADDR_REG_OFFSET ); 153 nlp -> extra_flags = NLOCAL | NREGVAR; 154 putlbracket(ftnno, op); 155 return nlp; 156 } 157 # endif mc68000 158 # endif PC 159 if (type == NIL) { 160 alignment = A_STACK; 161 } else if (type == nl+TPTR) { 162 alignment = A_POINT; 163 } else { 164 alignment = align(type); 165 } 166 op->curtmps.om_off = 167 roundup((int)(op->curtmps.om_off - size), alignment); 168 offset = op->curtmps.om_off; 169 if ( offset < op->om_max ) { 170 op->om_max = offset; 171 } 172 nlp = defnl( (char *) 0 , VAR , type , offset ); 173 # ifdef PC 174 nlp -> extra_flags = NLOCAL; 175 putlbracket(ftnno, op); 176 # endif PC 177 return nlp; 178 } 179 180 /* 181 * deallocate runtime temporary variables 182 */ 183 /*ARGSUSED*/ 184 tmpfree(restore) 185 register struct tmps *restore; 186 { 187 # ifdef PC 188 register struct om *op = &sizes[ cbn ]; 189 bool change = FALSE; 190 191 # if defined(vax) || defined(tahoe) 192 if (restore->next_avail[REG_GENERAL] 193 > op->curtmps.next_avail[REG_GENERAL]) { 194 op->curtmps.next_avail[REG_GENERAL] 195 = restore->next_avail[REG_GENERAL]; 196 change = TRUE; 197 } 198 # endif vax || tahoe 199 # ifdef mc68000 200 if (restore->next_avail[REG_DATA] 201 > op->curtmps.next_avail[REG_DATA]) { 202 op->curtmps.next_avail[REG_DATA] 203 = restore->next_avail[REG_DATA]; 204 change = TRUE; 205 } 206 if (restore->next_avail[REG_ADDR] 207 > op->curtmps.next_avail[REG_ADDR]) { 208 op->curtmps.next_avail[REG_ADDR] 209 = restore->next_avail[REG_ADDR]; 210 change = TRUE; 211 } 212 # endif mc68000 213 if (restore->om_off > op->curtmps.om_off) { 214 op->curtmps.om_off = restore->om_off; 215 change = TRUE; 216 } 217 if (change) { 218 putlbracket(ftnno, op); 219 } 220 #endif PC 221 } 222 223 #ifdef PC 224 #if defined(vax) || defined(tahoe) 225 /* 226 * create a save mask for registers which have been used 227 * in this level 228 */ 229 savmask() 230 { 231 int mask; 232 int i; 233 234 mask = RSAVEMASK; 235 if (opt('t')) 236 mask |= RUNCHECK; 237 for (i = 0; i <= regtypes[REG_GENERAL].highreg; i++) { 238 if (i >= sizes[cbn].low_water[REG_GENERAL]) { 239 mask |= 1 << i; 240 } 241 } 242 return mask; 243 } 244 #endif vax || tahoe 245 #endif PC 246