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