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.1 (Berkeley) 06/05/85"; 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 mc68000 51 /* 52 * first pass register declaration constants 53 */ 54 struct regtype { 55 long lowreg; 56 long highreg; 57 long regsize; 58 } regtypes[NUMREGTYPES] = { 59 { 2, 7, 4 }, /* d2..d7 */ 60 { 2, 5, 4 }, /* a2..a5 */ 61 }; 62 #endif mc68000 63 #endif PC 64 65 tmpinit(cbn) 66 int cbn; 67 { 68 struct om *sizesp = &sizes[cbn]; 69 # ifdef PC 70 int i; 71 # endif PC 72 73 sizesp->om_max = -DPOFF1; 74 sizesp->curtmps.om_off = -DPOFF1; 75 # ifdef PC 76 for (i = 0; i < NUMREGTYPES; i++) { 77 sizesp->low_water[i] = regtypes[i].highreg + 1; 78 sizesp->curtmps.next_avail[i] = regtypes[i].highreg; 79 } 80 # endif PC 81 } 82 83 /* 84 * allocate runtime temporary variables 85 */ 86 /*ARGSUSED*/ 87 struct nl * 88 tmpalloc(size, type, mode) 89 long size; 90 struct nl *type; 91 int mode; 92 { 93 register struct om *op = &sizes[ cbn ]; 94 register int offset; 95 register struct nl *nlp; 96 long alignment; 97 98 # ifdef PC 99 # ifdef vax 100 if ( mode == REGOK 101 && size == regtypes[REG_GENERAL].regsize 102 && op->curtmps.next_avail[REG_GENERAL] 103 >= regtypes[REG_GENERAL].lowreg) { 104 offset = op->curtmps.next_avail[REG_GENERAL]--; 105 if (offset < op->low_water[REG_GENERAL]) { 106 op->low_water[REG_GENERAL] = offset; 107 } 108 nlp = defnl( (char *) 0 , VAR , type , offset ); 109 nlp -> extra_flags = NLOCAL | NREGVAR; 110 putlbracket(ftnno, op); 111 return nlp; 112 } 113 # endif vax 114 # ifdef mc68000 115 if ( mode == REGOK 116 && type != nl + TPTR 117 && size == regtypes[REG_DATA].regsize 118 && op->curtmps.next_avail[REG_DATA] 119 >= regtypes[REG_DATA].lowreg) { 120 offset = op->curtmps.next_avail[REG_DATA]--; 121 if (offset < op->low_water[REG_DATA]) { 122 op->low_water[REG_DATA] = offset; 123 } 124 nlp = defnl(0, VAR, type, offset + DATA_REG_OFFSET ); 125 nlp -> extra_flags = NLOCAL | NREGVAR; 126 putlbracket(ftnno, op); 127 return nlp; 128 } 129 if ( mode == REGOK 130 && type == nl + TPTR 131 && size == regtypes[REG_ADDR].regsize 132 && op->curtmps.next_avail[REG_ADDR] 133 >= regtypes[REG_ADDR].lowreg) { 134 offset = op->curtmps.next_avail[REG_ADDR]--; 135 if (offset < op->low_water[REG_ADDR]) { 136 op->low_water[REG_ADDR] = offset; 137 } 138 nlp = defnl(0, VAR, type, offset + ADDR_REG_OFFSET ); 139 nlp -> extra_flags = NLOCAL | NREGVAR; 140 putlbracket(ftnno, op); 141 return nlp; 142 } 143 # endif mc68000 144 # endif PC 145 if (type == NIL) { 146 alignment = A_STACK; 147 } else if (type == nl+TPTR) { 148 alignment = A_POINT; 149 } else { 150 alignment = align(type); 151 } 152 op->curtmps.om_off = 153 roundup((int)(op->curtmps.om_off - size), alignment); 154 offset = op->curtmps.om_off; 155 if ( offset < op->om_max ) { 156 op->om_max = offset; 157 } 158 nlp = defnl( (char *) 0 , VAR , type , offset ); 159 # ifdef PC 160 nlp -> extra_flags = NLOCAL; 161 putlbracket(ftnno, op); 162 # endif PC 163 return nlp; 164 } 165 166 /* 167 * deallocate runtime temporary variables 168 */ 169 /*ARGSUSED*/ 170 tmpfree(restore) 171 register struct tmps *restore; 172 { 173 # ifdef PC 174 register struct om *op = &sizes[ cbn ]; 175 bool change = FALSE; 176 177 # ifdef vax 178 if (restore->next_avail[REG_GENERAL] 179 > op->curtmps.next_avail[REG_GENERAL]) { 180 op->curtmps.next_avail[REG_GENERAL] 181 = restore->next_avail[REG_GENERAL]; 182 change = TRUE; 183 } 184 # endif vax 185 # ifdef mc68000 186 if (restore->next_avail[REG_DATA] 187 > op->curtmps.next_avail[REG_DATA]) { 188 op->curtmps.next_avail[REG_DATA] 189 = restore->next_avail[REG_DATA]; 190 change = TRUE; 191 } 192 if (restore->next_avail[REG_ADDR] 193 > op->curtmps.next_avail[REG_ADDR]) { 194 op->curtmps.next_avail[REG_ADDR] 195 = restore->next_avail[REG_ADDR]; 196 change = TRUE; 197 } 198 # endif mc68000 199 if (restore->om_off > op->curtmps.om_off) { 200 op->curtmps.om_off = restore->om_off; 201 change = TRUE; 202 } 203 if (change) { 204 putlbracket(ftnno, op); 205 } 206 #endif PC 207 } 208 209 #ifdef PC 210 #ifdef vax 211 /* 212 * create a save mask for registers which have been used 213 * in this level 214 */ 215 savmask() 216 { 217 int mask; 218 int i; 219 220 mask = RSAVEMASK; 221 if (opt('t')) 222 mask |= RUNCHECK; 223 for (i = 0; i <= regtypes[REG_GENERAL].highreg; i++) { 224 if (i >= sizes[cbn].low_water[REG_GENERAL]) { 225 mask |= 1 << i; 226 } 227 } 228 return mask; 229 } 230 #endif vax 231 #endif PC 232