1File: ICODE.C Page 1 1 /* 2 Copyright 1982 3 Alcyon Corporation 4 8716 Production Ave. 5 San Diego, Ca. 92121 6 */ 7 8 #include "parser.h" 9 10 int bol 1; 11 int inittype; 12 int begseq; 13 /* int onepass; */ 14 15 /* 16 This interfaces the Parser and the Code Generator, note that these 17 allow you to link together the Parser and the Code Generator. 18 */ 19 20 /* outbdata - set up for byte data*/ 21 outbdata() /* returns - none*/ 22 { 23 inittype = CHAR; 24 printf("\t.dc.b "); 25 } 26 27 /* outc - output a constant*/ 28 outc(type,value) /* returns - none*/ 29 int type; 30 int value; 31 { 32 if( type == CHAR ) 33 outbdata(); 34 else 35 outwdata(); 36 printf("%d\n",value); 37 } 38 39 /* outwdata - set up for word data*/ 40 outwdata() /* returns - none*/ 41 { 42 inittype = INT; 43 printf("\t.dc.w "); 44 } 45 46 /* outdata - set up for data output*/ 47 outdata() /* returns - none*/ 48 { 49 inittype = INT; 50 printf("\t.data\n"); 51 } 52 53 /* outldata - set up for long data output*/ 54 outldata() /* returns - none*/ 55 { 56 inittype = LONG; 57 printf("\t.data\n"); 58 } 59 1File: ICODE.C Page 2 60 /* outfpdata - set up for floating point data output*/ 61 outfpdata() /*[vlh] 3.4 returns - none*/ 62 { 63 inittype = FLOAT; 64 printf("\t.data\n"); 65 } 66 67 /* outbentry - outputs block/function entry code*/ 68 outbentry(nlocs,nds,nas) /* returns - none*/ 69 int nlocs; /* local size*/ 70 int nds; /* number of D registers*/ 71 int nas; /* number of A registers*/ 72 { 73 if( !nds && !nas ) /* adjust for 1 arg*/ 74 nlocs =+ 4; 75 printf("\tlink R14,#%d\n",-nlocs); 76 if( nds || nas ) { 77 printf("\tmovem.l R%d-R7",7-nds); /*7 for one arg*/ 78 if( nas ) { 79 putchar('/'); 80 printf("R%d-R13",14-nas); 81 } 82 printf(",-(sp)\n"); 83 } 84 } 85 86 /* outbexit - output function exit code*/ 87 outbexit(nds,nas) /* returns - none*/ 88 int nds; /* number of D registers*/ 89 int nas; /* number of A registers*/ 90 { 91 if( nds || nas ) { 92 printf("\ttst.l (sp)+\n\tmovem.l (sp)+,"); /*1 arg stuff*/ 93 if( nds ) { 94 printf("R%d-R7",8-nds); 95 if( nas ) 96 putchar('/'); 97 } 98 if( nas ) 99 printf("R%d-R13",14-nas); 100 putchar('\n'); 101 } 102 printf("\tunlk R14\n\trts\n"); 103 } 104 105 /* outlocal - output local symbol for debugger*/ 106 outlocal(type,sc,sym,val) 107 int type; /* local name type*/ 108 int sc; /* storage type*/ 109 char *sym; /* symbol name*/ 110 int val; 111 { 112 switch( sc ) { 113 114 case STATIC: 115 if( notfunction(type) ) 116 printf("\t~%.8s=L%d\n",sym,val); 117 break; 118 1File: ICODE.C Page 3 119 case REGISTER: 120 printf("\t~%.8s=R%d\n",sym,val); 121 break; 122 123 case AUTO: 124 printf("\t~%.8s=%d\n",sym,val); 125 break; 126 } 127 } 128 129 /* outswitch - output switch table info*/ 130 outswitch(ncases,deflab,sp) /* returns - none*/ 131 int ncases; /* number of cases in switch*/ 132 int deflab; /* default label*/ 133 struct swtch *sp; /* switch table pointer*/ 134 { 135 register int vdif, val, hval, i, tlab; 136 register struct swtch *s; 137 138 val = sp->sw_value; 139 hval = sp[ncases-1].sw_value; 140 vdif = hval - val; 141 if( ncases <= 4 ) { 142 /* 143 *simple switch, do compares and brances, followed by branch to default 144 */ 145 for( s = sp; --ncases >= 0; s++ ) { 146 if( !s->sw_value ) 147 printf("\ttst R0\n"); 148 else 149 printf("\tcmp #%d,R0\n",s->sw_value); 150 printf("\tbeq L%d\n",s->sw_label); 151 } 152 outgoto(deflab); 153 } 154 else if( vdif > 0 && vdif <= ncases*3 ) { 155 156 /*jump switch, uses value in R0 to index into table of labels*/ 157 158 if( val ) 159 printf("\tsub #%d,R0\n",val); 160 tlab = nextlabel++; 161 printf("\tcmp #%d,R0\n\tbhi L%d\n",vdif,deflab); /*check for max*/ 162 printf("\tasl #2,R0\n\tmove R0,R8\n\tadd.l #L%d,R8\n",tlab); 163 printf("\tmove.l (R8),R8\n\tjmp (R8)\n"); 164 outdata(); 165 outlab(tlab); 166 for( s = sp; val <= hval; val++ ) { 167 if( val == s->sw_value ) { 168 outclab(s->sw_label); 169 s++; 170 } 171 else 172 outclab(deflab); 173 } 174 outtext(); 175 } 176 else { 177 /* 1File: ICODE.C Page 4 178 * direct switch, searches down table of values for match, if match 179 * found, branches to corresponding label in label table. 180 */ 181 tlab = nextlabel++; 182 printf("\text.l R0\n\tmove.l #L%d,R8\n\tmove #%d,R1\n",tlab,ncases); 183 i = nextlabel++; 184 outlab(i); /*loop label*/ 185 printf("\tcmp.l (R8)+,R0\n\tdbeq R1,L%d\n",i); 186 printf("\tmove.l %d(R8),R8\n\tjmp (R8)\n",ncases*4); 187 outdata(); 188 outlab(tlab); 189 for( s = sp, i = ncases; --i >= 0; s++ ) 190 outlcon(s->sw_value); 191 outlcon(0); /* mark for default label*/ 192 for( s = sp, i = ncases; --i >= 0; s++ ) 193 outclab(s->sw_label); 194 outclab(deflab); 195 outtext(); 196 } 197 } 198 199 outeof() 200 { 201 register int c; 202 203 v6flush(&sbuf); 204 v6flush(&obuf); 205 } 206 207 /* copysfile - copy string file to end of output file*/ 208 copysfile(fname) 209 char *fname; 210 { 211 register int c; 212 213 close(sbuf.io_fd); 214 if( fopen(fname,&sbuf,0) < 0 ) /* 3rd arg for versados */ 215 ferror("can't copy %s",fname); 216 while( (c=getc(&sbuf)) > 0 ) 217 putc(c,&obuf); 218 v6flush(&obuf); 219 } 220 221 /* outword - output a word of data*/ 222 outword(w) /* word expression*/ 223 int w; 224 { 225 if( begseq ) 226 putchar(','); 227 begseq++; 228 printf("%d",w); 229 } 230 231 /* outlong - output a long data*/ 232 outlong(l) /* returns - none*/ 233 long l; /* long data to output*/ 234 { 235 outwdata(); 236 outword(l.hiword); 1File: ICODE.C Page 5 237 outword(l.loword); 238 outendseq(); 239 } 240 241 /* outfp - output floating point data*/ 242 outfp(l) /*[vlh] 3.4 returns - none*/ 243 long l; /* floating point data to output*/ 244 { 245 outwdata(); 246 outword(l.hiword); 247 outword(l.loword); 248 outendseq(); 249 } 250 251 outendseq() /* returns - none*/ 252 { 253 begseq = 0; 254 putchar('\n'); 255 } 256 257 /* 258 * outtstr - output text string 259 * This outputs a string to the string file, this is used wherever 260 * you cannot output the string directly to data space, such as in 261 * the middle of expressions. 262 */ 263 outtstr(lab) 264 int lab; 265 { 266 char *savep; 267 int sbol; 268 269 savep = obp; /*save to restore later...*/ 270 obp = &sbuf; 271 sbol = bol; 272 bol = 1; 273 printf("\tL%d:",lab); 274 outstr(); 275 obp = savep; 276 bol = sbol; 277 } 278 279 /* outstr - output a string as a sequence of bytes*/ 280 /* Outputs ".dc.b ,,...,<0>*/ 281 outstr() 282 { 283 register char *s; 284 register int i; 285 286 outbdata(); 287 for( s = cstr, i = cstrsize; i > 0; i-- ) 288 outword(*s++ & 0xff); 289 outendseq(); 290 } 291 292 /* 293 * putchar - handle outputting to intermediate or error files 294 * This catches tabs to allow for the integration of the parser 295 * and code generator into one pass. By merely throwing away the 1File: ICODE.C Page 6 296 * tabs here, the output will be OK for the assembler. 297 */ 298 putchar(c) 299 char c; 300 { 301 if( !obp ) 302 write(1,&c,1); 303 else if( c == '\t' ) { 304 if( bol ) /* not used && !onepass ) */ 305 putc('(',obp); /*for code generator*/ 306 } 307 else { 308 bol = (c == '\n'); 309 putc(c,obp); 310 } 311 }