Make "value_pseudo()" always return the same pseudo for
[smatch.git] / compile-i386.c
blobc22b11e856a861c04410ee0b5ff97423242bb9b0
1 /*
2 * sparse/compile-i386.c
4 * Copyright (C) 2003 Transmeta Corp.
5 * 2003 Linus Torvalds
6 * Copyright 2003 Jeff Garzik
8 * Licensed under the Open Software License version 1.1
10 * x86 backend
12 * TODO list:
13 * in general, any non-32bit SYM_BASETYPE is unlikely to work.
14 * complex initializers
15 * bitfields
16 * global struct/union variables
17 * addressing structures, and members of structures (as opposed to
18 * scalars) on the stack. Requires smarter stack frame allocation.
19 * labels / goto
20 * any function argument that isn't 32 bits (or promoted to such)
21 * inline asm
22 * floating point
25 #include <stdarg.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <ctype.h>
30 #include <unistd.h>
31 #include <fcntl.h>
32 #include <assert.h>
34 #include "lib.h"
35 #include "token.h"
36 #include "parse.h"
37 #include "symbol.h"
38 #include "scope.h"
39 #include "expression.h"
40 #include "target.h"
41 #include "compile.h"
42 #include "bitmap.h"
44 struct textbuf {
45 unsigned int len; /* does NOT include terminating null */
46 char *text;
47 struct textbuf *next;
48 struct textbuf *prev;
51 struct loop_stack {
52 int continue_lbl;
53 int loop_bottom_lbl;
54 struct loop_stack *next;
57 struct function {
58 int stack_size;
59 int pseudo_nr;
60 struct ptr_list *pseudo_list;
61 struct ptr_list *atom_list;
62 struct ptr_list *str_list;
63 struct loop_stack *loop_stack;
64 struct symbol **argv;
65 unsigned int argc;
66 int ret_target;
69 enum storage_type {
70 STOR_PSEUDO, /* variable stored on the stack */
71 STOR_ARG, /* function argument */
72 STOR_SYM, /* a symbol we can directly ref in the asm */
73 STOR_REG, /* scratch register */
74 STOR_VALUE, /* integer constant */
75 STOR_LABEL, /* label / jump target */
76 STOR_LABELSYM, /* label generated from symbol's pointer value */
79 struct reg_info {
80 const char *name;
81 struct storage *contains;
82 const unsigned char aliases[12];
83 #define own_regno aliases[0]
86 struct storage {
87 enum storage_type type;
88 unsigned long flags;
90 /* STOR_REG */
91 struct reg_info *reg;
92 struct symbol *ctype;
94 union {
95 /* STOR_PSEUDO */
96 struct {
97 int pseudo;
98 int offset;
99 int size;
101 /* STOR_ARG */
102 struct {
103 int idx;
105 /* STOR_SYM */
106 struct {
107 struct symbol *sym;
109 /* STOR_VALUE */
110 struct {
111 long long value;
113 /* STOR_LABEL */
114 struct {
115 int label;
117 /* STOR_LABELSYM */
118 struct {
119 struct symbol *labelsym;
124 enum {
125 STOR_LABEL_VAL = (1 << 0),
126 STOR_WANTS_FREE = (1 << 1),
129 struct symbol_private {
130 struct storage *addr;
133 enum atom_type {
134 ATOM_TEXT,
135 ATOM_INSN,
136 ATOM_CSTR,
139 struct atom {
140 enum atom_type type;
141 union {
142 /* stuff for text */
143 struct {
144 char *text;
145 unsigned int text_len; /* w/o terminating null */
148 /* stuff for insns */
149 struct {
150 char insn[32];
151 char comment[40];
152 struct storage *op1;
153 struct storage *op2;
156 /* stuff for C strings */
157 struct {
158 struct string *string;
159 int label;
165 struct function *current_func = NULL;
166 struct textbuf *unit_post_text = NULL;
167 static const char *current_section;
169 static void emit_comment(const char * fmt, ...);
170 static void emit_move(struct storage *src, struct storage *dest,
171 struct symbol *ctype, const char *comment);
172 static int type_is_signed(struct symbol *sym);
173 static struct storage *x86_address_gen(struct expression *expr);
174 static struct storage *x86_symbol_expr(struct symbol *sym);
175 static void x86_symbol(struct symbol *sym);
176 static struct storage *x86_statement(struct statement *stmt);
177 static struct storage *x86_expression(struct expression *expr);
179 enum registers {
180 NOREG,
181 AL, DL, CL, BL, AH, DH, CH, BH, // 8-bit
182 AX, DX, CX, BX, SI, DI, BP, SP, // 16-bit
183 EAX, EDX, ECX, EBX, ESI, EDI, EBP, ESP, // 32-bit
184 EAX_EDX, ECX_EBX, ESI_EDI, // 64-bit
187 /* This works on regno's, reg_info's and hardreg_storage's */
188 #define byte_reg(reg) ((reg) - 16)
189 #define highbyte_reg(reg) ((reg)-12)
190 #define word_reg(reg) ((reg)-8)
192 #define REGINFO(nr, str, conflicts...) [nr] = { .name = str, .aliases = { nr , conflicts } }
194 static struct reg_info reg_info_table[] = {
195 REGINFO( AL, "%al", AX, EAX, EAX_EDX),
196 REGINFO( DL, "%dl", DX, EDX, EAX_EDX),
197 REGINFO( CL, "%cl", CX, ECX, ECX_EBX),
198 REGINFO( BL, "%bl", BX, EBX, ECX_EBX),
199 REGINFO( AH, "%ah", AX, EAX, EAX_EDX),
200 REGINFO( DH, "%dh", DX, EDX, EAX_EDX),
201 REGINFO( CH, "%ch", CX, ECX, ECX_EBX),
202 REGINFO( BH, "%bh", BX, EBX, ECX_EBX),
203 REGINFO( AX, "%ax", AL, AH, EAX, EAX_EDX),
204 REGINFO( DX, "%dx", DL, DH, EDX, EAX_EDX),
205 REGINFO( CX, "%cx", CL, CH, ECX, ECX_EBX),
206 REGINFO( BX, "%bx", BL, BH, EBX, ECX_EBX),
207 REGINFO( SI, "%si", ESI, ESI_EDI),
208 REGINFO( DI, "%di", EDI, ESI_EDI),
209 REGINFO( BP, "%bp", EBP),
210 REGINFO( SP, "%sp", ESP),
211 REGINFO(EAX, "%eax", AL, AH, AX, EAX_EDX),
212 REGINFO(EDX, "%edx", DL, DH, DX, EAX_EDX),
213 REGINFO(ECX, "%ecx", CL, CH, CX, ECX_EBX),
214 REGINFO(EBX, "%ebx", BL, BH, BX, ECX_EBX),
215 REGINFO(ESI, "%esi", SI, ESI_EDI),
216 REGINFO(EDI, "%edi", DI, ESI_EDI),
217 REGINFO(EBP, "%ebp", BP),
218 REGINFO(ESP, "%esp", SP),
219 REGINFO(EAX_EDX, "%eax:%edx", AL, AH, AX, EAX, DL, DH, DX, EDX),
220 REGINFO(ECX_EBX, "%ecx:%ebx", CL, CH, CX, ECX, BL, BH, BX, EBX),
221 REGINFO(ESI_EDI, "%esi:%edi", SI, ESI, DI, EDI),
224 #define REGSTORAGE(nr) [nr] = { .type = STOR_REG, .reg = reg_info_table + (nr) }
226 static struct storage hardreg_storage_table[] = {
227 REGSTORAGE(AL), REGSTORAGE(DL), REGSTORAGE(CL), REGSTORAGE(BL),
228 REGSTORAGE(AH), REGSTORAGE(DH), REGSTORAGE(CH), REGSTORAGE(BH),
229 REGSTORAGE(AX), REGSTORAGE(DX), REGSTORAGE(CX), REGSTORAGE(BX),
230 REGSTORAGE(SI), REGSTORAGE(DI), REGSTORAGE(BP), REGSTORAGE(SP),
231 REGSTORAGE(EAX), REGSTORAGE(EDX), REGSTORAGE(ECX), REGSTORAGE(EBX),
232 REGSTORAGE(ESI), REGSTORAGE(EDI), REGSTORAGE(EBP), REGSTORAGE(ESP),
233 REGSTORAGE(EAX_EDX), REGSTORAGE(ECX_EBX), REGSTORAGE(ESI_EDI),
236 #define REG_EAX (&hardreg_storage_table[EAX])
237 #define REG_ECX (&hardreg_storage_table[ECX])
238 #define REG_EDX (&hardreg_storage_table[EDX])
239 #define REG_ESP (&hardreg_storage_table[ESP])
240 #define REG_DL (&hardreg_storage_table[DL])
241 #define REG_DX (&hardreg_storage_table[DX])
242 #define REG_AL (&hardreg_storage_table[AL])
243 #define REG_AX (&hardreg_storage_table[AX])
245 DECLARE_BITMAP(regs_in_use, 256);
247 static inline struct storage * reginfo_reg(struct reg_info *info)
249 return hardreg_storage_table + info->own_regno;
252 struct storage * get_hardreg(struct storage *reg, int clear)
254 struct reg_info *info = reg->reg;
255 const unsigned char *aliases;
256 int regno;
258 aliases = info->aliases;
259 while ((regno = *aliases++) != NOREG) {
260 if (test_bit(regno, regs_in_use))
261 goto busy;
262 if (clear)
263 reg_info_table[regno].contains = NULL;
265 set_bit(info->own_regno, regs_in_use);
266 return reg;
267 busy:
268 fprintf(stderr, "register %s is busy\n", info->name);
269 if (regno + reg_info_table != info)
270 fprintf(stderr, " conflicts with %s\n", reg_info_table[regno].name);
271 exit(1);
274 void put_reg(struct storage *reg)
276 struct reg_info *info = reg->reg;
277 int regno = info->own_regno;
279 if (test_and_clear_bit(regno, regs_in_use))
280 return;
281 fprintf(stderr, "freeing already free'd register %s\n", reg_info_table[regno].name);
284 struct regclass {
285 const char *name;
286 const unsigned char regs[30];
289 static struct regclass regclass_8 = { "8-bit", { AL, DL, CL, BL, AH, DH, CH, BH }};
290 static struct regclass regclass_16 = { "16-bit", { AX, DX, CX, BX, SI, DI, BP }};
291 static struct regclass regclass_32 = { "32-bit", { EAX, EDX, ECX, EBX, ESI, EDI, EBP }};
292 static struct regclass regclass_64 = { "64-bit", { EAX_EDX, ECX_EBX, ESI_EDI }};
294 struct regclass regclass_32_8 = { "32-bit bytes", { EAX, EDX, ECX, EBX }};
296 static struct regclass *get_regclass_bits(int bits)
298 switch (bits) {
299 case 8: return &regclass_8;
300 case 16: return &regclass_16;
301 case 64: return &regclass_64;
302 default: return &regclass_32;
306 static struct regclass *get_regclass(struct expression *expr)
308 return get_regclass_bits(expr->ctype->bit_size);
311 static int register_busy(int regno)
313 if (!test_bit(regno, regs_in_use)) {
314 struct reg_info *info = reg_info_table + regno;
315 const unsigned char *regs = info->aliases+1;
317 while ((regno = *regs) != NOREG) {
318 regs++;
319 if (test_bit(regno, regs_in_use))
320 goto busy;
322 return 0;
324 busy:
325 return 1;
328 struct storage *get_reg(struct regclass *class)
330 const unsigned char *regs = class->regs;
331 int regno;
333 while ((regno = *regs) != NOREG) {
334 regs++;
335 if (register_busy(regno))
336 continue;
337 return get_hardreg(hardreg_storage_table + regno, 1);
339 fprintf(stderr, "Ran out of %s registers\n", class->name);
340 exit(1);
343 struct storage *get_reg_value(struct storage *value, struct regclass *class)
345 struct reg_info *info;
346 struct storage *reg;
348 /* Do we already have it somewhere */
349 info = value->reg;
350 if (info && info->contains == value) {
351 emit_comment("already have register %s", info->name);
352 return get_hardreg(hardreg_storage_table + info->own_regno, 0);
355 reg = get_reg(class);
356 emit_move(value, reg, value->ctype, "reload register");
357 info = reg->reg;
358 info->contains = value;
359 value->reg = info;
360 return reg;
363 static struct storage *temp_from_bits(unsigned int bit_size)
365 return get_reg(get_regclass_bits(bit_size));
368 static inline unsigned int pseudo_offset(struct storage *s)
370 if (s->type != STOR_PSEUDO)
371 return 123456; /* intentionally bogus value */
373 return s->offset;
376 static inline unsigned int arg_offset(struct storage *s)
378 if (s->type != STOR_ARG)
379 return 123456; /* intentionally bogus value */
381 /* FIXME: this is wrong wrong wrong */
382 return current_func->stack_size + ((1 + s->idx) * 4);
385 static const char *pretty_offset(int ofs)
387 static char esp_buf[64];
389 if (ofs)
390 sprintf(esp_buf, "%d(%%esp)", ofs);
391 else
392 strcpy(esp_buf, "(%esp)");
394 return esp_buf;
397 static void stor_sym_init(struct symbol *sym)
399 struct storage *stor;
400 struct symbol_private *priv;
402 priv = calloc(1, sizeof(*priv) + sizeof(*stor));
403 if (!priv)
404 die("OOM in stor_sym_init");
406 stor = (struct storage *) (priv + 1);
408 priv->addr = stor;
409 stor->type = STOR_SYM;
410 stor->sym = sym;
413 static const char *stor_op_name(struct storage *s)
415 static char name[32];
417 switch (s->type) {
418 case STOR_PSEUDO:
419 strcpy(name, pretty_offset((int) pseudo_offset(s)));
420 break;
421 case STOR_ARG:
422 strcpy(name, pretty_offset((int) arg_offset(s)));
423 break;
424 case STOR_SYM:
425 strcpy(name, show_ident(s->sym->ident));
426 break;
427 case STOR_REG:
428 strcpy(name, s->reg->name);
429 break;
430 case STOR_VALUE:
431 sprintf(name, "$%Ld", s->value);
432 break;
433 case STOR_LABEL:
434 sprintf(name, "%s.L%d", s->flags & STOR_LABEL_VAL ? "$" : "",
435 s->label);
436 break;
437 case STOR_LABELSYM:
438 sprintf(name, "%s.LS%p", s->flags & STOR_LABEL_VAL ? "$" : "",
439 s->labelsym);
440 break;
443 return name;
446 static struct atom *new_atom(enum atom_type type)
448 struct atom *atom;
450 atom = calloc(1, sizeof(*atom)); /* TODO: chunked alloc */
451 if (!atom)
452 die("nuclear OOM");
454 atom->type = type;
456 return atom;
459 static inline void push_cstring(struct function *f, struct string *str,
460 int label)
462 struct atom *atom;
464 atom = new_atom(ATOM_CSTR);
465 atom->string = str;
466 atom->label = label;
468 add_ptr_list(&f->str_list, atom); /* note: _not_ atom_list */
471 static inline void push_atom(struct function *f, struct atom *atom)
473 add_ptr_list(&f->atom_list, atom);
476 static void push_text_atom(struct function *f, const char *text)
478 struct atom *atom = new_atom(ATOM_TEXT);
480 atom->text = strdup(text);
481 atom->text_len = strlen(text);
483 push_atom(f, atom);
486 static struct storage *new_storage(enum storage_type type)
488 struct storage *stor;
490 stor = calloc(1, sizeof(*stor));
491 if (!stor)
492 die("OOM in new_storage");
494 stor->type = type;
496 return stor;
499 static struct storage *stack_alloc(int n_bytes)
501 struct function *f = current_func;
502 struct storage *stor;
504 assert(f != NULL);
506 stor = new_storage(STOR_PSEUDO);
507 stor->type = STOR_PSEUDO;
508 stor->pseudo = f->pseudo_nr;
509 stor->offset = f->stack_size; /* FIXME: stack req. natural align */
510 stor->size = n_bytes;
511 f->stack_size += n_bytes;
512 f->pseudo_nr++;
514 add_ptr_list(&f->pseudo_list, stor);
516 return stor;
519 static struct storage *new_labelsym(struct symbol *sym)
521 struct storage *stor;
523 stor = new_storage(STOR_LABELSYM);
525 if (stor) {
526 stor->flags |= STOR_WANTS_FREE;
527 stor->labelsym = sym;
530 return stor;
533 static struct storage *new_val(long long value)
535 struct storage *stor;
537 stor = new_storage(STOR_VALUE);
539 if (stor) {
540 stor->flags |= STOR_WANTS_FREE;
541 stor->value = value;
544 return stor;
547 static int new_label(void)
549 static int label = 0;
550 return ++label;
553 static void textbuf_push(struct textbuf **buf_p, const char *text)
555 struct textbuf *tmp, *list = *buf_p;
556 unsigned int text_len = strlen(text);
557 unsigned int alloc_len = text_len + 1 + sizeof(*list);
559 tmp = calloc(1, alloc_len);
560 if (!tmp)
561 die("OOM on textbuf alloc");
563 tmp->text = ((void *) tmp) + sizeof(*tmp);
564 memcpy(tmp->text, text, text_len + 1);
565 tmp->len = text_len;
567 /* add to end of list */
568 if (!list) {
569 list = tmp;
570 tmp->prev = tmp;
571 } else {
572 tmp->prev = list->prev;
573 tmp->prev->next = tmp;
574 list->prev = tmp;
576 tmp->next = list;
578 *buf_p = list;
581 static void textbuf_emit(struct textbuf **buf_p)
583 struct textbuf *tmp, *list = *buf_p;
585 while (list) {
586 tmp = list;
587 if (tmp->next == tmp)
588 list = NULL;
589 else {
590 tmp->prev->next = tmp->next;
591 tmp->next->prev = tmp->prev;
592 list = tmp->next;
595 fputs(tmp->text, stdout);
597 free(tmp);
600 *buf_p = list;
603 static void insn(const char *insn, struct storage *op1, struct storage *op2,
604 const char *comment_in)
606 struct function *f = current_func;
607 struct atom *atom = new_atom(ATOM_INSN);
609 assert(insn != NULL);
611 strcpy(atom->insn, insn);
612 if (comment_in && (*comment_in))
613 strncpy(atom->comment, comment_in,
614 sizeof(atom->comment) - 1);
616 atom->op1 = op1;
617 atom->op2 = op2;
619 push_atom(f, atom);
622 static void emit_comment(const char *fmt, ...)
624 struct function *f = current_func;
625 static char tmpbuf[100] = "\t# ";
626 va_list args;
627 int i;
629 va_start(args, fmt);
630 i = vsnprintf(tmpbuf+3, sizeof(tmpbuf)-4, fmt, args);
631 va_end(args);
632 tmpbuf[i+3] = '\n';
633 tmpbuf[i+4] = '\0';
634 push_text_atom(f, tmpbuf);
637 static void emit_label (int label, const char *comment)
639 struct function *f = current_func;
640 char s[64];
642 if (!comment)
643 sprintf(s, ".L%d:\n", label);
644 else
645 sprintf(s, ".L%d:\t\t\t\t\t# %s\n", label, comment);
647 push_text_atom(f, s);
650 static void emit_labelsym (struct symbol *sym, const char *comment)
652 struct function *f = current_func;
653 char s[64];
655 if (!comment)
656 sprintf(s, ".LS%p:\n", sym);
657 else
658 sprintf(s, ".LS%p:\t\t\t\t# %s\n", sym, comment);
660 push_text_atom(f, s);
663 void emit_unit_begin(const char *basename)
665 printf("\t.file\t\"%s\"\n", basename);
668 void emit_unit_end(void)
670 textbuf_emit(&unit_post_text);
671 printf("\t.ident\t\"sparse silly x86 backend (built %s)\"\n", __DATE__);
674 /* conditionally switch sections */
675 static void emit_section(const char *s)
677 if (s == current_section)
678 return;
679 if (current_section && (!strcmp(s, current_section)))
680 return;
682 printf("\t%s\n", s);
683 current_section = s;
686 static void emit_insn_atom(struct function *f, struct atom *atom)
688 char s[128];
689 char comment[64];
690 struct storage *op1 = atom->op1;
691 struct storage *op2 = atom->op2;
693 if (atom->comment[0])
694 sprintf(comment, "\t\t# %s", atom->comment);
695 else
696 comment[0] = 0;
698 if (atom->op2) {
699 char tmp[16];
700 strcpy(tmp, stor_op_name(op1));
701 sprintf(s, "\t%s\t%s, %s%s\n",
702 atom->insn, tmp, stor_op_name(op2), comment);
703 } else if (atom->op1)
704 sprintf(s, "\t%s\t%s%s%s\n",
705 atom->insn, stor_op_name(op1),
706 comment[0] ? "\t" : "", comment);
707 else
708 sprintf(s, "\t%s\t%s%s\n",
709 atom->insn,
710 comment[0] ? "\t\t" : "", comment);
712 write(STDOUT_FILENO, s, strlen(s));
715 static void emit_atom_list(struct function *f)
717 struct atom *atom;
719 FOR_EACH_PTR(f->atom_list, atom) {
720 switch (atom->type) {
721 case ATOM_TEXT: {
722 ssize_t rc = write(STDOUT_FILENO, atom->text,
723 atom->text_len);
724 (void) rc; /* FIXME */
725 break;
727 case ATOM_INSN:
728 emit_insn_atom(f, atom);
729 break;
730 case ATOM_CSTR:
731 assert(0);
732 break;
734 } END_FOR_EACH_PTR(atom);
737 static void emit_string_list(struct function *f)
739 struct atom *atom;
741 emit_section(".section\t.rodata");
743 FOR_EACH_PTR(f->str_list, atom) {
744 /* FIXME: escape " in string */
745 printf(".L%d:\n", atom->label);
746 printf("\t.string\t%s\n", show_string(atom->string));
748 free(atom);
749 } END_FOR_EACH_PTR(atom);
752 static void func_cleanup(struct function *f)
754 struct storage *stor;
755 struct atom *atom;
757 FOR_EACH_PTR(f->pseudo_list, stor) {
758 free(stor);
759 } END_FOR_EACH_PTR(stor);
761 FOR_EACH_PTR(f->atom_list, atom) {
762 if ((atom->type == ATOM_TEXT) && (atom->text))
763 free(atom->text);
764 if (atom->op1 && (atom->op1->flags & STOR_WANTS_FREE))
765 free(atom->op1);
766 if (atom->op2 && (atom->op2->flags & STOR_WANTS_FREE))
767 free(atom->op2);
768 free(atom);
769 } END_FOR_EACH_PTR(atom);
771 free_ptr_list(&f->pseudo_list);
772 free(f);
775 /* function prologue */
776 static void emit_func_pre(struct symbol *sym)
778 struct function *f;
779 struct symbol *arg;
780 unsigned int i, argc = 0, alloc_len;
781 unsigned char *mem;
782 struct symbol_private *privbase;
783 struct storage *storage_base;
784 struct symbol *base_type = sym->ctype.base_type;
786 FOR_EACH_PTR(base_type->arguments, arg) {
787 argc++;
788 } END_FOR_EACH_PTR(arg);
790 alloc_len =
791 sizeof(*f) +
792 (argc * sizeof(struct symbol *)) +
793 (argc * sizeof(struct symbol_private)) +
794 (argc * sizeof(struct storage));
795 mem = calloc(1, alloc_len);
796 if (!mem)
797 die("OOM on func info");
799 f = (struct function *) mem;
800 mem += sizeof(*f);
801 f->argv = (struct symbol **) mem;
802 mem += (argc * sizeof(struct symbol *));
803 privbase = (struct symbol_private *) mem;
804 mem += (argc * sizeof(struct symbol_private));
805 storage_base = (struct storage *) mem;
807 f->argc = argc;
808 f->ret_target = new_label();
810 i = 0;
811 FOR_EACH_PTR(base_type->arguments, arg) {
812 f->argv[i] = arg;
813 arg->aux = &privbase[i];
814 storage_base[i].type = STOR_ARG;
815 storage_base[i].idx = i;
816 privbase[i].addr = &storage_base[i];
817 i++;
818 } END_FOR_EACH_PTR(arg);
820 assert(current_func == NULL);
821 current_func = f;
824 /* function epilogue */
825 static void emit_func_post(struct symbol *sym)
827 const char *name = show_ident(sym->ident);
828 struct function *f = current_func;
829 int stack_size = f->stack_size;
831 if (f->str_list)
832 emit_string_list(f);
834 /* function prologue */
835 emit_section(".text");
836 if ((sym->ctype.modifiers & MOD_STATIC) == 0)
837 printf(".globl %s\n", name);
838 printf("\t.type\t%s, @function\n", name);
839 printf("%s:\n", name);
841 if (stack_size) {
842 char pseudo_const[16];
844 sprintf(pseudo_const, "$%d", stack_size);
845 printf("\tsubl\t%s, %%esp\n", pseudo_const);
848 /* function epilogue */
850 /* jump target for 'return' statements */
851 emit_label(f->ret_target, NULL);
853 if (stack_size) {
854 struct storage *val;
856 val = new_storage(STOR_VALUE);
857 val->value = (long long) (stack_size);
858 val->flags = STOR_WANTS_FREE;
860 insn("addl", val, REG_ESP, NULL);
863 insn("ret", NULL, NULL, NULL);
865 /* output everything to stdout */
866 fflush(stdout); /* paranoia; needed? */
867 emit_atom_list(f);
869 /* function footer */
870 name = show_ident(sym->ident);
871 printf("\t.size\t%s, .-%s\n", name, name);
873 func_cleanup(f);
874 current_func = NULL;
877 /* emit object (a.k.a. variable, a.k.a. data) prologue */
878 static void emit_object_pre(const char *name, unsigned long modifiers,
879 unsigned long alignment, unsigned int byte_size)
881 if ((modifiers & MOD_STATIC) == 0)
882 printf(".globl %s\n", name);
883 emit_section(".data");
884 if (alignment)
885 printf("\t.align %lu\n", alignment);
886 printf("\t.type\t%s, @object\n", name);
887 printf("\t.size\t%s, %d\n", name, byte_size);
888 printf("%s:\n", name);
891 /* emit value (only) for an initializer scalar */
892 static void emit_scalar(struct expression *expr, unsigned int bit_size)
894 const char *type;
895 long long ll;
897 assert(expr->type == EXPR_VALUE);
899 if (expr->value == 0ULL) {
900 printf("\t.zero\t%d\n", bit_size / 8);
901 return;
904 ll = (long long) expr->value;
906 switch (bit_size) {
907 case 8: type = "byte"; ll = (char) ll; break;
908 case 16: type = "value"; ll = (short) ll; break;
909 case 32: type = "long"; ll = (int) ll; break;
910 case 64: type = "quad"; break;
911 default: type = NULL; break;
914 assert(type != NULL);
916 printf("\t.%s\t%Ld\n", type, ll);
919 static void emit_global_noinit(const char *name, unsigned long modifiers,
920 unsigned long alignment, unsigned int byte_size)
922 char s[64];
924 if (modifiers & MOD_STATIC) {
925 sprintf(s, "\t.local\t%s\n", name);
926 textbuf_push(&unit_post_text, s);
928 if (alignment)
929 sprintf(s, "\t.comm\t%s,%d,%lu\n", name, byte_size, alignment);
930 else
931 sprintf(s, "\t.comm\t%s,%d\n", name, byte_size);
932 textbuf_push(&unit_post_text, s);
935 static int ea_current, ea_last;
937 static void emit_initializer(struct symbol *sym,
938 struct expression *expr)
940 int distance = ea_current - ea_last - 1;
942 if (distance > 0)
943 printf("\t.zero\t%d\n", (sym->bit_size / 8) * distance);
945 if (expr->type == EXPR_VALUE) {
946 struct symbol *base_type = sym->ctype.base_type;
947 assert(base_type != NULL);
949 emit_scalar(expr, sym->bit_size / get_expression_value(base_type->array_size));
950 return;
952 if (expr->type != EXPR_INITIALIZER)
953 return;
955 assert(0); /* FIXME */
958 static int sort_array_cmp(const struct expression *a,
959 const struct expression *b)
961 int a_ofs = 0, b_ofs = 0;
963 if (a->type == EXPR_POS)
964 a_ofs = (int) a->init_offset;
965 if (b->type == EXPR_POS)
966 b_ofs = (int) b->init_offset;
968 return a_ofs - b_ofs;
971 /* move to front-end? */
972 static void sort_array(struct expression *expr)
974 struct expression *entry, **list;
975 unsigned int elem, sorted, i;
977 elem = 0;
978 FOR_EACH_PTR(expr->expr_list, entry) {
979 elem++;
980 } END_FOR_EACH_PTR(entry);
982 if (!elem)
983 return;
985 list = malloc(sizeof(entry) * elem);
986 if (!list)
987 die("OOM in sort_array");
989 /* this code is no doubt evil and ignores EXPR_INDEX possibly
990 * to its detriment and other nasty things. improvements
991 * welcome.
993 i = 0;
994 sorted = 0;
995 FOR_EACH_PTR(expr->expr_list, entry) {
996 if ((entry->type == EXPR_POS) || (entry->type == EXPR_VALUE)) {
997 /* add entry to list[], in sorted order */
998 if (sorted == 0) {
999 list[0] = entry;
1000 sorted = 1;
1001 } else {
1002 unsigned int i;
1004 for (i = 0; i < sorted; i++)
1005 if (sort_array_cmp(entry, list[i]) <= 0)
1006 break;
1008 /* If inserting into the middle of list[]
1009 * instead of appending, we memmove.
1010 * This is ugly, but thankfully
1011 * uncommon. Input data with tons of
1012 * entries very rarely have explicit
1013 * offsets. convert to qsort eventually...
1015 if (i != sorted)
1016 memmove(&list[i + 1], &list[i],
1017 (sorted - i) * sizeof(entry));
1018 list[i] = entry;
1019 sorted++;
1022 } END_FOR_EACH_PTR(entry);
1024 i = 0;
1025 FOR_EACH_PTR(expr->expr_list, entry) {
1026 if ((entry->type == EXPR_POS) || (entry->type == EXPR_VALUE))
1027 *THIS_ADDRESS(entry) = list[i++];
1028 } END_FOR_EACH_PTR(entry);
1032 static void emit_array(struct symbol *sym)
1034 struct symbol *base_type = sym->ctype.base_type;
1035 struct expression *expr = sym->initializer;
1036 struct expression *entry;
1038 assert(base_type != NULL);
1040 stor_sym_init(sym);
1042 ea_last = -1;
1044 emit_object_pre(show_ident(sym->ident), sym->ctype.modifiers,
1045 sym->ctype.alignment,
1046 sym->bit_size / 8);
1048 sort_array(expr);
1050 FOR_EACH_PTR(expr->expr_list, entry) {
1051 if (entry->type == EXPR_VALUE) {
1052 ea_current = 0;
1053 emit_initializer(sym, entry);
1054 ea_last = ea_current;
1055 } else if (entry->type == EXPR_POS) {
1056 ea_current =
1057 entry->init_offset / (base_type->bit_size / 8);
1058 emit_initializer(sym, entry->init_expr);
1059 ea_last = ea_current;
1061 } END_FOR_EACH_PTR(entry);
1064 void emit_one_symbol(struct symbol *sym)
1066 x86_symbol(sym);
1069 static void emit_copy(struct storage *dest, struct storage *src,
1070 struct symbol *ctype)
1072 struct storage *reg = NULL;
1073 unsigned int bit_size;
1075 /* FIXME: Bitfield copy! */
1077 bit_size = src->size * 8;
1078 if (!bit_size)
1079 bit_size = 32;
1080 if ((src->type == STOR_ARG) && (bit_size < 32))
1081 bit_size = 32;
1083 reg = temp_from_bits(bit_size);
1084 emit_move(src, reg, ctype, "begin copy ..");
1086 bit_size = dest->size * 8;
1087 if (!bit_size)
1088 bit_size = 32;
1089 if ((dest->type == STOR_ARG) && (bit_size < 32))
1090 bit_size = 32;
1092 emit_move(reg, dest, ctype, ".... end copy");
1093 put_reg(reg);
1096 static void emit_store(struct expression *dest_expr, struct storage *dest,
1097 struct storage *src, int bits)
1099 /* FIXME: Bitfield store! */
1100 printf("\tst.%d\t\tv%d,[v%d]\n", bits, src->pseudo, dest->pseudo);
1103 static void emit_scalar_noinit(struct symbol *sym)
1105 emit_global_noinit(show_ident(sym->ident),
1106 sym->ctype.modifiers, sym->ctype.alignment,
1107 sym->bit_size / 8);
1108 stor_sym_init(sym);
1111 static void emit_array_noinit(struct symbol *sym)
1113 emit_global_noinit(show_ident(sym->ident),
1114 sym->ctype.modifiers, sym->ctype.alignment,
1115 get_expression_value(sym->array_size) * (sym->bit_size / 8));
1116 stor_sym_init(sym);
1119 static const char *opbits(const char *insn, unsigned int bits)
1121 static char opbits_str[32];
1122 char c;
1124 switch (bits) {
1125 case 8: c = 'b'; break;
1126 case 16: c = 'w'; break;
1127 case 32: c = 'l'; break;
1128 case 64: c = 'q'; break;
1129 default: abort(); break;
1132 sprintf(opbits_str, "%s%c", insn, c);
1134 return opbits_str;
1137 static void emit_move(struct storage *src, struct storage *dest,
1138 struct symbol *ctype, const char *comment)
1140 unsigned int bits;
1141 unsigned int is_signed;
1142 unsigned int is_dest = (src->type == STOR_REG);
1143 const char *opname;
1145 if (ctype) {
1146 bits = ctype->bit_size;
1147 is_signed = type_is_signed(ctype);
1148 } else {
1149 bits = 32;
1150 is_signed = 0;
1154 * Are we moving from a register to a register?
1155 * Make the new reg to be the "cache".
1157 if ((dest->type == STOR_REG) && (src->type == STOR_REG)) {
1158 struct storage *backing;
1160 reg_reg_move:
1161 if (dest == src)
1162 return;
1164 backing = src->reg->contains;
1165 if (backing) {
1166 /* Is it still valid? */
1167 if (backing->reg != src->reg)
1168 backing = NULL;
1169 else
1170 backing->reg = dest->reg;
1172 dest->reg->contains = backing;
1173 insn("mov", src, dest, NULL);
1174 return;
1178 * Are we moving to a register from a non-reg?
1180 * See if we have the non-reg source already cached
1181 * in a register..
1183 if (dest->type == STOR_REG) {
1184 if (src->reg) {
1185 struct reg_info *info = src->reg;
1186 if (info->contains == src) {
1187 src = reginfo_reg(info);
1188 goto reg_reg_move;
1191 dest->reg->contains = src;
1192 src->reg = dest->reg;
1195 if (src->type == STOR_REG) {
1196 /* We could just mark the register dirty here and do lazy store.. */
1197 src->reg->contains = dest;
1198 dest->reg = src->reg;
1201 if ((bits == 8) || (bits == 16)) {
1202 if (is_dest)
1203 opname = "mov";
1204 else
1205 opname = is_signed ? "movsx" : "movzx";
1206 } else
1207 opname = "mov";
1209 insn(opbits(opname, bits), src, dest, comment);
1212 static struct storage *emit_compare(struct expression *expr)
1214 struct storage *left = x86_expression(expr->left);
1215 struct storage *right = x86_expression(expr->right);
1216 struct storage *reg1, *reg2;
1217 struct storage *new, *val;
1218 const char *opname = NULL;
1219 unsigned int right_bits = expr->right->ctype->bit_size;
1221 switch(expr->op) {
1222 case '<': opname = "setl"; break;
1223 case '>': opname = "setg"; break;
1224 case SPECIAL_LTE:
1225 opname = "setle"; break;
1226 case SPECIAL_GTE:
1227 opname = "setge"; break;
1228 case SPECIAL_EQUAL: opname = "sete"; break;
1229 case SPECIAL_NOTEQUAL: opname = "setne"; break;
1230 case SPECIAL_UNSIGNED_LT:
1231 opname = "setb"; break;
1232 case SPECIAL_UNSIGNED_GT:
1233 opname = "seta"; break;
1234 case SPECIAL_UNSIGNED_LTE:
1235 opname = "setb"; break;
1236 case SPECIAL_UNSIGNED_GTE:
1237 opname = "setae"; break;
1238 default:
1239 assert(0);
1240 break;
1243 /* init EDX to 0 */
1244 val = new_storage(STOR_VALUE);
1245 val->flags = STOR_WANTS_FREE;
1247 reg1 = get_reg(&regclass_32_8);
1248 emit_move(val, reg1, NULL, NULL);
1250 /* move op1 into EAX */
1251 reg2 = get_reg_value(left, get_regclass(expr->left));
1253 /* perform comparison, RHS (op1, right) and LHS (op2, EAX) */
1254 insn(opbits("cmp", right_bits), right, reg2, NULL);
1255 put_reg(reg2);
1257 /* store result of operation, 0 or 1, in DL using SETcc */
1258 insn(opname, byte_reg(reg1), NULL, NULL);
1260 /* finally, store the result (DL) in a new pseudo / stack slot */
1261 new = stack_alloc(4);
1262 emit_move(reg1, new, NULL, "end EXPR_COMPARE");
1263 put_reg(reg1);
1265 return new;
1268 static struct storage *emit_value(struct expression *expr)
1270 #if 0 /* old and slow way */
1271 struct storage *new = stack_alloc(4);
1272 struct storage *val;
1274 val = new_storage(STOR_VALUE);
1275 val->value = (long long) expr->value;
1276 val->flags = STOR_WANTS_FREE;
1277 insn("movl", val, new, NULL);
1279 return new;
1280 #else
1281 struct storage *val;
1283 val = new_storage(STOR_VALUE);
1284 val->value = (long long) expr->value;
1286 return val; /* FIXME: memory leak */
1287 #endif
1290 static struct storage *emit_divide(struct expression *expr, struct storage *left, struct storage *right)
1292 struct storage *eax_edx;
1293 struct storage *reg, *new;
1294 struct storage *val = new_storage(STOR_VALUE);
1296 emit_comment("begin DIVIDE");
1297 eax_edx = get_hardreg(hardreg_storage_table + EAX_EDX, 1);
1299 /* init EDX to 0 */
1300 val = new_storage(STOR_VALUE);
1301 val->flags = STOR_WANTS_FREE;
1302 emit_move(val, REG_EDX, NULL, NULL);
1304 new = stack_alloc(expr->ctype->bit_size / 8);
1306 /* EAX is dividend */
1307 emit_move(left, REG_EAX, NULL, NULL);
1309 reg = get_reg_value(right, &regclass_32);
1311 /* perform binop */
1312 insn("div", reg, REG_EAX, NULL);
1313 put_reg(reg);
1315 reg = REG_EAX;
1316 if (expr->op == '%')
1317 reg = REG_EDX;
1318 emit_move(reg, new, NULL, NULL);
1320 put_reg(eax_edx);
1321 emit_comment("end DIVIDE");
1322 return new;
1325 static struct storage *emit_binop(struct expression *expr)
1327 struct storage *left = x86_expression(expr->left);
1328 struct storage *right = x86_expression(expr->right);
1329 struct storage *new;
1330 struct storage *dest, *src;
1331 const char *opname = NULL;
1332 const char *suffix = NULL;
1333 char opstr[16];
1334 int is_signed;
1336 /* Divides have special register constraints */
1337 if ((expr->op == '/') || (expr->op == '%'))
1338 return emit_divide(expr, left, right);
1340 is_signed = type_is_signed(expr->ctype);
1342 switch (expr->op) {
1343 case '+':
1344 opname = "add";
1345 break;
1346 case '-':
1347 opname = "sub";
1348 break;
1349 case '&':
1350 opname = "and";
1351 break;
1352 case '|':
1353 opname = "or";
1354 break;
1355 case '^':
1356 opname = "xor";
1357 break;
1358 case SPECIAL_LEFTSHIFT:
1359 opname = "shl";
1360 break;
1361 case SPECIAL_RIGHTSHIFT:
1362 if (is_signed)
1363 opname = "sar";
1364 else
1365 opname = "shr";
1366 break;
1367 case '*':
1368 if (is_signed)
1369 opname = "imul";
1370 else
1371 opname = "mul";
1372 break;
1373 case SPECIAL_LOGICAL_AND:
1374 warning(expr->pos, "bogus bitwise and for logical op (should use '2*setne + and' or something)");
1375 opname = "and";
1376 break;
1377 case SPECIAL_LOGICAL_OR:
1378 warning(expr->pos, "bogus bitwise or for logical op (should use 'or + setne' or something)");
1379 opname = "or";
1380 break;
1381 default:
1382 error_die(expr->pos, "unhandled binop '%s'\n", show_special(expr->op));
1383 break;
1386 dest = get_reg_value(right, &regclass_32);
1387 src = get_reg_value(left, &regclass_32);
1388 switch (expr->ctype->bit_size) {
1389 case 8:
1390 suffix = "b";
1391 break;
1392 case 16:
1393 suffix = "w";
1394 break;
1395 case 32:
1396 suffix = "l";
1397 break;
1398 case 64:
1399 suffix = "q"; /* FIXME */
1400 break;
1401 default:
1402 assert(0);
1403 break;
1406 snprintf(opstr, sizeof(opstr), "%s%s", opname, suffix);
1408 /* perform binop */
1409 insn(opstr, src, dest, NULL);
1410 put_reg(src);
1412 /* store result in new pseudo / stack slot */
1413 new = stack_alloc(expr->ctype->bit_size / 8);
1414 emit_move(dest, new, NULL, "end EXPR_BINOP");
1416 put_reg(dest);
1418 return new;
1421 static int emit_conditional_test(struct storage *val)
1423 struct storage *reg;
1424 struct storage *target_val;
1425 int target_false;
1427 /* load result into EAX */
1428 emit_comment("begin if/conditional");
1429 reg = get_reg_value(val, &regclass_32);
1431 /* compare result with zero */
1432 insn("test", reg, reg, NULL);
1433 put_reg(reg);
1435 /* create conditional-failed label to jump to */
1436 target_false = new_label();
1437 target_val = new_storage(STOR_LABEL);
1438 target_val->label = target_false;
1439 target_val->flags = STOR_WANTS_FREE;
1440 insn("jz", target_val, NULL, NULL);
1442 return target_false;
1445 static int emit_conditional_end(int target_false)
1447 struct storage *cond_end_st;
1448 int cond_end;
1450 /* finished generating code for if-true statement.
1451 * add a jump-to-end jump to avoid falling through
1452 * to the if-false statement code.
1454 cond_end = new_label();
1455 cond_end_st = new_storage(STOR_LABEL);
1456 cond_end_st->label = cond_end;
1457 cond_end_st->flags = STOR_WANTS_FREE;
1458 insn("jmp", cond_end_st, NULL, NULL);
1460 /* if we have both if-true and if-false statements,
1461 * the failed-conditional case will fall through to here
1463 emit_label(target_false, NULL);
1465 return cond_end;
1468 static void emit_if_conditional(struct statement *stmt)
1470 struct storage *val;
1471 int cond_end;
1473 /* emit test portion of conditional */
1474 val = x86_expression(stmt->if_conditional);
1475 cond_end = emit_conditional_test(val);
1477 /* emit if-true statement */
1478 x86_statement(stmt->if_true);
1480 /* emit if-false statement, if present */
1481 if (stmt->if_false) {
1482 cond_end = emit_conditional_end(cond_end);
1483 x86_statement(stmt->if_false);
1486 /* end of conditional; jump target for if-true branch */
1487 emit_label(cond_end, "end if");
1490 static struct storage *emit_inc_dec(struct expression *expr, int postop)
1492 struct storage *addr = x86_address_gen(expr->unop);
1493 struct storage *retval;
1494 char opname[16];
1496 strcpy(opname, opbits(expr->op == SPECIAL_INCREMENT ? "inc" : "dec",
1497 expr->ctype->bit_size));
1499 if (postop) {
1500 struct storage *new = stack_alloc(4);
1502 emit_copy(new, addr, expr->unop->ctype);
1504 retval = new;
1505 } else
1506 retval = addr;
1508 insn(opname, addr, NULL, NULL);
1510 return retval;
1513 static struct storage *emit_postop(struct expression *expr)
1515 return emit_inc_dec(expr, 1);
1518 static struct storage *emit_return_stmt(struct statement *stmt)
1520 struct function *f = current_func;
1521 struct expression *expr = stmt->ret_value;
1522 struct storage *val = NULL, *jmplbl;
1524 if (expr && expr->ctype) {
1525 val = x86_expression(expr);
1526 assert(val != NULL);
1527 emit_move(val, REG_EAX, expr->ctype, "return");
1530 jmplbl = new_storage(STOR_LABEL);
1531 jmplbl->flags |= STOR_WANTS_FREE;
1532 jmplbl->label = f->ret_target;
1533 insn("jmp", jmplbl, NULL, NULL);
1535 return val;
1538 static struct storage *emit_conditional_expr(struct expression *expr)
1540 struct storage *cond, *true = NULL, *false = NULL;
1541 struct storage *new = stack_alloc(expr->ctype->bit_size / 8);
1542 int target_false, cond_end;
1544 /* evaluate conditional */
1545 cond = x86_expression(expr->conditional);
1546 target_false = emit_conditional_test(cond);
1548 /* handle if-true part of the expression */
1549 true = x86_expression(expr->cond_true);
1551 emit_copy(new, true, expr->ctype);
1553 cond_end = emit_conditional_end(target_false);
1555 /* handle if-false part of the expression */
1556 false = x86_expression(expr->cond_false);
1558 emit_copy(new, false, expr->ctype);
1560 /* end of conditional; jump target for if-true branch */
1561 emit_label(cond_end, "end conditional");
1563 return new;
1566 static struct storage *emit_select_expr(struct expression *expr)
1568 struct storage *cond = x86_expression(expr->conditional);
1569 struct storage *true = x86_expression(expr->cond_true);
1570 struct storage *false = x86_expression(expr->cond_false);
1571 struct storage *reg_cond, *reg_true, *reg_false;
1572 struct storage *new = stack_alloc(4);
1574 emit_comment("begin SELECT");
1575 reg_cond = get_reg_value(cond, get_regclass(expr->conditional));
1576 reg_true = get_reg_value(true, get_regclass(expr));
1577 reg_false = get_reg_value(false, get_regclass(expr));
1580 * Do the actual select: check the conditional for zero,
1581 * move false over true if zero
1583 insn("test", reg_cond, reg_cond, NULL);
1584 insn("cmovz", reg_false, reg_true, NULL);
1586 /* Store it back */
1587 emit_move(reg_true, new, expr->ctype, NULL);
1588 put_reg(reg_cond);
1589 put_reg(reg_true);
1590 put_reg(reg_false);
1591 emit_comment("end SELECT");
1592 return new;
1595 static struct storage *emit_symbol_expr_init(struct symbol *sym)
1597 struct expression *expr = sym->initializer;
1598 struct symbol_private *priv = sym->aux;
1600 if (priv == NULL) {
1601 priv = calloc(1, sizeof(*priv));
1602 sym->aux = priv;
1604 if (expr == NULL) {
1605 struct storage *new = stack_alloc(4);
1606 fprintf(stderr, "FIXME! no value for symbol %s. creating pseudo %d (stack offset %d)\n",
1607 show_ident(sym->ident),
1608 new->pseudo, new->pseudo * 4);
1609 priv->addr = new;
1610 } else {
1611 priv->addr = x86_expression(expr);
1615 return priv->addr;
1618 static struct storage *emit_string_expr(struct expression *expr)
1620 struct function *f = current_func;
1621 int label = new_label();
1622 struct storage *new;
1624 push_cstring(f, expr->string, label);
1626 new = new_storage(STOR_LABEL);
1627 new->label = label;
1628 new->flags = STOR_LABEL_VAL | STOR_WANTS_FREE;
1629 return new;
1632 static struct storage *emit_cast_expr(struct expression *expr)
1634 struct symbol *old_type, *new_type;
1635 struct storage *op = x86_expression(expr->cast_expression);
1636 int oldbits, newbits;
1637 struct storage *new;
1639 old_type = expr->cast_expression->ctype;
1640 new_type = expr->cast_type;
1642 oldbits = old_type->bit_size;
1643 newbits = new_type->bit_size;
1644 if (oldbits >= newbits)
1645 return op;
1647 emit_move(op, REG_EAX, old_type, "begin cast ..");
1649 new = stack_alloc(newbits / 8);
1650 emit_move(REG_EAX, new, new_type, ".... end cast");
1652 return new;
1655 static struct storage *emit_regular_preop(struct expression *expr)
1657 struct storage *target = x86_expression(expr->unop);
1658 struct storage *val, *new = stack_alloc(4);
1659 const char *opname = NULL;
1661 switch (expr->op) {
1662 case '!':
1663 val = new_storage(STOR_VALUE);
1664 val->flags = STOR_WANTS_FREE;
1665 emit_move(val, REG_EDX, NULL, NULL);
1666 emit_move(target, REG_EAX, expr->unop->ctype, NULL);
1667 insn("test", REG_EAX, REG_EAX, NULL);
1668 insn("setz", REG_DL, NULL, NULL);
1669 emit_move(REG_EDX, new, expr->unop->ctype, NULL);
1671 break;
1672 case '~':
1673 opname = "not";
1674 case '-':
1675 if (!opname)
1676 opname = "neg";
1677 emit_move(target, REG_EAX, expr->unop->ctype, NULL);
1678 insn(opname, REG_EAX, NULL, NULL);
1679 emit_move(REG_EAX, new, expr->unop->ctype, NULL);
1680 break;
1681 default:
1682 assert(0);
1683 break;
1686 return new;
1689 static void emit_case_statement(struct statement *stmt)
1691 emit_labelsym(stmt->case_label, NULL);
1692 x86_statement(stmt->case_statement);
1695 static void emit_switch_statement(struct statement *stmt)
1697 struct storage *val = x86_expression(stmt->switch_expression);
1698 struct symbol *sym, *default_sym = NULL;
1699 struct storage *labelsym, *label;
1700 int switch_end = 0;
1702 emit_move(val, REG_EAX, stmt->switch_expression->ctype, "begin case");
1705 * This is where a _real_ back-end would go through the
1706 * cases to decide whether to use a lookup table or a
1707 * series of comparisons etc
1709 FOR_EACH_PTR(stmt->switch_case->symbol_list, sym) {
1710 struct statement *case_stmt = sym->stmt;
1711 struct expression *expr = case_stmt->case_expression;
1712 struct expression *to = case_stmt->case_to;
1714 /* default: */
1715 if (!expr)
1716 default_sym = sym;
1718 /* case NNN: */
1719 else {
1720 struct storage *case_val = new_val(expr->value);
1722 assert (expr->type == EXPR_VALUE);
1724 insn("cmpl", case_val, REG_EAX, NULL);
1726 if (!to) {
1727 labelsym = new_labelsym(sym);
1728 insn("je", labelsym, NULL, NULL);
1729 } else {
1730 int next_test;
1732 label = new_storage(STOR_LABEL);
1733 label->flags |= STOR_WANTS_FREE;
1734 label->label = next_test = new_label();
1736 /* FIXME: signed/unsigned */
1737 insn("jl", label, NULL, NULL);
1739 case_val = new_val(to->value);
1740 insn("cmpl", case_val, REG_EAX, NULL);
1742 /* TODO: implement and use refcounting... */
1743 label = new_storage(STOR_LABEL);
1744 label->flags |= STOR_WANTS_FREE;
1745 label->label = next_test;
1747 /* FIXME: signed/unsigned */
1748 insn("jg", label, NULL, NULL);
1750 labelsym = new_labelsym(sym);
1751 insn("jmp", labelsym, NULL, NULL);
1753 emit_label(next_test, NULL);
1756 } END_FOR_EACH_PTR(sym);
1758 if (default_sym) {
1759 labelsym = new_labelsym(default_sym);
1760 insn("jmp", labelsym, NULL, "default");
1761 } else {
1762 label = new_storage(STOR_LABEL);
1763 label->flags |= STOR_WANTS_FREE;
1764 label->label = switch_end = new_label();
1765 insn("jmp", label, NULL, "goto end of switch");
1768 x86_statement(stmt->switch_statement);
1770 if (stmt->switch_break->used)
1771 emit_labelsym(stmt->switch_break, NULL);
1773 if (switch_end)
1774 emit_label(switch_end, NULL);
1777 static void x86_struct_member(struct symbol *sym)
1779 printf("\t%s:%d:%ld at offset %ld.%d", show_ident(sym->ident), sym->bit_size, sym->ctype.alignment, sym->offset, sym->bit_offset);
1780 printf("\n");
1783 static void x86_symbol(struct symbol *sym)
1785 struct symbol *type;
1787 if (!sym)
1788 return;
1790 type = sym->ctype.base_type;
1791 if (!type)
1792 return;
1795 * Show actual implementation information
1797 switch (type->type) {
1799 case SYM_ARRAY:
1800 if (sym->initializer)
1801 emit_array(sym);
1802 else
1803 emit_array_noinit(sym);
1804 break;
1806 case SYM_BASETYPE:
1807 if (sym->initializer) {
1808 emit_object_pre(show_ident(sym->ident),
1809 sym->ctype.modifiers,
1810 sym->ctype.alignment,
1811 sym->bit_size / 8);
1812 emit_scalar(sym->initializer, sym->bit_size);
1813 stor_sym_init(sym);
1814 } else
1815 emit_scalar_noinit(sym);
1816 break;
1818 case SYM_STRUCT:
1819 case SYM_UNION: {
1820 struct symbol *member;
1822 printf(" {\n");
1823 FOR_EACH_PTR(type->symbol_list, member) {
1824 x86_struct_member(member);
1825 } END_FOR_EACH_PTR(member);
1826 printf("}\n");
1827 break;
1830 case SYM_FN: {
1831 struct statement *stmt = type->stmt;
1832 if (stmt) {
1833 emit_func_pre(sym);
1834 x86_statement(stmt);
1835 emit_func_post(sym);
1837 break;
1840 default:
1841 break;
1844 if (sym->initializer && (type->type != SYM_BASETYPE) &&
1845 (type->type != SYM_ARRAY)) {
1846 printf(" = \n");
1847 x86_expression(sym->initializer);
1851 static void x86_symbol_init(struct symbol *sym);
1853 static void x86_symbol_decl(struct symbol_list *syms)
1855 struct symbol *sym;
1856 FOR_EACH_PTR(syms, sym) {
1857 x86_symbol_init(sym);
1858 } END_FOR_EACH_PTR(sym);
1861 static void loopstk_push(int cont_lbl, int loop_bottom_lbl)
1863 struct function *f = current_func;
1864 struct loop_stack *ls;
1866 ls = malloc(sizeof(*ls));
1867 ls->continue_lbl = cont_lbl;
1868 ls->loop_bottom_lbl = loop_bottom_lbl;
1869 ls->next = f->loop_stack;
1870 f->loop_stack = ls;
1873 static void loopstk_pop(void)
1875 struct function *f = current_func;
1876 struct loop_stack *ls;
1878 assert(f->loop_stack != NULL);
1879 ls = f->loop_stack;
1880 f->loop_stack = f->loop_stack->next;
1881 free(ls);
1884 static int loopstk_break(void)
1886 return current_func->loop_stack->loop_bottom_lbl;
1889 static int loopstk_continue(void)
1891 return current_func->loop_stack->continue_lbl;
1894 static void emit_loop(struct statement *stmt)
1896 struct statement *pre_statement = stmt->iterator_pre_statement;
1897 struct expression *pre_condition = stmt->iterator_pre_condition;
1898 struct statement *statement = stmt->iterator_statement;
1899 struct statement *post_statement = stmt->iterator_post_statement;
1900 struct expression *post_condition = stmt->iterator_post_condition;
1901 int loop_top = 0, loop_bottom, loop_continue;
1902 int have_bottom = 0;
1903 struct storage *val;
1905 loop_bottom = new_label();
1906 loop_continue = new_label();
1907 loopstk_push(loop_continue, loop_bottom);
1909 x86_symbol_decl(stmt->iterator_syms);
1910 x86_statement(pre_statement);
1911 if (pre_condition) {
1912 if (pre_condition->type == EXPR_VALUE) {
1913 if (!pre_condition->value) {
1914 struct storage *lbv;
1915 lbv = new_storage(STOR_LABEL);
1916 lbv->label = loop_bottom;
1917 lbv->flags = STOR_WANTS_FREE;
1918 insn("jmp", lbv, NULL, "go to loop bottom");
1919 have_bottom = 1;
1921 } else {
1922 struct storage *lbv = new_storage(STOR_LABEL);
1923 lbv->label = loop_bottom;
1924 lbv->flags = STOR_WANTS_FREE;
1925 have_bottom = 1;
1927 val = x86_expression(pre_condition);
1929 emit_move(val, REG_EAX, NULL, "loop pre condition");
1930 insn("test", REG_EAX, REG_EAX, NULL);
1931 insn("jz", lbv, NULL, NULL);
1934 if (!post_condition || post_condition->type != EXPR_VALUE || post_condition->value) {
1935 loop_top = new_label();
1936 emit_label(loop_top, "loop top");
1938 x86_statement(statement);
1939 if (stmt->iterator_continue->used)
1940 emit_label(loop_continue, "'continue' iterator");
1941 x86_statement(post_statement);
1942 if (!post_condition) {
1943 struct storage *lbv = new_storage(STOR_LABEL);
1944 lbv->label = loop_top;
1945 lbv->flags = STOR_WANTS_FREE;
1946 insn("jmp", lbv, NULL, "go to loop top");
1947 } else if (post_condition->type == EXPR_VALUE) {
1948 if (post_condition->value) {
1949 struct storage *lbv = new_storage(STOR_LABEL);
1950 lbv->label = loop_top;
1951 lbv->flags = STOR_WANTS_FREE;
1952 insn("jmp", lbv, NULL, "go to loop top");
1954 } else {
1955 struct storage *lbv = new_storage(STOR_LABEL);
1956 lbv->label = loop_top;
1957 lbv->flags = STOR_WANTS_FREE;
1959 val = x86_expression(post_condition);
1961 emit_move(val, REG_EAX, NULL, "loop post condition");
1962 insn("test", REG_EAX, REG_EAX, NULL);
1963 insn("jnz", lbv, NULL, NULL);
1965 if (have_bottom || stmt->iterator_break->used)
1966 emit_label(loop_bottom, "loop bottom");
1968 loopstk_pop();
1972 * Print out a statement
1974 static struct storage *x86_statement(struct statement *stmt)
1976 if (!stmt)
1977 return NULL;
1978 switch (stmt->type) {
1979 case STMT_RETURN:
1980 return emit_return_stmt(stmt);
1981 case STMT_COMPOUND: {
1982 struct statement *s;
1983 struct storage *last = NULL;
1985 x86_symbol_decl(stmt->syms);
1986 FOR_EACH_PTR(stmt->stmts, s) {
1987 last = x86_statement(s);
1988 } END_FOR_EACH_PTR(s);
1990 return last;
1993 case STMT_EXPRESSION:
1994 return x86_expression(stmt->expression);
1995 case STMT_IF:
1996 emit_if_conditional(stmt);
1997 return NULL;
1999 case STMT_CASE:
2000 emit_case_statement(stmt);
2001 break;
2002 case STMT_SWITCH:
2003 emit_switch_statement(stmt);
2004 break;
2006 case STMT_ITERATOR:
2007 emit_loop(stmt);
2008 break;
2010 case STMT_NONE:
2011 break;
2013 case STMT_LABEL:
2014 printf(".L%p:\n", stmt->label_identifier);
2015 x86_statement(stmt->label_statement);
2016 break;
2018 case STMT_GOTO:
2019 if (stmt->goto_expression) {
2020 struct storage *val = x86_expression(stmt->goto_expression);
2021 printf("\tgoto *v%d\n", val->pseudo);
2022 } else if (!strcmp("break", show_ident(stmt->goto_label->ident))) {
2023 struct storage *lbv = new_storage(STOR_LABEL);
2024 lbv->label = loopstk_break();
2025 lbv->flags = STOR_WANTS_FREE;
2026 insn("jmp", lbv, NULL, "'break'; go to loop bottom");
2027 } else if (!strcmp("continue", show_ident(stmt->goto_label->ident))) {
2028 struct storage *lbv = new_storage(STOR_LABEL);
2029 lbv->label = loopstk_continue();
2030 lbv->flags = STOR_WANTS_FREE;
2031 insn("jmp", lbv, NULL, "'continue'; go to loop top");
2032 } else {
2033 struct storage *labelsym = new_labelsym(stmt->goto_label);
2034 insn("jmp", labelsym, NULL, NULL);
2036 break;
2037 case STMT_ASM:
2038 printf("\tasm( .... )\n");
2039 break;
2041 return NULL;
2044 static struct storage *x86_call_expression(struct expression *expr)
2046 struct function *f = current_func;
2047 struct symbol *direct;
2048 struct expression *arg, *fn;
2049 struct storage *retval, *fncall;
2050 int framesize;
2051 char s[64];
2053 if (!expr->ctype) {
2054 warning(expr->pos, "\tcall with no type!");
2055 return NULL;
2058 framesize = 0;
2059 FOR_EACH_PTR_REVERSE(expr->args, arg) {
2060 struct storage *new = x86_expression(arg);
2061 int size = arg->ctype->bit_size;
2064 * FIXME: i386 SysV ABI dictates that values
2065 * smaller than 32 bits should be placed onto
2066 * the stack as 32-bit objects. We should not
2067 * blindly do a 32-bit push on objects smaller
2068 * than 32 bits.
2070 if (size < 32)
2071 size = 32;
2072 insn("pushl", new, NULL,
2073 !framesize ? "begin function call" : NULL);
2075 framesize += size >> 3;
2076 } END_FOR_EACH_PTR_REVERSE(arg);
2078 fn = expr->fn;
2080 /* Remove dereference, if any */
2081 direct = NULL;
2082 if (fn->type == EXPR_PREOP) {
2083 if (fn->unop->type == EXPR_SYMBOL) {
2084 struct symbol *sym = fn->unop->symbol;
2085 if (sym->ctype.base_type->type == SYM_FN)
2086 direct = sym;
2089 if (direct) {
2090 struct storage *direct_stor = new_storage(STOR_SYM);
2091 direct_stor->flags |= STOR_WANTS_FREE;
2092 direct_stor->sym = direct;
2093 insn("call", direct_stor, NULL, NULL);
2094 } else {
2095 fncall = x86_expression(fn);
2096 emit_move(fncall, REG_EAX, fn->ctype, NULL);
2098 strcpy(s, "\tcall\t*%eax\n");
2099 push_text_atom(f, s);
2102 /* FIXME: pay attention to BITS_IN_POINTER */
2103 if (framesize) {
2104 struct storage *val = new_storage(STOR_VALUE);
2105 val->value = (long long) framesize;
2106 val->flags = STOR_WANTS_FREE;
2107 insn("addl", val, REG_ESP, NULL);
2110 retval = stack_alloc(4);
2111 emit_move(REG_EAX, retval, NULL, "end function call");
2113 return retval;
2116 static struct storage *x86_address_gen(struct expression *expr)
2118 struct function *f = current_func;
2119 struct storage *addr;
2120 struct storage *new;
2121 char s[32];
2123 addr = x86_expression(expr->unop);
2124 if (expr->unop->type == EXPR_SYMBOL)
2125 return addr;
2127 emit_move(addr, REG_EAX, NULL, "begin deref ..");
2129 /* FIXME: operand size */
2130 strcpy(s, "\tmovl\t(%eax), %ecx\n");
2131 push_text_atom(f, s);
2133 new = stack_alloc(4);
2134 emit_move(REG_ECX, new, NULL, ".... end deref");
2136 return new;
2139 static struct storage *x86_assignment(struct expression *expr)
2141 struct expression *target = expr->left;
2142 struct storage *val, *addr;
2144 if (!expr->ctype)
2145 return NULL;
2147 val = x86_expression(expr->right);
2148 addr = x86_address_gen(target);
2150 switch (val->type) {
2151 /* copy, where both operands are memory */
2152 case STOR_PSEUDO:
2153 case STOR_ARG:
2154 emit_copy(addr, val, expr->ctype);
2155 break;
2157 /* copy, one or zero operands are memory */
2158 case STOR_REG:
2159 case STOR_SYM:
2160 case STOR_VALUE:
2161 case STOR_LABEL:
2162 emit_move(val, addr, expr->left->ctype, NULL);
2163 break;
2165 case STOR_LABELSYM:
2166 assert(0);
2167 break;
2169 return val;
2172 static int x86_initialization(struct symbol *sym, struct expression *expr)
2174 struct storage *val, *addr;
2175 int bits;
2177 if (!expr->ctype)
2178 return 0;
2180 bits = expr->ctype->bit_size;
2181 val = x86_expression(expr);
2182 addr = x86_symbol_expr(sym);
2183 // FIXME! The "target" expression is for bitfield store information.
2184 // Leave it NULL, which works fine.
2185 emit_store(NULL, addr, val, bits);
2186 return 0;
2189 static struct storage *x86_access(struct expression *expr)
2191 return x86_address_gen(expr);
2194 static struct storage *x86_preop(struct expression *expr)
2197 * '*' is an lvalue access, and is fundamentally different
2198 * from an arithmetic operation. Maybe it should have an
2199 * expression type of its own..
2201 if (expr->op == '*')
2202 return x86_access(expr);
2203 if (expr->op == SPECIAL_INCREMENT || expr->op == SPECIAL_DECREMENT)
2204 return emit_inc_dec(expr, 0);
2205 return emit_regular_preop(expr);
2208 static struct storage *x86_symbol_expr(struct symbol *sym)
2210 struct storage *new = stack_alloc(4);
2212 if (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_EXTERN | MOD_STATIC)) {
2213 printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer, new->pseudo, show_ident(sym->ident));
2214 return new;
2216 if (sym->ctype.modifiers & MOD_ADDRESSABLE) {
2217 printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer, new->pseudo, sym->value);
2218 return new;
2220 printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer, new->pseudo, show_ident(sym->ident), sym);
2221 return new;
2224 static void x86_symbol_init(struct symbol *sym)
2226 struct symbol_private *priv = sym->aux;
2227 struct expression *expr = sym->initializer;
2228 struct storage *new;
2230 if (expr)
2231 new = x86_expression(expr);
2232 else
2233 new = stack_alloc(sym->bit_size / 8);
2235 if (!priv) {
2236 priv = calloc(1, sizeof(*priv));
2237 sym->aux = priv;
2238 /* FIXME: leak! we don't free... */
2239 /* (well, we don't free symbols either) */
2242 priv->addr = new;
2245 static int type_is_signed(struct symbol *sym)
2247 if (sym->type == SYM_NODE)
2248 sym = sym->ctype.base_type;
2249 if (sym->type == SYM_PTR)
2250 return 0;
2251 return !(sym->ctype.modifiers & MOD_UNSIGNED);
2254 static struct storage *x86_label_expr(struct expression *expr)
2256 struct storage *new = stack_alloc(4);
2257 printf("\tmovi.%d\t\tv%d,.L%p\n", bits_in_pointer, new->pseudo, expr->label_symbol);
2258 return new;
2261 static struct storage *x86_statement_expr(struct expression *expr)
2263 return x86_statement(expr->statement);
2266 static int x86_position_expr(struct expression *expr, struct symbol *base)
2268 struct storage *new = x86_expression(expr->init_expr);
2269 struct symbol *ctype = expr->init_expr->ctype;
2271 printf("\tinsert v%d at [%d:%d] of %s\n", new->pseudo,
2272 expr->init_offset, ctype->bit_offset,
2273 show_ident(base->ident));
2274 return 0;
2277 static void x86_initializer_expr(struct expression *expr, struct symbol *ctype)
2279 struct expression *entry;
2281 FOR_EACH_PTR(expr->expr_list, entry) {
2282 // Nested initializers have their positions already
2283 // recursively calculated - just output them too
2284 if (entry->type == EXPR_INITIALIZER) {
2285 x86_initializer_expr(entry, ctype);
2286 continue;
2289 // Ignore initializer indexes and identifiers - the
2290 // evaluator has taken them into account
2291 if (entry->type == EXPR_IDENTIFIER || entry->type == EXPR_INDEX)
2292 continue;
2293 if (entry->type == EXPR_POS) {
2294 x86_position_expr(entry, ctype);
2295 continue;
2297 x86_initialization(ctype, entry);
2298 } END_FOR_EACH_PTR(entry);
2302 * Print out an expression. Return the pseudo that contains the
2303 * variable.
2305 static struct storage *x86_expression(struct expression *expr)
2307 if (!expr)
2308 return NULL;
2310 if (!expr->ctype) {
2311 struct position *pos = &expr->pos;
2312 printf("\tno type at %s:%d:%d\n",
2313 input_streams[pos->stream].name,
2314 pos->line, pos->pos);
2315 return NULL;
2318 switch (expr->type) {
2319 case EXPR_CALL:
2320 return x86_call_expression(expr);
2322 case EXPR_ASSIGNMENT:
2323 return x86_assignment(expr);
2325 case EXPR_COMPARE:
2326 return emit_compare(expr);
2327 case EXPR_BINOP:
2328 case EXPR_COMMA:
2329 case EXPR_LOGICAL:
2330 return emit_binop(expr);
2331 case EXPR_PREOP:
2332 return x86_preop(expr);
2333 case EXPR_POSTOP:
2334 return emit_postop(expr);
2335 case EXPR_SYMBOL:
2336 return emit_symbol_expr_init(expr->symbol);
2337 case EXPR_DEREF:
2338 case EXPR_SIZEOF:
2339 case EXPR_ALIGNOF:
2340 warning(expr->pos, "invalid expression after evaluation");
2341 return NULL;
2342 case EXPR_CAST:
2343 case EXPR_IMPLIED_CAST:
2344 return emit_cast_expr(expr);
2345 case EXPR_VALUE:
2346 return emit_value(expr);
2347 case EXPR_STRING:
2348 return emit_string_expr(expr);
2349 case EXPR_INITIALIZER:
2350 x86_initializer_expr(expr, expr->ctype);
2351 return NULL;
2352 case EXPR_SELECT:
2353 return emit_select_expr(expr);
2354 case EXPR_CONDITIONAL:
2355 return emit_conditional_expr(expr);
2356 case EXPR_STATEMENT:
2357 return x86_statement_expr(expr);
2358 case EXPR_LABEL:
2359 return x86_label_expr(expr);
2361 // None of these should exist as direct expressions: they are only
2362 // valid as sub-expressions of initializers.
2363 case EXPR_POS:
2364 warning(expr->pos, "unable to show plain initializer position expression");
2365 return NULL;
2366 case EXPR_IDENTIFIER:
2367 warning(expr->pos, "unable to show identifier expression");
2368 return NULL;
2369 case EXPR_INDEX:
2370 warning(expr->pos, "unable to show index expression");
2371 return NULL;
2372 case EXPR_TYPE:
2373 warning(expr->pos, "unable to show type expression");
2374 return NULL;
2375 case EXPR_FVALUE:
2376 warning(expr->pos, "floating point support is not implemented");
2377 return NULL;
2379 return NULL;