code.c (10400B)
1 #include <assert.h> 2 #include <ctype.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <stdarg.h> 6 7 #include <scc/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] = "\te\n", 70 [OBLOOP] = "\tb\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 Node * 169 prtree(char *s, Node *np) 170 { 171 FILE *tmp = outfp; 172 173 outfp = stderr; 174 fprintf(outfp, "DBG prtree %s", s); 175 emitnode(np); 176 putc('\n', outfp); 177 outfp = tmp; 178 179 return np; 180 } 181 182 void 183 emit(int op, void *arg) 184 { 185 extern int failure; 186 187 if (failure || onlycpp || onlyheader) 188 return; 189 (*opcode[op])(op, arg); 190 } 191 192 static void 193 emitvar(Symbol *sym) 194 { 195 int c; 196 short flags = sym->flags; 197 198 if (flags & SLOCAL) 199 c = 'T'; 200 else if (flags & SPRIVATE) 201 c = 'Y'; 202 else if (flags & SGLOBAL) 203 c = 'G'; 204 else if (flags & SREGISTER) 205 c = 'R'; 206 else if (flags & SFIELD) 207 c = 'M'; 208 else if (flags & SEXTERN) 209 c = 'X'; 210 else 211 c = 'A'; 212 fprintf(outfp, "%c%u", c, sym->id); 213 } 214 215 static void 216 emitconst(Node *np) 217 { 218 int n; 219 unsigned char *fp, *p; 220 Symbol *sym = np->sym; 221 Type *tp = np->type; 222 unsigned long long u; 223 224 switch (tp->op) { 225 case FLOAT: 226 if (tp == floattype) 227 u = *(uint32_t *) &sym->u.f; 228 else if (tp == doubletype) 229 u = *(uint64_t *) &sym->u.d; 230 else 231 abort(); /* TODO: What here?? */ 232 goto print; 233 case PTR: 234 case INT: 235 case ENUM: 236 u = (tp->prop & TSIGNED) ? sym->u.i : sym->u.u; 237 print: 238 fprintf(outfp, 239 "#%c%llX", 240 tp->letter, 241 u & ones(tp->size)); 242 break; 243 default: 244 abort(); 245 } 246 } 247 248 static void 249 emitsym(int op, void *arg) 250 { 251 Node *np = arg; 252 253 if ((np->sym->flags & SINITLST) == 0) { 254 /* 255 * When we have a compound literal we are going 256 * to call to emitnode for every element of it, 257 * and it means that we will have two '\t' 258 * for the first element 259 */ 260 putc('\t', outfp); 261 } 262 (np->flags & NCONST) ? emitconst(np) : emitvar(np->sym); 263 } 264 265 static void 266 emitletter(Type *tp) 267 { 268 int letter; 269 270 letter = (tp->prop&TELLIPSIS) ? 'E' : tp->letter; 271 putc(letter, outfp); 272 switch (tp->op) { 273 case ARY: 274 case STRUCT: 275 case UNION: 276 fprintf(outfp, "%u", tp->id); 277 } 278 } 279 280 static void 281 emittype(int op, void *arg) 282 { 283 long long n; 284 Symbol **sp; 285 char *tag; 286 Type *tp = arg; 287 288 if (!(tp->prop & TDEFINED)) 289 return; 290 291 switch (tp->op) { 292 case ARY: 293 emitletter(tp); 294 putc('\t', outfp); 295 emitletter(tp->type); 296 fprintf(outfp, 297 "\t#%c%llX\n", 298 sizettype->letter, (long long) tp->n.elem); 299 return; 300 case UNION: 301 case STRUCT: 302 emitletter(tp); 303 tag = tp->tag->name; 304 fprintf(outfp, 305 "\t\"%s\t#%c%lX\t#%c%X\n", 306 (tag) ? tag : "", 307 sizettype->letter, 308 tp->size, 309 sizettype->letter, 310 tp->align); 311 n = tp->n.elem; 312 for (sp = tp->p.fields; n-- > 0; ++sp) 313 emit(ODECL, *sp); 314 break; 315 case PTR: 316 case FTN: 317 case ENUM: 318 return; 319 default: 320 abort(); 321 } 322 } 323 324 static void 325 emitstring(Symbol *sym, Type *tp) 326 { 327 char *bp, *s, *lim; 328 int n; 329 330 bp = sym->u.s; 331 lim = &sym->u.s[tp->n.elem]; 332 while (bp < lim) { 333 s = bp; 334 while (bp < lim && isprint(*bp)) 335 ++bp; 336 if ((n = bp - s) > 1) 337 fprintf(outfp, "\t#\"%.*s\n", n, s); 338 else 339 bp = s; 340 if (bp == lim) 341 break; 342 do { 343 fprintf(outfp, 344 "\t#%c%X\n", 345 chartype->letter, (*bp++) & 0xFF); 346 } while (bp < lim && !isprint(*bp)); 347 } 348 } 349 350 Node * 351 zeronode(Type *tp) 352 { 353 return simplify(convert(constnode(zero), tp, 0)); 354 } 355 356 static void 357 emitpadding(Type *tp, unsigned long long *addr) 358 { 359 int i, align; 360 unsigned long long a, n; 361 362 align = tp->align - 1; 363 a = *addr; 364 n = a+align & ~align; 365 366 for ( ; a != n; ++a) 367 emitexp(OEXPR, zeronode(chartype)); 368 *addr = n; 369 } 370 371 static void 372 emitdesig(Node *np, Type *tp, unsigned long long *addr) 373 { 374 Symbol *sym; 375 unsigned long long n; 376 Node *aux; 377 Type *p; 378 379 emitpadding(tp, addr); 380 381 if (!np) { 382 sym = NULL; 383 } else { 384 if (!np->sym) 385 goto emit_expression; 386 sym = np->sym; 387 if (sym->flags & SSTRING) { 388 emitstring(sym, tp); 389 *addr += tp->n.elem; 390 return; 391 } 392 if ((sym->flags & SINITLST) == 0) 393 goto emit_expression; 394 } 395 396 switch (tp->op) { 397 case PTR: 398 case INT: 399 case ENUM: 400 aux = sym ? *sym->u.init : zeronode(tp); 401 *addr += aux->type->size; 402 emitexp(OEXPR, aux); 403 break; 404 case UNION: 405 aux = (sym) ? sym->u.init[0] : NULL; 406 p = (aux) ? aux->type : tp->p.fields[0]->type; 407 emitdesig(aux, p, addr); 408 emitpadding(tp, addr); 409 break; 410 case STRUCT: 411 case ARY: 412 for (n = 0; n < tp->n.elem; ++n) { 413 aux = (sym) ? sym->u.init[n] : NULL; 414 p = (tp->op == ARY) ? tp->type : tp->p.fields[n]->type; 415 emitdesig(aux, p, addr); 416 } 417 emitpadding(tp, addr); 418 break; 419 default: 420 abort(); 421 } 422 423 if (sym) { 424 free(sym->u.init); 425 sym->u.init = NULL; 426 } 427 freetree(np); 428 return; 429 430 emit_expression: 431 emitexp(OEXPR, np); 432 *addr += tp->size; 433 } 434 435 static void 436 emitinit(int op, void *arg) 437 { 438 Node *np = arg; 439 unsigned long long addr = 0; 440 441 fputs("\t(\n", outfp); 442 emitdesig(np, np->type, &addr); 443 fputs(")\n", outfp); 444 } 445 446 static void 447 emitdcl(int op, void *arg) 448 { 449 Symbol *sym = arg; 450 451 if (sym->flags & SEMITTED) 452 return; 453 emitvar(sym); 454 putc('\t', outfp); 455 if (sym->type->op == FTN) { 456 emitletter(sym->type->type); 457 putc('\t', outfp); 458 } 459 emitletter(sym->type); 460 fprintf(outfp, "\t\"%s", (sym->name) ? sym->name : ""); 461 if (sym->flags & SFIELD) 462 fprintf(outfp, "\t#%c%llX", sizettype->letter, sym->u.i); 463 sym->flags |= SEMITTED; 464 if ((sym->flags & SHASINIT) == 0) 465 putc('\n', outfp); 466 } 467 468 static void 469 emitcast(int op, void *arg) 470 { 471 Node *np = arg, *lp = np->left; 472 473 emitnode(lp); 474 if (np->type != voidtype) 475 fprintf(outfp, "\tg%c", np->type->letter); 476 } 477 478 static void 479 emitbin(int op, void *arg) 480 { 481 Node *np = arg; 482 char *s; 483 484 emitnode(np->left); 485 emitnode(np->right); 486 487 /* do not print in OCOLON case */ 488 if ((s = optxt[op]) != NULL) { 489 fprintf(outfp, "\t%s", s); 490 emitletter(np->type); 491 } 492 } 493 494 static void 495 emitbuilt(int op, void *arg) 496 { 497 Node *np = arg; 498 499 emitnode(np->left); 500 emitnode(np->right); 501 fprintf(outfp, "\t\"%s\tm", np->sym->name); 502 emitletter(np->type); 503 } 504 505 506 static void 507 emitexp(int op, void *arg) 508 { 509 Node *np = arg; 510 511 emitnode(np); 512 putc('\n', outfp); 513 freetree(np); 514 } 515 516 static void 517 emitfun(int op, void *arg) 518 { 519 Symbol *sym = arg, **sp; 520 521 emitdcl(op, arg); 522 fputs("{\n", outfp); 523 524 for (sp = sym->u.pars; sp && *sp; ++sp) 525 emit(ODECL, *sp); 526 fputs("\\\n", outfp); 527 } 528 529 static void 530 emittext(int op, void *arg) 531 { 532 fputs(optxt[op], outfp); 533 } 534 535 static void 536 emitsymid(int op, void *arg) 537 { 538 Symbol *sym = arg; 539 fprintf(outfp, optxt[op], sym->id); 540 } 541 542 Node * 543 node(int op, Type *tp, Node *lp, Node *rp) 544 { 545 Node *np; 546 547 np = xmalloc(sizeof(*np)); 548 np->op = op; 549 np->type = tp; 550 np->sym = NULL; 551 np->flags = 0; 552 np->left = lp; 553 np->right = rp; 554 555 if (lp) 556 np->flags |= lp->flags & NEFFECT; 557 if (rp) 558 np->flags |= rp->flags & NEFFECT; 559 return np; 560 } 561 562 Node * 563 varnode(Symbol *sym) 564 { 565 Node *np; 566 Type *tp = sym->type; 567 568 np = node(OSYM, sym->type, NULL, NULL); 569 np->type = sym->type; 570 np->flags = (tp->op != FTN && tp->op != ARY) ? NLVAL : 0; 571 np->sym = sym; 572 return np; 573 } 574 575 Node * 576 constnode(Symbol *sym) 577 { 578 Node *np; 579 580 np = node(OSYM, sym->type, NULL, NULL); 581 np->flags = NCONST; 582 np->sym = sym; 583 return np; 584 } 585 586 Node * 587 sizeofnode(Type *tp) 588 { 589 Symbol *sym; 590 591 sym = newsym(NS_IDEN, NULL); 592 sym->type = sizettype; 593 sym->flags |= SCONSTANT; 594 sym->u.u = tp->size; 595 DBG("EXPR sizeof %llu", sym->u.u); 596 return constnode(sym); 597 } 598 599 Node * 600 offsetnode(Symbol *field, Type *tp) 601 { 602 Symbol *sym; 603 604 assert(field->flags & SFIELD); 605 sym = newsym(NS_IDEN, NULL); 606 sym->type = tp; 607 sym->flags |= SCONSTANT; 608 sym->u.u = field->u.u; 609 610 return constnode(sym); 611 } 612 613 Node * 614 addrnode(unsigned long long u) 615 { 616 Symbol *sym; 617 618 sym = newsym(NS_IDEN, NULL); 619 sym->type = pvoidtype; 620 sym->flags |= SCONSTANT; 621 sym->u.u = u; 622 623 return constnode(sym); 624 }