1 /* Copyright (c) 1979 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)tmps.c 1.10 09/05/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, 100 offset + regtypes[REG_GENERAL].regno_offset ); 101 nlp -> extra_flags = NLOCAL | NREGVAR; 102 putlbracket(ftnno, op); 103 return nlp; 104 } 105 # endif vax 106 # ifdef mc68000 107 if ( mode == REGOK 108 && type != nl + TPTR 109 && size == regtypes[REG_DATA].regsize 110 && op->curtmps.next_avail[REG_DATA] 111 >= regtypes[REG_DATA].lowreg) { 112 offset = op->curtmps.next_avail[REG_DATA]--; 113 if (offset < op->low_water[REG_DATA]) { 114 op->low_water[REG_DATA] = offset; 115 } 116 nlp = defnl(0, VAR, type, offset + DATA_REG_OFFSET ); 117 nlp -> extra_flags = NLOCAL | NREGVAR; 118 putlbracket(ftnno, op); 119 return nlp; 120 } 121 if ( mode == REGOK 122 && type == nl + TPTR 123 && size == regtypes[REG_ADDR].regsize 124 && op->curtmps.next_avail[REG_ADDR] 125 >= regtypes[REG_ADDR].lowreg) { 126 offset = op->curtmps.next_avail[REG_ADDR]--; 127 if (offset < op->low_water[REG_ADDR]) { 128 op->low_water[REG_ADDR] = offset; 129 } 130 nlp = defnl(0, VAR, type, offset + ADDR_REG_OFFSET ); 131 nlp -> extra_flags = NLOCAL | NREGVAR; 132 putlbracket(ftnno, op); 133 return nlp; 134 } 135 # endif mc68000 136 # endif PC 137 if (type == NIL) { 138 alignment = A_STACK; 139 } else { 140 alignment = align(type); 141 } 142 op->curtmps.om_off = 143 roundup((int)(op->curtmps.om_off - size), alignment); 144 offset = op->curtmps.om_off; 145 if ( offset < op->om_max ) { 146 op->om_max = offset; 147 } 148 nlp = defnl( 0 , VAR , type , offset ); 149 # ifdef PC 150 nlp -> extra_flags = NLOCAL; 151 putlbracket(ftnno, op); 152 # endif PC 153 return nlp; 154 } 155 156 /* 157 * deallocate runtime temporary variables 158 */ 159 tmpfree(restore) 160 register struct tmps *restore; 161 { 162 register struct om *op = &sizes[ cbn ]; 163 bool change = FALSE; 164 165 # ifdef PC 166 # ifdef vax 167 if (restore->next_avail[REG_GENERAL] 168 > op->curtmps.next_avail[REG_GENERAL]) { 169 op->curtmps.next_avail[REG_GENERAL] 170 = restore->next_avail[REG_GENERAL]; 171 change = TRUE; 172 } 173 # endif vax 174 # ifdef mc68000 175 if (restore->next_avail[REG_DATA] 176 > op->curtmps.next_avail[REG_DATA]) { 177 op->curtmps.next_avail[REG_DATA] 178 = restore->next_avail[REG_DATA]; 179 change = TRUE; 180 } 181 if (restore->next_avail[REG_ADDR] 182 > op->curtmps.next_avail[REG_ADDR]) { 183 op->curtmps.next_avail[REG_ADDR] 184 = restore->next_avail[REG_ADDR]; 185 change = TRUE; 186 } 187 # endif mc68000 188 # endif PC 189 if (restore->om_off > op->curtmps.om_off) { 190 op->curtmps.om_off = restore->om_off; 191 change = TRUE; 192 } 193 # ifdef PC 194 if (change) { 195 putlbracket(ftnno, op); 196 } 197 # endif PC 198 } 199 200 #ifdef PC 201 #ifdef vax 202 /* 203 * create a save mask for registers which have been used 204 * in this level 205 */ 206 savmask() 207 { 208 int mask; 209 int i; 210 211 mask = RSAVEMASK; 212 if (opt('t')) 213 mask |= RUNCHECK; 214 for (i = 0; i <= regtypes[REG_GENERAL].highreg; i++) { 215 if (i >= sizes[cbn].low_water[REG_GENERAL]) { 216 mask |= 1 << i; 217 } 218 } 219 return mask; 220 } 221 #endif vax 222 #endif PC 223