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