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