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