code.c (9208B)
1 static char sccsid[] = "@(#) ./cc1/code.c"; 2 #include <ctype.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <stdarg.h> 6 7 #include "../inc/scc.h" 8 #include "cc1.h" 9 10 static void emitbin(int, void *), 11 emitcast(int, void *), 12 emitsym(int, void *), 13 emitexp(int, void *), 14 emitsymid(int, void *), 15 emittext(int, void *), 16 emitfun(int, void *), 17 emitdcl(int, void *), 18 emitinit(int, void *), 19 emittype(int, void *), 20 emitbuilt(int, void *); 21 22 char *optxt[] = { 23 [OADD] = "+", 24 [OSUB] = "-", 25 [OMUL] = "*", 26 [OINC] = ":i", 27 [ODEC] = ":d", 28 [OPTR] = "@", 29 [OMOD] = "%", 30 [ODIV] = "/", 31 [OSHL] = "l", 32 [OSHR] = "r", 33 [OLT] = "<", 34 [OGT] = ">", 35 [OGE] = "]", 36 [OLE] = "[", 37 [OEQ] = "=", 38 [ONE] = "!", 39 [OBAND] = "&", 40 [OBXOR] = "^", 41 [OBOR] = "|", 42 [OASSIGN] = ":", 43 [OA_MUL] = ":*", 44 [OA_DIV] = ":/", 45 [OA_MOD] = ":%", 46 [OA_ADD] = ":+", 47 [OA_SUB] = ":-", 48 [OA_SHL] = ":l", 49 [OA_SHR] = ":r", 50 [OA_AND] = ":&", 51 [OA_XOR] = ":^", 52 [OA_OR] = ":|", 53 [OADDR] = "'", 54 [OSNEG] = "_", 55 [ONEG] = "n", 56 [OCPL] = "~", 57 [OAND] = "a", 58 [OOR] = "o", 59 [OASK] = "?", 60 [OCOMMA] = ",", 61 [OLABEL] = "L%d\n", 62 [ODEFAULT] = "\tf\tL%d\n", 63 [OBSWITCH] = "\ts", 64 [OESWITCH] = "\tt\tL%d\n", 65 [OCASE] = "\tv\tL%d", 66 [OJUMP] = "\tj\tL%d\n", 67 [OBRANCH] = "\ty\tL%d", 68 [OEFUN] = "}\n", 69 [OELOOP] = "\tb\n", 70 [OBLOOP] = "\te\n", 71 [ORET] = "\th", 72 [OPAR] = "p", 73 [OCALL] = "c", 74 [OCALLE] = "z", 75 [OFIELD] = "." 76 }; 77 78 void (*opcode[])(int, void *) = { 79 [OADD] = emitbin, 80 [OSUB] = emitbin, 81 [OMUL] = emitbin, 82 [OINC] = emitbin, 83 [ODEC] = emitbin, 84 [OPTR] = emitbin, 85 [OMOD] = emitbin, 86 [ODIV] = emitbin, 87 [OSHL] = emitbin, 88 [OSHR] = emitbin, 89 [OLT] = emitbin, 90 [OGT] = emitbin, 91 [OGE] = emitbin, 92 [OLE] = emitbin, 93 [OEQ] = emitbin, 94 [ONE] = emitbin, 95 [OBAND] = emitbin, 96 [OBXOR] = emitbin, 97 [OBOR] = emitbin, 98 [OASSIGN] = emitbin, 99 [OA_MUL] = emitbin, 100 [OA_DIV] = emitbin, 101 [OA_MOD] = emitbin, 102 [OA_ADD] = emitbin, 103 [OA_SUB] = emitbin, 104 [OA_SHL] = emitbin, 105 [OA_SHR] = emitbin, 106 [OA_AND] = emitbin, 107 [OA_XOR] = emitbin, 108 [OA_OR] = emitbin, 109 [OADDR] = emitbin, 110 [OSNEG] = emitbin, 111 [ONEG] = emitbin, 112 [OCPL] = emitbin, 113 [OAND] = emitbin, 114 [OOR] = emitbin, 115 [OCOMMA] = emitbin, 116 [OCAST] = emitcast, 117 [OSYM] = emitsym, 118 [OASK] = emitbin, 119 [OCOLON] = emitbin, 120 [OFIELD]= emitbin, 121 [OEXPR] = emitexp, 122 [OLABEL] = emitsymid, 123 [ODEFAULT] = emitsymid, 124 [OCASE] = emitsymid, 125 [OJUMP] = emitsymid, 126 [OBRANCH] = emitsymid, 127 [OEFUN] = emittext, 128 [OELOOP] = emittext, 129 [OBLOOP] = emittext, 130 [OFUN] = emitfun, 131 [ORET] = emittext, 132 [ODECL] = emitdcl, 133 [OBSWITCH] = emittext, 134 [OESWITCH] = emitsymid, 135 [OPAR] = emitbin, 136 [OCALL] = emitbin, 137 [OCALLE] = emitbin, 138 [OINIT] = emitinit, 139 [OBUILTIN] = emitbuilt, 140 [OTYP] = emittype, 141 }; 142 143 static FILE *outfp; 144 145 void 146 icode(void) 147 { 148 outfp = stdout; 149 } 150 151 void 152 freetree(Node *np) 153 { 154 if (!np) 155 return; 156 freetree(np->left); 157 freetree(np->right); 158 free(np); 159 } 160 161 static void 162 emitnode(Node *np) 163 { 164 if (np) 165 (*opcode[np->op])(np->op, np); 166 } 167 168 void 169 prtree(Node *np) 170 { 171 outfp = stderr; 172 fputs("DBG prtree", outfp); 173 emitnode(np); 174 putc('\n', outfp); 175 outfp = stdout; 176 } 177 178 void 179 emit(int op, void *arg) 180 { 181 extern int failure; 182 183 if (failure || onlycpp || onlyheader) 184 return; 185 (*opcode[op])(op, arg); 186 } 187 188 static void 189 emitvar(Symbol *sym) 190 { 191 int c; 192 short flags = sym->flags; 193 194 if (flags & SLOCAL) 195 c = 'T'; 196 else if (flags & SPRIVATE) 197 c = 'Y'; 198 else if (flags & SGLOBAL) 199 c = 'G'; 200 else if (flags & SREGISTER) 201 c = 'R'; 202 else if (flags & SFIELD) 203 c = 'M'; 204 else if (flags & SEXTERN) 205 c = 'X'; 206 else 207 c = 'A'; 208 fprintf(outfp, "%c%u", c, sym->id); 209 } 210 211 static void 212 emitconst(Node *np) 213 { 214 Symbol *sym = np->sym; 215 Type *tp = np->type; 216 TUINT u; 217 218 switch (tp->op) { 219 case PTR: 220 case INT: 221 case ENUM: 222 u = (tp->prop & TSIGNED) ? (TUINT) sym->u.i : sym->u.u; 223 fprintf(outfp, 224 "#%c%llX", 225 np->type->letter, 226 (long long) u & ones(tp->size)); 227 break; 228 default: 229 abort(); 230 } 231 } 232 233 static void 234 emitsym(int op, void *arg) 235 { 236 Node *np = arg; 237 238 if ((np->sym->flags & SINITLST) == 0) { 239 /* 240 * When we have a compound literal we are going 241 * to call to emitnode for every element of it, 242 * and it means that we will have two '\t' 243 * for the first element 244 */ 245 putc('\t', outfp); 246 } 247 (np->flags & NCONST) ? emitconst(np) : emitvar(np->sym); 248 } 249 250 static void 251 emitletter(Type *tp) 252 { 253 int letter; 254 255 letter = (tp->prop&TELLIPSIS) ? 'E' : tp->letter; 256 putc(letter, outfp); 257 switch (tp->op) { 258 case ARY: 259 case STRUCT: 260 case UNION: 261 fprintf(outfp, "%u", tp->id); 262 } 263 } 264 265 static void 266 emittype(int op, void *arg) 267 { 268 TINT n; 269 Symbol **sp; 270 char *tag; 271 Type *tp = arg; 272 273 if (!(tp->prop & TDEFINED)) 274 return; 275 276 switch (tp->op) { 277 case ARY: 278 emitletter(tp); 279 putc('\t', outfp); 280 emitletter(tp->type); 281 fprintf(outfp, 282 "\t#%c%llX\n", 283 sizettype->letter, (long long) tp->n.elem); 284 return; 285 case UNION: 286 case STRUCT: 287 emitletter(tp); 288 tag = tp->tag->name; 289 fprintf(outfp, 290 "\t\"%s\t#%c%lX\t#%c%X\n", 291 (tag) ? tag : "", 292 sizettype->letter, 293 tp->size, 294 sizettype->letter, 295 tp->align); 296 n = tp->n.elem; 297 for (sp = tp->p.fields; n-- > 0; ++sp) 298 emit(ODECL, *sp); 299 break; 300 case PTR: 301 case FTN: 302 case ENUM: 303 return; 304 default: 305 abort(); 306 } 307 } 308 309 static void 310 emitstring(Symbol *sym, Type *tp) 311 { 312 char *bp, *s, *lim; 313 int n; 314 315 bp = sym->u.s; 316 lim = &sym->u.s[tp->n.elem]; 317 while (bp < lim) { 318 s = bp; 319 while (bp < lim && isprint(*bp)) 320 ++bp; 321 if ((n = bp - s) > 1) 322 fprintf(outfp, "\t#\"%.*s\n", n, s); 323 else 324 bp = s; 325 if (bp == lim) 326 break; 327 do { 328 fprintf(outfp, 329 "\t#%c%02X\n", 330 chartype->letter, (*bp++) & 0xFF); 331 } while (bp < lim && !isprint(*bp)); 332 } 333 } 334 335 static void 336 emitdesig(Node *np, Type *tp) 337 { 338 Symbol *sym; 339 size_t n; /* TODO: This should be SIZET */ 340 Node *aux; 341 Type *p; 342 343 if (!np) { 344 sym = NULL; 345 } else { 346 if (!np->sym) 347 goto emit_expression; 348 sym = np->sym; 349 if (sym->flags & SSTRING) { 350 emitstring(sym, tp); 351 return; 352 } 353 if ((sym->flags & SINITLST) == 0) 354 goto emit_expression; 355 } 356 357 switch (tp->op) { 358 case PTR: 359 case INT: 360 case ENUM: 361 aux = (sym) ? *sym->u.init : convert(constnode(zero), tp, 0); 362 emitexp(OEXPR, aux); 363 break; 364 case UNION: 365 n = tp->n.elem-1; 366 aux = (sym) ? sym->u.init[0] : NULL; 367 emitdesig(aux, aux->type); 368 break; 369 case STRUCT: 370 case ARY: 371 for (n = 0; n < tp->n.elem; ++n) { 372 aux = (sym) ? sym->u.init[n] : NULL; 373 p = (tp->op == ARY) ? tp->type : tp->p.fields[n]->type; 374 emitdesig(aux, p); 375 } 376 break; 377 default: 378 abort(); 379 } 380 381 if (sym) { 382 free(sym->u.init); 383 sym->u.init = NULL; 384 } 385 freetree(np); 386 return; 387 388 emit_expression: 389 emitexp(OEXPR, np); 390 } 391 392 static void 393 emitinit(int op, void *arg) 394 { 395 Node *np = arg; 396 397 fputs("\t(\n", outfp); 398 emitdesig(np, np->type); 399 fputs(")\n", outfp); 400 } 401 402 static void 403 emitdcl(int op, void *arg) 404 { 405 Symbol *sym = arg; 406 407 if (sym->flags & SEMITTED) 408 return; 409 emitvar(sym); 410 putc('\t', outfp); 411 if (sym->type->op == FTN) { 412 emitletter(sym->type->type); 413 putc('\t', outfp); 414 } 415 emitletter(sym->type); 416 fprintf(outfp, "\t\"%s", (sym->name) ? sym->name : ""); 417 if (sym->flags & SFIELD) 418 fprintf(outfp, "\t#%c%llX", sizettype->letter, sym->u.i); 419 sym->flags |= SEMITTED; 420 if ((sym->flags & SHASINIT) == 0) 421 putc('\n', outfp); 422 } 423 424 static void 425 emitcast(int op, void *arg) 426 { 427 Node *np = arg, *lp = np->left; 428 429 emitnode(lp); 430 if (np->type != voidtype) 431 fprintf(outfp, "\tg%c", np->type->letter); 432 } 433 434 static void 435 emitbin(int op, void *arg) 436 { 437 Node *np = arg; 438 char *s; 439 440 emitnode(np->left); 441 emitnode(np->right); 442 if ((s = optxt[op]) != NULL) { /* do not print in OCOLON case */ 443 fprintf(outfp, "\t%s", s); 444 emitletter(np->type); 445 } 446 } 447 448 static void 449 emitbuilt(int op, void *arg) 450 { 451 Node *np = arg; 452 453 emitnode(np->left); 454 emitnode(np->right); 455 fprintf(outfp, "\t\"%s\tm", np->sym->name); 456 emitletter(np->type); 457 } 458 459 460 static void 461 emitexp(int op, void *arg) 462 { 463 Node *np = arg; 464 465 emitnode(np); 466 putc('\n', outfp); 467 freetree(np); 468 } 469 470 static void 471 emitfun(int op, void *arg) 472 { 473 Symbol *sym = arg, **sp; 474 475 emitdcl(op, arg); 476 fputs("{\n", outfp); 477 478 for (sp = sym->u.pars; sp && *sp; ++sp) 479 emit(ODECL, *sp); 480 fputs("\\\n", outfp); 481 } 482 483 static void 484 emittext(int op, void *arg) 485 { 486 fputs(optxt[op], outfp); 487 } 488 489 static void 490 emitsymid(int op, void *arg) 491 { 492 Symbol *sym = arg; 493 fprintf(outfp, optxt[op], sym->id); 494 } 495 496 Node * 497 node(int op, Type *tp, Node *lp, Node *rp) 498 { 499 Node *np; 500 501 np = xmalloc(sizeof(*np)); 502 np->op = op; 503 np->type = tp; 504 np->sym = NULL; 505 np->flags = 0; 506 np->left = lp; 507 np->right = rp; 508 509 if (lp) 510 np->flags |= lp->flags & NEFFECT; 511 if (rp) 512 np->flags |= rp->flags & NEFFECT; 513 return np; 514 } 515 516 Node * 517 varnode(Symbol *sym) 518 { 519 Node *np; 520 Type *tp = sym->type; 521 522 np = node(OSYM, sym->type, NULL, NULL); 523 np->type = sym->type; 524 np->flags = (tp->op != FTN && tp->op != ARY) ? NLVAL : 0; 525 np->sym = sym; 526 return np; 527 } 528 529 Node * 530 constnode(Symbol *sym) 531 { 532 Node *np; 533 534 np = node(OSYM, sym->type, NULL, NULL); 535 np->type = sym->type; 536 np->flags = NCONST; 537 np->sym = sym; 538 return np; 539 } 540 541 Node * 542 sizeofnode(Type *tp) 543 { 544 Symbol *sym; 545 546 sym = newsym(NS_IDEN, NULL); 547 sym->type = sizettype; 548 sym->u.i = tp->size; 549 return constnode(sym); 550 }