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