1 /* 2 * sparse/show-parse.c 3 * 4 * Copyright (C) 2003 Transmeta Corp. 5 * 2003-2004 Linus Torvalds 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in 15 * all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 * THE SOFTWARE. 24 * 25 * Print out results of parsing for debugging and testing. 26 */ 27 #include <stdarg.h> 28 #include <stdlib.h> 29 #include <stdio.h> 30 #include <string.h> 31 #include <ctype.h> 32 #include <unistd.h> 33 #include <fcntl.h> 34 35 #include "lib.h" 36 #include "allocate.h" 37 #include "token.h" 38 #include "parse.h" 39 #include "symbol.h" 40 #include "scope.h" 41 #include "expression.h" 42 #include "target.h" 43 44 static int show_symbol_expr(struct symbol *sym); 45 static int show_string_expr(struct expression *expr); 46 47 static void do_debug_symbol(struct symbol *sym, int indent) 48 { 49 static const char indent_string[] = " "; 50 static const char *typestr[] = { 51 [SYM_UNINITIALIZED] = "none", 52 [SYM_PREPROCESSOR] = "cpp.", 53 [SYM_BASETYPE] = "base", 54 [SYM_NODE] = "node", 55 [SYM_PTR] = "ptr.", 56 [SYM_FN] = "fn..", 57 [SYM_ARRAY] = "arry", 58 [SYM_STRUCT] = "strt", 59 [SYM_UNION] = "unin", 60 [SYM_ENUM] = "enum", 61 [SYM_TYPEDEF] = "tdef", 62 [SYM_TYPEOF] = "tpof", 63 [SYM_MEMBER] = "memb", 64 [SYM_BITFIELD] = "bitf", 65 [SYM_LABEL] = "labl", 66 [SYM_RESTRICT] = "rstr", 67 [SYM_FOULED] = "foul", 68 [SYM_BAD] = "bad.", 69 }; 70 struct context *context; 71 int i; 72 73 if (!sym) 74 return; 75 fprintf(stderr, "%.*s%s%3d:%lu %s %s (as: %d) %p (%s:%d:%d) %s\n", 76 indent, indent_string, typestr[sym->type], 77 sym->bit_size, sym->ctype.alignment, 78 modifier_string(sym->ctype.modifiers), show_ident(sym->ident), sym->ctype.as, 79 sym, stream_name(sym->pos.stream), sym->pos.line, sym->pos.pos, 80 builtin_typename(sym) ?: ""); 81 i = 0; 82 FOR_EACH_PTR(sym->ctype.contexts, context) { 83 /* FIXME: should print context expression */ 84 fprintf(stderr, "< context%d: in=%d, out=%d\n", 85 i, context->in, context->out); 86 fprintf(stderr, " end context%d >\n", i); 87 i++; 88 } END_FOR_EACH_PTR(context); 89 if (sym->type == SYM_FN) { 90 struct symbol *arg; 91 i = 0; 92 FOR_EACH_PTR(sym->arguments, arg) { 93 fprintf(stderr, "< arg%d:\n", i); 94 do_debug_symbol(arg, 0); 95 fprintf(stderr, " end arg%d >\n", i); 96 i++; 97 } END_FOR_EACH_PTR(arg); 98 } 99 do_debug_symbol(sym->ctype.base_type, indent+2); 100 } 101 102 void debug_symbol(struct symbol *sym) 103 { 104 do_debug_symbol(sym, 0); 105 } 106 107 /* 108 * Symbol type printout. The type system is by far the most 109 * complicated part of C - everything else is trivial. 110 */ 111 const char *modifier_string(unsigned long mod) 112 { 113 static char buffer[100]; 114 int len = 0; 115 int i; 116 struct mod_name { 117 unsigned long mod; 118 const char *name; 119 } *m; 120 121 static struct mod_name mod_names[] = { 122 {MOD_AUTO, "auto"}, 123 {MOD_REGISTER, "register"}, 124 {MOD_STATIC, "static"}, 125 {MOD_EXTERN, "extern"}, 126 {MOD_CONST, "const"}, 127 {MOD_VOLATILE, "volatile"}, 128 {MOD_SIGNED, "[signed]"}, 129 {MOD_UNSIGNED, "[unsigned]"}, 130 {MOD_CHAR, "[char]"}, 131 {MOD_SHORT, "[short]"}, 132 {MOD_LONG, "[long]"}, 133 {MOD_LONGLONG, "[long long]"}, 134 {MOD_LONGLONGLONG, "[long long long]"}, 135 {MOD_TYPEDEF, "[typedef]"}, 136 {MOD_TLS, "[tls]"}, 137 {MOD_INLINE, "inline"}, 138 {MOD_ADDRESSABLE, "[addressable]"}, 139 {MOD_NOCAST, "[nocast]"}, 140 {MOD_NODEREF, "[noderef]"}, 141 {MOD_ACCESSED, "[accessed]"}, 142 {MOD_TOPLEVEL, "[toplevel]"}, 143 {MOD_ASSIGNED, "[assigned]"}, 144 {MOD_TYPE, "[type]"}, 145 {MOD_SAFE, "[safe]"}, 146 {MOD_USERTYPE, "[usertype]"}, 147 {MOD_NORETURN, "[noreturn]"}, 148 {MOD_EXPLICITLY_SIGNED, "[explicitly-signed]"}, 149 {MOD_BITWISE, "[bitwise]"}, 150 {MOD_PURE, "[pure]"}, 151 }; 152 153 for (i = 0; i < ARRAY_SIZE(mod_names); i++) { 154 m = mod_names + i; 155 if (mod & m->mod) { 156 char c; 157 const char *name = m->name; 158 while ((c = *name++) != '\0' && len + 2 < sizeof buffer) 159 buffer[len++] = c; 160 buffer[len++] = ' '; 161 } 162 } 163 buffer[len] = 0; 164 return buffer; 165 } 166 167 static void show_struct_member(struct symbol *sym) 168 { 169 printf("\t%s:%d:%ld at offset %ld.%d", show_ident(sym->ident), sym->bit_size, sym->ctype.alignment, sym->offset, sym->bit_offset); 170 printf("\n"); 171 } 172 173 void show_symbol_list(struct symbol_list *list, const char *sep) 174 { 175 struct symbol *sym; 176 const char *prepend = ""; 177 178 FOR_EACH_PTR(list, sym) { 179 puts(prepend); 180 prepend = ", "; 181 show_symbol(sym); 182 } END_FOR_EACH_PTR(sym); 183 } 184 185 struct type_name { 186 char *start; 187 char *end; 188 }; 189 190 static void FORMAT_ATTR(2) prepend(struct type_name *name, const char *fmt, ...) 191 { 192 static char buffer[512]; 193 int n; 194 195 va_list args; 196 va_start(args, fmt); 197 n = vsprintf(buffer, fmt, args); 198 va_end(args); 199 200 name->start -= n; 201 memcpy(name->start, buffer, n); 202 } 203 204 static void FORMAT_ATTR(2) append(struct type_name *name, const char *fmt, ...) 205 { 206 static char buffer[512]; 207 int n; 208 209 va_list args; 210 va_start(args, fmt); 211 n = vsprintf(buffer, fmt, args); 212 va_end(args); 213 214 memcpy(name->end, buffer, n); 215 name->end += n; 216 } 217 218 static struct ctype_name { 219 struct symbol *sym; 220 const char *name; 221 } typenames[] = { 222 { & char_ctype, "char" }, 223 { &schar_ctype, "signed char" }, 224 { &uchar_ctype, "unsigned char" }, 225 { & short_ctype, "short" }, 226 { &sshort_ctype, "signed short" }, 227 { &ushort_ctype, "unsigned short" }, 228 { & int_ctype, "int" }, 229 { &sint_ctype, "signed int" }, 230 { &uint_ctype, "unsigned int" }, 231 { &slong_ctype, "signed long" }, 232 { & long_ctype, "long" }, 233 { &ulong_ctype, "unsigned long" }, 234 { & llong_ctype, "long long" }, 235 { &sllong_ctype, "signed long long" }, 236 { &ullong_ctype, "unsigned long long" }, 237 { & lllong_ctype, "long long long" }, 238 { &slllong_ctype, "signed long long long" }, 239 { &ulllong_ctype, "unsigned long long long" }, 240 241 { &void_ctype, "void" }, 242 { &bool_ctype, "bool" }, 243 { &string_ctype, "string" }, 244 245 { &float_ctype, "float" }, 246 { &double_ctype, "double" }, 247 { &ldouble_ctype,"long double" }, 248 { &incomplete_ctype, "incomplete type" }, 249 { &int_type, "abstract int" }, 250 { &fp_type, "abstract fp" }, 251 { &label_ctype, "label type" }, 252 { &bad_ctype, "bad type" }, 253 }; 254 255 const char *builtin_typename(struct symbol *sym) 256 { 257 int i; 258 259 for (i = 0; i < ARRAY_SIZE(typenames); i++) 260 if (typenames[i].sym == sym) 261 return typenames[i].name; 262 return NULL; 263 } 264 265 const char *builtin_ctypename(struct ctype *ctype) 266 { 267 int i; 268 269 for (i = 0; i < ARRAY_SIZE(typenames); i++) 270 if (&typenames[i].sym->ctype == ctype) 271 return typenames[i].name; 272 return NULL; 273 } 274 275 static void do_show_type(struct symbol *sym, struct type_name *name) 276 { 277 const char *typename; 278 unsigned long mod = 0; 279 int as = 0; 280 int was_ptr = 0; 281 int restr = 0; 282 int fouled = 0; 283 284 deeper: 285 if (!sym || (sym->type != SYM_NODE && sym->type != SYM_ARRAY && 286 sym->type != SYM_BITFIELD)) { 287 const char *s; 288 size_t len; 289 290 if (as) 291 prepend(name, "<asn:%d>", as); 292 293 s = modifier_string(mod); 294 len = strlen(s); 295 name->start -= len; 296 memcpy(name->start, s, len); 297 mod = 0; 298 as = 0; 299 } 300 301 if (!sym) 302 goto out; 303 304 if ((typename = builtin_typename(sym))) { 305 int len = strlen(typename); 306 if (name->start != name->end) 307 *--name->start = ' '; 308 name->start -= len; 309 memcpy(name->start, typename, len); 310 goto out; 311 } 312 313 /* Prepend */ 314 switch (sym->type) { 315 case SYM_PTR: 316 prepend(name, "*"); 317 mod = sym->ctype.modifiers; 318 as = sym->ctype.as; 319 was_ptr = 1; 320 break; 321 322 case SYM_FN: 323 if (was_ptr) { 324 prepend(name, "( "); 325 append(name, " )"); 326 was_ptr = 0; 327 } 328 append(name, "( ... )"); 329 break; 330 331 case SYM_STRUCT: 332 if (name->start != name->end) 333 *--name->start = ' '; 334 prepend(name, "struct %s", show_ident(sym->ident)); 335 goto out; 336 337 case SYM_UNION: 338 if (name->start != name->end) 339 *--name->start = ' '; 340 prepend(name, "union %s", show_ident(sym->ident)); 341 goto out; 342 343 case SYM_ENUM: 344 prepend(name, "enum %s ", show_ident(sym->ident)); 345 break; 346 347 case SYM_NODE: 348 append(name, "%s", show_ident(sym->ident)); 349 mod |= sym->ctype.modifiers; 350 as |= sym->ctype.as; 351 break; 352 353 case SYM_BITFIELD: 354 mod |= sym->ctype.modifiers; 355 as |= sym->ctype.as; 356 append(name, ":%d", sym->bit_size); 357 break; 358 359 case SYM_LABEL: 360 append(name, "label(%s:%p)", show_ident(sym->ident), sym); 361 return; 362 363 case SYM_ARRAY: 364 mod |= sym->ctype.modifiers; 365 as |= sym->ctype.as; 366 if (was_ptr) { 367 prepend(name, "( "); 368 append(name, " )"); 369 was_ptr = 0; 370 } 371 append(name, "[%lld]", get_expression_value(sym->array_size)); 372 break; 373 374 case SYM_RESTRICT: 375 if (!sym->ident) { 376 restr = 1; 377 break; 378 } 379 if (name->start != name->end) 380 *--name->start = ' '; 381 prepend(name, "restricted %s", show_ident(sym->ident)); 382 goto out; 383 384 case SYM_FOULED: 385 fouled = 1; 386 break; 387 388 default: 389 if (name->start != name->end) 390 *--name->start = ' '; 391 prepend(name, "unknown type %d", sym->type); 392 goto out; 393 } 394 395 sym = sym->ctype.base_type; 396 goto deeper; 397 398 out: 399 if (restr) 400 prepend(name, "restricted "); 401 if (fouled) 402 prepend(name, "fouled "); 403 } 404 405 void show_type(struct symbol *sym) 406 { 407 char array[200]; 408 struct type_name name; 409 410 name.start = name.end = array+100; 411 do_show_type(sym, &name); 412 *name.end = 0; 413 printf("%s", name.start); 414 } 415 416 const char *show_typename(struct symbol *sym) 417 { 418 static char array[200]; 419 struct type_name name; 420 421 name.start = name.end = array+100; 422 do_show_type(sym, &name); 423 *name.end = 0; 424 return name.start; 425 } 426 427 void show_symbol(struct symbol *sym) 428 { 429 struct symbol *type; 430 431 if (!sym) 432 return; 433 434 if (sym->ctype.alignment) 435 printf(".align %ld\n", sym->ctype.alignment); 436 437 show_type(sym); 438 type = sym->ctype.base_type; 439 if (!type) { 440 printf("\n"); 441 return; 442 } 443 444 /* 445 * Show actual implementation information 446 */ 447 switch (type->type) { 448 struct symbol *member; 449 450 case SYM_STRUCT: 451 case SYM_UNION: 452 printf(" {\n"); 453 FOR_EACH_PTR(type->symbol_list, member) { 454 show_struct_member(member); 455 } END_FOR_EACH_PTR(member); 456 printf("}\n"); 457 break; 458 459 case SYM_FN: { 460 struct statement *stmt = type->stmt; 461 printf("\n"); 462 if (stmt) { 463 int val; 464 val = show_statement(stmt); 465 if (val) 466 printf("\tmov.%d\t\tretval,%d\n", stmt->ret->bit_size, val); 467 printf("\tret\n"); 468 } 469 break; 470 } 471 472 default: 473 printf("\n"); 474 break; 475 } 476 477 if (sym->initializer) { 478 printf(" = \n"); 479 show_expression(sym->initializer); 480 } 481 } 482 483 static int show_symbol_init(struct symbol *sym); 484 485 static int new_pseudo(void) 486 { 487 static int nr = 0; 488 return ++nr; 489 } 490 491 static int new_label(void) 492 { 493 static int label = 0; 494 return ++label; 495 } 496 497 static void show_switch_statement(struct statement *stmt) 498 { 499 int val = show_expression(stmt->switch_expression); 500 struct symbol *sym; 501 printf("\tswitch v%d\n", val); 502 503 /* 504 * Debugging only: Check that the case list is correct 505 * by printing it out. 506 * 507 * This is where a _real_ back-end would go through the 508 * cases to decide whether to use a lookup table or a 509 * series of comparisons etc 510 */ 511 printf("# case table:\n"); 512 FOR_EACH_PTR(stmt->switch_case->symbol_list, sym) { 513 struct statement *case_stmt = sym->stmt; 514 struct expression *expr = case_stmt->case_expression; 515 struct expression *to = case_stmt->case_to; 516 517 if (!expr) { 518 printf(" default"); 519 } else { 520 if (expr->type == EXPR_VALUE) { 521 printf(" case %lld", expr->value); 522 if (to) { 523 if (to->type == EXPR_VALUE) { 524 printf(" .. %lld", to->value); 525 } else { 526 printf(" .. what?"); 527 } 528 } 529 } else 530 printf(" what?"); 531 } 532 printf(": .L%p\n", sym); 533 } END_FOR_EACH_PTR(sym); 534 printf("# end case table\n"); 535 536 show_statement(stmt->switch_statement); 537 538 if (stmt->switch_break->used) 539 printf(".L%p:\n", stmt->switch_break); 540 } 541 542 static void show_symbol_decl(struct symbol_list *syms) 543 { 544 struct symbol *sym; 545 FOR_EACH_PTR(syms, sym) { 546 show_symbol_init(sym); 547 } END_FOR_EACH_PTR(sym); 548 } 549 550 static int show_return_stmt(struct statement *stmt); 551 552 /* 553 * Print out a statement 554 */ 555 int show_statement(struct statement *stmt) 556 { 557 if (!stmt) 558 return 0; 559 switch (stmt->type) { 560 case STMT_DECLARATION: 561 show_symbol_decl(stmt->declaration); 562 return 0; 563 case STMT_RETURN: 564 return show_return_stmt(stmt); 565 case STMT_COMPOUND: { 566 struct statement *s; 567 int last = 0; 568 569 if (stmt->inline_fn) { 570 show_statement(stmt->args); 571 printf("\tbegin_inline \t%s\n", show_ident(stmt->inline_fn->ident)); 572 } 573 FOR_EACH_PTR(stmt->stmts, s) { 574 last = show_statement(s); 575 } END_FOR_EACH_PTR(s); 576 if (stmt->ret) { 577 int addr, bits; 578 printf(".L%p:\n", stmt->ret); 579 addr = show_symbol_expr(stmt->ret); 580 bits = stmt->ret->bit_size; 581 last = new_pseudo(); 582 printf("\tld.%d\t\tv%d,[v%d]\n", bits, last, addr); 583 } 584 if (stmt->inline_fn) 585 printf("\tend_inlined\t%s\n", show_ident(stmt->inline_fn->ident)); 586 return last; 587 } 588 589 case STMT_EXPRESSION: 590 return show_expression(stmt->expression); 591 case STMT_IF: { 592 int val, target; 593 struct expression *cond = stmt->if_conditional; 594 595 /* This is only valid if nobody can jump into the "dead" statement */ 596 #if 0 597 if (cond->type == EXPR_VALUE) { 598 struct statement *s = stmt->if_true; 599 if (!cond->value) 600 s = stmt->if_false; 601 show_statement(s); 602 break; 603 } 604 #endif 605 val = show_expression(cond); 606 target = new_label(); 607 printf("\tje\t\tv%d,.L%d\n", val, target); 608 show_statement(stmt->if_true); 609 if (stmt->if_false) { 610 int last = new_label(); 611 printf("\tjmp\t\t.L%d\n", last); 612 printf(".L%d:\n", target); 613 target = last; 614 show_statement(stmt->if_false); 615 } 616 printf(".L%d:\n", target); 617 break; 618 } 619 case STMT_SWITCH: 620 show_switch_statement(stmt); 621 break; 622 623 case STMT_CASE: 624 printf(".L%p:\n", stmt->case_label); 625 show_statement(stmt->case_statement); 626 break; 627 628 case STMT_ITERATOR: { 629 struct statement *pre_statement = stmt->iterator_pre_statement; 630 struct expression *pre_condition = stmt->iterator_pre_condition; 631 struct statement *statement = stmt->iterator_statement; 632 struct statement *post_statement = stmt->iterator_post_statement; 633 struct expression *post_condition = stmt->iterator_post_condition; 634 int val, loop_top = 0, loop_bottom = 0; 635 636 show_symbol_decl(stmt->iterator_syms); 637 show_statement(pre_statement); 638 if (pre_condition) { 639 if (pre_condition->type == EXPR_VALUE) { 640 if (!pre_condition->value) { 641 loop_bottom = new_label(); 642 printf("\tjmp\t\t.L%d\n", loop_bottom); 643 } 644 } else { 645 loop_bottom = new_label(); 646 val = show_expression(pre_condition); 647 printf("\tje\t\tv%d, .L%d\n", val, loop_bottom); 648 } 649 } 650 if (!post_condition || post_condition->type != EXPR_VALUE || post_condition->value) { 651 loop_top = new_label(); 652 printf(".L%d:\n", loop_top); 653 } 654 show_statement(statement); 655 if (stmt->iterator_continue->used) 656 printf(".L%p:\n", stmt->iterator_continue); 657 show_statement(post_statement); 658 if (!post_condition) { 659 printf("\tjmp\t\t.L%d\n", loop_top); 660 } else if (post_condition->type == EXPR_VALUE) { 661 if (post_condition->value) 662 printf("\tjmp\t\t.L%d\n", loop_top); 663 } else { 664 val = show_expression(post_condition); 665 printf("\tjne\t\tv%d, .L%d\n", val, loop_top); 666 } 667 if (stmt->iterator_break->used) 668 printf(".L%p:\n", stmt->iterator_break); 669 if (loop_bottom) 670 printf(".L%d:\n", loop_bottom); 671 break; 672 } 673 case STMT_NONE: 674 break; 675 676 case STMT_LABEL: 677 printf(".L%p:\n", stmt->label_identifier); 678 show_statement(stmt->label_statement); 679 break; 680 681 case STMT_GOTO: 682 if (stmt->goto_expression) { 683 int val = show_expression(stmt->goto_expression); 684 printf("\tgoto\t\t*v%d\n", val); 685 } else { 686 printf("\tgoto\t\t.L%p\n", stmt->goto_label); 687 } 688 break; 689 case STMT_ASM: 690 printf("\tasm( .... )\n"); 691 break; 692 case STMT_CONTEXT: { 693 int val = show_expression(stmt->expression); 694 printf("\tcontext( %d )\n", val); 695 break; 696 } 697 case STMT_RANGE: { 698 int val = show_expression(stmt->range_expression); 699 int low = show_expression(stmt->range_low); 700 int high = show_expression(stmt->range_high); 701 printf("\trange( %d %d-%d)\n", val, low, high); 702 break; 703 } 704 } 705 return 0; 706 } 707 708 static int show_call_expression(struct expression *expr) 709 { 710 struct symbol *direct; 711 struct expression *arg, *fn; 712 int fncall, retval; 713 int framesize; 714 715 if (!expr->ctype) { 716 warning(expr->pos, "\tcall with no type!"); 717 return 0; 718 } 719 720 framesize = 0; 721 FOR_EACH_PTR_REVERSE(expr->args, arg) { 722 int new = show_expression(arg); 723 int size = arg->ctype->bit_size; 724 printf("\tpush.%d\t\tv%d\n", size, new); 725 framesize += bits_to_bytes(size); 726 } END_FOR_EACH_PTR_REVERSE(arg); 727 728 fn = expr->fn; 729 730 /* Remove dereference, if any */ 731 direct = NULL; 732 if (fn->type == EXPR_PREOP) { 733 if (fn->unop->type == EXPR_SYMBOL) { 734 struct symbol *sym = fn->unop->symbol; 735 if (sym->ctype.base_type->type == SYM_FN) 736 direct = sym; 737 } 738 } 739 if (direct) { 740 printf("\tcall\t\t%s\n", show_ident(direct->ident)); 741 } else { 742 fncall = show_expression(fn); 743 printf("\tcall\t\t*v%d\n", fncall); 744 } 745 if (framesize) 746 printf("\tadd.%d\t\tvSP,vSP,$%d\n", bits_in_pointer, framesize); 747 748 retval = new_pseudo(); 749 printf("\tmov.%d\t\tv%d,retval\n", expr->ctype->bit_size, retval); 750 return retval; 751 } 752 753 static int show_comma(struct expression *expr) 754 { 755 show_expression(expr->left); 756 return show_expression(expr->right); 757 } 758 759 static int show_binop(struct expression *expr) 760 { 761 int left = show_expression(expr->left); 762 int right = show_expression(expr->right); 763 int new = new_pseudo(); 764 const char *opname; 765 static const char *name[] = { 766 ['+'] = "add", ['-'] = "sub", 767 ['*'] = "mul", ['/'] = "div", 768 ['%'] = "mod", ['&'] = "and", 769 ['|'] = "lor", ['^'] = "xor" 770 }; 771 unsigned int op = expr->op; 772 773 opname = show_special(op); 774 if (op < ARRAY_SIZE(name)) 775 opname = name[op]; 776 printf("\t%s.%d\t\tv%d,v%d,v%d\n", opname, 777 expr->ctype->bit_size, 778 new, left, right); 779 return new; 780 } 781 782 static int show_slice(struct expression *expr) 783 { 784 int target = show_expression(expr->base); 785 int new = new_pseudo(); 786 printf("\tslice.%d\t\tv%d,v%d,%d\n", expr->r_nrbits, target, new, expr->r_bitpos); 787 return new; 788 } 789 790 static int show_regular_preop(struct expression *expr) 791 { 792 int target = show_expression(expr->unop); 793 int new = new_pseudo(); 794 static const char *name[] = { 795 ['!'] = "nonzero", ['-'] = "neg", 796 ['~'] = "not", 797 }; 798 unsigned int op = expr->op; 799 const char *opname; 800 801 opname = show_special(op); 802 if (op < ARRAY_SIZE(name)) 803 opname = name[op]; 804 printf("\t%s.%d\t\tv%d,v%d\n", opname, expr->ctype->bit_size, new, target); 805 return new; 806 } 807 808 /* 809 * FIXME! Not all accesses are memory loads. We should 810 * check what kind of symbol is behind the dereference. 811 */ 812 static int show_address_gen(struct expression *expr) 813 { 814 return show_expression(expr->unop); 815 } 816 817 static int show_load_gen(int bits, struct expression *expr, int addr) 818 { 819 int new = new_pseudo(); 820 821 printf("\tld.%d\t\tv%d,[v%d]\n", bits, new, addr); 822 return new; 823 } 824 825 static void show_store_gen(int bits, int value, struct expression *expr, int addr) 826 { 827 /* FIXME!!! Bitfield store! */ 828 printf("\tst.%d\t\tv%d,[v%d]\n", bits, value, addr); 829 } 830 831 static int show_assignment(struct expression *expr) 832 { 833 struct expression *target = expr->left; 834 int val, addr, bits; 835 836 if (!expr->ctype) 837 return 0; 838 839 bits = expr->ctype->bit_size; 840 val = show_expression(expr->right); 841 addr = show_address_gen(target); 842 show_store_gen(bits, val, target, addr); 843 return val; 844 } 845 846 static int show_return_stmt(struct statement *stmt) 847 { 848 struct expression *expr = stmt->ret_value; 849 struct symbol *target = stmt->ret_target; 850 851 if (expr && expr->ctype) { 852 int val = show_expression(expr); 853 int bits = expr->ctype->bit_size; 854 int addr = show_symbol_expr(target); 855 show_store_gen(bits, val, NULL, addr); 856 } 857 printf("\tret\t\t(%p)\n", target); 858 return 0; 859 } 860 861 static int show_initialization(struct symbol *sym, struct expression *expr) 862 { 863 int val, addr, bits; 864 865 if (!expr->ctype) 866 return 0; 867 868 bits = expr->ctype->bit_size; 869 val = show_expression(expr); 870 addr = show_symbol_expr(sym); 871 // FIXME! The "target" expression is for bitfield store information. 872 // Leave it NULL, which works fine. 873 show_store_gen(bits, val, NULL, addr); 874 return 0; 875 } 876 877 static int show_access(struct expression *expr) 878 { 879 int addr = show_address_gen(expr); 880 return show_load_gen(expr->ctype->bit_size, expr, addr); 881 } 882 883 static int show_inc_dec(struct expression *expr, int postop) 884 { 885 int addr = show_address_gen(expr->unop); 886 int retval, new; 887 const char *opname = expr->op == SPECIAL_INCREMENT ? "add" : "sub"; 888 int bits = expr->ctype->bit_size; 889 890 retval = show_load_gen(bits, expr->unop, addr); 891 new = retval; 892 if (postop) 893 new = new_pseudo(); 894 printf("\t%s.%d\t\tv%d,v%d,$1\n", opname, bits, new, retval); 895 show_store_gen(bits, new, expr->unop, addr); 896 return retval; 897 } 898 899 static int show_preop(struct expression *expr) 900 { 901 /* 902 * '*' is an lvalue access, and is fundamentally different 903 * from an arithmetic operation. Maybe it should have an 904 * expression type of its own.. 905 */ 906 if (expr->op == '*') 907 return show_access(expr); 908 if (expr->op == SPECIAL_INCREMENT || expr->op == SPECIAL_DECREMENT) 909 return show_inc_dec(expr, 0); 910 return show_regular_preop(expr); 911 } 912 913 static int show_postop(struct expression *expr) 914 { 915 return show_inc_dec(expr, 1); 916 } 917 918 static int show_symbol_expr(struct symbol *sym) 919 { 920 int new = new_pseudo(); 921 922 if (sym->initializer && sym->initializer->type == EXPR_STRING) 923 return show_string_expr(sym->initializer); 924 925 if (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_EXTERN | MOD_STATIC)) { 926 printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer, new, show_ident(sym->ident)); 927 return new; 928 } 929 if (sym->ctype.modifiers & MOD_ADDRESSABLE) { 930 printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer, new, sym->value); 931 return new; 932 } 933 printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer, new, show_ident(sym->ident), sym); 934 return new; 935 } 936 937 static int show_symbol_init(struct symbol *sym) 938 { 939 struct expression *expr = sym->initializer; 940 941 if (expr) { 942 int val, addr, bits; 943 944 bits = expr->ctype->bit_size; 945 val = show_expression(expr); 946 addr = show_symbol_expr(sym); 947 show_store_gen(bits, val, NULL, addr); 948 } 949 return 0; 950 } 951 952 static int type_is_signed(struct symbol *sym) 953 { 954 if (sym->type == SYM_NODE) 955 sym = sym->ctype.base_type; 956 if (sym->type == SYM_PTR) 957 return 0; 958 return !(sym->ctype.modifiers & MOD_UNSIGNED); 959 } 960 961 static int show_cast_expr(struct expression *expr) 962 { 963 struct symbol *old_type, *new_type; 964 int op = show_expression(expr->cast_expression); 965 int oldbits, newbits; 966 int new, is_signed; 967 968 old_type = expr->cast_expression->ctype; 969 new_type = expr->cast_type; 970 971 oldbits = old_type->bit_size; 972 newbits = new_type->bit_size; 973 if (oldbits >= newbits) 974 return op; 975 new = new_pseudo(); 976 is_signed = type_is_signed(old_type); 977 if (is_signed) { 978 printf("\tsext%d.%d\tv%d,v%d\n", oldbits, newbits, new, op); 979 } else { 980 printf("\tandl.%d\t\tv%d,v%d,$%lu\n", newbits, new, op, (1UL << oldbits)-1); 981 } 982 return new; 983 } 984 985 static int show_value(struct expression *expr) 986 { 987 int new = new_pseudo(); 988 unsigned long long value = expr->value; 989 990 printf("\tmovi.%d\t\tv%d,$%llu\n", expr->ctype->bit_size, new, value); 991 return new; 992 } 993 994 static int show_fvalue(struct expression *expr) 995 { 996 int new = new_pseudo(); 997 long double value = expr->fvalue; 998 999 printf("\tmovf.%d\t\tv%d,$%Lf\n", expr->ctype->bit_size, new, value); 1000 return new; 1001 } 1002 1003 static int show_string_expr(struct expression *expr) 1004 { 1005 int new = new_pseudo(); 1006 1007 printf("\tmovi.%d\t\tv%d,&%s\n", bits_in_pointer, new, show_string(expr->string)); 1008 return new; 1009 } 1010 1011 static int show_label_expr(struct expression *expr) 1012 { 1013 int new = new_pseudo(); 1014 printf("\tmovi.%d\t\tv%d,.L%p\n",bits_in_pointer, new, expr->label_symbol); 1015 return new; 1016 } 1017 1018 static int show_conditional_expr(struct expression *expr) 1019 { 1020 int cond = show_expression(expr->conditional); 1021 int true = show_expression(expr->cond_true); 1022 int false = show_expression(expr->cond_false); 1023 int new = new_pseudo(); 1024 1025 printf("[v%d]\tcmov.%d\t\tv%d,v%d,v%d\n", cond, expr->ctype->bit_size, new, true, false); 1026 return new; 1027 } 1028 1029 static int show_statement_expr(struct expression *expr) 1030 { 1031 return show_statement(expr->statement); 1032 } 1033 1034 static int show_position_expr(struct expression *expr, struct symbol *base) 1035 { 1036 int new = show_expression(expr->init_expr); 1037 struct symbol *ctype = expr->init_expr->ctype; 1038 int bit_offset; 1039 1040 bit_offset = ctype ? ctype->bit_offset : -1; 1041 1042 printf("\tinsert v%d at [%d:%d] of %s\n", new, 1043 expr->init_offset, bit_offset, 1044 show_ident(base->ident)); 1045 return 0; 1046 } 1047 1048 static int show_initializer_expr(struct expression *expr, struct symbol *ctype) 1049 { 1050 struct expression *entry; 1051 1052 FOR_EACH_PTR(expr->expr_list, entry) { 1053 1054 again: 1055 // Nested initializers have their positions already 1056 // recursively calculated - just output them too 1057 if (entry->type == EXPR_INITIALIZER) { 1058 show_initializer_expr(entry, ctype); 1059 continue; 1060 } 1061 1062 // Initializer indexes and identifiers should 1063 // have been evaluated to EXPR_POS 1064 if (entry->type == EXPR_IDENTIFIER) { 1065 printf(" AT '%s':\n", show_ident(entry->expr_ident)); 1066 entry = entry->ident_expression; 1067 goto again; 1068 } 1069 1070 if (entry->type == EXPR_INDEX) { 1071 printf(" AT '%d..%d:\n", entry->idx_from, entry->idx_to); 1072 entry = entry->idx_expression; 1073 goto again; 1074 } 1075 if (entry->type == EXPR_POS) { 1076 show_position_expr(entry, ctype); 1077 continue; 1078 } 1079 show_initialization(ctype, entry); 1080 } END_FOR_EACH_PTR(entry); 1081 return 0; 1082 } 1083 1084 int show_symbol_expr_init(struct symbol *sym) 1085 { 1086 struct expression *expr = sym->initializer; 1087 1088 if (expr) 1089 show_expression(expr); 1090 return show_symbol_expr(sym); 1091 } 1092 1093 /* 1094 * Print out an expression. Return the pseudo that contains the 1095 * variable. 1096 */ 1097 int show_expression(struct expression *expr) 1098 { 1099 if (!expr) 1100 return 0; 1101 1102 if (!expr->ctype) { 1103 struct position *pos = &expr->pos; 1104 printf("\tno type at %s:%d:%d\n", 1105 stream_name(pos->stream), 1106 pos->line, pos->pos); 1107 return 0; 1108 } 1109 1110 switch (expr->type) { 1111 case EXPR_CALL: 1112 return show_call_expression(expr); 1113 1114 case EXPR_ASSIGNMENT: 1115 return show_assignment(expr); 1116 1117 case EXPR_COMMA: 1118 return show_comma(expr); 1119 case EXPR_BINOP: 1120 case EXPR_COMPARE: 1121 case EXPR_LOGICAL: 1122 return show_binop(expr); 1123 case EXPR_PREOP: 1124 return show_preop(expr); 1125 case EXPR_POSTOP: 1126 return show_postop(expr); 1127 case EXPR_SYMBOL: 1128 return show_symbol_expr(expr->symbol); 1129 case EXPR_DEREF: 1130 case EXPR_SIZEOF: 1131 case EXPR_PTRSIZEOF: 1132 case EXPR_ALIGNOF: 1133 case EXPR_OFFSETOF: 1134 warning(expr->pos, "invalid expression after evaluation"); 1135 return 0; 1136 case EXPR_CAST: 1137 case EXPR_FORCE_CAST: 1138 case EXPR_IMPLIED_CAST: 1139 return show_cast_expr(expr); 1140 case EXPR_VALUE: 1141 return show_value(expr); 1142 case EXPR_FVALUE: 1143 return show_fvalue(expr); 1144 case EXPR_STRING: 1145 return show_string_expr(expr); 1146 case EXPR_INITIALIZER: 1147 return show_initializer_expr(expr, expr->ctype); 1148 case EXPR_SELECT: 1149 case EXPR_CONDITIONAL: 1150 return show_conditional_expr(expr); 1151 case EXPR_STATEMENT: 1152 return show_statement_expr(expr); 1153 case EXPR_LABEL: 1154 return show_label_expr(expr); 1155 case EXPR_SLICE: 1156 return show_slice(expr); 1157 1158 // None of these should exist as direct expressions: they are only 1159 // valid as sub-expressions of initializers. 1160 case EXPR_POS: 1161 warning(expr->pos, "unable to show plain initializer position expression"); 1162 return 0; 1163 case EXPR_IDENTIFIER: 1164 warning(expr->pos, "unable to show identifier expression"); 1165 return 0; 1166 case EXPR_INDEX: 1167 warning(expr->pos, "unable to show index expression"); 1168 return 0; 1169 case EXPR_TYPE: 1170 warning(expr->pos, "unable to show type expression"); 1171 return 0; 1172 } 1173 return 0; 1174 } 1175