1 /*
   2  * sparse/compile-i386.c
   3  *
   4  * Copyright (C) 2003 Transmeta Corp.
   5  *               2003 Linus Torvalds
   6  * Copyright 2003 Jeff Garzik
   7  *
   8  * Permission is hereby granted, free of charge, to any person obtaining a copy
   9  * of this software and associated documentation files (the "Software"), to deal
  10  * in the Software without restriction, including without limitation the rights
  11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12  * copies of the Software, and to permit persons to whom the Software is
  13  * furnished to do so, subject to the following conditions:
  14  *
  15  * The above copyright notice and this permission notice shall be included in
  16  * all copies or substantial portions of the Software.
  17  *
  18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24  * THE SOFTWARE.
  25  *
  26  * x86 backend
  27  *
  28  * TODO list:
  29  * in general, any non-32bit SYM_BASETYPE is unlikely to work.
  30  * complex initializers
  31  * bitfields
  32  * global struct/union variables
  33  * addressing structures, and members of structures (as opposed to
  34  *     scalars) on the stack.  Requires smarter stack frame allocation.
  35  * labels / goto
  36  * any function argument that isn't 32 bits (or promoted to such)
  37  * inline asm
  38  * floating point
  39  *
  40  */
  41 #include <stdarg.h>
  42 #include <stdlib.h>
  43 #include <stdio.h>
  44 #include <string.h>
  45 #include <ctype.h>
  46 #include <unistd.h>
  47 #include <fcntl.h>
  48 #include <assert.h>
  49 
  50 #include "lib.h"
  51 #include "allocate.h"
  52 #include "token.h"
  53 #include "parse.h"
  54 #include "symbol.h"
  55 #include "scope.h"
  56 #include "expression.h"
  57 #include "target.h"
  58 #include "compile.h"
  59 #include "bitmap.h"
  60 #include "version.h"
  61 
  62 struct textbuf {
  63         unsigned int    len;    /* does NOT include terminating null */
  64         char            *text;
  65         struct textbuf  *next;
  66         struct textbuf  *prev;
  67 };
  68 
  69 struct loop_stack {
  70         int             continue_lbl;
  71         int             loop_bottom_lbl;
  72         struct loop_stack *next;
  73 };
  74 
  75 struct atom;
  76 struct storage;
  77 DECLARE_PTR_LIST(str_list, struct atom);
  78 DECLARE_PTR_LIST(atom_list, struct atom);
  79 DECLARE_PTR_LIST(storage_list, struct storage);
  80 
  81 struct function {
  82         int stack_size;
  83         int pseudo_nr;
  84         struct storage_list *pseudo_list;
  85         struct atom_list *atom_list;
  86         struct str_list *str_list;
  87         struct loop_stack *loop_stack;
  88         struct symbol **argv;
  89         unsigned int argc;
  90         int ret_target;
  91 };
  92 
  93 enum storage_type {
  94         STOR_PSEUDO,    /* variable stored on the stack */
  95         STOR_ARG,       /* function argument */
  96         STOR_SYM,       /* a symbol we can directly ref in the asm */
  97         STOR_REG,       /* scratch register */
  98         STOR_VALUE,     /* integer constant */
  99         STOR_LABEL,     /* label / jump target */
 100         STOR_LABELSYM,  /* label generated from symbol's pointer value */
 101 };
 102 
 103 struct reg_info {
 104         const char      *name;
 105         struct storage  *contains;
 106         const unsigned char aliases[12];
 107 #define own_regno aliases[0]
 108 };
 109 
 110 struct storage {
 111         enum storage_type type;
 112         unsigned long flags;
 113 
 114         /* STOR_REG */
 115         struct reg_info *reg;
 116         struct symbol *ctype;
 117 
 118         union {
 119                 /* STOR_PSEUDO */
 120                 struct {
 121                         int pseudo;
 122                         int offset;
 123                         int size;
 124                 };
 125                 /* STOR_ARG */
 126                 struct {
 127                         int idx;
 128                 };
 129                 /* STOR_SYM */
 130                 struct {
 131                         struct symbol *sym;
 132                 };
 133                 /* STOR_VALUE */
 134                 struct {
 135                         long long value;
 136                 };
 137                 /* STOR_LABEL */
 138                 struct {
 139                         int label;
 140                 };
 141                 /* STOR_LABELSYM */
 142                 struct {
 143                         struct symbol *labelsym;
 144                 };
 145         };
 146 };
 147 
 148 enum {
 149         STOR_LABEL_VAL  = (1 << 0),
 150         STOR_WANTS_FREE = (1 << 1),
 151 };
 152 
 153 struct symbol_private {
 154         struct storage *addr;
 155 };
 156 
 157 enum atom_type {
 158         ATOM_TEXT,
 159         ATOM_INSN,
 160         ATOM_CSTR,
 161 };
 162 
 163 struct atom {
 164         enum atom_type type;
 165         union {
 166                 /* stuff for text */
 167                 struct {
 168                         char *text;
 169                         unsigned int text_len;  /* w/o terminating null */
 170                 };
 171 
 172                 /* stuff for insns */
 173                 struct {
 174                         char insn[32];
 175                         char comment[40];
 176                         struct storage *op1;
 177                         struct storage *op2;
 178                 };
 179 
 180                 /* stuff for C strings */
 181                 struct {
 182                         struct string *string;
 183                         int label;
 184                 };
 185         };
 186 };
 187 
 188 
 189 static struct function *current_func = NULL;
 190 static struct textbuf *unit_post_text = NULL;
 191 static const char *current_section;
 192 
 193 static void emit_comment(const char * fmt, ...) FORMAT_ATTR(1);
 194 static void emit_move(struct storage *src, struct storage *dest,
 195                       struct symbol *ctype, const char *comment);
 196 static struct storage *x86_address_gen(struct expression *expr);
 197 static struct storage *x86_symbol_expr(struct symbol *sym);
 198 static void x86_symbol(struct symbol *sym);
 199 static struct storage *x86_statement(struct statement *stmt);
 200 static struct storage *x86_expression(struct expression *expr);
 201 
 202 enum registers {
 203         NOREG,
 204          AL,  DL,  CL,  BL,  AH,  DH,  CH,  BH, // 8-bit
 205          AX,  DX,  CX,  BX,  SI,  DI,  BP,  SP, // 16-bit
 206         EAX, EDX, ECX, EBX, ESI, EDI, EBP, ESP, // 32-bit
 207         EAX_EDX, ECX_EBX, ESI_EDI,              // 64-bit
 208 };
 209 
 210 /* This works on regno's, reg_info's and hardreg_storage's */
 211 #define byte_reg(reg) ((reg) - 16)
 212 #define highbyte_reg(reg) ((reg)-12)
 213 #define word_reg(reg) ((reg)-8)
 214 
 215 #define REGINFO(nr, str, conflicts...)  [nr] = { .name = str, .aliases = { nr , conflicts } }
 216 
 217 static struct reg_info reg_info_table[] = {
 218         REGINFO( AL,  "%al", AX, EAX, EAX_EDX),
 219         REGINFO( DL,  "%dl", DX, EDX, EAX_EDX),
 220         REGINFO( CL,  "%cl", CX, ECX, ECX_EBX),
 221         REGINFO( BL,  "%bl", BX, EBX, ECX_EBX),
 222         REGINFO( AH,  "%ah", AX, EAX, EAX_EDX),
 223         REGINFO( DH,  "%dh", DX, EDX, EAX_EDX),
 224         REGINFO( CH,  "%ch", CX, ECX, ECX_EBX),
 225         REGINFO( BH,  "%bh", BX, EBX, ECX_EBX),
 226         REGINFO( AX,  "%ax", AL, AH, EAX, EAX_EDX),
 227         REGINFO( DX,  "%dx", DL, DH, EDX, EAX_EDX),
 228         REGINFO( CX,  "%cx", CL, CH, ECX, ECX_EBX),
 229         REGINFO( BX,  "%bx", BL, BH, EBX, ECX_EBX),
 230         REGINFO( SI,  "%si", ESI, ESI_EDI),
 231         REGINFO( DI,  "%di", EDI, ESI_EDI),
 232         REGINFO( BP,  "%bp", EBP),
 233         REGINFO( SP,  "%sp", ESP),
 234         REGINFO(EAX, "%eax", AL, AH, AX, EAX_EDX),
 235         REGINFO(EDX, "%edx", DL, DH, DX, EAX_EDX),
 236         REGINFO(ECX, "%ecx", CL, CH, CX, ECX_EBX),
 237         REGINFO(EBX, "%ebx", BL, BH, BX, ECX_EBX),
 238         REGINFO(ESI, "%esi", SI, ESI_EDI),
 239         REGINFO(EDI, "%edi", DI, ESI_EDI),
 240         REGINFO(EBP, "%ebp", BP),
 241         REGINFO(ESP, "%esp", SP),
 242         REGINFO(EAX_EDX, "%eax:%edx", AL, AH, AX, EAX, DL, DH, DX, EDX),
 243         REGINFO(ECX_EBX, "%ecx:%ebx", CL, CH, CX, ECX, BL, BH, BX, EBX),
 244         REGINFO(ESI_EDI, "%esi:%edi", SI, ESI, DI, EDI),
 245 };
 246 
 247 #define REGSTORAGE(nr) [nr] = { .type = STOR_REG, .reg = reg_info_table + (nr) }
 248 
 249 static struct storage hardreg_storage_table[] = {
 250         REGSTORAGE(AL), REGSTORAGE(DL), REGSTORAGE(CL), REGSTORAGE(BL),
 251         REGSTORAGE(AH), REGSTORAGE(DH), REGSTORAGE(CH), REGSTORAGE(BH),
 252         REGSTORAGE(AX), REGSTORAGE(DX), REGSTORAGE(CX), REGSTORAGE(BX),
 253         REGSTORAGE(SI), REGSTORAGE(DI), REGSTORAGE(BP), REGSTORAGE(SP),
 254         REGSTORAGE(EAX), REGSTORAGE(EDX), REGSTORAGE(ECX), REGSTORAGE(EBX),
 255         REGSTORAGE(ESI), REGSTORAGE(EDI), REGSTORAGE(EBP), REGSTORAGE(ESP),
 256         REGSTORAGE(EAX_EDX), REGSTORAGE(ECX_EBX), REGSTORAGE(ESI_EDI),
 257 };
 258 
 259 #define REG_EAX (&hardreg_storage_table[EAX])
 260 #define REG_ECX (&hardreg_storage_table[ECX])
 261 #define REG_EDX (&hardreg_storage_table[EDX])
 262 #define REG_ESP (&hardreg_storage_table[ESP])
 263 #define REG_DL  (&hardreg_storage_table[DL])
 264 #define REG_DX  (&hardreg_storage_table[DX])
 265 #define REG_AL  (&hardreg_storage_table[AL])
 266 #define REG_AX  (&hardreg_storage_table[AX])
 267 
 268 static DECLARE_BITMAP(regs_in_use, 256);
 269 
 270 static inline struct storage * reginfo_reg(struct reg_info *info)
 271 {
 272         return hardreg_storage_table + info->own_regno;
 273 }
 274 
 275 static struct storage * get_hardreg(struct storage *reg, int clear)
 276 {
 277         struct reg_info *info = reg->reg;
 278         const unsigned char *aliases;
 279         int regno;
 280 
 281         aliases = info->aliases;
 282         while ((regno = *aliases++) != NOREG) {
 283                 if (test_bit(regno, regs_in_use))
 284                         goto busy;
 285                 if (clear)
 286                         reg_info_table[regno].contains = NULL;
 287         }
 288         set_bit(info->own_regno, regs_in_use);
 289         return reg;
 290 busy:
 291         fprintf(stderr, "register %s is busy\n", info->name);
 292         if (regno + reg_info_table != info)
 293                 fprintf(stderr, "  conflicts with %s\n", reg_info_table[regno].name);
 294         exit(1);
 295 }
 296 
 297 static void put_reg(struct storage *reg)
 298 {
 299         struct reg_info *info = reg->reg;
 300         int regno = info->own_regno;
 301 
 302         if (test_and_clear_bit(regno, regs_in_use))
 303                 return;
 304         fprintf(stderr, "freeing already free'd register %s\n", reg_info_table[regno].name);
 305 }
 306 
 307 struct regclass {
 308         const char *name;
 309         const unsigned char regs[30];
 310 };
 311 
 312 static struct regclass regclass_8 = { "8-bit", { AL, DL, CL, BL, AH, DH, CH, BH }};
 313 static struct regclass regclass_16 = { "16-bit", { AX, DX, CX, BX, SI, DI, BP }};
 314 static struct regclass regclass_32 = { "32-bit", { EAX, EDX, ECX, EBX, ESI, EDI, EBP }};
 315 static struct regclass regclass_64 = { "64-bit", { EAX_EDX, ECX_EBX, ESI_EDI }};
 316 
 317 static struct regclass regclass_32_8 = { "32-bit bytes", { EAX, EDX, ECX, EBX }};
 318 
 319 static struct regclass *get_regclass_bits(int bits)
 320 {
 321         switch (bits) {
 322         case 8: return &regclass_8;
 323         case 16: return &regclass_16;
 324         case 64: return &regclass_64;
 325         default: return &regclass_32;
 326         }
 327 }
 328 
 329 static struct regclass *get_regclass(struct expression *expr)
 330 {
 331         return get_regclass_bits(expr->ctype->bit_size);
 332 }
 333 
 334 static int register_busy(int regno)
 335 {
 336         if (!test_bit(regno, regs_in_use)) {
 337                 struct reg_info *info = reg_info_table + regno;
 338                 const unsigned char *regs = info->aliases+1;
 339 
 340                 while ((regno = *regs) != NOREG) {
 341                         regs++;
 342                         if (test_bit(regno, regs_in_use))
 343                                 goto busy;
 344                 }
 345                 return 0;
 346         }
 347 busy:
 348         return 1;
 349 }
 350 
 351 static struct storage *get_reg(struct regclass *class)
 352 {
 353         const unsigned char *regs = class->regs;
 354         int regno;
 355 
 356         while ((regno = *regs) != NOREG) {
 357                 regs++;
 358                 if (register_busy(regno))
 359                         continue;
 360                 return get_hardreg(hardreg_storage_table + regno, 1);
 361         }
 362         fprintf(stderr, "Ran out of %s registers\n", class->name);
 363         exit(1);
 364 }
 365 
 366 static struct storage *get_reg_value(struct storage *value, struct regclass *class)
 367 {
 368         struct reg_info *info;
 369         struct storage *reg;
 370 
 371         /* Do we already have it somewhere */
 372         info = value->reg;
 373         if (info && info->contains == value) {
 374                 emit_comment("already have register %s", info->name);
 375                 return get_hardreg(hardreg_storage_table + info->own_regno, 0);
 376         }
 377 
 378         reg = get_reg(class);
 379         emit_move(value, reg, value->ctype, "reload register");
 380         info = reg->reg;
 381         info->contains = value;
 382         value->reg = info;
 383         return reg;
 384 }
 385 
 386 static struct storage *temp_from_bits(unsigned int bit_size)
 387 {
 388         return get_reg(get_regclass_bits(bit_size));
 389 }
 390 
 391 static inline unsigned int pseudo_offset(struct storage *s)
 392 {
 393         if (s->type != STOR_PSEUDO)
 394                 return 123456;  /* intentionally bogus value */
 395 
 396         return s->offset;
 397 }
 398 
 399 static inline unsigned int arg_offset(struct storage *s)
 400 {
 401         if (s->type != STOR_ARG)
 402                 return 123456;  /* intentionally bogus value */
 403 
 404         /* FIXME: this is wrong wrong wrong */
 405         return current_func->stack_size + ((1 + s->idx) * 4);
 406 }
 407 
 408 static const char *pretty_offset(int ofs)
 409 {
 410         static char esp_buf[64];
 411 
 412         if (ofs)
 413                 sprintf(esp_buf, "%d(%%esp)", ofs);
 414         else
 415                 strcpy(esp_buf, "(%esp)");
 416 
 417         return esp_buf;
 418 }
 419 
 420 static void stor_sym_init(struct symbol *sym)
 421 {
 422         struct storage *stor;
 423         struct symbol_private *priv;
 424 
 425         priv = calloc(1, sizeof(*priv) + sizeof(*stor));
 426         if (!priv)
 427                 die("OOM in stor_sym_init");
 428 
 429         stor = (struct storage *) (priv + 1);
 430 
 431         priv->addr = stor;
 432         stor->type = STOR_SYM;
 433         stor->sym = sym;
 434 }
 435 
 436 static const char *stor_op_name(struct storage *s)
 437 {
 438         static char name[32];
 439 
 440         switch (s->type) {
 441         case STOR_PSEUDO:
 442                 strcpy(name, pretty_offset((int) pseudo_offset(s)));
 443                 break;
 444         case STOR_ARG:
 445                 strcpy(name, pretty_offset((int) arg_offset(s)));
 446                 break;
 447         case STOR_SYM:
 448                 strcpy(name, show_ident(s->sym->ident));
 449                 break;
 450         case STOR_REG:
 451                 strcpy(name, s->reg->name);
 452                 break;
 453         case STOR_VALUE:
 454                 sprintf(name, "$%lld", s->value);
 455                 break;
 456         case STOR_LABEL:
 457                 sprintf(name, "%s.L%d", s->flags & STOR_LABEL_VAL ? "$" : "",
 458                         s->label);
 459                 break;
 460         case STOR_LABELSYM:
 461                 sprintf(name, "%s.LS%p", s->flags & STOR_LABEL_VAL ? "$" : "",
 462                         s->labelsym);
 463                 break;
 464         }
 465 
 466         return name;
 467 }
 468 
 469 static struct atom *new_atom(enum atom_type type)
 470 {
 471         struct atom *atom;
 472 
 473         atom = calloc(1, sizeof(*atom));        /* TODO: chunked alloc */
 474         if (!atom)
 475                 die("nuclear OOM");
 476 
 477         atom->type = type;
 478 
 479         return atom;
 480 }
 481 
 482 static inline void push_cstring(struct function *f, struct string *str,
 483                                 int label)
 484 {
 485         struct atom *atom;
 486 
 487         atom = new_atom(ATOM_CSTR);
 488         atom->string = str;
 489         atom->label = label;
 490 
 491         add_ptr_list(&f->str_list, atom);        /* note: _not_ atom_list */
 492 }
 493 
 494 static inline void push_atom(struct function *f, struct atom *atom)
 495 {
 496         add_ptr_list(&f->atom_list, atom);
 497 }
 498 
 499 static void push_text_atom(struct function *f, const char *text)
 500 {
 501         struct atom *atom = new_atom(ATOM_TEXT);
 502 
 503         atom->text = strdup(text);
 504         atom->text_len = strlen(text);
 505 
 506         push_atom(f, atom);
 507 }
 508 
 509 static struct storage *new_storage(enum storage_type type)
 510 {
 511         struct storage *stor;
 512 
 513         stor = calloc(1, sizeof(*stor));
 514         if (!stor)
 515                 die("OOM in new_storage");
 516 
 517         stor->type = type;
 518 
 519         return stor;
 520 }
 521 
 522 static struct storage *stack_alloc(int n_bytes)
 523 {
 524         struct function *f = current_func;
 525         struct storage *stor;
 526 
 527         assert(f != NULL);
 528 
 529         stor = new_storage(STOR_PSEUDO);
 530         stor->type = STOR_PSEUDO;
 531         stor->pseudo = f->pseudo_nr;
 532         stor->offset = f->stack_size; /* FIXME: stack req. natural align */
 533         stor->size = n_bytes;
 534         f->stack_size += n_bytes;
 535         f->pseudo_nr++;
 536 
 537         add_ptr_list(&f->pseudo_list, stor);
 538 
 539         return stor;
 540 }
 541 
 542 static struct storage *new_labelsym(struct symbol *sym)
 543 {
 544         struct storage *stor;
 545 
 546         stor = new_storage(STOR_LABELSYM);
 547 
 548         if (stor) {
 549                 stor->flags |= STOR_WANTS_FREE;
 550                 stor->labelsym = sym;
 551         }
 552 
 553         return stor;
 554 }
 555 
 556 static struct storage *new_val(long long value)
 557 {
 558         struct storage *stor;
 559 
 560         stor = new_storage(STOR_VALUE);
 561 
 562         if (stor) {
 563                 stor->flags |= STOR_WANTS_FREE;
 564                 stor->value = value;
 565         }
 566 
 567         return stor;
 568 }
 569 
 570 static int new_label(void)
 571 {
 572         static int label = 0;
 573         return ++label;
 574 }
 575 
 576 static void textbuf_push(struct textbuf **buf_p, const char *text)
 577 {
 578         struct textbuf *tmp, *list = *buf_p;
 579         unsigned int text_len = strlen(text);
 580         unsigned int alloc_len = text_len + 1 + sizeof(*list);
 581 
 582         tmp = calloc(1, alloc_len);
 583         if (!tmp)
 584                 die("OOM on textbuf alloc");
 585 
 586         tmp->text = ((void *) tmp) + sizeof(*tmp);
 587         memcpy(tmp->text, text, text_len + 1);
 588         tmp->len = text_len;
 589 
 590         /* add to end of list */
 591         if (!list) {
 592                 list = tmp;
 593                 tmp->prev = tmp;
 594         } else {
 595                 tmp->prev = list->prev;
 596                 tmp->prev->next = tmp;
 597                 list->prev = tmp;
 598         }
 599         tmp->next = list;
 600 
 601         *buf_p = list;
 602 }
 603 
 604 static void textbuf_emit(struct textbuf **buf_p)
 605 {
 606         struct textbuf *tmp, *list = *buf_p;
 607 
 608         while (list) {
 609                 tmp = list;
 610                 if (tmp->next == tmp)
 611                         list = NULL;
 612                 else {
 613                         tmp->prev->next = tmp->next;
 614                         tmp->next->prev = tmp->prev;
 615                         list = tmp->next;
 616                 }
 617 
 618                 fputs(tmp->text, stdout);
 619 
 620                 free(tmp);
 621         }
 622 
 623         *buf_p = list;
 624 }
 625 
 626 static void insn(const char *insn, struct storage *op1, struct storage *op2,
 627                  const char *comment_in)
 628 {
 629         struct function *f = current_func;
 630         struct atom *atom = new_atom(ATOM_INSN);
 631 
 632         assert(insn != NULL);
 633 
 634         strcpy(atom->insn, insn);
 635         if (comment_in && (*comment_in))
 636                 strncpy(atom->comment, comment_in,
 637                         sizeof(atom->comment) - 1);
 638 
 639         atom->op1 = op1;
 640         atom->op2 = op2;
 641 
 642         push_atom(f, atom);
 643 }
 644 
 645 static void emit_comment(const char *fmt, ...)
 646 {
 647         struct function *f = current_func;
 648         static char tmpbuf[100] = "\t# ";
 649         va_list args;
 650         int i;
 651 
 652         va_start(args, fmt);
 653         i = vsnprintf(tmpbuf+3, sizeof(tmpbuf)-4, fmt, args);
 654         va_end(args);
 655         tmpbuf[i+3] = '\n';
 656         tmpbuf[i+4] = '\0';
 657         push_text_atom(f, tmpbuf);
 658 }
 659 
 660 static void emit_label (int label, const char *comment)
 661 {
 662         struct function *f = current_func;
 663         char s[64];
 664 
 665         if (!comment)
 666                 sprintf(s, ".L%d:\n", label);
 667         else
 668                 sprintf(s, ".L%d:\t\t\t\t\t# %s\n", label, comment);
 669 
 670         push_text_atom(f, s);
 671 }
 672 
 673 static void emit_labelsym (struct symbol *sym, const char *comment)
 674 {
 675         struct function *f = current_func;
 676         char s[64];
 677 
 678         if (!comment)
 679                 sprintf(s, ".LS%p:\n", sym);
 680         else
 681                 sprintf(s, ".LS%p:\t\t\t\t# %s\n", sym, comment);
 682 
 683         push_text_atom(f, s);
 684 }
 685 
 686 void emit_unit_begin(const char *basename)
 687 {
 688         printf("\t.file\t\"%s\"\n", basename);
 689 }
 690 
 691 void emit_unit_end(void)
 692 {
 693         textbuf_emit(&unit_post_text);
 694         printf("\t.ident\t\"sparse silly x86 backend (version %s)\"\n", SPARSE_VERSION);
 695 }
 696 
 697 /* conditionally switch sections */
 698 static void emit_section(const char *s)
 699 {
 700         if (s == current_section)
 701                 return;
 702         if (current_section && (!strcmp(s, current_section)))
 703                 return;
 704 
 705         printf("\t%s\n", s);
 706         current_section = s;
 707 }
 708 
 709 static void emit_insn_atom(struct function *f, struct atom *atom)
 710 {
 711         char s[128];
 712         char comment[64];
 713         struct storage *op1 = atom->op1;
 714         struct storage *op2 = atom->op2;
 715 
 716         if (atom->comment[0])
 717                 sprintf(comment, "\t\t# %s", atom->comment);
 718         else
 719                 comment[0] = 0;
 720 
 721         if (atom->op2) {
 722                 char tmp[16];
 723                 strcpy(tmp, stor_op_name(op1));
 724                 sprintf(s, "\t%s\t%s, %s%s\n",
 725                         atom->insn, tmp, stor_op_name(op2), comment);
 726         } else if (atom->op1)
 727                 sprintf(s, "\t%s\t%s%s%s\n",
 728                         atom->insn, stor_op_name(op1),
 729                         comment[0] ? "\t" : "", comment);
 730         else
 731                 sprintf(s, "\t%s\t%s%s\n",
 732                         atom->insn,
 733                         comment[0] ? "\t\t" : "", comment);
 734 
 735         if (write(STDOUT_FILENO, s, strlen(s)) < 0)
 736                 die("can't write to stdout");
 737 }
 738 
 739 static void emit_atom_list(struct function *f)
 740 {
 741         struct atom *atom;
 742 
 743         FOR_EACH_PTR(f->atom_list, atom) {
 744                 switch (atom->type) {
 745                 case ATOM_TEXT: {
 746                         if (write(STDOUT_FILENO, atom->text, atom->text_len) < 0)
 747                                 die("can't write to stdout");
 748                         break;
 749                 }
 750                 case ATOM_INSN:
 751                         emit_insn_atom(f, atom);
 752                         break;
 753                 case ATOM_CSTR:
 754                         assert(0);
 755                         break;
 756                 }
 757         } END_FOR_EACH_PTR(atom);
 758 }
 759 
 760 static void emit_string_list(struct function *f)
 761 {
 762         struct atom *atom;
 763 
 764         emit_section(".section\t.rodata");
 765 
 766         FOR_EACH_PTR(f->str_list, atom) {
 767                 /* FIXME: escape " in string */
 768                 printf(".L%d:\n", atom->label);
 769                 printf("\t.string\t%s\n", show_string(atom->string));
 770 
 771                 free(atom);
 772         } END_FOR_EACH_PTR(atom);
 773 }
 774 
 775 static void func_cleanup(struct function *f)
 776 {
 777         struct storage *stor;
 778         struct atom *atom;
 779 
 780         FOR_EACH_PTR(f->atom_list, atom) {
 781                 if ((atom->type == ATOM_TEXT) && (atom->text))
 782                         free(atom->text);
 783                 if (atom->op1 && (atom->op1->flags & STOR_WANTS_FREE))
 784                         free(atom->op1);
 785                 if (atom->op2 && (atom->op2->flags & STOR_WANTS_FREE))
 786                         free(atom->op2);
 787                 free(atom);
 788         } END_FOR_EACH_PTR(atom);
 789 
 790         FOR_EACH_PTR(f->pseudo_list, stor) {
 791                 free(stor);
 792         } END_FOR_EACH_PTR(stor);
 793 
 794         free_ptr_list(&f->pseudo_list);
 795         free(f);
 796 }
 797 
 798 /* function prologue */
 799 static void emit_func_pre(struct symbol *sym)
 800 {
 801         struct function *f;
 802         struct symbol *arg;
 803         unsigned int i, argc = 0, alloc_len;
 804         unsigned char *mem;
 805         struct symbol_private *privbase;
 806         struct storage *storage_base;
 807         struct symbol *base_type = sym->ctype.base_type;
 808 
 809         FOR_EACH_PTR(base_type->arguments, arg) {
 810                 argc++;
 811         } END_FOR_EACH_PTR(arg);
 812 
 813         alloc_len =
 814                 sizeof(*f) +
 815                 (argc * sizeof(struct symbol *)) +
 816                 (argc * sizeof(struct symbol_private)) +
 817                 (argc * sizeof(struct storage));
 818         mem = calloc(1, alloc_len);
 819         if (!mem)
 820                 die("OOM on func info");
 821 
 822         f               =  (struct function *) mem;
 823         mem             += sizeof(*f);
 824         f->argv              =  (struct symbol **) mem;
 825         mem             += (argc * sizeof(struct symbol *));
 826         privbase        =  (struct symbol_private *) mem;
 827         mem             += (argc * sizeof(struct symbol_private));
 828         storage_base    =  (struct storage *) mem;
 829 
 830         f->argc = argc;
 831         f->ret_target = new_label();
 832 
 833         i = 0;
 834         FOR_EACH_PTR(base_type->arguments, arg) {
 835                 f->argv[i] = arg;
 836                 arg->aux = &privbase[i];
 837                 storage_base[i].type = STOR_ARG;
 838                 storage_base[i].idx = i;
 839                 privbase[i].addr = &storage_base[i];
 840                 i++;
 841         } END_FOR_EACH_PTR(arg);
 842 
 843         assert(current_func == NULL);
 844         current_func = f;
 845 }
 846 
 847 /* function epilogue */
 848 static void emit_func_post(struct symbol *sym)
 849 {
 850         const char *name = show_ident(sym->ident);
 851         struct function *f = current_func;
 852         int stack_size = f->stack_size;
 853 
 854         if (f->str_list)
 855                 emit_string_list(f);
 856 
 857         /* function prologue */
 858         emit_section(".text");
 859         if ((sym->ctype.modifiers & MOD_STATIC) == 0)
 860                 printf(".globl %s\n", name);
 861         printf("\t.type\t%s, @function\n", name);
 862         printf("%s:\n", name);
 863 
 864         if (stack_size) {
 865                 char pseudo_const[16];
 866 
 867                 sprintf(pseudo_const, "$%d", stack_size);
 868                 printf("\tsubl\t%s, %%esp\n", pseudo_const);
 869         }
 870 
 871         /* function epilogue */
 872 
 873         /* jump target for 'return' statements */
 874         emit_label(f->ret_target, NULL);
 875 
 876         if (stack_size) {
 877                 struct storage *val;
 878 
 879                 val = new_storage(STOR_VALUE);
 880                 val->value = (long long) (stack_size);
 881                 val->flags = STOR_WANTS_FREE;
 882 
 883                 insn("addl", val, REG_ESP, NULL);
 884         }
 885 
 886         insn("ret", NULL, NULL, NULL);
 887 
 888         /* output everything to stdout */
 889         fflush(stdout);         /* paranoia; needed? */
 890         emit_atom_list(f);
 891 
 892         /* function footer */
 893         name = show_ident(sym->ident);
 894         printf("\t.size\t%s, .-%s\n", name, name);
 895 
 896         func_cleanup(f);
 897         current_func = NULL;
 898 }
 899 
 900 /* emit object (a.k.a. variable, a.k.a. data) prologue */
 901 static void emit_object_pre(const char *name, unsigned long modifiers,
 902                             unsigned long alignment, unsigned int byte_size)
 903 {
 904         if ((modifiers & MOD_STATIC) == 0)
 905                 printf(".globl %s\n", name);
 906         emit_section(".data");
 907         if (alignment)
 908                 printf("\t.align %lu\n", alignment);
 909         printf("\t.type\t%s, @object\n", name);
 910         printf("\t.size\t%s, %d\n", name, byte_size);
 911         printf("%s:\n", name);
 912 }
 913 
 914 /* emit value (only) for an initializer scalar */
 915 static void emit_scalar(struct expression *expr, unsigned int bit_size)
 916 {
 917         const char *type;
 918         long long ll;
 919 
 920         assert(expr->type == EXPR_VALUE);
 921 
 922         if (expr->value == 0ULL) {
 923                 printf("\t.zero\t%d\n", bit_size / 8);
 924                 return;
 925         }
 926 
 927         ll = (long long) expr->value;
 928 
 929         switch (bit_size) {
 930         case 8:         type = "byte";  ll = (char) ll; break;
 931         case 16:        type = "value"; ll = (short) ll; break;
 932         case 32:        type = "long";  ll = (int) ll; break;
 933         case 64:        type = "quad";  break;
 934         default:        type = NULL;    break;
 935         }
 936 
 937         assert(type != NULL);
 938 
 939         printf("\t.%s\t%lld\n", type, ll);
 940 }
 941 
 942 static void emit_global_noinit(const char *name, unsigned long modifiers,
 943                                unsigned long alignment, unsigned int byte_size)
 944 {
 945         char s[64];
 946 
 947         if (modifiers & MOD_STATIC) {
 948                 sprintf(s, "\t.local\t%s\n", name);
 949                 textbuf_push(&unit_post_text, s);
 950         }
 951         if (alignment)
 952                 sprintf(s, "\t.comm\t%s,%d,%lu\n", name, byte_size, alignment);
 953         else
 954                 sprintf(s, "\t.comm\t%s,%d\n", name, byte_size);
 955         textbuf_push(&unit_post_text, s);
 956 }
 957 
 958 static int ea_current, ea_last;
 959 
 960 static void emit_initializer(struct symbol *sym,
 961                              struct expression *expr)
 962 {
 963         int distance = ea_current - ea_last - 1;
 964 
 965         if (distance > 0)
 966                 printf("\t.zero\t%d\n", (sym->bit_size / 8) * distance);
 967 
 968         if (expr->type == EXPR_VALUE) {
 969                 struct symbol *base_type = sym->ctype.base_type;
 970                 assert(base_type != NULL);
 971 
 972                 emit_scalar(expr, sym->bit_size / get_expression_value(base_type->array_size));
 973                 return;
 974         }
 975         if (expr->type != EXPR_INITIALIZER)
 976                 return;
 977 
 978         assert(0); /* FIXME */
 979 }
 980 
 981 static int sort_array_cmp(const struct expression *a,
 982                           const struct expression *b)
 983 {
 984         int a_ofs = 0, b_ofs = 0;
 985 
 986         if (a->type == EXPR_POS)
 987                 a_ofs = (int) a->init_offset;
 988         if (b->type == EXPR_POS)
 989                 b_ofs = (int) b->init_offset;
 990 
 991         return a_ofs - b_ofs;
 992 }
 993 
 994 /* move to front-end? */
 995 static void sort_array(struct expression *expr)
 996 {
 997         struct expression *entry, **list;
 998         unsigned int elem, sorted, i;
 999 
1000         elem = expression_list_size(expr->expr_list);
1001         if (!elem)
1002                 return;
1003 
1004         list = malloc(sizeof(entry) * elem);
1005         if (!list)
1006                 die("OOM in sort_array");
1007 
1008         /* this code is no doubt evil and ignores EXPR_INDEX possibly
1009          * to its detriment and other nasty things.  improvements
1010          * welcome.
1011          */
1012         i = 0;
1013         sorted = 0;
1014         FOR_EACH_PTR(expr->expr_list, entry) {
1015                 if ((entry->type == EXPR_POS) || (entry->type == EXPR_VALUE)) {
1016                         /* add entry to list[], in sorted order */
1017                         if (sorted == 0) {
1018                                 list[0] = entry;
1019                                 sorted = 1;
1020                         } else {
1021                                 for (i = 0; i < sorted; i++)
1022                                         if (sort_array_cmp(entry, list[i]) <= 0)
1023                                                 break;
1024 
1025                                 /* If inserting into the middle of list[]
1026                                  * instead of appending, we memmove.
1027                                  * This is ugly, but thankfully
1028                                  * uncommon.  Input data with tons of
1029                                  * entries very rarely have explicit
1030                                  * offsets.  convert to qsort eventually...
1031                                  */
1032                                 if (i != sorted)
1033                                         memmove(&list[i + 1], &list[i],
1034                                                 (sorted - i) * sizeof(entry));
1035                                 list[i] = entry;
1036                                 sorted++;
1037                         }
1038                 }
1039         } END_FOR_EACH_PTR(entry);
1040 
1041         i = 0;
1042         FOR_EACH_PTR(expr->expr_list, entry) {
1043                 if ((entry->type == EXPR_POS) || (entry->type == EXPR_VALUE))
1044                         *THIS_ADDRESS(entry) = list[i++];
1045         } END_FOR_EACH_PTR(entry);
1046 
1047         free(list);
1048 }
1049 
1050 static void emit_array(struct symbol *sym)
1051 {
1052         struct symbol *base_type = sym->ctype.base_type;
1053         struct expression *expr = sym->initializer;
1054         struct expression *entry;
1055 
1056         assert(base_type != NULL);
1057 
1058         stor_sym_init(sym);
1059 
1060         ea_last = -1;
1061 
1062         emit_object_pre(show_ident(sym->ident), sym->ctype.modifiers,
1063                         sym->ctype.alignment,
1064                         sym->bit_size / 8);
1065 
1066         sort_array(expr);
1067 
1068         FOR_EACH_PTR(expr->expr_list, entry) {
1069                 if (entry->type == EXPR_VALUE) {
1070                         ea_current = 0;
1071                         emit_initializer(sym, entry);
1072                         ea_last = ea_current;
1073                 } else if (entry->type == EXPR_POS) {
1074                         ea_current =
1075                             entry->init_offset / (base_type->bit_size / 8);
1076                         emit_initializer(sym, entry->init_expr);
1077                         ea_last = ea_current;
1078                 }
1079         } END_FOR_EACH_PTR(entry);
1080 }
1081 
1082 void emit_one_symbol(struct symbol *sym)
1083 {
1084         x86_symbol(sym);
1085 }
1086 
1087 static void emit_copy(struct storage *dest, struct storage *src,
1088                       struct symbol *ctype)
1089 {
1090         struct storage *reg = NULL;
1091         unsigned int bit_size;
1092 
1093         /* FIXME: Bitfield copy! */
1094 
1095         bit_size = src->size * 8;
1096         if (!bit_size)
1097                 bit_size = 32;
1098         if ((src->type == STOR_ARG) && (bit_size < 32))
1099                 bit_size = 32;
1100 
1101         reg = temp_from_bits(bit_size);
1102         emit_move(src, reg, ctype, "begin copy ..");
1103 
1104         bit_size = dest->size * 8;
1105         if (!bit_size)
1106                 bit_size = 32;
1107         if ((dest->type == STOR_ARG) && (bit_size < 32))
1108                 bit_size = 32;
1109 
1110         emit_move(reg, dest, ctype, ".... end copy");
1111         put_reg(reg);
1112 }
1113 
1114 static void emit_store(struct expression *dest_expr, struct storage *dest,
1115                        struct storage *src, int bits)
1116 {
1117         /* FIXME: Bitfield store! */
1118         printf("\tst.%d\t\tv%d,[v%d]\n", bits, src->pseudo, dest->pseudo);
1119 }
1120 
1121 static void emit_scalar_noinit(struct symbol *sym)
1122 {
1123         emit_global_noinit(show_ident(sym->ident),
1124                            sym->ctype.modifiers, sym->ctype.alignment,
1125                            sym->bit_size / 8);
1126         stor_sym_init(sym);
1127 }
1128 
1129 static void emit_array_noinit(struct symbol *sym)
1130 {
1131         emit_global_noinit(show_ident(sym->ident),
1132                            sym->ctype.modifiers, sym->ctype.alignment,
1133                            get_expression_value(sym->array_size) * (sym->bit_size / 8));
1134         stor_sym_init(sym);
1135 }
1136 
1137 static const char *opbits(const char *insn, unsigned int bits)
1138 {
1139         static char opbits_str[32];
1140         char c;
1141 
1142         switch (bits) {
1143         case 8:  c = 'b'; break;
1144         case 16: c = 'w'; break;
1145         case 32: c = 'l'; break;
1146         case 64: c = 'q'; break;
1147         default: abort(); break;
1148         }
1149 
1150         sprintf(opbits_str, "%s%c", insn, c);
1151 
1152         return opbits_str;
1153 }
1154 
1155 static void emit_move(struct storage *src, struct storage *dest,
1156                       struct symbol *ctype, const char *comment)
1157 {
1158         unsigned int bits;
1159         unsigned int is_signed;
1160         unsigned int is_dest = (src->type == STOR_REG);
1161         const char *opname;
1162 
1163         if (ctype) {
1164                 bits = ctype->bit_size;
1165                 is_signed = is_signed_type(ctype);
1166         } else {
1167                 bits = 32;
1168                 is_signed = 0;
1169         }
1170 
1171         /*
1172          * Are we moving from a register to a register?
1173          * Make the new reg to be the "cache".
1174          */
1175         if ((dest->type == STOR_REG) && (src->type == STOR_REG)) {
1176                 struct storage *backing;
1177 
1178 reg_reg_move:
1179                 if (dest == src)
1180                         return;
1181 
1182                 backing = src->reg->contains;
1183                 if (backing) {
1184                         /* Is it still valid? */
1185                         if (backing->reg != src->reg)
1186                                 backing = NULL;
1187                         else
1188                                 backing->reg = dest->reg;
1189                 }
1190                 dest->reg->contains = backing;
1191                 insn("mov", src, dest, NULL);
1192                 return;
1193         }
1194 
1195         /*
1196          * Are we moving to a register from a non-reg?
1197          *
1198          * See if we have the non-reg source already cached
1199          * in a register..
1200          */
1201         if (dest->type == STOR_REG) {
1202                 if (src->reg) {
1203                         struct reg_info *info = src->reg;
1204                         if (info->contains == src) {
1205                                 src = reginfo_reg(info);
1206                                 goto reg_reg_move;
1207                         }
1208                 }
1209                 dest->reg->contains = src;
1210                 src->reg = dest->reg;
1211         }
1212 
1213         if (src->type == STOR_REG) {
1214                 /* We could just mark the register dirty here and do lazy store.. */
1215                 src->reg->contains = dest;
1216                 dest->reg = src->reg;
1217         }
1218 
1219         if ((bits == 8) || (bits == 16)) {
1220                 if (is_dest)
1221                         opname = "mov";
1222                 else
1223                         opname = is_signed ? "movsx" : "movzx";
1224         } else
1225                 opname = "mov";
1226 
1227         insn(opbits(opname, bits), src, dest, comment);
1228 }
1229 
1230 static struct storage *emit_compare(struct expression *expr)
1231 {
1232         struct storage *left = x86_expression(expr->left);
1233         struct storage *right = x86_expression(expr->right);
1234         struct storage *reg1, *reg2;
1235         struct storage *new, *val;
1236         const char *opname = NULL;
1237         unsigned int right_bits = expr->right->ctype->bit_size;
1238 
1239         switch(expr->op) {
1240         case '<':            opname = "setl";        break;
1241         case '>':            opname = "setg";        break;
1242         case SPECIAL_LTE:
1243                                 opname = "setle";       break;
1244         case SPECIAL_GTE:
1245                                 opname = "setge";       break;
1246         case SPECIAL_EQUAL:     opname = "sete";        break;
1247         case SPECIAL_NOTEQUAL:  opname = "setne";       break;
1248         case SPECIAL_UNSIGNED_LT:
1249                                 opname = "setb";        break;
1250         case SPECIAL_UNSIGNED_GT:
1251                                 opname = "seta";        break;
1252         case SPECIAL_UNSIGNED_LTE:
1253                                 opname = "setb";        break;
1254         case SPECIAL_UNSIGNED_GTE:
1255                                 opname = "setae";       break;
1256         default:
1257                 assert(0);
1258                 break;
1259         }
1260 
1261         /* init EDX to 0 */
1262         val = new_storage(STOR_VALUE);
1263         val->flags = STOR_WANTS_FREE;
1264 
1265         reg1 = get_reg(&regclass_32_8);
1266         emit_move(val, reg1, NULL, NULL);
1267 
1268         /* move op1 into EAX */
1269         reg2 = get_reg_value(left, get_regclass(expr->left));
1270 
1271         /* perform comparison, RHS (op1, right) and LHS (op2, EAX) */
1272         insn(opbits("cmp", right_bits), right, reg2, NULL);
1273         put_reg(reg2);
1274 
1275         /* store result of operation, 0 or 1, in DL using SETcc */
1276         insn(opname, byte_reg(reg1), NULL, NULL);
1277 
1278         /* finally, store the result (DL) in a new pseudo / stack slot */
1279         new = stack_alloc(4);
1280         emit_move(reg1, new, NULL, "end EXPR_COMPARE");
1281         put_reg(reg1);
1282 
1283         return new;
1284 }
1285 
1286 static struct storage *emit_value(struct expression *expr)
1287 {
1288 #if 0 /* old and slow way */
1289         struct storage *new = stack_alloc(4);
1290         struct storage *val;
1291 
1292         val = new_storage(STOR_VALUE);
1293         val->value = (long long) expr->value;
1294         val->flags = STOR_WANTS_FREE;
1295         insn("movl", val, new, NULL);
1296 
1297         return new;
1298 #else
1299         struct storage *val;
1300 
1301         val = new_storage(STOR_VALUE);
1302         val->value = (long long) expr->value;
1303 
1304         return val;     /* FIXME: memory leak */
1305 #endif
1306 }
1307 
1308 static struct storage *emit_divide(struct expression *expr, struct storage *left, struct storage *right)
1309 {
1310         struct storage *eax_edx;
1311         struct storage *reg, *new;
1312         struct storage *val = new_storage(STOR_VALUE);
1313 
1314         emit_comment("begin DIVIDE");
1315         eax_edx = get_hardreg(hardreg_storage_table + EAX_EDX, 1);
1316 
1317         /* init EDX to 0 */
1318         val->flags = STOR_WANTS_FREE;
1319         emit_move(val, REG_EDX, NULL, NULL);
1320 
1321         new = stack_alloc(expr->ctype->bit_size / 8);
1322 
1323         /* EAX is dividend */
1324         emit_move(left, REG_EAX, NULL, NULL);
1325 
1326         reg = get_reg_value(right, &regclass_32);
1327 
1328         /* perform binop */
1329         insn("div", reg, REG_EAX, NULL);
1330         put_reg(reg);
1331 
1332         reg = REG_EAX;
1333         if (expr->op == '%')
1334                 reg = REG_EDX;
1335         emit_move(reg, new, NULL, NULL);
1336 
1337         put_reg(eax_edx);
1338         emit_comment("end DIVIDE");
1339         return new;
1340 }
1341 
1342 static struct storage *emit_binop(struct expression *expr)
1343 {
1344         struct storage *left = x86_expression(expr->left);
1345         struct storage *right = x86_expression(expr->right);
1346         struct storage *new;
1347         struct storage *dest, *src;
1348         const char *opname = NULL;
1349         const char *suffix = NULL;
1350         char opstr[16];
1351         int is_signed;
1352 
1353         /* Divides have special register constraints */
1354         if ((expr->op == '/') || (expr->op == '%'))
1355                 return emit_divide(expr, left, right);
1356 
1357         is_signed = is_signed_type(expr->ctype);
1358 
1359         switch (expr->op) {
1360         case '+':
1361                 opname = "add";
1362                 break;
1363         case '-':
1364                 opname = "sub";
1365                 break;
1366         case '&':
1367                 opname = "and";
1368                 break;
1369         case '|':
1370                 opname = "or";
1371                 break;
1372         case '^':
1373                 opname = "xor";
1374                 break;
1375         case SPECIAL_LEFTSHIFT:
1376                 opname = "shl";
1377                 break;
1378         case SPECIAL_RIGHTSHIFT:
1379                 if (is_signed)
1380                         opname = "sar";
1381                 else
1382                         opname = "shr";
1383                 break;
1384         case '*':
1385                 if (is_signed)
1386                         opname = "imul";
1387                 else
1388                         opname = "mul";
1389                 break;
1390         case SPECIAL_LOGICAL_AND:
1391                 warning(expr->pos, "bogus bitwise and for logical op (should use '2*setne + and' or something)");
1392                 opname = "and";
1393                 break;
1394         case SPECIAL_LOGICAL_OR:
1395                 warning(expr->pos, "bogus bitwise or for logical op (should use 'or + setne' or something)");
1396                 opname = "or";
1397                 break;
1398         default:
1399                 error_die(expr->pos, "unhandled binop '%s'\n", show_special(expr->op));
1400                 break;
1401         }
1402 
1403         dest = get_reg_value(right, &regclass_32);
1404         src = get_reg_value(left, &regclass_32);
1405         switch (expr->ctype->bit_size) {
1406         case 8:
1407                 suffix = "b";
1408                 break;
1409         case 16:
1410                 suffix = "w";
1411                 break;
1412         case 32:
1413                 suffix = "l";
1414                 break;
1415         case 64:
1416                 suffix = "q";           /* FIXME */
1417                 break;
1418         default:
1419                 assert(0);
1420                 break;
1421         }
1422 
1423         snprintf(opstr, sizeof(opstr), "%s%s", opname, suffix);
1424 
1425         /* perform binop */
1426         insn(opstr, src, dest, NULL);
1427         put_reg(src);
1428 
1429         /* store result in new pseudo / stack slot */
1430         new = stack_alloc(expr->ctype->bit_size / 8);
1431         emit_move(dest, new, NULL, "end EXPR_BINOP");
1432 
1433         put_reg(dest);
1434 
1435         return new;
1436 }
1437 
1438 static int emit_conditional_test(struct storage *val)
1439 {
1440         struct storage *reg;
1441         struct storage *target_val;
1442         int target_false;
1443 
1444         /* load result into EAX */
1445         emit_comment("begin if/conditional");
1446         reg = get_reg_value(val, &regclass_32);
1447 
1448         /* compare result with zero */
1449         insn("test", reg, reg, NULL);
1450         put_reg(reg);
1451 
1452         /* create conditional-failed label to jump to */
1453         target_false = new_label();
1454         target_val = new_storage(STOR_LABEL);
1455         target_val->label = target_false;
1456         target_val->flags = STOR_WANTS_FREE;
1457         insn("jz", target_val, NULL, NULL);
1458 
1459         return target_false;
1460 }
1461 
1462 static int emit_conditional_end(int target_false)
1463 {
1464         struct storage *cond_end_st;
1465         int cond_end;
1466 
1467         /* finished generating code for if-true statement.
1468          * add a jump-to-end jump to avoid falling through
1469          * to the if-false statement code.
1470          */
1471         cond_end = new_label();
1472         cond_end_st = new_storage(STOR_LABEL);
1473         cond_end_st->label = cond_end;
1474         cond_end_st->flags = STOR_WANTS_FREE;
1475         insn("jmp", cond_end_st, NULL, NULL);
1476 
1477         /* if we have both if-true and if-false statements,
1478          * the failed-conditional case will fall through to here
1479          */
1480         emit_label(target_false, NULL);
1481 
1482         return cond_end;
1483 }
1484 
1485 static void emit_if_conditional(struct statement *stmt)
1486 {
1487         struct storage *val;
1488         int cond_end;
1489 
1490         /* emit test portion of conditional */
1491         val = x86_expression(stmt->if_conditional);
1492         cond_end = emit_conditional_test(val);
1493 
1494         /* emit if-true statement */
1495         x86_statement(stmt->if_true);
1496 
1497         /* emit if-false statement, if present */
1498         if (stmt->if_false) {
1499                 cond_end = emit_conditional_end(cond_end);
1500                 x86_statement(stmt->if_false);
1501         }
1502 
1503         /* end of conditional; jump target for if-true branch */
1504         emit_label(cond_end, "end if");
1505 }
1506 
1507 static struct storage *emit_inc_dec(struct expression *expr, int postop)
1508 {
1509         struct storage *addr = x86_address_gen(expr->unop);
1510         struct storage *retval;
1511         char opname[16];
1512 
1513         strcpy(opname, opbits(expr->op == SPECIAL_INCREMENT ? "inc" : "dec",
1514                               expr->ctype->bit_size));
1515 
1516         if (postop) {
1517                 struct storage *new = stack_alloc(4);
1518 
1519                 emit_copy(new, addr, expr->unop->ctype);
1520 
1521                 retval = new;
1522         } else
1523                 retval = addr;
1524 
1525         insn(opname, addr, NULL, NULL);
1526 
1527         return retval;
1528 }
1529 
1530 static struct storage *emit_postop(struct expression *expr)
1531 {
1532         return emit_inc_dec(expr, 1);
1533 }
1534 
1535 static struct storage *emit_return_stmt(struct statement *stmt)
1536 {
1537         struct function *f = current_func;
1538         struct expression *expr = stmt->ret_value;
1539         struct storage *val = NULL, *jmplbl;
1540 
1541         if (expr && expr->ctype) {
1542                 val = x86_expression(expr);
1543                 assert(val != NULL);
1544                 emit_move(val, REG_EAX, expr->ctype, "return");
1545         }
1546 
1547         jmplbl = new_storage(STOR_LABEL);
1548         jmplbl->flags |= STOR_WANTS_FREE;
1549         jmplbl->label = f->ret_target;
1550         insn("jmp", jmplbl, NULL, NULL);
1551 
1552         return val;
1553 }
1554 
1555 static struct storage *emit_conditional_expr(struct expression *expr)
1556 {
1557         struct storage *cond, *stot = NULL, *stof = NULL;
1558         struct storage *new = stack_alloc(expr->ctype->bit_size / 8);
1559         int target_false, cond_end;
1560 
1561         /* evaluate conditional */
1562         cond = x86_expression(expr->conditional);
1563         target_false = emit_conditional_test(cond);
1564 
1565         /* handle if-true part of the expression */
1566         stot = x86_expression(expr->cond_true);
1567 
1568         emit_copy(new, stot, expr->ctype);
1569 
1570         cond_end = emit_conditional_end(target_false);
1571 
1572         /* handle if-false part of the expression */
1573         stof = x86_expression(expr->cond_false);
1574 
1575         emit_copy(new, stof, expr->ctype);
1576 
1577         /* end of conditional; jump target for if-true branch */
1578         emit_label(cond_end, "end conditional");
1579 
1580         return new;
1581 }
1582 
1583 static struct storage *emit_select_expr(struct expression *expr)
1584 {
1585         struct storage *cond = x86_expression(expr->conditional);
1586         struct storage *stot = x86_expression(expr->cond_true);
1587         struct storage *stof = x86_expression(expr->cond_false);
1588         struct storage *reg_cond, *reg_true, *reg_false;
1589         struct storage *new = stack_alloc(4);
1590 
1591         emit_comment("begin SELECT");
1592         reg_cond = get_reg_value(cond, get_regclass(expr->conditional));
1593         reg_true = get_reg_value(stot, get_regclass(expr));
1594         reg_false = get_reg_value(stof, get_regclass(expr));
1595 
1596         /*
1597          * Do the actual select: check the conditional for zero,
1598          * move false over true if zero
1599          */ 
1600         insn("test", reg_cond, reg_cond, NULL);
1601         insn("cmovz", reg_false, reg_true, NULL);
1602 
1603         /* Store it back */
1604         emit_move(reg_true, new, expr->ctype, NULL);
1605         put_reg(reg_cond);
1606         put_reg(reg_true);
1607         put_reg(reg_false);
1608         emit_comment("end SELECT");
1609         return new;
1610 }
1611 
1612 static struct storage *emit_symbol_expr_init(struct symbol *sym)
1613 {
1614         struct expression *expr = sym->initializer;
1615         struct symbol_private *priv = sym->aux;
1616 
1617         if (priv == NULL) {
1618                 priv = calloc(1, sizeof(*priv));
1619                 sym->aux = priv;
1620 
1621                 if (expr == NULL) {
1622                         struct storage *new = stack_alloc(4);
1623                         fprintf(stderr, "FIXME! no value for symbol %s.  creating pseudo %d (stack offset %d)\n",
1624                                 show_ident(sym->ident),
1625                                 new->pseudo, new->pseudo * 4);
1626                         priv->addr = new;
1627                 } else {
1628                         priv->addr = x86_expression(expr);
1629                 }
1630         }
1631 
1632         return priv->addr;
1633 }
1634 
1635 static struct storage *emit_string_expr(struct expression *expr)
1636 {
1637         struct function *f = current_func;
1638         int label = new_label();
1639         struct storage *new;
1640 
1641         push_cstring(f, expr->string, label);
1642 
1643         new = new_storage(STOR_LABEL);
1644         new->label = label;
1645         new->flags = STOR_LABEL_VAL | STOR_WANTS_FREE;
1646         return new;
1647 }
1648 
1649 static struct storage *emit_cast_expr(struct expression *expr)
1650 {
1651         struct symbol *old_type, *new_type;
1652         struct storage *op = x86_expression(expr->cast_expression);
1653         int oldbits, newbits;
1654         struct storage *new;
1655 
1656         old_type = expr->cast_expression->ctype;
1657         new_type = expr->cast_type;
1658 
1659         oldbits = old_type->bit_size;
1660         newbits = new_type->bit_size;
1661         if (oldbits >= newbits)
1662                 return op;
1663 
1664         emit_move(op, REG_EAX, old_type, "begin cast ..");
1665 
1666         new = stack_alloc(newbits / 8);
1667         emit_move(REG_EAX, new, new_type, ".... end cast");
1668 
1669         return new;
1670 }
1671 
1672 static struct storage *emit_regular_preop(struct expression *expr)
1673 {
1674         struct storage *target = x86_expression(expr->unop);
1675         struct storage *val, *new = stack_alloc(4);
1676         const char *opname = NULL;
1677 
1678         switch (expr->op) {
1679         case '!':
1680                 val = new_storage(STOR_VALUE);
1681                 val->flags = STOR_WANTS_FREE;
1682                 emit_move(val, REG_EDX, NULL, NULL);
1683                 emit_move(target, REG_EAX, expr->unop->ctype, NULL);
1684                 insn("test", REG_EAX, REG_EAX, NULL);
1685                 insn("setz", REG_DL, NULL, NULL);
1686                 emit_move(REG_EDX, new, expr->unop->ctype, NULL);
1687 
1688                 break;
1689         case '~':
1690                 opname = "not";
1691         case '-':
1692                 if (!opname)
1693                         opname = "neg";
1694                 emit_move(target, REG_EAX, expr->unop->ctype, NULL);
1695                 insn(opname, REG_EAX, NULL, NULL);
1696                 emit_move(REG_EAX, new, expr->unop->ctype, NULL);
1697                 break;
1698         default:
1699                 assert(0);
1700                 break;
1701         }
1702 
1703         return new;
1704 }
1705 
1706 static void emit_case_statement(struct statement *stmt)
1707 {
1708         emit_labelsym(stmt->case_label, NULL);
1709         x86_statement(stmt->case_statement);
1710 }
1711 
1712 static void emit_switch_statement(struct statement *stmt)
1713 {
1714         struct storage *val = x86_expression(stmt->switch_expression);
1715         struct symbol *sym, *default_sym = NULL;
1716         struct storage *labelsym, *label;
1717         int switch_end = 0;
1718 
1719         emit_move(val, REG_EAX, stmt->switch_expression->ctype, "begin case");
1720 
1721         /*
1722          * This is where a _real_ back-end would go through the
1723          * cases to decide whether to use a lookup table or a
1724          * series of comparisons etc
1725          */
1726         FOR_EACH_PTR(stmt->switch_case->symbol_list, sym) {
1727                 struct statement *case_stmt = sym->stmt;
1728                 struct expression *expr = case_stmt->case_expression;
1729                 struct expression *to = case_stmt->case_to;
1730 
1731                 /* default: */
1732                 if (!expr)
1733                         default_sym = sym;
1734 
1735                 /* case NNN: */
1736                 else {
1737                         struct storage *case_val = new_val(expr->value);
1738 
1739                         assert (expr->type == EXPR_VALUE);
1740 
1741                         insn("cmpl", case_val, REG_EAX, NULL);
1742 
1743                         if (!to) {
1744                                 labelsym = new_labelsym(sym);
1745                                 insn("je", labelsym, NULL, NULL);
1746                         } else {
1747                                 int next_test;
1748 
1749                                 label = new_storage(STOR_LABEL);
1750                                 label->flags |= STOR_WANTS_FREE;
1751                                 label->label = next_test = new_label();
1752 
1753                                 /* FIXME: signed/unsigned */
1754                                 insn("jl", label, NULL, NULL);
1755 
1756                                 case_val = new_val(to->value);
1757                                 insn("cmpl", case_val, REG_EAX, NULL);
1758 
1759                                 /* TODO: implement and use refcounting... */
1760                                 label = new_storage(STOR_LABEL);
1761                                 label->flags |= STOR_WANTS_FREE;
1762                                 label->label = next_test;
1763 
1764                                 /* FIXME: signed/unsigned */
1765                                 insn("jg", label, NULL, NULL);
1766 
1767                                 labelsym = new_labelsym(sym);
1768                                 insn("jmp", labelsym, NULL, NULL);
1769 
1770                                 emit_label(next_test, NULL);
1771                         }
1772                 }
1773         } END_FOR_EACH_PTR(sym);
1774 
1775         if (default_sym) {
1776                 labelsym = new_labelsym(default_sym);
1777                 insn("jmp", labelsym, NULL, "default");
1778         } else {
1779                 label = new_storage(STOR_LABEL);
1780                 label->flags |= STOR_WANTS_FREE;
1781                 label->label = switch_end = new_label();
1782                 insn("jmp", label, NULL, "goto end of switch");
1783         }
1784 
1785         x86_statement(stmt->switch_statement);
1786 
1787         if (stmt->switch_break->used)
1788                 emit_labelsym(stmt->switch_break, NULL);
1789 
1790         if (switch_end)
1791                 emit_label(switch_end, NULL);
1792 }
1793 
1794 static void x86_struct_member(struct symbol *sym)
1795 {
1796         printf("\t%s:%d:%ld at offset %ld.%d", show_ident(sym->ident), sym->bit_size, sym->ctype.alignment, sym->offset, sym->bit_offset);
1797         printf("\n");
1798 }
1799 
1800 static void x86_symbol(struct symbol *sym)
1801 {
1802         struct symbol *type;
1803 
1804         if (!sym)
1805                 return;
1806 
1807         type = sym->ctype.base_type;
1808         if (!type)
1809                 return;
1810 
1811         /*
1812          * Show actual implementation information
1813          */
1814         switch (type->type) {
1815 
1816         case SYM_ARRAY:
1817                 if (sym->initializer)
1818                         emit_array(sym);
1819                 else
1820                         emit_array_noinit(sym);
1821                 break;
1822 
1823         case SYM_BASETYPE:
1824                 if (sym->initializer) {
1825                         emit_object_pre(show_ident(sym->ident),
1826                                         sym->ctype.modifiers,
1827                                         sym->ctype.alignment,
1828                                         sym->bit_size / 8);
1829                         emit_scalar(sym->initializer, sym->bit_size);
1830                         stor_sym_init(sym);
1831                 } else
1832                         emit_scalar_noinit(sym);
1833                 break;
1834 
1835         case SYM_STRUCT:
1836         case SYM_UNION: {
1837                 struct symbol *member;
1838 
1839                 printf(" {\n");
1840                 FOR_EACH_PTR(type->symbol_list, member) {
1841                         x86_struct_member(member);
1842                 } END_FOR_EACH_PTR(member);
1843                 printf("}\n");
1844                 break;
1845         }
1846 
1847         case SYM_FN: {
1848                 struct statement *stmt = type->stmt;
1849                 if (stmt) {
1850                         emit_func_pre(sym);
1851                         x86_statement(stmt);
1852                         emit_func_post(sym);
1853                 }
1854                 break;
1855         }
1856 
1857         default:
1858                 break;
1859         }
1860 
1861         if (sym->initializer && (type->type != SYM_BASETYPE) &&
1862             (type->type != SYM_ARRAY)) {
1863                 printf(" = \n");
1864                 x86_expression(sym->initializer);
1865         }
1866 }
1867 
1868 static void x86_symbol_init(struct symbol *sym);
1869 
1870 static void x86_symbol_decl(struct symbol_list *syms)
1871 {
1872         struct symbol *sym;
1873         FOR_EACH_PTR(syms, sym) {
1874                 x86_symbol_init(sym);
1875         } END_FOR_EACH_PTR(sym);
1876 }
1877 
1878 static void loopstk_push(int cont_lbl, int loop_bottom_lbl)
1879 {
1880         struct function *f = current_func;
1881         struct loop_stack *ls;
1882 
1883         ls = malloc(sizeof(*ls));
1884         ls->continue_lbl = cont_lbl;
1885         ls->loop_bottom_lbl = loop_bottom_lbl;
1886         ls->next = f->loop_stack;
1887         f->loop_stack = ls;
1888 }
1889 
1890 static void loopstk_pop(void)
1891 {
1892         struct function *f = current_func;
1893         struct loop_stack *ls;
1894 
1895         assert(f->loop_stack != NULL);
1896         ls = f->loop_stack;
1897         f->loop_stack = f->loop_stack->next;
1898         free(ls);
1899 }
1900 
1901 static int loopstk_break(void)
1902 {
1903         return current_func->loop_stack->loop_bottom_lbl;
1904 }
1905 
1906 static int loopstk_continue(void)
1907 {
1908         return current_func->loop_stack->continue_lbl;
1909 }
1910 
1911 static void emit_loop(struct statement *stmt)
1912 {
1913         struct statement  *pre_statement = stmt->iterator_pre_statement;
1914         struct expression *pre_condition = stmt->iterator_pre_condition;
1915         struct statement  *statement = stmt->iterator_statement;
1916         struct statement  *post_statement = stmt->iterator_post_statement;
1917         struct expression *post_condition = stmt->iterator_post_condition;
1918         int loop_top = 0, loop_bottom, loop_continue;
1919         int have_bottom = 0;
1920         struct storage *val;
1921 
1922         loop_bottom = new_label();
1923         loop_continue = new_label();
1924         loopstk_push(loop_continue, loop_bottom);
1925 
1926         x86_symbol_decl(stmt->iterator_syms);
1927         x86_statement(pre_statement);
1928         if (!post_condition || post_condition->type != EXPR_VALUE || post_condition->value) {
1929                 loop_top = new_label();
1930                 emit_label(loop_top, "loop top");
1931         }
1932         if (pre_condition) {
1933                 if (pre_condition->type == EXPR_VALUE) {
1934                         if (!pre_condition->value) {
1935                                 struct storage *lbv;
1936                                 lbv = new_storage(STOR_LABEL);
1937                                 lbv->label = loop_bottom;
1938                                 lbv->flags = STOR_WANTS_FREE;
1939                                 insn("jmp", lbv, NULL, "go to loop bottom");
1940                                 have_bottom = 1;
1941                         }
1942                 } else {
1943                         struct storage *lbv = new_storage(STOR_LABEL);
1944                         lbv->label = loop_bottom;
1945                         lbv->flags = STOR_WANTS_FREE;
1946                         have_bottom = 1;
1947 
1948                         val = x86_expression(pre_condition);
1949 
1950                         emit_move(val, REG_EAX, NULL, "loop pre condition");
1951                         insn("test", REG_EAX, REG_EAX, NULL);
1952                         insn("jz", lbv, NULL, NULL);
1953                 }
1954         }
1955         x86_statement(statement);
1956         if (stmt->iterator_continue->used)
1957                 emit_label(loop_continue, "'continue' iterator");
1958         x86_statement(post_statement);
1959         if (!post_condition) {
1960                 struct storage *lbv = new_storage(STOR_LABEL);
1961                 lbv->label = loop_top;
1962                 lbv->flags = STOR_WANTS_FREE;
1963                 insn("jmp", lbv, NULL, "go to loop top");
1964         } else if (post_condition->type == EXPR_VALUE) {
1965                 if (post_condition->value) {
1966                         struct storage *lbv = new_storage(STOR_LABEL);
1967                         lbv->label = loop_top;
1968                         lbv->flags = STOR_WANTS_FREE;
1969                         insn("jmp", lbv, NULL, "go to loop top");
1970                 }
1971         } else {
1972                 struct storage *lbv = new_storage(STOR_LABEL);
1973                 lbv->label = loop_top;
1974                 lbv->flags = STOR_WANTS_FREE;
1975 
1976                 val = x86_expression(post_condition);
1977 
1978                 emit_move(val, REG_EAX, NULL, "loop post condition");
1979                 insn("test", REG_EAX, REG_EAX, NULL);
1980                 insn("jnz", lbv, NULL, NULL);
1981         }
1982         if (have_bottom || stmt->iterator_break->used)
1983                 emit_label(loop_bottom, "loop bottom");
1984 
1985         loopstk_pop();
1986 }
1987 
1988 /*
1989  * Print out a statement
1990  */
1991 static struct storage *x86_statement(struct statement *stmt)
1992 {
1993         if (!stmt)
1994                 return NULL;
1995         switch (stmt->type) {
1996         default:
1997                 return NULL;
1998         case STMT_RETURN:
1999                 return emit_return_stmt(stmt);
2000         case STMT_DECLARATION:
2001                 x86_symbol_decl(stmt->declaration);
2002                 break;
2003         case STMT_COMPOUND: {
2004                 struct statement *s;
2005                 struct storage *last = NULL;
2006 
2007                 FOR_EACH_PTR(stmt->stmts, s) {
2008                         last = x86_statement(s);
2009                 } END_FOR_EACH_PTR(s);
2010 
2011                 return last;
2012         }
2013 
2014         case STMT_EXPRESSION:
2015                 return x86_expression(stmt->expression);
2016         case STMT_IF:
2017                 emit_if_conditional(stmt);
2018                 return NULL;
2019 
2020         case STMT_CASE:
2021                 emit_case_statement(stmt);
2022                 break;
2023         case STMT_SWITCH:
2024                 emit_switch_statement(stmt);
2025                 break;
2026 
2027         case STMT_ITERATOR:
2028                 emit_loop(stmt);
2029                 break;
2030 
2031         case STMT_NONE:
2032                 break;
2033 
2034         case STMT_LABEL:
2035                 printf(".L%p:\n", stmt->label_identifier);
2036                 x86_statement(stmt->label_statement);
2037                 break;
2038 
2039         case STMT_GOTO:
2040                 if (stmt->goto_expression) {
2041                         struct storage *val = x86_expression(stmt->goto_expression);
2042                         printf("\tgoto *v%d\n", val->pseudo);
2043                 } else if (!strcmp("break", show_ident(stmt->goto_label->ident))) {
2044                         struct storage *lbv = new_storage(STOR_LABEL);
2045                         lbv->label = loopstk_break();
2046                         lbv->flags = STOR_WANTS_FREE;
2047                         insn("jmp", lbv, NULL, "'break'; go to loop bottom");
2048                 } else if (!strcmp("continue", show_ident(stmt->goto_label->ident))) {
2049                         struct storage *lbv = new_storage(STOR_LABEL);
2050                         lbv->label = loopstk_continue();
2051                         lbv->flags = STOR_WANTS_FREE;
2052                         insn("jmp", lbv, NULL, "'continue'; go to loop top");
2053                 } else {
2054                         struct storage *labelsym = new_labelsym(stmt->goto_label);
2055                         insn("jmp", labelsym, NULL, NULL);
2056                 }
2057                 break;
2058         case STMT_ASM:
2059                 printf("\tasm( .... )\n");
2060                 break;
2061         }
2062         return NULL;
2063 }
2064 
2065 static struct storage *x86_call_expression(struct expression *expr)
2066 {
2067         struct function *f = current_func;
2068         struct symbol *direct;
2069         struct expression *arg, *fn;
2070         struct storage *retval, *fncall;
2071         int framesize;
2072         char s[64];
2073 
2074         if (!expr->ctype) {
2075                 warning(expr->pos, "\tcall with no type!");
2076                 return NULL;
2077         }
2078 
2079         framesize = 0;
2080         FOR_EACH_PTR_REVERSE(expr->args, arg) {
2081                 struct storage *new = x86_expression(arg);
2082                 int size = arg->ctype->bit_size;
2083 
2084                 /*
2085                  * FIXME: i386 SysV ABI dictates that values
2086                  * smaller than 32 bits should be placed onto
2087                  * the stack as 32-bit objects.  We should not
2088                  * blindly do a 32-bit push on objects smaller
2089                  * than 32 bits.
2090                  */
2091                 if (size < 32)
2092                         size = 32;
2093                 insn("pushl", new, NULL,
2094                      !framesize ? "begin function call" : NULL);
2095 
2096                 framesize += bits_to_bytes(size);
2097         } END_FOR_EACH_PTR_REVERSE(arg);
2098 
2099         fn = expr->fn;
2100 
2101         /* Remove dereference, if any */
2102         direct = NULL;
2103         if (fn->type == EXPR_PREOP) {
2104                 if (fn->unop->type == EXPR_SYMBOL) {
2105                         struct symbol *sym = fn->unop->symbol;
2106                         if (sym->ctype.base_type->type == SYM_FN)
2107                                 direct = sym;
2108                 }
2109         }
2110         if (direct) {
2111                 struct storage *direct_stor = new_storage(STOR_SYM);
2112                 direct_stor->flags |= STOR_WANTS_FREE;
2113                 direct_stor->sym = direct;
2114                 insn("call", direct_stor, NULL, NULL);
2115         } else {
2116                 fncall = x86_expression(fn);
2117                 emit_move(fncall, REG_EAX, fn->ctype, NULL);
2118 
2119                 strcpy(s, "\tcall\t*%eax\n");
2120                 push_text_atom(f, s);
2121         }
2122 
2123         /* FIXME: pay attention to BITS_IN_POINTER */
2124         if (framesize) {
2125                 struct storage *val = new_storage(STOR_VALUE);
2126                 val->value = (long long) framesize;
2127                 val->flags = STOR_WANTS_FREE;
2128                 insn("addl", val, REG_ESP, NULL);
2129         }
2130 
2131         retval = stack_alloc(4);
2132         emit_move(REG_EAX, retval, NULL, "end function call");
2133 
2134         return retval;
2135 }
2136 
2137 static struct storage *x86_address_gen(struct expression *expr)
2138 {
2139         struct function *f = current_func;
2140         struct storage *addr;
2141         struct storage *new;
2142         char s[32];
2143 
2144         addr = x86_expression(expr->unop);
2145         if (expr->unop->type == EXPR_SYMBOL)
2146                 return addr;
2147 
2148         emit_move(addr, REG_EAX, NULL, "begin deref ..");
2149 
2150         /* FIXME: operand size */
2151         strcpy(s, "\tmovl\t(%eax), %ecx\n");
2152         push_text_atom(f, s);
2153 
2154         new = stack_alloc(4);
2155         emit_move(REG_ECX, new, NULL, ".... end deref");
2156 
2157         return new;
2158 }
2159 
2160 static struct storage *x86_assignment(struct expression *expr)
2161 {
2162         struct expression *target = expr->left;
2163         struct storage *val, *addr;
2164 
2165         if (!expr->ctype)
2166                 return NULL;
2167 
2168         val = x86_expression(expr->right);
2169         addr = x86_address_gen(target);
2170 
2171         switch (val->type) {
2172         /* copy, where both operands are memory */
2173         case STOR_PSEUDO:
2174         case STOR_ARG:
2175                 emit_copy(addr, val, expr->ctype);
2176                 break;
2177 
2178         /* copy, one or zero operands are memory */
2179         case STOR_REG:
2180         case STOR_SYM:
2181         case STOR_VALUE:
2182         case STOR_LABEL:
2183                 emit_move(val, addr, expr->left->ctype, NULL);
2184                 break;
2185 
2186         case STOR_LABELSYM:
2187                 assert(0);
2188                 break;
2189         }
2190         return val;
2191 }
2192 
2193 static int x86_initialization(struct symbol *sym, struct expression *expr)
2194 {
2195         struct storage *val, *addr;
2196         int bits;
2197 
2198         if (!expr->ctype)
2199                 return 0;
2200 
2201         bits = expr->ctype->bit_size;
2202         val = x86_expression(expr);
2203         addr = x86_symbol_expr(sym);
2204         // FIXME! The "target" expression is for bitfield store information.
2205         // Leave it NULL, which works fine.
2206         emit_store(NULL, addr, val, bits);
2207         return 0;
2208 }
2209 
2210 static struct storage *x86_access(struct expression *expr)
2211 {
2212         return x86_address_gen(expr);
2213 }
2214 
2215 static struct storage *x86_preop(struct expression *expr)
2216 {
2217         /*
2218          * '*' is an lvalue access, and is fundamentally different
2219          * from an arithmetic operation. Maybe it should have an
2220          * expression type of its own..
2221          */
2222         if (expr->op == '*')
2223                 return x86_access(expr);
2224         if (expr->op == SPECIAL_INCREMENT || expr->op == SPECIAL_DECREMENT)
2225                 return emit_inc_dec(expr, 0);
2226         return emit_regular_preop(expr);
2227 }
2228 
2229 static struct storage *x86_symbol_expr(struct symbol *sym)
2230 {
2231         struct storage *new = stack_alloc(4);
2232 
2233         if (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_EXTERN | MOD_STATIC)) {
2234                 printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer, new->pseudo, show_ident(sym->ident));
2235                 return new;
2236         }
2237         if (sym->ctype.modifiers & MOD_ADDRESSABLE) {
2238                 printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer, new->pseudo, 0LL);
2239                 return new;
2240         }
2241         printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer, new->pseudo, show_ident(sym->ident), sym);
2242         return new;
2243 }
2244 
2245 static void x86_symbol_init(struct symbol *sym)
2246 {
2247         struct symbol_private *priv = sym->aux;
2248         struct expression *expr = sym->initializer;
2249         struct storage *new;
2250 
2251         if (expr)
2252                 new = x86_expression(expr);
2253         else
2254                 new = stack_alloc(sym->bit_size / 8);
2255 
2256         if (!priv) {
2257                 priv = calloc(1, sizeof(*priv));
2258                 sym->aux = priv;
2259                 /* FIXME: leak! we don't free... */
2260                 /* (well, we don't free symbols either) */
2261         }
2262 
2263         priv->addr = new;
2264 }
2265 
2266 static struct storage *x86_label_expr(struct expression *expr)
2267 {
2268         struct storage *new = stack_alloc(4);
2269         printf("\tmovi.%d\t\tv%d,.L%p\n", bits_in_pointer, new->pseudo, expr->label_symbol);
2270         return new;
2271 }
2272 
2273 static struct storage *x86_statement_expr(struct expression *expr)
2274 {
2275         return x86_statement(expr->statement);
2276 }
2277 
2278 static int x86_position_expr(struct expression *expr, struct symbol *base)
2279 {
2280         struct storage *new = x86_expression(expr->init_expr);
2281         struct symbol *ctype = expr->init_expr->ctype;
2282 
2283         printf("\tinsert v%d at [%d:%d] of %s\n", new->pseudo,
2284                 expr->init_offset, ctype->bit_offset,
2285                 show_ident(base->ident));
2286         return 0;
2287 }
2288 
2289 static void x86_initializer_expr(struct expression *expr, struct symbol *ctype)
2290 {
2291         struct expression *entry;
2292 
2293         FOR_EACH_PTR(expr->expr_list, entry) {
2294                 // Nested initializers have their positions already
2295                 // recursively calculated - just output them too
2296                 if (entry->type == EXPR_INITIALIZER) {
2297                         x86_initializer_expr(entry, ctype);
2298                         continue;
2299                 }
2300 
2301                 // Ignore initializer indexes and identifiers - the
2302                 // evaluator has taken them into account
2303                 if (entry->type == EXPR_IDENTIFIER || entry->type == EXPR_INDEX)
2304                         continue;
2305                 if (entry->type == EXPR_POS) {
2306                         x86_position_expr(entry, ctype);
2307                         continue;
2308                 }
2309                 x86_initialization(ctype, entry);
2310         } END_FOR_EACH_PTR(entry);
2311 }
2312 
2313 /*
2314  * Print out an expression. Return the pseudo that contains the
2315  * variable.
2316  */
2317 static struct storage *x86_expression(struct expression *expr)
2318 {
2319         if (!expr)
2320                 return NULL;
2321 
2322         if (!expr->ctype) {
2323                 struct position *pos = &expr->pos;
2324                 printf("\tno type at %s:%d:%d\n",
2325                         stream_name(pos->stream),
2326                         pos->line, pos->pos);
2327                 return NULL;
2328         }
2329 
2330         switch (expr->type) {
2331         default:
2332                 return NULL;
2333         case EXPR_CALL:
2334                 return x86_call_expression(expr);
2335 
2336         case EXPR_ASSIGNMENT:
2337                 return x86_assignment(expr);
2338 
2339         case EXPR_COMPARE:
2340                 return emit_compare(expr);
2341         case EXPR_BINOP:
2342         case EXPR_COMMA:
2343         case EXPR_LOGICAL:
2344                 return emit_binop(expr);
2345         case EXPR_PREOP:
2346                 return x86_preop(expr);
2347         case EXPR_POSTOP:
2348                 return emit_postop(expr);
2349         case EXPR_SYMBOL:
2350                 return emit_symbol_expr_init(expr->symbol);
2351         case EXPR_DEREF:
2352         case EXPR_SIZEOF:
2353         case EXPR_ALIGNOF:
2354                 warning(expr->pos, "invalid expression after evaluation");
2355                 return NULL;
2356         case EXPR_CAST:
2357         case EXPR_FORCE_CAST:
2358         case EXPR_IMPLIED_CAST:
2359                 return emit_cast_expr(expr);
2360         case EXPR_VALUE:
2361                 return emit_value(expr);
2362         case EXPR_STRING:
2363                 return emit_string_expr(expr);
2364         case EXPR_INITIALIZER:
2365                 x86_initializer_expr(expr, expr->ctype);
2366                 return NULL;
2367         case EXPR_SELECT:
2368                 return emit_select_expr(expr);
2369         case EXPR_CONDITIONAL:
2370                 return emit_conditional_expr(expr);
2371         case EXPR_STATEMENT:
2372                 return x86_statement_expr(expr);
2373         case EXPR_LABEL:
2374                 return x86_label_expr(expr);
2375 
2376         // None of these should exist as direct expressions: they are only
2377         // valid as sub-expressions of initializers.
2378         case EXPR_POS:
2379                 warning(expr->pos, "unable to show plain initializer position expression");
2380                 return NULL;
2381         case EXPR_IDENTIFIER:
2382                 warning(expr->pos, "unable to show identifier expression");
2383                 return NULL;
2384         case EXPR_INDEX:
2385                 warning(expr->pos, "unable to show index expression");
2386                 return NULL;
2387         case EXPR_TYPE:
2388                 warning(expr->pos, "unable to show type expression");
2389                 return NULL;
2390         case EXPR_FVALUE:
2391                 warning(expr->pos, "floating point support is not implemented");
2392                 return NULL;
2393         }
2394         return NULL;
2395 }