extra: revert the mod_expr changes for modify expression hooks
[smatch.git] / compile-i386.c
blob16b3893a4ef1c4a94ec18b558d9d775500d58630
1 /*
2 * sparse/compile-i386.c
4 * Copyright (C) 2003 Transmeta Corp.
5 * 2003 Linus Torvalds
6 * Copyright 2003 Jeff Garzik
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:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
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.
26 * x86 backend
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
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>
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"
61 struct textbuf {
62 unsigned int len; /* does NOT include terminating null */
63 char *text;
64 struct textbuf *next;
65 struct textbuf *prev;
68 struct loop_stack {
69 int continue_lbl;
70 int loop_bottom_lbl;
71 struct loop_stack *next;
74 struct atom;
75 struct storage;
76 DECLARE_PTR_LIST(str_list, struct atom);
77 DECLARE_PTR_LIST(atom_list, struct atom);
78 DECLARE_PTR_LIST(storage_list, struct storage);
80 struct function {
81 int stack_size;
82 int pseudo_nr;
83 struct storage_list *pseudo_list;
84 struct atom_list *atom_list;
85 struct str_list *str_list;
86 struct loop_stack *loop_stack;
87 struct symbol **argv;
88 unsigned int argc;
89 int ret_target;
92 enum storage_type {
93 STOR_PSEUDO, /* variable stored on the stack */
94 STOR_ARG, /* function argument */
95 STOR_SYM, /* a symbol we can directly ref in the asm */
96 STOR_REG, /* scratch register */
97 STOR_VALUE, /* integer constant */
98 STOR_LABEL, /* label / jump target */
99 STOR_LABELSYM, /* label generated from symbol's pointer value */
102 struct reg_info {
103 const char *name;
104 struct storage *contains;
105 const unsigned char aliases[12];
106 #define own_regno aliases[0]
109 struct storage {
110 enum storage_type type;
111 unsigned long flags;
113 /* STOR_REG */
114 struct reg_info *reg;
115 struct symbol *ctype;
117 union {
118 /* STOR_PSEUDO */
119 struct {
120 int pseudo;
121 int offset;
122 int size;
124 /* STOR_ARG */
125 struct {
126 int idx;
128 /* STOR_SYM */
129 struct {
130 struct symbol *sym;
132 /* STOR_VALUE */
133 struct {
134 long long value;
136 /* STOR_LABEL */
137 struct {
138 int label;
140 /* STOR_LABELSYM */
141 struct {
142 struct symbol *labelsym;
147 enum {
148 STOR_LABEL_VAL = (1 << 0),
149 STOR_WANTS_FREE = (1 << 1),
152 struct symbol_private {
153 struct storage *addr;
156 enum atom_type {
157 ATOM_TEXT,
158 ATOM_INSN,
159 ATOM_CSTR,
162 struct atom {
163 enum atom_type type;
164 union {
165 /* stuff for text */
166 struct {
167 char *text;
168 unsigned int text_len; /* w/o terminating null */
171 /* stuff for insns */
172 struct {
173 char insn[32];
174 char comment[40];
175 struct storage *op1;
176 struct storage *op2;
179 /* stuff for C strings */
180 struct {
181 struct string *string;
182 int label;
188 static struct function *current_func = NULL;
189 static struct textbuf *unit_post_text = NULL;
190 static const char *current_section;
192 static void emit_comment(const char * fmt, ...) FORMAT_ATTR(1);
193 static void emit_move(struct storage *src, struct storage *dest,
194 struct symbol *ctype, const char *comment);
195 static struct storage *x86_address_gen(struct expression *expr);
196 static struct storage *x86_symbol_expr(struct symbol *sym);
197 static void x86_symbol(struct symbol *sym);
198 static struct storage *x86_statement(struct statement *stmt);
199 static struct storage *x86_expression(struct expression *expr);
201 enum registers {
202 NOREG,
203 AL, DL, CL, BL, AH, DH, CH, BH, // 8-bit
204 AX, DX, CX, BX, SI, DI, BP, SP, // 16-bit
205 EAX, EDX, ECX, EBX, ESI, EDI, EBP, ESP, // 32-bit
206 EAX_EDX, ECX_EBX, ESI_EDI, // 64-bit
209 /* This works on regno's, reg_info's and hardreg_storage's */
210 #define byte_reg(reg) ((reg) - 16)
211 #define highbyte_reg(reg) ((reg)-12)
212 #define word_reg(reg) ((reg)-8)
214 #define REGINFO(nr, str, conflicts...) [nr] = { .name = str, .aliases = { nr , conflicts } }
216 static struct reg_info reg_info_table[] = {
217 REGINFO( AL, "%al", AX, EAX, EAX_EDX),
218 REGINFO( DL, "%dl", DX, EDX, EAX_EDX),
219 REGINFO( CL, "%cl", CX, ECX, ECX_EBX),
220 REGINFO( BL, "%bl", BX, EBX, ECX_EBX),
221 REGINFO( AH, "%ah", AX, EAX, EAX_EDX),
222 REGINFO( DH, "%dh", DX, EDX, EAX_EDX),
223 REGINFO( CH, "%ch", CX, ECX, ECX_EBX),
224 REGINFO( BH, "%bh", BX, EBX, ECX_EBX),
225 REGINFO( AX, "%ax", AL, AH, EAX, EAX_EDX),
226 REGINFO( DX, "%dx", DL, DH, EDX, EAX_EDX),
227 REGINFO( CX, "%cx", CL, CH, ECX, ECX_EBX),
228 REGINFO( BX, "%bx", BL, BH, EBX, ECX_EBX),
229 REGINFO( SI, "%si", ESI, ESI_EDI),
230 REGINFO( DI, "%di", EDI, ESI_EDI),
231 REGINFO( BP, "%bp", EBP),
232 REGINFO( SP, "%sp", ESP),
233 REGINFO(EAX, "%eax", AL, AH, AX, EAX_EDX),
234 REGINFO(EDX, "%edx", DL, DH, DX, EAX_EDX),
235 REGINFO(ECX, "%ecx", CL, CH, CX, ECX_EBX),
236 REGINFO(EBX, "%ebx", BL, BH, BX, ECX_EBX),
237 REGINFO(ESI, "%esi", SI, ESI_EDI),
238 REGINFO(EDI, "%edi", DI, ESI_EDI),
239 REGINFO(EBP, "%ebp", BP),
240 REGINFO(ESP, "%esp", SP),
241 REGINFO(EAX_EDX, "%eax:%edx", AL, AH, AX, EAX, DL, DH, DX, EDX),
242 REGINFO(ECX_EBX, "%ecx:%ebx", CL, CH, CX, ECX, BL, BH, BX, EBX),
243 REGINFO(ESI_EDI, "%esi:%edi", SI, ESI, DI, EDI),
246 #define REGSTORAGE(nr) [nr] = { .type = STOR_REG, .reg = reg_info_table + (nr) }
248 static struct storage hardreg_storage_table[] = {
249 REGSTORAGE(AL), REGSTORAGE(DL), REGSTORAGE(CL), REGSTORAGE(BL),
250 REGSTORAGE(AH), REGSTORAGE(DH), REGSTORAGE(CH), REGSTORAGE(BH),
251 REGSTORAGE(AX), REGSTORAGE(DX), REGSTORAGE(CX), REGSTORAGE(BX),
252 REGSTORAGE(SI), REGSTORAGE(DI), REGSTORAGE(BP), REGSTORAGE(SP),
253 REGSTORAGE(EAX), REGSTORAGE(EDX), REGSTORAGE(ECX), REGSTORAGE(EBX),
254 REGSTORAGE(ESI), REGSTORAGE(EDI), REGSTORAGE(EBP), REGSTORAGE(ESP),
255 REGSTORAGE(EAX_EDX), REGSTORAGE(ECX_EBX), REGSTORAGE(ESI_EDI),
258 #define REG_EAX (&hardreg_storage_table[EAX])
259 #define REG_ECX (&hardreg_storage_table[ECX])
260 #define REG_EDX (&hardreg_storage_table[EDX])
261 #define REG_ESP (&hardreg_storage_table[ESP])
262 #define REG_DL (&hardreg_storage_table[DL])
263 #define REG_DX (&hardreg_storage_table[DX])
264 #define REG_AL (&hardreg_storage_table[AL])
265 #define REG_AX (&hardreg_storage_table[AX])
267 static DECLARE_BITMAP(regs_in_use, 256);
269 static inline struct storage * reginfo_reg(struct reg_info *info)
271 return hardreg_storage_table + info->own_regno;
274 static struct storage * get_hardreg(struct storage *reg, int clear)
276 struct reg_info *info = reg->reg;
277 const unsigned char *aliases;
278 int regno;
280 aliases = info->aliases;
281 while ((regno = *aliases++) != NOREG) {
282 if (test_bit(regno, regs_in_use))
283 goto busy;
284 if (clear)
285 reg_info_table[regno].contains = NULL;
287 set_bit(info->own_regno, regs_in_use);
288 return reg;
289 busy:
290 fprintf(stderr, "register %s is busy\n", info->name);
291 if (regno + reg_info_table != info)
292 fprintf(stderr, " conflicts with %s\n", reg_info_table[regno].name);
293 exit(1);
296 static void put_reg(struct storage *reg)
298 struct reg_info *info = reg->reg;
299 int regno = info->own_regno;
301 if (test_and_clear_bit(regno, regs_in_use))
302 return;
303 fprintf(stderr, "freeing already free'd register %s\n", reg_info_table[regno].name);
306 struct regclass {
307 const char *name;
308 const unsigned char regs[30];
311 static struct regclass regclass_8 = { "8-bit", { AL, DL, CL, BL, AH, DH, CH, BH }};
312 static struct regclass regclass_16 = { "16-bit", { AX, DX, CX, BX, SI, DI, BP }};
313 static struct regclass regclass_32 = { "32-bit", { EAX, EDX, ECX, EBX, ESI, EDI, EBP }};
314 static struct regclass regclass_64 = { "64-bit", { EAX_EDX, ECX_EBX, ESI_EDI }};
316 static struct regclass regclass_32_8 = { "32-bit bytes", { EAX, EDX, ECX, EBX }};
318 static struct regclass *get_regclass_bits(int bits)
320 switch (bits) {
321 case 8: return &regclass_8;
322 case 16: return &regclass_16;
323 case 64: return &regclass_64;
324 default: return &regclass_32;
328 static struct regclass *get_regclass(struct expression *expr)
330 return get_regclass_bits(expr->ctype->bit_size);
333 static int register_busy(int regno)
335 if (!test_bit(regno, regs_in_use)) {
336 struct reg_info *info = reg_info_table + regno;
337 const unsigned char *regs = info->aliases+1;
339 while ((regno = *regs) != NOREG) {
340 regs++;
341 if (test_bit(regno, regs_in_use))
342 goto busy;
344 return 0;
346 busy:
347 return 1;
350 static struct storage *get_reg(struct regclass *class)
352 const unsigned char *regs = class->regs;
353 int regno;
355 while ((regno = *regs) != NOREG) {
356 regs++;
357 if (register_busy(regno))
358 continue;
359 return get_hardreg(hardreg_storage_table + regno, 1);
361 fprintf(stderr, "Ran out of %s registers\n", class->name);
362 exit(1);
365 static struct storage *get_reg_value(struct storage *value, struct regclass *class)
367 struct reg_info *info;
368 struct storage *reg;
370 /* Do we already have it somewhere */
371 info = value->reg;
372 if (info && info->contains == value) {
373 emit_comment("already have register %s", info->name);
374 return get_hardreg(hardreg_storage_table + info->own_regno, 0);
377 reg = get_reg(class);
378 emit_move(value, reg, value->ctype, "reload register");
379 info = reg->reg;
380 info->contains = value;
381 value->reg = info;
382 return reg;
385 static struct storage *temp_from_bits(unsigned int bit_size)
387 return get_reg(get_regclass_bits(bit_size));
390 static inline unsigned int pseudo_offset(struct storage *s)
392 if (s->type != STOR_PSEUDO)
393 return 123456; /* intentionally bogus value */
395 return s->offset;
398 static inline unsigned int arg_offset(struct storage *s)
400 if (s->type != STOR_ARG)
401 return 123456; /* intentionally bogus value */
403 /* FIXME: this is wrong wrong wrong */
404 return current_func->stack_size + ((1 + s->idx) * 4);
407 static const char *pretty_offset(int ofs)
409 static char esp_buf[64];
411 if (ofs)
412 sprintf(esp_buf, "%d(%%esp)", ofs);
413 else
414 strcpy(esp_buf, "(%esp)");
416 return esp_buf;
419 static void stor_sym_init(struct symbol *sym)
421 struct storage *stor;
422 struct symbol_private *priv;
424 priv = calloc(1, sizeof(*priv) + sizeof(*stor));
425 if (!priv)
426 die("OOM in stor_sym_init");
428 stor = (struct storage *) (priv + 1);
430 priv->addr = stor;
431 stor->type = STOR_SYM;
432 stor->sym = sym;
435 static const char *stor_op_name(struct storage *s)
437 static char name[32];
439 switch (s->type) {
440 case STOR_PSEUDO:
441 strcpy(name, pretty_offset((int) pseudo_offset(s)));
442 break;
443 case STOR_ARG:
444 strcpy(name, pretty_offset((int) arg_offset(s)));
445 break;
446 case STOR_SYM:
447 strcpy(name, show_ident(s->sym->ident));
448 break;
449 case STOR_REG:
450 strcpy(name, s->reg->name);
451 break;
452 case STOR_VALUE:
453 sprintf(name, "$%lld", s->value);
454 break;
455 case STOR_LABEL:
456 sprintf(name, "%s.L%d", s->flags & STOR_LABEL_VAL ? "$" : "",
457 s->label);
458 break;
459 case STOR_LABELSYM:
460 sprintf(name, "%s.LS%p", s->flags & STOR_LABEL_VAL ? "$" : "",
461 s->labelsym);
462 break;
465 return name;
468 static struct atom *new_atom(enum atom_type type)
470 struct atom *atom;
472 atom = calloc(1, sizeof(*atom)); /* TODO: chunked alloc */
473 if (!atom)
474 die("nuclear OOM");
476 atom->type = type;
478 return atom;
481 static inline void push_cstring(struct function *f, struct string *str,
482 int label)
484 struct atom *atom;
486 atom = new_atom(ATOM_CSTR);
487 atom->string = str;
488 atom->label = label;
490 add_ptr_list(&f->str_list, atom); /* note: _not_ atom_list */
493 static inline void push_atom(struct function *f, struct atom *atom)
495 add_ptr_list(&f->atom_list, atom);
498 static void push_text_atom(struct function *f, const char *text)
500 struct atom *atom = new_atom(ATOM_TEXT);
502 atom->text = strdup(text);
503 atom->text_len = strlen(text);
505 push_atom(f, atom);
508 static struct storage *new_storage(enum storage_type type)
510 struct storage *stor;
512 stor = calloc(1, sizeof(*stor));
513 if (!stor)
514 die("OOM in new_storage");
516 stor->type = type;
518 return stor;
521 static struct storage *stack_alloc(int n_bytes)
523 struct function *f = current_func;
524 struct storage *stor;
526 assert(f != NULL);
528 stor = new_storage(STOR_PSEUDO);
529 stor->type = STOR_PSEUDO;
530 stor->pseudo = f->pseudo_nr;
531 stor->offset = f->stack_size; /* FIXME: stack req. natural align */
532 stor->size = n_bytes;
533 f->stack_size += n_bytes;
534 f->pseudo_nr++;
536 add_ptr_list(&f->pseudo_list, stor);
538 return stor;
541 static struct storage *new_labelsym(struct symbol *sym)
543 struct storage *stor;
545 stor = new_storage(STOR_LABELSYM);
547 if (stor) {
548 stor->flags |= STOR_WANTS_FREE;
549 stor->labelsym = sym;
552 return stor;
555 static struct storage *new_val(long long value)
557 struct storage *stor;
559 stor = new_storage(STOR_VALUE);
561 if (stor) {
562 stor->flags |= STOR_WANTS_FREE;
563 stor->value = value;
566 return stor;
569 static int new_label(void)
571 static int label = 0;
572 return ++label;
575 static void textbuf_push(struct textbuf **buf_p, const char *text)
577 struct textbuf *tmp, *list = *buf_p;
578 unsigned int text_len = strlen(text);
579 unsigned int alloc_len = text_len + 1 + sizeof(*list);
581 tmp = calloc(1, alloc_len);
582 if (!tmp)
583 die("OOM on textbuf alloc");
585 tmp->text = ((void *) tmp) + sizeof(*tmp);
586 memcpy(tmp->text, text, text_len + 1);
587 tmp->len = text_len;
589 /* add to end of list */
590 if (!list) {
591 list = tmp;
592 tmp->prev = tmp;
593 } else {
594 tmp->prev = list->prev;
595 tmp->prev->next = tmp;
596 list->prev = tmp;
598 tmp->next = list;
600 *buf_p = list;
603 static void textbuf_emit(struct textbuf **buf_p)
605 struct textbuf *tmp, *list = *buf_p;
607 while (list) {
608 tmp = list;
609 if (tmp->next == tmp)
610 list = NULL;
611 else {
612 tmp->prev->next = tmp->next;
613 tmp->next->prev = tmp->prev;
614 list = tmp->next;
617 fputs(tmp->text, stdout);
619 free(tmp);
622 *buf_p = list;
625 static void insn(const char *insn, struct storage *op1, struct storage *op2,
626 const char *comment_in)
628 struct function *f = current_func;
629 struct atom *atom = new_atom(ATOM_INSN);
631 assert(insn != NULL);
633 strcpy(atom->insn, insn);
634 if (comment_in && (*comment_in))
635 strncpy(atom->comment, comment_in,
636 sizeof(atom->comment) - 1);
638 atom->op1 = op1;
639 atom->op2 = op2;
641 push_atom(f, atom);
644 static void emit_comment(const char *fmt, ...)
646 struct function *f = current_func;
647 static char tmpbuf[100] = "\t# ";
648 va_list args;
649 int i;
651 va_start(args, fmt);
652 i = vsnprintf(tmpbuf+3, sizeof(tmpbuf)-4, fmt, args);
653 va_end(args);
654 tmpbuf[i+3] = '\n';
655 tmpbuf[i+4] = '\0';
656 push_text_atom(f, tmpbuf);
659 static void emit_label (int label, const char *comment)
661 struct function *f = current_func;
662 char s[64];
664 if (!comment)
665 sprintf(s, ".L%d:\n", label);
666 else
667 sprintf(s, ".L%d:\t\t\t\t\t# %s\n", label, comment);
669 push_text_atom(f, s);
672 static void emit_labelsym (struct symbol *sym, const char *comment)
674 struct function *f = current_func;
675 char s[64];
677 if (!comment)
678 sprintf(s, ".LS%p:\n", sym);
679 else
680 sprintf(s, ".LS%p:\t\t\t\t# %s\n", sym, comment);
682 push_text_atom(f, s);
685 void emit_unit_begin(const char *basename)
687 printf("\t.file\t\"%s\"\n", basename);
690 void emit_unit_end(void)
692 textbuf_emit(&unit_post_text);
693 printf("\t.ident\t\"sparse silly x86 backend (version %s)\"\n", sparse_version);
696 /* conditionally switch sections */
697 static void emit_section(const char *s)
699 if (s == current_section)
700 return;
701 if (current_section && (!strcmp(s, current_section)))
702 return;
704 printf("\t%s\n", s);
705 current_section = s;
708 static void emit_insn_atom(struct function *f, struct atom *atom)
710 char s[128];
711 char comment[64];
712 struct storage *op1 = atom->op1;
713 struct storage *op2 = atom->op2;
715 if (atom->comment[0])
716 sprintf(comment, "\t\t# %s", atom->comment);
717 else
718 comment[0] = 0;
720 if (atom->op2) {
721 char tmp[16];
722 strcpy(tmp, stor_op_name(op1));
723 sprintf(s, "\t%s\t%s, %s%s\n",
724 atom->insn, tmp, stor_op_name(op2), comment);
725 } else if (atom->op1)
726 sprintf(s, "\t%s\t%s%s%s\n",
727 atom->insn, stor_op_name(op1),
728 comment[0] ? "\t" : "", comment);
729 else
730 sprintf(s, "\t%s\t%s%s\n",
731 atom->insn,
732 comment[0] ? "\t\t" : "", comment);
734 if (write(STDOUT_FILENO, s, strlen(s)) < 0)
735 die("can't write to stdout");
738 static void emit_atom_list(struct function *f)
740 struct atom *atom;
742 FOR_EACH_PTR(f->atom_list, atom) {
743 switch (atom->type) {
744 case ATOM_TEXT: {
745 if (write(STDOUT_FILENO, atom->text, atom->text_len) < 0)
746 die("can't write to stdout");
747 break;
749 case ATOM_INSN:
750 emit_insn_atom(f, atom);
751 break;
752 case ATOM_CSTR:
753 assert(0);
754 break;
756 } END_FOR_EACH_PTR(atom);
759 static void emit_string_list(struct function *f)
761 struct atom *atom;
763 emit_section(".section\t.rodata");
765 FOR_EACH_PTR(f->str_list, atom) {
766 /* FIXME: escape " in string */
767 printf(".L%d:\n", atom->label);
768 printf("\t.string\t%s\n", show_string(atom->string));
770 free(atom);
771 } END_FOR_EACH_PTR(atom);
774 static void func_cleanup(struct function *f)
776 struct storage *stor;
777 struct atom *atom;
779 FOR_EACH_PTR(f->atom_list, atom) {
780 if ((atom->type == ATOM_TEXT) && (atom->text))
781 free(atom->text);
782 if (atom->op1 && (atom->op1->flags & STOR_WANTS_FREE))
783 free(atom->op1);
784 if (atom->op2 && (atom->op2->flags & STOR_WANTS_FREE))
785 free(atom->op2);
786 free(atom);
787 } END_FOR_EACH_PTR(atom);
789 FOR_EACH_PTR(f->pseudo_list, stor) {
790 free(stor);
791 } END_FOR_EACH_PTR(stor);
793 free_ptr_list(&f->pseudo_list);
794 free(f);
797 /* function prologue */
798 static void emit_func_pre(struct symbol *sym)
800 struct function *f;
801 struct symbol *arg;
802 unsigned int i, argc = 0, alloc_len;
803 unsigned char *mem;
804 struct symbol_private *privbase;
805 struct storage *storage_base;
806 struct symbol *base_type = sym->ctype.base_type;
808 FOR_EACH_PTR(base_type->arguments, arg) {
809 argc++;
810 } END_FOR_EACH_PTR(arg);
812 alloc_len =
813 sizeof(*f) +
814 (argc * sizeof(struct symbol *)) +
815 (argc * sizeof(struct symbol_private)) +
816 (argc * sizeof(struct storage));
817 mem = calloc(1, alloc_len);
818 if (!mem)
819 die("OOM on func info");
821 f = (struct function *) mem;
822 mem += sizeof(*f);
823 f->argv = (struct symbol **) mem;
824 mem += (argc * sizeof(struct symbol *));
825 privbase = (struct symbol_private *) mem;
826 mem += (argc * sizeof(struct symbol_private));
827 storage_base = (struct storage *) mem;
829 f->argc = argc;
830 f->ret_target = new_label();
832 i = 0;
833 FOR_EACH_PTR(base_type->arguments, arg) {
834 f->argv[i] = arg;
835 arg->aux = &privbase[i];
836 storage_base[i].type = STOR_ARG;
837 storage_base[i].idx = i;
838 privbase[i].addr = &storage_base[i];
839 i++;
840 } END_FOR_EACH_PTR(arg);
842 assert(current_func == NULL);
843 current_func = f;
846 /* function epilogue */
847 static void emit_func_post(struct symbol *sym)
849 const char *name = show_ident(sym->ident);
850 struct function *f = current_func;
851 int stack_size = f->stack_size;
853 if (f->str_list)
854 emit_string_list(f);
856 /* function prologue */
857 emit_section(".text");
858 if ((sym->ctype.modifiers & MOD_STATIC) == 0)
859 printf(".globl %s\n", name);
860 printf("\t.type\t%s, @function\n", name);
861 printf("%s:\n", name);
863 if (stack_size) {
864 char pseudo_const[16];
866 sprintf(pseudo_const, "$%d", stack_size);
867 printf("\tsubl\t%s, %%esp\n", pseudo_const);
870 /* function epilogue */
872 /* jump target for 'return' statements */
873 emit_label(f->ret_target, NULL);
875 if (stack_size) {
876 struct storage *val;
878 val = new_storage(STOR_VALUE);
879 val->value = (long long) (stack_size);
880 val->flags = STOR_WANTS_FREE;
882 insn("addl", val, REG_ESP, NULL);
885 insn("ret", NULL, NULL, NULL);
887 /* output everything to stdout */
888 fflush(stdout); /* paranoia; needed? */
889 emit_atom_list(f);
891 /* function footer */
892 name = show_ident(sym->ident);
893 printf("\t.size\t%s, .-%s\n", name, name);
895 func_cleanup(f);
896 current_func = NULL;
899 /* emit object (a.k.a. variable, a.k.a. data) prologue */
900 static void emit_object_pre(const char *name, unsigned long modifiers,
901 unsigned long alignment, unsigned int byte_size)
903 if ((modifiers & MOD_STATIC) == 0)
904 printf(".globl %s\n", name);
905 emit_section(".data");
906 if (alignment)
907 printf("\t.align %lu\n", alignment);
908 printf("\t.type\t%s, @object\n", name);
909 printf("\t.size\t%s, %d\n", name, byte_size);
910 printf("%s:\n", name);
913 /* emit value (only) for an initializer scalar */
914 static void emit_scalar(struct expression *expr, unsigned int bit_size)
916 const char *type;
917 long long ll;
919 assert(expr->type == EXPR_VALUE);
921 if (expr->value == 0ULL) {
922 printf("\t.zero\t%d\n", bit_size / 8);
923 return;
926 ll = (long long) expr->value;
928 switch (bit_size) {
929 case 8: type = "byte"; ll = (char) ll; break;
930 case 16: type = "value"; ll = (short) ll; break;
931 case 32: type = "long"; ll = (int) ll; break;
932 case 64: type = "quad"; break;
933 default: type = NULL; break;
936 assert(type != NULL);
938 printf("\t.%s\t%lld\n", type, ll);
941 static void emit_global_noinit(const char *name, unsigned long modifiers,
942 unsigned long alignment, unsigned int byte_size)
944 char s[64];
946 if (modifiers & MOD_STATIC) {
947 sprintf(s, "\t.local\t%s\n", name);
948 textbuf_push(&unit_post_text, s);
950 if (alignment)
951 sprintf(s, "\t.comm\t%s,%d,%lu\n", name, byte_size, alignment);
952 else
953 sprintf(s, "\t.comm\t%s,%d\n", name, byte_size);
954 textbuf_push(&unit_post_text, s);
957 static int ea_current, ea_last;
959 static void emit_initializer(struct symbol *sym,
960 struct expression *expr)
962 int distance = ea_current - ea_last - 1;
964 if (distance > 0)
965 printf("\t.zero\t%d\n", (sym->bit_size / 8) * distance);
967 if (expr->type == EXPR_VALUE) {
968 struct symbol *base_type = sym->ctype.base_type;
969 assert(base_type != NULL);
971 emit_scalar(expr, sym->bit_size / get_expression_value(base_type->array_size));
972 return;
974 if (expr->type != EXPR_INITIALIZER)
975 return;
977 assert(0); /* FIXME */
980 static int sort_array_cmp(const struct expression *a,
981 const struct expression *b)
983 int a_ofs = 0, b_ofs = 0;
985 if (a->type == EXPR_POS)
986 a_ofs = (int) a->init_offset;
987 if (b->type == EXPR_POS)
988 b_ofs = (int) b->init_offset;
990 return a_ofs - b_ofs;
993 /* move to front-end? */
994 static void sort_array(struct expression *expr)
996 struct expression *entry, **list;
997 unsigned int elem, sorted, i;
999 elem = expression_list_size(expr->expr_list);
1000 if (!elem)
1001 return;
1003 list = malloc(sizeof(entry) * elem);
1004 if (!list)
1005 die("OOM in sort_array");
1007 /* this code is no doubt evil and ignores EXPR_INDEX possibly
1008 * to its detriment and other nasty things. improvements
1009 * welcome.
1011 i = 0;
1012 sorted = 0;
1013 FOR_EACH_PTR(expr->expr_list, entry) {
1014 if ((entry->type == EXPR_POS) || (entry->type == EXPR_VALUE)) {
1015 /* add entry to list[], in sorted order */
1016 if (sorted == 0) {
1017 list[0] = entry;
1018 sorted = 1;
1019 } else {
1020 for (i = 0; i < sorted; i++)
1021 if (sort_array_cmp(entry, list[i]) <= 0)
1022 break;
1024 /* If inserting into the middle of list[]
1025 * instead of appending, we memmove.
1026 * This is ugly, but thankfully
1027 * uncommon. Input data with tons of
1028 * entries very rarely have explicit
1029 * offsets. convert to qsort eventually...
1031 if (i != sorted)
1032 memmove(&list[i + 1], &list[i],
1033 (sorted - i) * sizeof(entry));
1034 list[i] = entry;
1035 sorted++;
1038 } END_FOR_EACH_PTR(entry);
1040 i = 0;
1041 FOR_EACH_PTR(expr->expr_list, entry) {
1042 if ((entry->type == EXPR_POS) || (entry->type == EXPR_VALUE))
1043 *THIS_ADDRESS(entry) = list[i++];
1044 } END_FOR_EACH_PTR(entry);
1046 free(list);
1049 static void emit_array(struct symbol *sym)
1051 struct symbol *base_type = sym->ctype.base_type;
1052 struct expression *expr = sym->initializer;
1053 struct expression *entry;
1055 assert(base_type != NULL);
1057 stor_sym_init(sym);
1059 ea_last = -1;
1061 emit_object_pre(show_ident(sym->ident), sym->ctype.modifiers,
1062 sym->ctype.alignment,
1063 sym->bit_size / 8);
1065 sort_array(expr);
1067 FOR_EACH_PTR(expr->expr_list, entry) {
1068 if (entry->type == EXPR_VALUE) {
1069 ea_current = 0;
1070 emit_initializer(sym, entry);
1071 ea_last = ea_current;
1072 } else if (entry->type == EXPR_POS) {
1073 ea_current =
1074 entry->init_offset / (base_type->bit_size / 8);
1075 emit_initializer(sym, entry->init_expr);
1076 ea_last = ea_current;
1078 } END_FOR_EACH_PTR(entry);
1081 void emit_one_symbol(struct symbol *sym)
1083 x86_symbol(sym);
1086 static void emit_copy(struct storage *dest, struct storage *src,
1087 struct symbol *ctype)
1089 struct storage *reg = NULL;
1090 unsigned int bit_size;
1092 /* FIXME: Bitfield copy! */
1094 bit_size = src->size * 8;
1095 if (!bit_size)
1096 bit_size = 32;
1097 if ((src->type == STOR_ARG) && (bit_size < 32))
1098 bit_size = 32;
1100 reg = temp_from_bits(bit_size);
1101 emit_move(src, reg, ctype, "begin copy ..");
1103 bit_size = dest->size * 8;
1104 if (!bit_size)
1105 bit_size = 32;
1106 if ((dest->type == STOR_ARG) && (bit_size < 32))
1107 bit_size = 32;
1109 emit_move(reg, dest, ctype, ".... end copy");
1110 put_reg(reg);
1113 static void emit_store(struct expression *dest_expr, struct storage *dest,
1114 struct storage *src, int bits)
1116 /* FIXME: Bitfield store! */
1117 printf("\tst.%d\t\tv%d,[v%d]\n", bits, src->pseudo, dest->pseudo);
1120 static void emit_scalar_noinit(struct symbol *sym)
1122 emit_global_noinit(show_ident(sym->ident),
1123 sym->ctype.modifiers, sym->ctype.alignment,
1124 sym->bit_size / 8);
1125 stor_sym_init(sym);
1128 static void emit_array_noinit(struct symbol *sym)
1130 emit_global_noinit(show_ident(sym->ident),
1131 sym->ctype.modifiers, sym->ctype.alignment,
1132 get_expression_value(sym->array_size) * (sym->bit_size / 8));
1133 stor_sym_init(sym);
1136 static const char *opbits(const char *insn, unsigned int bits)
1138 static char opbits_str[32];
1139 char c;
1141 switch (bits) {
1142 case 8: c = 'b'; break;
1143 case 16: c = 'w'; break;
1144 case 32: c = 'l'; break;
1145 case 64: c = 'q'; break;
1146 default: abort(); break;
1149 sprintf(opbits_str, "%s%c", insn, c);
1151 return opbits_str;
1154 static void emit_move(struct storage *src, struct storage *dest,
1155 struct symbol *ctype, const char *comment)
1157 unsigned int bits;
1158 unsigned int is_signed;
1159 unsigned int is_dest = (src->type == STOR_REG);
1160 const char *opname;
1162 if (ctype) {
1163 bits = ctype->bit_size;
1164 is_signed = is_signed_type(ctype);
1165 } else {
1166 bits = 32;
1167 is_signed = 0;
1171 * Are we moving from a register to a register?
1172 * Make the new reg to be the "cache".
1174 if ((dest->type == STOR_REG) && (src->type == STOR_REG)) {
1175 struct storage *backing;
1177 reg_reg_move:
1178 if (dest == src)
1179 return;
1181 backing = src->reg->contains;
1182 if (backing) {
1183 /* Is it still valid? */
1184 if (backing->reg != src->reg)
1185 backing = NULL;
1186 else
1187 backing->reg = dest->reg;
1189 dest->reg->contains = backing;
1190 insn("mov", src, dest, NULL);
1191 return;
1195 * Are we moving to a register from a non-reg?
1197 * See if we have the non-reg source already cached
1198 * in a register..
1200 if (dest->type == STOR_REG) {
1201 if (src->reg) {
1202 struct reg_info *info = src->reg;
1203 if (info->contains == src) {
1204 src = reginfo_reg(info);
1205 goto reg_reg_move;
1208 dest->reg->contains = src;
1209 src->reg = dest->reg;
1212 if (src->type == STOR_REG) {
1213 /* We could just mark the register dirty here and do lazy store.. */
1214 src->reg->contains = dest;
1215 dest->reg = src->reg;
1218 if ((bits == 8) || (bits == 16)) {
1219 if (is_dest)
1220 opname = "mov";
1221 else
1222 opname = is_signed ? "movsx" : "movzx";
1223 } else
1224 opname = "mov";
1226 insn(opbits(opname, bits), src, dest, comment);
1229 static struct storage *emit_compare(struct expression *expr)
1231 struct storage *left = x86_expression(expr->left);
1232 struct storage *right = x86_expression(expr->right);
1233 struct storage *reg1, *reg2;
1234 struct storage *new, *val;
1235 const char *opname = NULL;
1236 unsigned int right_bits = expr->right->ctype->bit_size;
1238 switch(expr->op) {
1239 case '<': opname = "setl"; break;
1240 case '>': opname = "setg"; break;
1241 case SPECIAL_LTE:
1242 opname = "setle"; break;
1243 case SPECIAL_GTE:
1244 opname = "setge"; break;
1245 case SPECIAL_EQUAL: opname = "sete"; break;
1246 case SPECIAL_NOTEQUAL: opname = "setne"; break;
1247 case SPECIAL_UNSIGNED_LT:
1248 opname = "setb"; break;
1249 case SPECIAL_UNSIGNED_GT:
1250 opname = "seta"; break;
1251 case SPECIAL_UNSIGNED_LTE:
1252 opname = "setb"; break;
1253 case SPECIAL_UNSIGNED_GTE:
1254 opname = "setae"; break;
1255 default:
1256 assert(0);
1257 break;
1260 /* init EDX to 0 */
1261 val = new_storage(STOR_VALUE);
1262 val->flags = STOR_WANTS_FREE;
1264 reg1 = get_reg(&regclass_32_8);
1265 emit_move(val, reg1, NULL, NULL);
1267 /* move op1 into EAX */
1268 reg2 = get_reg_value(left, get_regclass(expr->left));
1270 /* perform comparison, RHS (op1, right) and LHS (op2, EAX) */
1271 insn(opbits("cmp", right_bits), right, reg2, NULL);
1272 put_reg(reg2);
1274 /* store result of operation, 0 or 1, in DL using SETcc */
1275 insn(opname, byte_reg(reg1), NULL, NULL);
1277 /* finally, store the result (DL) in a new pseudo / stack slot */
1278 new = stack_alloc(4);
1279 emit_move(reg1, new, NULL, "end EXPR_COMPARE");
1280 put_reg(reg1);
1282 return new;
1285 static struct storage *emit_value(struct expression *expr)
1287 #if 0 /* old and slow way */
1288 struct storage *new = stack_alloc(4);
1289 struct storage *val;
1291 val = new_storage(STOR_VALUE);
1292 val->value = (long long) expr->value;
1293 val->flags = STOR_WANTS_FREE;
1294 insn("movl", val, new, NULL);
1296 return new;
1297 #else
1298 struct storage *val;
1300 val = new_storage(STOR_VALUE);
1301 val->value = (long long) expr->value;
1303 return val; /* FIXME: memory leak */
1304 #endif
1307 static struct storage *emit_divide(struct expression *expr, struct storage *left, struct storage *right)
1309 struct storage *eax_edx;
1310 struct storage *reg, *new;
1311 struct storage *val = new_storage(STOR_VALUE);
1313 emit_comment("begin DIVIDE");
1314 eax_edx = get_hardreg(hardreg_storage_table + EAX_EDX, 1);
1316 /* init EDX to 0 */
1317 val->flags = STOR_WANTS_FREE;
1318 emit_move(val, REG_EDX, NULL, NULL);
1320 new = stack_alloc(expr->ctype->bit_size / 8);
1322 /* EAX is dividend */
1323 emit_move(left, REG_EAX, NULL, NULL);
1325 reg = get_reg_value(right, &regclass_32);
1327 /* perform binop */
1328 insn("div", reg, REG_EAX, NULL);
1329 put_reg(reg);
1331 reg = REG_EAX;
1332 if (expr->op == '%')
1333 reg = REG_EDX;
1334 emit_move(reg, new, NULL, NULL);
1336 put_reg(eax_edx);
1337 emit_comment("end DIVIDE");
1338 return new;
1341 static struct storage *emit_binop(struct expression *expr)
1343 struct storage *left = x86_expression(expr->left);
1344 struct storage *right = x86_expression(expr->right);
1345 struct storage *new;
1346 struct storage *dest, *src;
1347 const char *opname = NULL;
1348 const char *suffix = NULL;
1349 char opstr[16];
1350 int is_signed;
1352 /* Divides have special register constraints */
1353 if ((expr->op == '/') || (expr->op == '%'))
1354 return emit_divide(expr, left, right);
1356 is_signed = is_signed_type(expr->ctype);
1358 switch (expr->op) {
1359 case '+':
1360 opname = "add";
1361 break;
1362 case '-':
1363 opname = "sub";
1364 break;
1365 case '&':
1366 opname = "and";
1367 break;
1368 case '|':
1369 opname = "or";
1370 break;
1371 case '^':
1372 opname = "xor";
1373 break;
1374 case SPECIAL_LEFTSHIFT:
1375 opname = "shl";
1376 break;
1377 case SPECIAL_RIGHTSHIFT:
1378 if (is_signed)
1379 opname = "sar";
1380 else
1381 opname = "shr";
1382 break;
1383 case '*':
1384 if (is_signed)
1385 opname = "imul";
1386 else
1387 opname = "mul";
1388 break;
1389 case SPECIAL_LOGICAL_AND:
1390 warning(expr->pos, "bogus bitwise and for logical op (should use '2*setne + and' or something)");
1391 opname = "and";
1392 break;
1393 case SPECIAL_LOGICAL_OR:
1394 warning(expr->pos, "bogus bitwise or for logical op (should use 'or + setne' or something)");
1395 opname = "or";
1396 break;
1397 default:
1398 error_die(expr->pos, "unhandled binop '%s'\n", show_special(expr->op));
1399 break;
1402 dest = get_reg_value(right, &regclass_32);
1403 src = get_reg_value(left, &regclass_32);
1404 switch (expr->ctype->bit_size) {
1405 case 8:
1406 suffix = "b";
1407 break;
1408 case 16:
1409 suffix = "w";
1410 break;
1411 case 32:
1412 suffix = "l";
1413 break;
1414 case 64:
1415 suffix = "q"; /* FIXME */
1416 break;
1417 default:
1418 assert(0);
1419 break;
1422 snprintf(opstr, sizeof(opstr), "%s%s", opname, suffix);
1424 /* perform binop */
1425 insn(opstr, src, dest, NULL);
1426 put_reg(src);
1428 /* store result in new pseudo / stack slot */
1429 new = stack_alloc(expr->ctype->bit_size / 8);
1430 emit_move(dest, new, NULL, "end EXPR_BINOP");
1432 put_reg(dest);
1434 return new;
1437 static int emit_conditional_test(struct storage *val)
1439 struct storage *reg;
1440 struct storage *target_val;
1441 int target_false;
1443 /* load result into EAX */
1444 emit_comment("begin if/conditional");
1445 reg = get_reg_value(val, &regclass_32);
1447 /* compare result with zero */
1448 insn("test", reg, reg, NULL);
1449 put_reg(reg);
1451 /* create conditional-failed label to jump to */
1452 target_false = new_label();
1453 target_val = new_storage(STOR_LABEL);
1454 target_val->label = target_false;
1455 target_val->flags = STOR_WANTS_FREE;
1456 insn("jz", target_val, NULL, NULL);
1458 return target_false;
1461 static int emit_conditional_end(int target_false)
1463 struct storage *cond_end_st;
1464 int cond_end;
1466 /* finished generating code for if-true statement.
1467 * add a jump-to-end jump to avoid falling through
1468 * to the if-false statement code.
1470 cond_end = new_label();
1471 cond_end_st = new_storage(STOR_LABEL);
1472 cond_end_st->label = cond_end;
1473 cond_end_st->flags = STOR_WANTS_FREE;
1474 insn("jmp", cond_end_st, NULL, NULL);
1476 /* if we have both if-true and if-false statements,
1477 * the failed-conditional case will fall through to here
1479 emit_label(target_false, NULL);
1481 return cond_end;
1484 static void emit_if_conditional(struct statement *stmt)
1486 struct storage *val;
1487 int cond_end;
1489 /* emit test portion of conditional */
1490 val = x86_expression(stmt->if_conditional);
1491 cond_end = emit_conditional_test(val);
1493 /* emit if-true statement */
1494 x86_statement(stmt->if_true);
1496 /* emit if-false statement, if present */
1497 if (stmt->if_false) {
1498 cond_end = emit_conditional_end(cond_end);
1499 x86_statement(stmt->if_false);
1502 /* end of conditional; jump target for if-true branch */
1503 emit_label(cond_end, "end if");
1506 static struct storage *emit_inc_dec(struct expression *expr, int postop)
1508 struct storage *addr = x86_address_gen(expr->unop);
1509 struct storage *retval;
1510 char opname[16];
1512 strcpy(opname, opbits(expr->op == SPECIAL_INCREMENT ? "inc" : "dec",
1513 expr->ctype->bit_size));
1515 if (postop) {
1516 struct storage *new = stack_alloc(4);
1518 emit_copy(new, addr, expr->unop->ctype);
1520 retval = new;
1521 } else
1522 retval = addr;
1524 insn(opname, addr, NULL, NULL);
1526 return retval;
1529 static struct storage *emit_postop(struct expression *expr)
1531 return emit_inc_dec(expr, 1);
1534 static struct storage *emit_return_stmt(struct statement *stmt)
1536 struct function *f = current_func;
1537 struct expression *expr = stmt->ret_value;
1538 struct storage *val = NULL, *jmplbl;
1540 if (expr && expr->ctype) {
1541 val = x86_expression(expr);
1542 assert(val != NULL);
1543 emit_move(val, REG_EAX, expr->ctype, "return");
1546 jmplbl = new_storage(STOR_LABEL);
1547 jmplbl->flags |= STOR_WANTS_FREE;
1548 jmplbl->label = f->ret_target;
1549 insn("jmp", jmplbl, NULL, NULL);
1551 return val;
1554 static struct storage *emit_conditional_expr(struct expression *expr)
1556 struct storage *cond, *stot = NULL, *stof = NULL;
1557 struct storage *new = stack_alloc(expr->ctype->bit_size / 8);
1558 int target_false, cond_end;
1560 /* evaluate conditional */
1561 cond = x86_expression(expr->conditional);
1562 target_false = emit_conditional_test(cond);
1564 /* handle if-true part of the expression */
1565 stot = x86_expression(expr->cond_true);
1567 emit_copy(new, stot, expr->ctype);
1569 cond_end = emit_conditional_end(target_false);
1571 /* handle if-false part of the expression */
1572 stof = x86_expression(expr->cond_false);
1574 emit_copy(new, stof, expr->ctype);
1576 /* end of conditional; jump target for if-true branch */
1577 emit_label(cond_end, "end conditional");
1579 return new;
1582 static struct storage *emit_select_expr(struct expression *expr)
1584 struct storage *cond = x86_expression(expr->conditional);
1585 struct storage *stot = x86_expression(expr->cond_true);
1586 struct storage *stof = x86_expression(expr->cond_false);
1587 struct storage *reg_cond, *reg_true, *reg_false;
1588 struct storage *new = stack_alloc(4);
1590 emit_comment("begin SELECT");
1591 reg_cond = get_reg_value(cond, get_regclass(expr->conditional));
1592 reg_true = get_reg_value(stot, get_regclass(expr));
1593 reg_false = get_reg_value(stof, get_regclass(expr));
1596 * Do the actual select: check the conditional for zero,
1597 * move false over true if zero
1599 insn("test", reg_cond, reg_cond, NULL);
1600 insn("cmovz", reg_false, reg_true, NULL);
1602 /* Store it back */
1603 emit_move(reg_true, new, expr->ctype, NULL);
1604 put_reg(reg_cond);
1605 put_reg(reg_true);
1606 put_reg(reg_false);
1607 emit_comment("end SELECT");
1608 return new;
1611 static struct storage *emit_symbol_expr_init(struct symbol *sym)
1613 struct expression *expr = sym->initializer;
1614 struct symbol_private *priv = sym->aux;
1616 if (priv == NULL) {
1617 priv = calloc(1, sizeof(*priv));
1618 sym->aux = priv;
1620 if (expr == NULL) {
1621 struct storage *new = stack_alloc(4);
1622 fprintf(stderr, "FIXME! no value for symbol %s. creating pseudo %d (stack offset %d)\n",
1623 show_ident(sym->ident),
1624 new->pseudo, new->pseudo * 4);
1625 priv->addr = new;
1626 } else {
1627 priv->addr = x86_expression(expr);
1631 return priv->addr;
1634 static struct storage *emit_string_expr(struct expression *expr)
1636 struct function *f = current_func;
1637 int label = new_label();
1638 struct storage *new;
1640 push_cstring(f, expr->string, label);
1642 new = new_storage(STOR_LABEL);
1643 new->label = label;
1644 new->flags = STOR_LABEL_VAL | STOR_WANTS_FREE;
1645 return new;
1648 static struct storage *emit_cast_expr(struct expression *expr)
1650 struct symbol *old_type, *new_type;
1651 struct storage *op = x86_expression(expr->cast_expression);
1652 int oldbits, newbits;
1653 struct storage *new;
1655 old_type = expr->cast_expression->ctype;
1656 new_type = expr->cast_type;
1658 oldbits = old_type->bit_size;
1659 newbits = new_type->bit_size;
1660 if (oldbits >= newbits)
1661 return op;
1663 emit_move(op, REG_EAX, old_type, "begin cast ..");
1665 new = stack_alloc(newbits / 8);
1666 emit_move(REG_EAX, new, new_type, ".... end cast");
1668 return new;
1671 static struct storage *emit_regular_preop(struct expression *expr)
1673 struct storage *target = x86_expression(expr->unop);
1674 struct storage *val, *new = stack_alloc(4);
1675 const char *opname = NULL;
1677 switch (expr->op) {
1678 case '!':
1679 val = new_storage(STOR_VALUE);
1680 val->flags = STOR_WANTS_FREE;
1681 emit_move(val, REG_EDX, NULL, NULL);
1682 emit_move(target, REG_EAX, expr->unop->ctype, NULL);
1683 insn("test", REG_EAX, REG_EAX, NULL);
1684 insn("setz", REG_DL, NULL, NULL);
1685 emit_move(REG_EDX, new, expr->unop->ctype, NULL);
1687 break;
1688 case '~':
1689 opname = "not";
1690 case '-':
1691 if (!opname)
1692 opname = "neg";
1693 emit_move(target, REG_EAX, expr->unop->ctype, NULL);
1694 insn(opname, REG_EAX, NULL, NULL);
1695 emit_move(REG_EAX, new, expr->unop->ctype, NULL);
1696 break;
1697 default:
1698 assert(0);
1699 break;
1702 return new;
1705 static void emit_case_statement(struct statement *stmt)
1707 emit_labelsym(stmt->case_label, NULL);
1708 x86_statement(stmt->case_statement);
1711 static void emit_switch_statement(struct statement *stmt)
1713 struct storage *val = x86_expression(stmt->switch_expression);
1714 struct symbol *sym, *default_sym = NULL;
1715 struct storage *labelsym, *label;
1716 int switch_end = 0;
1718 emit_move(val, REG_EAX, stmt->switch_expression->ctype, "begin case");
1721 * This is where a _real_ back-end would go through the
1722 * cases to decide whether to use a lookup table or a
1723 * series of comparisons etc
1725 FOR_EACH_PTR(stmt->switch_case->symbol_list, sym) {
1726 struct statement *case_stmt = sym->stmt;
1727 struct expression *expr = case_stmt->case_expression;
1728 struct expression *to = case_stmt->case_to;
1730 /* default: */
1731 if (!expr)
1732 default_sym = sym;
1734 /* case NNN: */
1735 else {
1736 struct storage *case_val = new_val(expr->value);
1738 assert (expr->type == EXPR_VALUE);
1740 insn("cmpl", case_val, REG_EAX, NULL);
1742 if (!to) {
1743 labelsym = new_labelsym(sym);
1744 insn("je", labelsym, NULL, NULL);
1745 } else {
1746 int next_test;
1748 label = new_storage(STOR_LABEL);
1749 label->flags |= STOR_WANTS_FREE;
1750 label->label = next_test = new_label();
1752 /* FIXME: signed/unsigned */
1753 insn("jl", label, NULL, NULL);
1755 case_val = new_val(to->value);
1756 insn("cmpl", case_val, REG_EAX, NULL);
1758 /* TODO: implement and use refcounting... */
1759 label = new_storage(STOR_LABEL);
1760 label->flags |= STOR_WANTS_FREE;
1761 label->label = next_test;
1763 /* FIXME: signed/unsigned */
1764 insn("jg", label, NULL, NULL);
1766 labelsym = new_labelsym(sym);
1767 insn("jmp", labelsym, NULL, NULL);
1769 emit_label(next_test, NULL);
1772 } END_FOR_EACH_PTR(sym);
1774 if (default_sym) {
1775 labelsym = new_labelsym(default_sym);
1776 insn("jmp", labelsym, NULL, "default");
1777 } else {
1778 label = new_storage(STOR_LABEL);
1779 label->flags |= STOR_WANTS_FREE;
1780 label->label = switch_end = new_label();
1781 insn("jmp", label, NULL, "goto end of switch");
1784 x86_statement(stmt->switch_statement);
1786 if (stmt->switch_break->used)
1787 emit_labelsym(stmt->switch_break, NULL);
1789 if (switch_end)
1790 emit_label(switch_end, NULL);
1793 static void x86_struct_member(struct symbol *sym)
1795 printf("\t%s:%d:%ld at offset %ld.%d", show_ident(sym->ident), sym->bit_size, sym->ctype.alignment, sym->offset, sym->bit_offset);
1796 printf("\n");
1799 static void x86_symbol(struct symbol *sym)
1801 struct symbol *type;
1803 if (!sym)
1804 return;
1806 type = sym->ctype.base_type;
1807 if (!type)
1808 return;
1811 * Show actual implementation information
1813 switch (type->type) {
1815 case SYM_ARRAY:
1816 if (sym->initializer)
1817 emit_array(sym);
1818 else
1819 emit_array_noinit(sym);
1820 break;
1822 case SYM_BASETYPE:
1823 if (sym->initializer) {
1824 emit_object_pre(show_ident(sym->ident),
1825 sym->ctype.modifiers,
1826 sym->ctype.alignment,
1827 sym->bit_size / 8);
1828 emit_scalar(sym->initializer, sym->bit_size);
1829 stor_sym_init(sym);
1830 } else
1831 emit_scalar_noinit(sym);
1832 break;
1834 case SYM_STRUCT:
1835 case SYM_UNION: {
1836 struct symbol *member;
1838 printf(" {\n");
1839 FOR_EACH_PTR(type->symbol_list, member) {
1840 x86_struct_member(member);
1841 } END_FOR_EACH_PTR(member);
1842 printf("}\n");
1843 break;
1846 case SYM_FN: {
1847 struct statement *stmt = type->stmt;
1848 if (stmt) {
1849 emit_func_pre(sym);
1850 x86_statement(stmt);
1851 emit_func_post(sym);
1853 break;
1856 default:
1857 break;
1860 if (sym->initializer && (type->type != SYM_BASETYPE) &&
1861 (type->type != SYM_ARRAY)) {
1862 printf(" = \n");
1863 x86_expression(sym->initializer);
1867 static void x86_symbol_init(struct symbol *sym);
1869 static void x86_symbol_decl(struct symbol_list *syms)
1871 struct symbol *sym;
1872 FOR_EACH_PTR(syms, sym) {
1873 x86_symbol_init(sym);
1874 } END_FOR_EACH_PTR(sym);
1877 static void loopstk_push(int cont_lbl, int loop_bottom_lbl)
1879 struct function *f = current_func;
1880 struct loop_stack *ls;
1882 ls = malloc(sizeof(*ls));
1883 ls->continue_lbl = cont_lbl;
1884 ls->loop_bottom_lbl = loop_bottom_lbl;
1885 ls->next = f->loop_stack;
1886 f->loop_stack = ls;
1889 static void loopstk_pop(void)
1891 struct function *f = current_func;
1892 struct loop_stack *ls;
1894 assert(f->loop_stack != NULL);
1895 ls = f->loop_stack;
1896 f->loop_stack = f->loop_stack->next;
1897 free(ls);
1900 static int loopstk_break(void)
1902 return current_func->loop_stack->loop_bottom_lbl;
1905 static int loopstk_continue(void)
1907 return current_func->loop_stack->continue_lbl;
1910 static void emit_loop(struct statement *stmt)
1912 struct statement *pre_statement = stmt->iterator_pre_statement;
1913 struct expression *pre_condition = stmt->iterator_pre_condition;
1914 struct statement *statement = stmt->iterator_statement;
1915 struct statement *post_statement = stmt->iterator_post_statement;
1916 struct expression *post_condition = stmt->iterator_post_condition;
1917 int loop_top = 0, loop_bottom, loop_continue;
1918 int have_bottom = 0;
1919 struct storage *val;
1921 loop_bottom = new_label();
1922 loop_continue = new_label();
1923 loopstk_push(loop_continue, loop_bottom);
1925 x86_symbol_decl(stmt->iterator_syms);
1926 x86_statement(pre_statement);
1927 if (!post_condition || post_condition->type != EXPR_VALUE || post_condition->value) {
1928 loop_top = new_label();
1929 emit_label(loop_top, "loop top");
1931 if (pre_condition) {
1932 if (pre_condition->type == EXPR_VALUE) {
1933 if (!pre_condition->value) {
1934 struct storage *lbv;
1935 lbv = new_storage(STOR_LABEL);
1936 lbv->label = loop_bottom;
1937 lbv->flags = STOR_WANTS_FREE;
1938 insn("jmp", lbv, NULL, "go to loop bottom");
1939 have_bottom = 1;
1941 } else {
1942 struct storage *lbv = new_storage(STOR_LABEL);
1943 lbv->label = loop_bottom;
1944 lbv->flags = STOR_WANTS_FREE;
1945 have_bottom = 1;
1947 val = x86_expression(pre_condition);
1949 emit_move(val, REG_EAX, NULL, "loop pre condition");
1950 insn("test", REG_EAX, REG_EAX, NULL);
1951 insn("jz", lbv, NULL, NULL);
1954 x86_statement(statement);
1955 if (stmt->iterator_continue->used)
1956 emit_label(loop_continue, "'continue' iterator");
1957 x86_statement(post_statement);
1958 if (!post_condition) {
1959 struct storage *lbv = new_storage(STOR_LABEL);
1960 lbv->label = loop_top;
1961 lbv->flags = STOR_WANTS_FREE;
1962 insn("jmp", lbv, NULL, "go to loop top");
1963 } else if (post_condition->type == EXPR_VALUE) {
1964 if (post_condition->value) {
1965 struct storage *lbv = new_storage(STOR_LABEL);
1966 lbv->label = loop_top;
1967 lbv->flags = STOR_WANTS_FREE;
1968 insn("jmp", lbv, NULL, "go to loop top");
1970 } else {
1971 struct storage *lbv = new_storage(STOR_LABEL);
1972 lbv->label = loop_top;
1973 lbv->flags = STOR_WANTS_FREE;
1975 val = x86_expression(post_condition);
1977 emit_move(val, REG_EAX, NULL, "loop post condition");
1978 insn("test", REG_EAX, REG_EAX, NULL);
1979 insn("jnz", lbv, NULL, NULL);
1981 if (have_bottom || stmt->iterator_break->used)
1982 emit_label(loop_bottom, "loop bottom");
1984 loopstk_pop();
1988 * Print out a statement
1990 static struct storage *x86_statement(struct statement *stmt)
1992 if (!stmt)
1993 return NULL;
1994 switch (stmt->type) {
1995 default:
1996 return NULL;
1997 case STMT_RETURN:
1998 return emit_return_stmt(stmt);
1999 case STMT_DECLARATION:
2000 x86_symbol_decl(stmt->declaration);
2001 break;
2002 case STMT_COMPOUND: {
2003 struct statement *s;
2004 struct storage *last = NULL;
2006 FOR_EACH_PTR(stmt->stmts, s) {
2007 last = x86_statement(s);
2008 } END_FOR_EACH_PTR(s);
2010 return last;
2013 case STMT_EXPRESSION:
2014 return x86_expression(stmt->expression);
2015 case STMT_IF:
2016 emit_if_conditional(stmt);
2017 return NULL;
2019 case STMT_CASE:
2020 emit_case_statement(stmt);
2021 break;
2022 case STMT_SWITCH:
2023 emit_switch_statement(stmt);
2024 break;
2026 case STMT_ITERATOR:
2027 emit_loop(stmt);
2028 break;
2030 case STMT_NONE:
2031 break;
2033 case STMT_LABEL:
2034 printf(".L%p:\n", stmt->label_identifier);
2035 x86_statement(stmt->label_statement);
2036 break;
2038 case STMT_GOTO:
2039 if (stmt->goto_expression) {
2040 struct storage *val = x86_expression(stmt->goto_expression);
2041 printf("\tgoto *v%d\n", val->pseudo);
2042 } else if (!strcmp("break", show_ident(stmt->goto_label->ident))) {
2043 struct storage *lbv = new_storage(STOR_LABEL);
2044 lbv->label = loopstk_break();
2045 lbv->flags = STOR_WANTS_FREE;
2046 insn("jmp", lbv, NULL, "'break'; go to loop bottom");
2047 } else if (!strcmp("continue", show_ident(stmt->goto_label->ident))) {
2048 struct storage *lbv = new_storage(STOR_LABEL);
2049 lbv->label = loopstk_continue();
2050 lbv->flags = STOR_WANTS_FREE;
2051 insn("jmp", lbv, NULL, "'continue'; go to loop top");
2052 } else {
2053 struct storage *labelsym = new_labelsym(stmt->goto_label);
2054 insn("jmp", labelsym, NULL, NULL);
2056 break;
2057 case STMT_ASM:
2058 printf("\tasm( .... )\n");
2059 break;
2061 return NULL;
2064 static struct storage *x86_call_expression(struct expression *expr)
2066 struct function *f = current_func;
2067 struct symbol *direct;
2068 struct expression *arg, *fn;
2069 struct storage *retval, *fncall;
2070 int framesize;
2071 char s[64];
2073 if (!expr->ctype) {
2074 warning(expr->pos, "\tcall with no type!");
2075 return NULL;
2078 framesize = 0;
2079 FOR_EACH_PTR_REVERSE(expr->args, arg) {
2080 struct storage *new = x86_expression(arg);
2081 int size = arg->ctype->bit_size;
2084 * FIXME: i386 SysV ABI dictates that values
2085 * smaller than 32 bits should be placed onto
2086 * the stack as 32-bit objects. We should not
2087 * blindly do a 32-bit push on objects smaller
2088 * than 32 bits.
2090 if (size < 32)
2091 size = 32;
2092 insn("pushl", new, NULL,
2093 !framesize ? "begin function call" : NULL);
2095 framesize += bits_to_bytes(size);
2096 } END_FOR_EACH_PTR_REVERSE(arg);
2098 fn = expr->fn;
2100 /* Remove dereference, if any */
2101 direct = NULL;
2102 if (fn->type == EXPR_PREOP) {
2103 if (fn->unop->type == EXPR_SYMBOL) {
2104 struct symbol *sym = fn->unop->symbol;
2105 if (sym->ctype.base_type->type == SYM_FN)
2106 direct = sym;
2109 if (direct) {
2110 struct storage *direct_stor = new_storage(STOR_SYM);
2111 direct_stor->flags |= STOR_WANTS_FREE;
2112 direct_stor->sym = direct;
2113 insn("call", direct_stor, NULL, NULL);
2114 } else {
2115 fncall = x86_expression(fn);
2116 emit_move(fncall, REG_EAX, fn->ctype, NULL);
2118 strcpy(s, "\tcall\t*%eax\n");
2119 push_text_atom(f, s);
2122 /* FIXME: pay attention to BITS_IN_POINTER */
2123 if (framesize) {
2124 struct storage *val = new_storage(STOR_VALUE);
2125 val->value = (long long) framesize;
2126 val->flags = STOR_WANTS_FREE;
2127 insn("addl", val, REG_ESP, NULL);
2130 retval = stack_alloc(4);
2131 emit_move(REG_EAX, retval, NULL, "end function call");
2133 return retval;
2136 static struct storage *x86_address_gen(struct expression *expr)
2138 struct function *f = current_func;
2139 struct storage *addr;
2140 struct storage *new;
2141 char s[32];
2143 addr = x86_expression(expr->unop);
2144 if (expr->unop->type == EXPR_SYMBOL)
2145 return addr;
2147 emit_move(addr, REG_EAX, NULL, "begin deref ..");
2149 /* FIXME: operand size */
2150 strcpy(s, "\tmovl\t(%eax), %ecx\n");
2151 push_text_atom(f, s);
2153 new = stack_alloc(4);
2154 emit_move(REG_ECX, new, NULL, ".... end deref");
2156 return new;
2159 static struct storage *x86_assignment(struct expression *expr)
2161 struct expression *target = expr->left;
2162 struct storage *val, *addr;
2164 if (!expr->ctype)
2165 return NULL;
2167 val = x86_expression(expr->right);
2168 addr = x86_address_gen(target);
2170 switch (val->type) {
2171 /* copy, where both operands are memory */
2172 case STOR_PSEUDO:
2173 case STOR_ARG:
2174 emit_copy(addr, val, expr->ctype);
2175 break;
2177 /* copy, one or zero operands are memory */
2178 case STOR_REG:
2179 case STOR_SYM:
2180 case STOR_VALUE:
2181 case STOR_LABEL:
2182 emit_move(val, addr, expr->left->ctype, NULL);
2183 break;
2185 case STOR_LABELSYM:
2186 assert(0);
2187 break;
2189 return val;
2192 static int x86_initialization(struct symbol *sym, struct expression *expr)
2194 struct storage *val, *addr;
2195 int bits;
2197 if (!expr->ctype)
2198 return 0;
2200 bits = expr->ctype->bit_size;
2201 val = x86_expression(expr);
2202 addr = x86_symbol_expr(sym);
2203 // FIXME! The "target" expression is for bitfield store information.
2204 // Leave it NULL, which works fine.
2205 emit_store(NULL, addr, val, bits);
2206 return 0;
2209 static struct storage *x86_access(struct expression *expr)
2211 return x86_address_gen(expr);
2214 static struct storage *x86_preop(struct expression *expr)
2217 * '*' is an lvalue access, and is fundamentally different
2218 * from an arithmetic operation. Maybe it should have an
2219 * expression type of its own..
2221 if (expr->op == '*')
2222 return x86_access(expr);
2223 if (expr->op == SPECIAL_INCREMENT || expr->op == SPECIAL_DECREMENT)
2224 return emit_inc_dec(expr, 0);
2225 return emit_regular_preop(expr);
2228 static struct storage *x86_symbol_expr(struct symbol *sym)
2230 struct storage *new = stack_alloc(4);
2232 if (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_EXTERN | MOD_STATIC)) {
2233 printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer, new->pseudo, show_ident(sym->ident));
2234 return new;
2236 if (sym->ctype.modifiers & MOD_ADDRESSABLE) {
2237 printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer, new->pseudo, 0LL);
2238 return new;
2240 printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer, new->pseudo, show_ident(sym->ident), sym);
2241 return new;
2244 static void x86_symbol_init(struct symbol *sym)
2246 struct symbol_private *priv = sym->aux;
2247 struct expression *expr = sym->initializer;
2248 struct storage *new;
2250 if (expr)
2251 new = x86_expression(expr);
2252 else
2253 new = stack_alloc(sym->bit_size / 8);
2255 if (!priv) {
2256 priv = calloc(1, sizeof(*priv));
2257 sym->aux = priv;
2258 /* FIXME: leak! we don't free... */
2259 /* (well, we don't free symbols either) */
2262 priv->addr = new;
2265 static struct storage *x86_label_expr(struct expression *expr)
2267 struct storage *new = stack_alloc(4);
2268 printf("\tmovi.%d\t\tv%d,.L%p\n", bits_in_pointer, new->pseudo, expr->label_symbol);
2269 return new;
2272 static struct storage *x86_statement_expr(struct expression *expr)
2274 return x86_statement(expr->statement);
2277 static int x86_position_expr(struct expression *expr, struct symbol *base)
2279 struct storage *new = x86_expression(expr->init_expr);
2280 struct symbol *ctype = expr->init_expr->ctype;
2282 printf("\tinsert v%d at [%d:%d] of %s\n", new->pseudo,
2283 expr->init_offset, ctype->bit_offset,
2284 show_ident(base->ident));
2285 return 0;
2288 static void x86_initializer_expr(struct expression *expr, struct symbol *ctype)
2290 struct expression *entry;
2292 FOR_EACH_PTR(expr->expr_list, entry) {
2293 // Nested initializers have their positions already
2294 // recursively calculated - just output them too
2295 if (entry->type == EXPR_INITIALIZER) {
2296 x86_initializer_expr(entry, ctype);
2297 continue;
2300 // Ignore initializer indexes and identifiers - the
2301 // evaluator has taken them into account
2302 if (entry->type == EXPR_IDENTIFIER || entry->type == EXPR_INDEX)
2303 continue;
2304 if (entry->type == EXPR_POS) {
2305 x86_position_expr(entry, ctype);
2306 continue;
2308 x86_initialization(ctype, entry);
2309 } END_FOR_EACH_PTR(entry);
2313 * Print out an expression. Return the pseudo that contains the
2314 * variable.
2316 static struct storage *x86_expression(struct expression *expr)
2318 if (!expr)
2319 return NULL;
2321 if (!expr->ctype) {
2322 struct position *pos = &expr->pos;
2323 printf("\tno type at %s:%d:%d\n",
2324 stream_name(pos->stream),
2325 pos->line, pos->pos);
2326 return NULL;
2329 switch (expr->type) {
2330 default:
2331 return NULL;
2332 case EXPR_CALL:
2333 return x86_call_expression(expr);
2335 case EXPR_ASSIGNMENT:
2336 return x86_assignment(expr);
2338 case EXPR_COMPARE:
2339 return emit_compare(expr);
2340 case EXPR_BINOP:
2341 case EXPR_COMMA:
2342 case EXPR_LOGICAL:
2343 return emit_binop(expr);
2344 case EXPR_PREOP:
2345 return x86_preop(expr);
2346 case EXPR_POSTOP:
2347 return emit_postop(expr);
2348 case EXPR_SYMBOL:
2349 return emit_symbol_expr_init(expr->symbol);
2350 case EXPR_DEREF:
2351 case EXPR_SIZEOF:
2352 case EXPR_ALIGNOF:
2353 warning(expr->pos, "invalid expression after evaluation");
2354 return NULL;
2355 case EXPR_CAST:
2356 case EXPR_FORCE_CAST:
2357 case EXPR_IMPLIED_CAST:
2358 return emit_cast_expr(expr);
2359 case EXPR_VALUE:
2360 return emit_value(expr);
2361 case EXPR_STRING:
2362 return emit_string_expr(expr);
2363 case EXPR_INITIALIZER:
2364 x86_initializer_expr(expr, expr->ctype);
2365 return NULL;
2366 case EXPR_SELECT:
2367 return emit_select_expr(expr);
2368 case EXPR_CONDITIONAL:
2369 return emit_conditional_expr(expr);
2370 case EXPR_STATEMENT:
2371 return x86_statement_expr(expr);
2372 case EXPR_LABEL:
2373 return x86_label_expr(expr);
2375 // None of these should exist as direct expressions: they are only
2376 // valid as sub-expressions of initializers.
2377 case EXPR_POS:
2378 warning(expr->pos, "unable to show plain initializer position expression");
2379 return NULL;
2380 case EXPR_IDENTIFIER:
2381 warning(expr->pos, "unable to show identifier expression");
2382 return NULL;
2383 case EXPR_INDEX:
2384 warning(expr->pos, "unable to show index expression");
2385 return NULL;
2386 case EXPR_TYPE:
2387 warning(expr->pos, "unable to show type expression");
2388 return NULL;
2389 case EXPR_FVALUE:
2390 warning(expr->pos, "floating point support is not implemented");
2391 return NULL;
2393 return NULL;