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