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