2 * sparse/compile-i386.c
4 * Copyright (C) 2003 Transmeta Corp.
6 * Copyright 2003 Jeff Garzik
8 * Licensed under the Open Software License version 1.1
13 * in general, any non-32bit SYM_BASETYPE is unlikely to work.
14 * complex initializers
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.
20 * any function argument that isn't 32 bits (or promoted to such)
39 #include "expression.h"
44 unsigned int len
; /* does NOT include terminating null */
53 struct loop_stack
*next
;
59 struct ptr_list
*pseudo_list
;
60 struct ptr_list
*atom_list
;
61 struct ptr_list
*str_list
;
62 struct loop_stack
*loop_stack
;
69 STOR_PSEUDO
, /* variable stored on the stack */
70 STOR_ARG
, /* function argument */
71 STOR_SYM
, /* a symbol we can directly ref in the asm */
72 STOR_REG
, /* scratch register */
73 STOR_VALUE
, /* integer constant */
74 STOR_LABEL
, /* label / jump target */
75 STOR_LABELSYM
, /* label generated from symbol's pointer value */
83 enum storage_type type
;
114 struct symbol
*labelsym
;
120 STOR_LABEL_VAL
= (1 << 0),
121 STOR_WANTS_FREE
= (1 << 1),
124 struct symbol_private
{
125 struct storage
*addr
;
140 unsigned int text_len
; /* w/o terminating null */
143 /* stuff for insns */
151 /* stuff for C strings */
153 struct string
*string
;
160 struct function
*current_func
= NULL
;
161 struct textbuf
*unit_post_text
= NULL
;
162 static const char *current_section
;
166 AL
, DL
, CL
, BL
, AH
, DH
, CH
, BH
, // 8-bit
167 AX
, DX
, CX
, BX
, SI
, DI
, BP
, SP
, // 16-bit
168 EAX
, EDX
, ECX
, EBX
, ESI
, EDI
, EBP
, ESP
, // 32-bit
169 EAX_EDX
, ECX_EBX
, ESI_EDI
, // 64-bit
172 #define REGINFO(nr, str, aliases...) [nr] = { .name = str }
174 static struct reg_info reg_info_table
[] = {
175 REGINFO( AL
, "%al", AX
, EAX
, EAX_EDX
),
176 REGINFO( DL
, "%dl", DX
, EDX
, EAX_EDX
),
177 REGINFO( CL
, "%cl", CX
, ECX
, ECX_EBX
),
178 REGINFO( BL
, "%bl", BX
, EBX
, ECX_EBX
),
179 REGINFO( AH
, "%ah", AX
, EAX
, EAX_EDX
),
180 REGINFO( DH
, "%dh", DX
, EDX
, EAX_EDX
),
181 REGINFO( CH
, "%ch", CX
, ECX
, ECX_EBX
),
182 REGINFO( BH
, "%bh", BX
, EBX
, ECX_EBX
),
183 REGINFO( AX
, "%ax", AL
, AH
, EAX
, EAX_EDX
),
184 REGINFO( DX
, "%dx", DL
, DH
, EDX
, EAX_EDX
),
185 REGINFO( CX
, "%cx", CL
, CH
, ECX
, ECX_EBX
),
186 REGINFO( BX
, "%bx", BL
, BH
, EBX
, ECX_EBX
),
187 REGINFO( SI
, "%si", ESI
, ESI_EDI
),
188 REGINFO( DI
, "%di", EDI
, ESI_EDI
),
189 REGINFO( BP
, "%bp", EBP
),
190 REGINFO( SP
, "%sp", ESP
),
191 REGINFO(EAX
, "%eax", AL
, AH
, AX
, EAX_EDX
),
192 REGINFO(EDX
, "%edx", DL
, DH
, DX
, EAX_EDX
),
193 REGINFO(ECX
, "%ecx", CL
, CH
, CX
, ECX_EBX
),
194 REGINFO(EBX
, "%ebx", BL
, BH
, BX
, ECX_EBX
),
195 REGINFO(ESI
, "%esi", SI
, ESI_EDI
),
196 REGINFO(EDI
, "%edi", DI
, ESI_EDI
),
197 REGINFO(EBP
, "%ebp", BP
),
198 REGINFO(ESP
, "%esp", SP
),
199 REGINFO(EAX_EDX
, "%eax:%edx", AL
, AH
, AX
, EAX
, DL
, DH
, DX
, EDX
),
200 REGINFO(ECX_EBX
, "%ecx:%ebx", CL
, CH
, CX
, ECX
, BL
, BH
, BX
, EBX
),
201 REGINFO(ESI_EDI
, "%esi:%edi", SI
, ESI
, DI
, EDI
),
204 #define REGSTORAGE(nr) [nr] = { .type = STOR_REG, .reg = reg_info_table + (nr) }
206 static struct storage hardreg_storage_table
[] = {
207 REGSTORAGE(AL
), REGSTORAGE(DL
), REGSTORAGE(CL
), REGSTORAGE(BL
),
208 REGSTORAGE(AH
), REGSTORAGE(DH
), REGSTORAGE(CH
), REGSTORAGE(BH
),
209 REGSTORAGE(AX
), REGSTORAGE(DX
), REGSTORAGE(CX
), REGSTORAGE(BX
),
210 REGSTORAGE(SI
), REGSTORAGE(DI
), REGSTORAGE(BP
), REGSTORAGE(SP
),
211 REGSTORAGE(EAX
), REGSTORAGE(EDX
), REGSTORAGE(ECX
), REGSTORAGE(EBX
),
212 REGSTORAGE(ESI
), REGSTORAGE(EDI
), REGSTORAGE(EBP
), REGSTORAGE(ESP
),
213 REGSTORAGE(EAX_EDX
), REGSTORAGE(ECX_EBX
), REGSTORAGE(ESI_EDI
),
216 #define REG_EAX (&hardreg_storage_table[EAX])
217 #define REG_ECX (&hardreg_storage_table[ECX])
218 #define REG_EDX (&hardreg_storage_table[EDX])
219 #define REG_ESP (&hardreg_storage_table[ESP])
220 #define REG_DL (&hardreg_storage_table[DL])
221 #define REG_DX (&hardreg_storage_table[DX])
222 #define REG_AL (&hardreg_storage_table[AL])
223 #define REG_AX (&hardreg_storage_table[AX])
225 static void emit_move(struct storage
*src
, struct storage
*dest
,
226 struct symbol
*ctype
, const char *comment
);
227 static int type_is_signed(struct symbol
*sym
);
228 static struct storage
*x86_address_gen(struct expression
*expr
);
229 static struct storage
*x86_symbol_expr(struct symbol
*sym
);
230 static void x86_symbol(struct symbol
*sym
);
231 static struct storage
*x86_statement(struct statement
*stmt
);
232 static struct storage
*x86_expression(struct expression
*expr
);
235 static struct storage
*temp_from_bits(unsigned int bit_size
)
238 case 8: return REG_AL
;
239 case 16: return REG_AX
;
240 case 32: return REG_EAX
;
251 static inline unsigned int pseudo_offset(struct storage
*s
)
253 if (s
->type
!= STOR_PSEUDO
)
254 return 123456; /* intentionally bogus value */
259 static inline unsigned int arg_offset(struct storage
*s
)
261 if (s
->type
!= STOR_ARG
)
262 return 123456; /* intentionally bogus value */
264 /* FIXME: this is wrong wrong wrong */
265 return current_func
->stack_size
+ ((1 + s
->idx
) * 4);
268 static const char *pretty_offset(int ofs
)
270 static char esp_buf
[64];
273 sprintf(esp_buf
, "%d(%%esp)", ofs
);
275 strcpy(esp_buf
, "(%esp)");
280 static void stor_sym_init(struct symbol
*sym
)
282 struct storage
*stor
;
283 struct symbol_private
*priv
;
285 priv
= calloc(1, sizeof(*priv
) + sizeof(*stor
));
287 die("OOM in stor_sym_init");
289 stor
= (struct storage
*) (priv
+ 1);
292 stor
->type
= STOR_SYM
;
296 static const char *stor_op_name(struct storage
*s
)
298 static char name
[32];
302 strcpy(name
, pretty_offset((int) pseudo_offset(s
)));
305 strcpy(name
, pretty_offset((int) arg_offset(s
)));
308 strcpy(name
, show_ident(s
->sym
->ident
));
311 strcpy(name
, s
->reg
->name
);
314 sprintf(name
, "$%Ld", s
->value
);
317 sprintf(name
, "%s.L%d", s
->flags
& STOR_LABEL_VAL
? "$" : "",
321 sprintf(name
, "%s.LS%p", s
->flags
& STOR_LABEL_VAL
? "$" : "",
329 static struct atom
*new_atom(enum atom_type type
)
333 atom
= calloc(1, sizeof(*atom
)); /* TODO: chunked alloc */
342 static inline void push_cstring(struct function
*f
, struct string
*str
,
347 atom
= new_atom(ATOM_CSTR
);
351 add_ptr_list(&f
->str_list
, atom
); /* note: _not_ atom_list */
354 static inline void push_atom(struct function
*f
, struct atom
*atom
)
356 add_ptr_list(&f
->atom_list
, atom
);
359 static void push_text_atom(struct function
*f
, const char *text
)
361 struct atom
*atom
= new_atom(ATOM_TEXT
);
363 atom
->text
= strdup(text
);
364 atom
->text_len
= strlen(text
);
369 static struct storage
*new_storage(enum storage_type type
)
371 struct storage
*stor
;
373 stor
= calloc(1, sizeof(*stor
));
375 die("OOM in new_storage");
382 static struct storage
*stack_alloc(int n_bytes
)
384 struct function
*f
= current_func
;
385 struct storage
*stor
;
389 stor
= new_storage(STOR_PSEUDO
);
390 stor
->type
= STOR_PSEUDO
;
391 stor
->pseudo
= f
->pseudo_nr
;
392 stor
->offset
= f
->stack_size
; /* FIXME: stack req. natural align */
393 stor
->size
= n_bytes
;
394 f
->stack_size
+= n_bytes
;
397 add_ptr_list(&f
->pseudo_list
, stor
);
402 static struct storage
*new_labelsym(struct symbol
*sym
)
404 struct storage
*stor
;
406 stor
= new_storage(STOR_LABELSYM
);
409 stor
->flags
|= STOR_WANTS_FREE
;
410 stor
->labelsym
= sym
;
416 static struct storage
*new_val(long long value
)
418 struct storage
*stor
;
420 stor
= new_storage(STOR_VALUE
);
423 stor
->flags
|= STOR_WANTS_FREE
;
430 static int new_label(void)
432 static int label
= 0;
436 static void textbuf_push(struct textbuf
**buf_p
, const char *text
)
438 struct textbuf
*tmp
, *list
= *buf_p
;
439 unsigned int text_len
= strlen(text
);
440 unsigned int alloc_len
= text_len
+ 1 + sizeof(*list
);
442 tmp
= calloc(1, alloc_len
);
444 die("OOM on textbuf alloc");
446 tmp
->text
= ((void *) tmp
) + sizeof(*tmp
);
447 memcpy(tmp
->text
, text
, text_len
+ 1);
450 /* add to end of list */
455 tmp
->prev
= list
->prev
;
456 tmp
->prev
->next
= tmp
;
464 static void textbuf_emit(struct textbuf
**buf_p
)
466 struct textbuf
*tmp
, *list
= *buf_p
;
470 if (tmp
->next
== tmp
)
473 tmp
->prev
->next
= tmp
->next
;
474 tmp
->next
->prev
= tmp
->prev
;
478 fputs(tmp
->text
, stdout
);
486 static void insn(const char *insn
, struct storage
*op1
, struct storage
*op2
,
487 const char *comment_in
)
489 struct function
*f
= current_func
;
490 struct atom
*atom
= new_atom(ATOM_INSN
);
492 assert(insn
!= NULL
);
494 strcpy(atom
->insn
, insn
);
495 if (comment_in
&& (*comment_in
))
496 strncpy(atom
->comment
, comment_in
,
497 sizeof(atom
->comment
) - 1);
505 static void emit_label (int label
, const char *comment
)
507 struct function
*f
= current_func
;
511 sprintf(s
, ".L%d:\n", label
);
513 sprintf(s
, ".L%d:\t\t\t\t\t# %s\n", label
, comment
);
515 push_text_atom(f
, s
);
518 static void emit_labelsym (struct symbol
*sym
, const char *comment
)
520 struct function
*f
= current_func
;
524 sprintf(s
, ".LS%p:\n", sym
);
526 sprintf(s
, ".LS%p:\t\t\t\t# %s\n", sym
, comment
);
528 push_text_atom(f
, s
);
531 void emit_unit_begin(const char *basename
)
533 printf("\t.file\t\"%s\"\n", basename
);
536 void emit_unit_end(void)
538 textbuf_emit(&unit_post_text
);
539 printf("\t.ident\t\"sparse silly x86 backend (built %s)\"\n", __DATE__
);
542 /* conditionally switch sections */
543 static void emit_section(const char *s
)
545 if (s
== current_section
)
547 if (current_section
&& (!strcmp(s
, current_section
)))
554 static void emit_insn_atom(struct function
*f
, struct atom
*atom
)
558 struct storage
*op1
= atom
->op1
;
559 struct storage
*op2
= atom
->op2
;
561 if (atom
->comment
[0])
562 sprintf(comment
, "\t\t# %s", atom
->comment
);
568 strcpy(tmp
, stor_op_name(op1
));
569 sprintf(s
, "\t%s\t%s, %s%s\n",
570 atom
->insn
, tmp
, stor_op_name(op2
), comment
);
571 } else if (atom
->op1
)
572 sprintf(s
, "\t%s\t%s%s%s\n",
573 atom
->insn
, stor_op_name(op1
),
574 comment
[0] ? "\t" : "", comment
);
576 sprintf(s
, "\t%s\t%s%s\n",
578 comment
[0] ? "\t\t" : "", comment
);
580 write(STDOUT_FILENO
, s
, strlen(s
));
583 static void emit_atom_list(struct function
*f
)
587 FOR_EACH_PTR(f
->atom_list
, atom
) {
588 switch (atom
->type
) {
590 ssize_t rc
= write(STDOUT_FILENO
, atom
->text
,
592 (void) rc
; /* FIXME */
596 emit_insn_atom(f
, atom
);
605 static void emit_string_list(struct function
*f
)
609 emit_section(".section\t.rodata");
611 FOR_EACH_PTR(f
->str_list
, atom
) {
612 /* FIXME: escape " in string */
613 printf(".L%d:\n", atom
->label
);
614 printf("\t.string\t%s\n", show_string(atom
->string
));
620 static void func_cleanup(struct function
*f
)
622 struct storage
*stor
;
625 FOR_EACH_PTR(f
->pseudo_list
, stor
) {
629 FOR_EACH_PTR(f
->atom_list
, atom
) {
630 if ((atom
->type
== ATOM_TEXT
) && (atom
->text
))
632 if (atom
->op1
&& (atom
->op1
->flags
& STOR_WANTS_FREE
))
634 if (atom
->op2
&& (atom
->op2
->flags
& STOR_WANTS_FREE
))
639 free_ptr_list(&f
->pseudo_list
);
643 /* function prologue */
644 static void emit_func_pre(struct symbol
*sym
)
648 unsigned int i
, argc
= 0, alloc_len
;
650 struct symbol_private
*privbase
;
651 struct storage
*storage_base
;
652 struct symbol
*base_type
= sym
->ctype
.base_type
;
654 FOR_EACH_PTR(base_type
->arguments
, arg
) {
660 (argc
* sizeof(struct symbol
*)) +
661 (argc
* sizeof(struct symbol_private
)) +
662 (argc
* sizeof(struct storage
));
663 mem
= calloc(1, alloc_len
);
665 die("OOM on func info");
667 f
= (struct function
*) mem
;
669 f
->argv
= (struct symbol
**) mem
;
670 mem
+= (argc
* sizeof(struct symbol
*));
671 privbase
= (struct symbol_private
*) mem
;
672 mem
+= (argc
* sizeof(struct symbol_private
));
673 storage_base
= (struct storage
*) mem
;
676 f
->ret_target
= new_label();
679 FOR_EACH_PTR(base_type
->arguments
, arg
) {
681 arg
->aux
= &privbase
[i
];
682 storage_base
[i
].type
= STOR_ARG
;
683 storage_base
[i
].idx
= i
;
684 privbase
[i
].addr
= &storage_base
[i
];
688 assert(current_func
== NULL
);
692 /* function epilogue */
693 static void emit_func_post(struct symbol
*sym
)
695 const char *name
= show_ident(sym
->ident
);
696 struct function
*f
= current_func
;
697 int stack_size
= f
->stack_size
;
702 /* function prologue */
703 emit_section(".text");
704 if ((sym
->ctype
.modifiers
& MOD_STATIC
) == 0)
705 printf(".globl %s\n", name
);
706 printf("\t.type\t%s, @function\n", name
);
707 printf("%s:\n", name
);
710 char pseudo_const
[16];
712 sprintf(pseudo_const
, "$%d", stack_size
);
713 printf("\tsubl\t%s, %%esp\n", pseudo_const
);
716 /* function epilogue */
718 /* jump target for 'return' statements */
719 emit_label(f
->ret_target
, NULL
);
724 val
= new_storage(STOR_VALUE
);
725 val
->value
= (long long) (stack_size
);
726 val
->flags
= STOR_WANTS_FREE
;
728 insn("addl", val
, REG_ESP
, NULL
);
731 insn("ret", NULL
, NULL
, NULL
);
733 /* output everything to stdout */
734 fflush(stdout
); /* paranoia; needed? */
737 /* function footer */
738 name
= show_ident(sym
->ident
);
739 printf("\t.size\t%s, .-%s\n", name
, name
);
745 /* emit object (a.k.a. variable, a.k.a. data) prologue */
746 static void emit_object_pre(const char *name
, unsigned long modifiers
,
747 unsigned long alignment
, unsigned int byte_size
)
749 if ((modifiers
& MOD_STATIC
) == 0)
750 printf(".globl %s\n", name
);
751 emit_section(".data");
753 printf("\t.align %lu\n", alignment
);
754 printf("\t.type\t%s, @object\n", name
);
755 printf("\t.size\t%s, %d\n", name
, byte_size
);
756 printf("%s:\n", name
);
759 /* emit value (only) for an initializer scalar */
760 static void emit_scalar(struct expression
*expr
, unsigned int bit_size
)
765 assert(expr
->type
== EXPR_VALUE
);
767 if (expr
->value
== 0ULL) {
768 printf("\t.zero\t%d\n", bit_size
/ 8);
772 ll
= (long long) expr
->value
;
775 case 8: type
= "byte"; ll
= (char) ll
; break;
776 case 16: type
= "value"; ll
= (short) ll
; break;
777 case 32: type
= "long"; ll
= (int) ll
; break;
778 case 64: type
= "quad"; break;
779 default: type
= NULL
; break;
782 assert(type
!= NULL
);
784 printf("\t.%s\t%Ld\n", type
, ll
);
787 static void emit_global_noinit(const char *name
, unsigned long modifiers
,
788 unsigned long alignment
, unsigned int byte_size
)
792 if (modifiers
& MOD_STATIC
) {
793 sprintf(s
, "\t.local\t%s\n", name
);
794 textbuf_push(&unit_post_text
, s
);
797 sprintf(s
, "\t.comm\t%s,%d,%lu\n", name
, byte_size
, alignment
);
799 sprintf(s
, "\t.comm\t%s,%d\n", name
, byte_size
);
800 textbuf_push(&unit_post_text
, s
);
803 static int ea_current
, ea_last
;
805 static void emit_initializer(struct symbol
*sym
,
806 struct expression
*expr
)
808 int distance
= ea_current
- ea_last
- 1;
811 printf("\t.zero\t%d\n", (sym
->bit_size
/ 8) * distance
);
813 if (expr
->type
== EXPR_VALUE
) {
814 struct symbol
*base_type
= sym
->ctype
.base_type
;
815 assert(base_type
!= NULL
);
817 emit_scalar(expr
, sym
->bit_size
/ get_expression_value(base_type
->array_size
));
820 if (expr
->type
!= EXPR_INITIALIZER
)
823 assert(0); /* FIXME */
826 static int sort_array_cmp(const struct expression
*a
,
827 const struct expression
*b
)
829 int a_ofs
= 0, b_ofs
= 0;
831 if (a
->type
== EXPR_POS
)
832 a_ofs
= (int) a
->init_offset
;
833 if (b
->type
== EXPR_POS
)
834 b_ofs
= (int) b
->init_offset
;
836 return a_ofs
- b_ofs
;
839 /* move to front-end? */
840 static void sort_array(struct expression
*expr
)
842 struct expression
*entry
, **list
;
843 unsigned int elem
, sorted
, i
;
846 FOR_EACH_PTR(expr
->expr_list
, entry
) {
853 list
= malloc(sizeof(entry
) * elem
);
855 die("OOM in sort_array");
857 /* this code is no doubt evil and ignores EXPR_INDEX possibly
858 * to its detriment and other nasty things. improvements
863 FOR_EACH_PTR(expr
->expr_list
, entry
) {
864 if ((entry
->type
== EXPR_POS
) || (entry
->type
== EXPR_VALUE
)) {
865 /* add entry to list[], in sorted order */
872 for (i
= 0; i
< sorted
; i
++)
873 if (sort_array_cmp(entry
, list
[i
]) <= 0)
876 /* If inserting into the middle of list[]
877 * instead of appending, we memmove.
878 * This is ugly, but thankfully
879 * uncommon. Input data with tons of
880 * entries very rarely have explicit
881 * offsets. convert to qsort eventually...
884 memmove(&list
[i
+ 1], &list
[i
],
885 (sorted
- i
) * sizeof(entry
));
893 FOR_EACH_PTR(expr
->expr_list
, entry
) {
894 if ((entry
->type
== EXPR_POS
) || (entry
->type
== EXPR_VALUE
))
895 __list
->list
[__i
] = list
[i
++];
900 static void emit_array(struct symbol
*sym
)
902 struct symbol
*base_type
= sym
->ctype
.base_type
;
903 struct expression
*expr
= sym
->initializer
;
904 struct expression
*entry
;
906 assert(base_type
!= NULL
);
912 emit_object_pre(show_ident(sym
->ident
), sym
->ctype
.modifiers
,
913 sym
->ctype
.alignment
,
918 FOR_EACH_PTR(expr
->expr_list
, entry
) {
919 if (entry
->type
== EXPR_VALUE
) {
921 emit_initializer(sym
, entry
);
922 ea_last
= ea_current
;
923 } else if (entry
->type
== EXPR_POS
) {
925 entry
->init_offset
/ (base_type
->bit_size
/ 8);
926 emit_initializer(sym
, entry
->init_expr
);
927 ea_last
= ea_current
;
932 void emit_one_symbol(struct symbol
*sym
)
937 static void emit_copy(struct storage
*dest
, struct storage
*src
,
938 struct symbol
*ctype
)
940 struct storage
*reg
= NULL
;
941 unsigned int bit_size
;
943 /* FIXME: Bitfield copy! */
945 bit_size
= src
->size
* 8;
948 if ((src
->type
== STOR_ARG
) && (bit_size
< 32))
951 reg
= temp_from_bits(bit_size
);
952 emit_move(src
, reg
, ctype
, "begin copy ..");
954 bit_size
= dest
->size
* 8;
957 if ((dest
->type
== STOR_ARG
) && (bit_size
< 32))
960 reg
= temp_from_bits(bit_size
);
961 emit_move(reg
, dest
, ctype
, ".... end copy");
964 static void emit_store(struct expression
*dest_expr
, struct storage
*dest
,
965 struct storage
*src
, int bits
)
967 /* FIXME: Bitfield store! */
968 printf("\tst.%d\t\tv%d,[v%d]\n", bits
, src
->pseudo
, dest
->pseudo
);
971 static void emit_scalar_noinit(struct symbol
*sym
)
973 emit_global_noinit(show_ident(sym
->ident
),
974 sym
->ctype
.modifiers
, sym
->ctype
.alignment
,
979 static void emit_array_noinit(struct symbol
*sym
)
981 emit_global_noinit(show_ident(sym
->ident
),
982 sym
->ctype
.modifiers
, sym
->ctype
.alignment
,
983 get_expression_value(sym
->array_size
) * (sym
->bit_size
/ 8));
987 static const char *opbits(const char *insn
, unsigned int bits
)
989 static char opbits_str
[32];
993 case 8: c
= 'b'; break;
994 case 16: c
= 'w'; break;
995 case 32: c
= 'l'; break;
996 case 64: c
= 'q'; break;
997 default: assert(0); break;
1000 sprintf(opbits_str
, "%s%c", insn
, c
);
1005 static void emit_move(struct storage
*src
, struct storage
*dest
,
1006 struct symbol
*ctype
, const char *comment
)
1009 unsigned int is_signed
;
1010 unsigned int is_dest
= (src
->type
== STOR_REG
);
1014 bits
= ctype
->bit_size
;
1015 is_signed
= type_is_signed(ctype
);
1021 if ((dest
->type
== STOR_REG
) && (src
->type
== STOR_REG
)) {
1022 insn("mov", src
, dest
, NULL
);
1026 if ((bits
== 8) || (bits
== 16)) {
1030 opname
= is_signed
? "movsx" : "movzx";
1034 insn(opbits(opname
, bits
), src
, dest
, comment
);
1037 static struct storage
*emit_compare(struct expression
*expr
)
1039 struct storage
*left
= x86_expression(expr
->left
);
1040 struct storage
*right
= x86_expression(expr
->right
);
1041 struct storage
*new, *val
;
1042 const char *opname
= NULL
;
1043 unsigned int right_bits
= expr
->right
->ctype
->bit_size
;
1046 case '<': opname
= "setl"; break;
1047 case '>': opname
= "setg"; break;
1049 opname
= "setle"; break;
1051 opname
= "setge"; break;
1052 case SPECIAL_EQUAL
: opname
= "sete"; break;
1053 case SPECIAL_NOTEQUAL
: opname
= "setne"; break;
1054 case SPECIAL_UNSIGNED_LT
:
1055 opname
= "setb"; break;
1056 case SPECIAL_UNSIGNED_GT
:
1057 opname
= "seta"; break;
1058 case SPECIAL_UNSIGNED_LTE
:
1059 opname
= "setb"; break;
1060 case SPECIAL_UNSIGNED_GTE
:
1061 opname
= "setae"; break;
1068 val
= new_storage(STOR_VALUE
);
1069 val
->flags
= STOR_WANTS_FREE
;
1070 emit_move(val
, REG_EDX
, NULL
, NULL
);
1072 /* move op1 into EAX */
1073 emit_move(left
, REG_EAX
, expr
->left
->ctype
, NULL
);
1075 /* perform comparison, RHS (op1, right) and LHS (op2, EAX) */
1076 insn(opbits("cmp", right_bits
), right
, REG_EAX
, NULL
);
1078 /* store result of operation, 0 or 1, in DL using SETcc */
1079 insn(opname
, REG_DL
, NULL
, NULL
);
1081 /* finally, store the result (DL) in a new pseudo / stack slot */
1082 new = stack_alloc(4);
1083 emit_move(REG_EDX
, new, NULL
, "end EXPR_COMPARE");
1088 static struct storage
*emit_value(struct expression
*expr
)
1090 #if 0 /* old and slow way */
1091 struct storage
*new = stack_alloc(4);
1092 struct storage
*val
;
1094 val
= new_storage(STOR_VALUE
);
1095 val
->value
= (long long) expr
->value
;
1096 val
->flags
= STOR_WANTS_FREE
;
1097 insn("movl", val
, new, NULL
);
1101 struct storage
*val
;
1103 val
= new_storage(STOR_VALUE
);
1104 val
->value
= (long long) expr
->value
;
1106 return val
; /* FIXME: memory leak */
1110 static struct storage
*emit_binop(struct expression
*expr
)
1112 struct storage
*left
= x86_expression(expr
->left
);
1113 struct storage
*right
= x86_expression(expr
->right
);
1114 struct storage
*new;
1115 struct storage
*accum_reg
= NULL
;
1116 struct storage
*result_reg
= NULL
;
1117 const char *opname
= NULL
;
1119 char movstr
[16], opstr
[16];
1120 int is_signed
, doing_divide
= 0;
1122 if ((expr
->op
== '/') || (expr
->op
== '%')) {
1123 struct storage
*val
;
1127 val
= new_storage(STOR_VALUE
);
1128 val
->flags
= STOR_WANTS_FREE
;
1129 emit_move(val
, REG_EDX
, NULL
, "begin EXPR_DIVIDE");
1132 is_signed
= type_is_signed(expr
->ctype
);
1150 case SPECIAL_LEFTSHIFT
:
1153 case SPECIAL_RIGHTSHIFT
:
1172 case SPECIAL_LOGICAL_AND
:
1173 warn(expr
->pos
, "bogus bitwise and for logical op (should use '2*setne + and' or something)");
1176 case SPECIAL_LOGICAL_OR
:
1177 warn(expr
->pos
, "bogus bitwise or for logical op (should use 'or + setne' or something)");
1181 error(expr
->pos
, "unhandled binop '%s'\n", show_special(expr
->op
));
1185 switch (expr
->ctype
->bit_size
) {
1188 result_reg
= accum_reg
= REG_AL
;
1189 if (expr
->op
== '%')
1190 result_reg
= REG_DL
;
1194 result_reg
= accum_reg
= REG_AX
;
1195 if (expr
->op
== '%')
1196 result_reg
= REG_DX
;
1200 result_reg
= accum_reg
= REG_EAX
;
1201 if (expr
->op
== '%')
1202 result_reg
= REG_EDX
;
1205 suffix
= "q"; /* FIXME */
1206 result_reg
= accum_reg
= REG_EAX
; /* FIXME */
1207 if (expr
->op
== '%')
1208 result_reg
= REG_EDX
;
1215 sprintf(movstr
, "mov%s", suffix
);
1216 sprintf(opstr
, "%s%s", opname
, suffix
);
1218 /* load op2 into EAX */
1219 insn(movstr
, right
, accum_reg
,
1220 doing_divide
? NULL
: "EXPR_BINOP/COMMA/LOGICAL");
1223 insn(opstr
, left
, accum_reg
, NULL
);
1225 /* store result (EAX or EDX) in new pseudo / stack slot */
1226 new = stack_alloc(expr
->ctype
->bit_size
/ 8);
1227 insn(movstr
, result_reg
, new,
1228 doing_divide
? "end EXPR_DIVIDE" : "end EXPR_BINOP");
1233 static int emit_conditional_test(struct storage
*val
)
1235 struct storage
*target_val
;
1238 /* load result into EAX */
1239 insn("movl", val
, REG_EAX
, "begin if/conditional");
1241 /* compare result with zero */
1242 insn("test", REG_EAX
, REG_EAX
, NULL
);
1244 /* create conditional-failed label to jump to */
1245 target_false
= new_label();
1246 target_val
= new_storage(STOR_LABEL
);
1247 target_val
->label
= target_false
;
1248 target_val
->flags
= STOR_WANTS_FREE
;
1249 insn("jz", target_val
, NULL
, NULL
);
1251 return target_false
;
1254 static int emit_conditional_end(int target_false
)
1256 struct storage
*cond_end_st
;
1259 /* finished generating code for if-true statement.
1260 * add a jump-to-end jump to avoid falling through
1261 * to the if-false statement code.
1263 cond_end
= new_label();
1264 cond_end_st
= new_storage(STOR_LABEL
);
1265 cond_end_st
->label
= cond_end
;
1266 cond_end_st
->flags
= STOR_WANTS_FREE
;
1267 insn("jmp", cond_end_st
, NULL
, NULL
);
1269 /* if we have both if-true and if-false statements,
1270 * the failed-conditional case will fall through to here
1272 emit_label(target_false
, NULL
);
1277 static void emit_if_conditional(struct statement
*stmt
)
1279 struct storage
*val
;
1282 /* emit test portion of conditional */
1283 val
= x86_expression(stmt
->if_conditional
);
1284 cond_end
= emit_conditional_test(val
);
1286 /* emit if-true statement */
1287 x86_statement(stmt
->if_true
);
1289 /* emit if-false statement, if present */
1290 if (stmt
->if_false
) {
1291 cond_end
= emit_conditional_end(cond_end
);
1292 x86_statement(stmt
->if_false
);
1295 /* end of conditional; jump target for if-true branch */
1296 emit_label(cond_end
, "end if");
1299 static struct storage
*emit_inc_dec(struct expression
*expr
, int postop
)
1301 struct storage
*addr
= x86_address_gen(expr
->unop
);
1302 struct storage
*retval
;
1305 strcpy(opname
, opbits(expr
->op
== SPECIAL_INCREMENT
? "inc" : "dec",
1306 expr
->ctype
->bit_size
));
1309 struct storage
*new = stack_alloc(4);
1311 emit_copy(new, addr
, expr
->unop
->ctype
);
1317 insn(opname
, addr
, NULL
, NULL
);
1322 static struct storage
*emit_postop(struct expression
*expr
)
1324 return emit_inc_dec(expr
, 1);
1327 static struct storage
*emit_return_stmt(struct statement
*stmt
)
1329 struct function
*f
= current_func
;
1330 struct expression
*expr
= stmt
->ret_value
;
1331 struct storage
*val
= NULL
, *jmplbl
;
1333 if (expr
&& expr
->ctype
) {
1334 val
= x86_expression(expr
);
1335 assert(val
!= NULL
);
1336 emit_move(val
, REG_EAX
, expr
->ctype
, "return");
1339 jmplbl
= new_storage(STOR_LABEL
);
1340 jmplbl
->flags
|= STOR_WANTS_FREE
;
1341 jmplbl
->label
= f
->ret_target
;
1342 insn("jmp", jmplbl
, NULL
, NULL
);
1347 static struct storage
*emit_conditional_expr(struct expression
*expr
)
1349 struct storage
*cond
, *true = NULL
, *false = NULL
;
1350 struct storage
*new = stack_alloc(expr
->ctype
->bit_size
/ 8);
1351 int target_false
, cond_end
;
1353 /* evaluate conditional */
1354 cond
= x86_expression(expr
->conditional
);
1355 target_false
= emit_conditional_test(cond
);
1357 /* handle if-true part of the expression */
1358 if (!expr
->cond_true
)
1361 true = x86_expression(expr
->cond_true
);
1363 emit_copy(new, true, expr
->ctype
);
1365 cond_end
= emit_conditional_end(target_false
);
1367 /* handle if-false part of the expression */
1368 false = x86_expression(expr
->cond_false
);
1370 emit_copy(new, false, expr
->ctype
);
1372 /* end of conditional; jump target for if-true branch */
1373 emit_label(cond_end
, "end conditional");
1378 static struct storage
*emit_select_expr(struct expression
*expr
)
1380 struct storage
*cond
= x86_expression(expr
->conditional
);
1381 struct storage
*true = x86_expression(expr
->cond_true
);
1382 struct storage
*false = x86_expression(expr
->cond_false
);
1383 struct storage
*new = stack_alloc(4);
1384 struct storage
*truereg
;
1386 emit_move(cond
, REG_EAX
, expr
->conditional
->ctype
, "begin SELECT");
1389 emit_move(true, REG_ECX
, expr
->cond_true
->ctype
, NULL
);
1392 emit_move(false, REG_EDX
, expr
->cond_false
->ctype
, NULL
);
1395 * Do the actual select: check the conditional for zero,
1396 * move false over true if zero
1398 insn("test", REG_EAX
, REG_EAX
, NULL
);
1399 insn("cmovz", REG_EDX
, truereg
, NULL
);
1402 emit_move(truereg
, new, expr
->ctype
, "end SELECT");
1406 static struct storage
*emit_symbol_expr_init(struct symbol
*sym
)
1408 struct expression
*expr
= sym
->initializer
;
1409 struct symbol_private
*priv
= sym
->aux
;
1412 priv
= calloc(1, sizeof(*priv
));
1416 struct storage
*new = stack_alloc(4);
1417 fprintf(stderr
, "FIXME! no value for symbol %s. creating pseudo %d (stack offset %d)\n",
1418 show_ident(sym
->ident
),
1419 new->pseudo
, new->pseudo
* 4);
1422 priv
->addr
= x86_expression(expr
);
1429 static struct storage
*emit_string_expr(struct expression
*expr
)
1431 struct function
*f
= current_func
;
1432 int label
= new_label();
1433 struct storage
*new;
1435 push_cstring(f
, expr
->string
, label
);
1437 new = new_storage(STOR_LABEL
);
1439 new->flags
= STOR_LABEL_VAL
| STOR_WANTS_FREE
;
1443 static struct storage
*emit_cast_expr(struct expression
*expr
)
1445 struct symbol
*old_type
, *new_type
;
1446 struct storage
*op
= x86_expression(expr
->cast_expression
);
1447 int oldbits
, newbits
;
1448 struct storage
*new;
1450 old_type
= expr
->cast_expression
->ctype
;
1451 new_type
= expr
->cast_type
;
1453 oldbits
= old_type
->bit_size
;
1454 newbits
= new_type
->bit_size
;
1455 if (oldbits
>= newbits
)
1458 emit_move(op
, REG_EAX
, old_type
, "begin cast ..");
1460 new = stack_alloc(newbits
/ 8);
1461 emit_move(REG_EAX
, new, new_type
, ".... end cast");
1466 static struct storage
*emit_regular_preop(struct expression
*expr
)
1468 struct storage
*target
= x86_expression(expr
->unop
);
1469 struct storage
*val
, *new = stack_alloc(4);
1470 const char *opname
= NULL
;
1474 val
= new_storage(STOR_VALUE
);
1475 val
->flags
= STOR_WANTS_FREE
;
1476 emit_move(val
, REG_EDX
, NULL
, NULL
);
1477 emit_move(target
, REG_EAX
, expr
->unop
->ctype
, NULL
);
1478 insn("test", REG_EAX
, REG_EAX
, NULL
);
1479 insn("setz", REG_DL
, NULL
, NULL
);
1480 emit_move(REG_EDX
, new, expr
->unop
->ctype
, NULL
);
1488 emit_move(target
, REG_EAX
, expr
->unop
->ctype
, NULL
);
1489 insn(opname
, REG_EAX
, NULL
, NULL
);
1490 emit_move(REG_EAX
, new, expr
->unop
->ctype
, NULL
);
1500 static void emit_case_statement(struct statement
*stmt
)
1502 emit_labelsym(stmt
->case_label
, NULL
);
1503 x86_statement(stmt
->case_statement
);
1506 static void emit_switch_statement(struct statement
*stmt
)
1508 struct storage
*val
= x86_expression(stmt
->switch_expression
);
1509 struct symbol
*sym
, *default_sym
= NULL
;
1510 struct storage
*labelsym
, *label
;
1513 emit_move(val
, REG_EAX
, stmt
->switch_expression
->ctype
, "begin case");
1516 * This is where a _real_ back-end would go through the
1517 * cases to decide whether to use a lookup table or a
1518 * series of comparisons etc
1520 FOR_EACH_PTR(stmt
->switch_case
->symbol_list
, sym
) {
1521 struct statement
*case_stmt
= sym
->stmt
;
1522 struct expression
*expr
= case_stmt
->case_expression
;
1523 struct expression
*to
= case_stmt
->case_to
;
1531 struct storage
*case_val
= new_val(expr
->value
);
1533 assert (expr
->type
== EXPR_VALUE
);
1535 insn("cmpl", case_val
, REG_EAX
, NULL
);
1538 labelsym
= new_labelsym(sym
);
1539 insn("je", labelsym
, NULL
, NULL
);
1543 label
= new_storage(STOR_LABEL
);
1544 label
->flags
|= STOR_WANTS_FREE
;
1545 label
->label
= next_test
= new_label();
1547 /* FIXME: signed/unsigned */
1548 insn("jl", label
, NULL
, NULL
);
1550 case_val
= new_val(to
->value
);
1551 insn("cmpl", case_val
, REG_EAX
, NULL
);
1553 /* TODO: implement and use refcounting... */
1554 label
= new_storage(STOR_LABEL
);
1555 label
->flags
|= STOR_WANTS_FREE
;
1556 label
->label
= next_test
;
1558 /* FIXME: signed/unsigned */
1559 insn("jg", label
, NULL
, NULL
);
1561 labelsym
= new_labelsym(sym
);
1562 insn("jmp", labelsym
, NULL
, NULL
);
1564 emit_label(next_test
, NULL
);
1570 labelsym
= new_labelsym(default_sym
);
1571 insn("jmp", labelsym
, NULL
, "default");
1573 label
= new_storage(STOR_LABEL
);
1574 label
->flags
|= STOR_WANTS_FREE
;
1575 label
->label
= switch_end
= new_label();
1576 insn("jmp", label
, NULL
, "goto end of switch");
1579 x86_statement(stmt
->switch_statement
);
1581 if (stmt
->switch_break
->used
)
1582 emit_labelsym(stmt
->switch_break
, NULL
);
1585 emit_label(switch_end
, NULL
);
1588 static void x86_struct_member(struct symbol
*sym
, void *data
, int flags
)
1590 if (flags
& ITERATE_FIRST
)
1592 printf("%s:%d:%ld at offset %ld", show_ident(sym
->ident
), sym
->bit_size
, sym
->ctype
.alignment
, sym
->offset
);
1593 if (sym
->fieldwidth
)
1594 printf("[%d..%d]", sym
->bit_offset
, sym
->bit_offset
+sym
->fieldwidth
-1);
1595 if (flags
& ITERATE_LAST
)
1601 static void x86_symbol(struct symbol
*sym
)
1603 struct symbol
*type
;
1608 type
= sym
->ctype
.base_type
;
1613 * Show actual implementation information
1615 switch (type
->type
) {
1618 if (sym
->initializer
)
1621 emit_array_noinit(sym
);
1625 if (sym
->initializer
) {
1626 emit_object_pre(show_ident(sym
->ident
),
1627 sym
->ctype
.modifiers
,
1628 sym
->ctype
.alignment
,
1630 emit_scalar(sym
->initializer
, sym
->bit_size
);
1633 emit_scalar_noinit(sym
);
1637 symbol_iterate(type
->symbol_list
, x86_struct_member
, NULL
);
1641 symbol_iterate(type
->symbol_list
, x86_struct_member
, NULL
);
1645 struct statement
*stmt
= type
->stmt
;
1648 x86_statement(stmt
);
1649 emit_func_post(sym
);
1658 if (sym
->initializer
&& (type
->type
!= SYM_BASETYPE
) &&
1659 (type
->type
!= SYM_ARRAY
)) {
1661 x86_expression(sym
->initializer
);
1665 static void x86_symbol_init(struct symbol
*sym
);
1667 static void x86_symbol_decl(struct symbol_list
*syms
)
1670 FOR_EACH_PTR(syms
, sym
) {
1671 x86_symbol_init(sym
);
1675 static void loopstk_push(int cont_lbl
, int loop_bottom_lbl
)
1677 struct function
*f
= current_func
;
1678 struct loop_stack
*ls
;
1680 ls
= malloc(sizeof(*ls
));
1681 ls
->continue_lbl
= cont_lbl
;
1682 ls
->loop_bottom_lbl
= loop_bottom_lbl
;
1683 ls
->next
= f
->loop_stack
;
1687 static void loopstk_pop(void)
1689 struct function
*f
= current_func
;
1690 struct loop_stack
*ls
;
1692 assert(f
->loop_stack
!= NULL
);
1694 f
->loop_stack
= f
->loop_stack
->next
;
1698 static int loopstk_break(void)
1700 return current_func
->loop_stack
->loop_bottom_lbl
;
1703 static int loopstk_continue(void)
1705 return current_func
->loop_stack
->continue_lbl
;
1708 static void emit_loop(struct statement
*stmt
)
1710 struct statement
*pre_statement
= stmt
->iterator_pre_statement
;
1711 struct expression
*pre_condition
= stmt
->iterator_pre_condition
;
1712 struct statement
*statement
= stmt
->iterator_statement
;
1713 struct statement
*post_statement
= stmt
->iterator_post_statement
;
1714 struct expression
*post_condition
= stmt
->iterator_post_condition
;
1715 int loop_top
= 0, loop_bottom
, loop_continue
;
1716 int have_bottom
= 0;
1717 struct storage
*val
;
1719 loop_bottom
= new_label();
1720 loop_continue
= new_label();
1721 loopstk_push(loop_continue
, loop_bottom
);
1723 x86_symbol_decl(stmt
->iterator_syms
);
1724 x86_statement(pre_statement
);
1725 if (pre_condition
) {
1726 if (pre_condition
->type
== EXPR_VALUE
) {
1727 if (!pre_condition
->value
) {
1728 struct storage
*lbv
;
1729 lbv
= new_storage(STOR_LABEL
);
1730 lbv
->label
= loop_bottom
;
1731 lbv
->flags
= STOR_WANTS_FREE
;
1732 insn("jmp", lbv
, NULL
, "go to loop bottom");
1736 struct storage
*lbv
= new_storage(STOR_LABEL
);
1737 lbv
->label
= loop_bottom
;
1738 lbv
->flags
= STOR_WANTS_FREE
;
1741 val
= x86_expression(pre_condition
);
1743 emit_move(val
, REG_EAX
, NULL
, "loop pre condition");
1744 insn("test", REG_EAX
, REG_EAX
, NULL
);
1745 insn("jz", lbv
, NULL
, NULL
);
1748 if (!post_condition
|| post_condition
->type
!= EXPR_VALUE
|| post_condition
->value
) {
1749 loop_top
= new_label();
1750 emit_label(loop_top
, "loop top");
1752 x86_statement(statement
);
1753 if (stmt
->iterator_continue
->used
)
1754 emit_label(loop_continue
, "'continue' iterator");
1755 x86_statement(post_statement
);
1756 if (!post_condition
) {
1757 struct storage
*lbv
= new_storage(STOR_LABEL
);
1758 lbv
->label
= loop_top
;
1759 lbv
->flags
= STOR_WANTS_FREE
;
1760 insn("jmp", lbv
, NULL
, "go to loop top");
1761 } else if (post_condition
->type
== EXPR_VALUE
) {
1762 if (post_condition
->value
) {
1763 struct storage
*lbv
= new_storage(STOR_LABEL
);
1764 lbv
->label
= loop_top
;
1765 lbv
->flags
= STOR_WANTS_FREE
;
1766 insn("jmp", lbv
, NULL
, "go to loop top");
1769 struct storage
*lbv
= new_storage(STOR_LABEL
);
1770 lbv
->label
= loop_top
;
1771 lbv
->flags
= STOR_WANTS_FREE
;
1773 val
= x86_expression(post_condition
);
1775 emit_move(val
, REG_EAX
, NULL
, "loop post condition");
1776 insn("test", REG_EAX
, REG_EAX
, NULL
);
1777 insn("jnz", lbv
, NULL
, NULL
);
1779 if (have_bottom
|| stmt
->iterator_break
->used
)
1780 emit_label(loop_bottom
, "loop bottom");
1786 * Print out a statement
1788 static struct storage
*x86_statement(struct statement
*stmt
)
1792 switch (stmt
->type
) {
1794 return emit_return_stmt(stmt
);
1795 case STMT_COMPOUND
: {
1796 struct statement
*s
;
1797 struct storage
*last
= NULL
;
1799 x86_symbol_decl(stmt
->syms
);
1800 FOR_EACH_PTR(stmt
->stmts
, s
) {
1801 last
= x86_statement(s
);
1807 case STMT_EXPRESSION
:
1808 return x86_expression(stmt
->expression
);
1810 emit_if_conditional(stmt
);
1814 emit_case_statement(stmt
);
1817 emit_switch_statement(stmt
);
1828 printf(".L%p:\n", stmt
->label_identifier
);
1829 x86_statement(stmt
->label_statement
);
1833 if (stmt
->goto_expression
) {
1834 struct storage
*val
= x86_expression(stmt
->goto_expression
);
1835 printf("\tgoto *v%d\n", val
->pseudo
);
1836 } else if (!strcmp("break", show_ident(stmt
->goto_label
->ident
))) {
1837 struct storage
*lbv
= new_storage(STOR_LABEL
);
1838 lbv
->label
= loopstk_break();
1839 lbv
->flags
= STOR_WANTS_FREE
;
1840 insn("jmp", lbv
, NULL
, "'break'; go to loop bottom");
1841 } else if (!strcmp("continue", show_ident(stmt
->goto_label
->ident
))) {
1842 struct storage
*lbv
= new_storage(STOR_LABEL
);
1843 lbv
->label
= loopstk_continue();
1844 lbv
->flags
= STOR_WANTS_FREE
;
1845 insn("jmp", lbv
, NULL
, "'continue'; go to loop top");
1847 struct storage
*labelsym
= new_labelsym(stmt
->goto_label
);
1848 insn("jmp", labelsym
, NULL
, NULL
);
1852 printf("\tasm( .... )\n");
1858 static struct storage
*x86_call_expression(struct expression
*expr
)
1860 struct function
*f
= current_func
;
1861 struct symbol
*direct
;
1862 struct expression
*arg
, *fn
;
1863 struct storage
*retval
, *fncall
;
1868 warn(expr
->pos
, "\tcall with no type!");
1873 FOR_EACH_PTR_REVERSE(expr
->args
, arg
) {
1874 struct storage
*new = x86_expression(arg
);
1875 int size
= arg
->ctype
->bit_size
;
1878 * FIXME: i386 SysV ABI dictates that values
1879 * smaller than 32 bits should be placed onto
1880 * the stack as 32-bit objects. We should not
1881 * blindly do a 32-bit push on objects smaller
1886 insn("pushl", new, NULL
,
1887 !framesize
? "begin function call" : NULL
);
1889 framesize
+= size
>> 3;
1890 } END_FOR_EACH_PTR_REVERSE
;
1894 /* Remove dereference, if any */
1896 if (fn
->type
== EXPR_PREOP
) {
1897 if (fn
->unop
->type
== EXPR_SYMBOL
) {
1898 struct symbol
*sym
= fn
->unop
->symbol
;
1899 if (sym
->ctype
.base_type
->type
== SYM_FN
)
1904 struct storage
*direct_stor
= new_storage(STOR_SYM
);
1905 direct_stor
->flags
|= STOR_WANTS_FREE
;
1906 direct_stor
->sym
= direct
;
1907 insn("call", direct_stor
, NULL
, NULL
);
1909 fncall
= x86_expression(fn
);
1910 emit_move(fncall
, REG_EAX
, fn
->ctype
, NULL
);
1912 strcpy(s
, "\tcall\t*%eax\n");
1913 push_text_atom(f
, s
);
1916 /* FIXME: pay attention to BITS_IN_POINTER */
1918 struct storage
*val
= new_storage(STOR_VALUE
);
1919 val
->value
= (long long) framesize
;
1920 val
->flags
= STOR_WANTS_FREE
;
1921 insn("addl", val
, REG_ESP
, NULL
);
1924 retval
= stack_alloc(4);
1925 emit_move(REG_EAX
, retval
, NULL
, "end function call");
1930 static struct storage
*x86_address_gen(struct expression
*expr
)
1932 struct function
*f
= current_func
;
1933 struct storage
*addr
;
1934 struct storage
*new;
1937 if ((expr
->type
!= EXPR_PREOP
) || (expr
->op
!= '*'))
1938 return x86_expression(expr
->address
);
1940 addr
= x86_expression(expr
->unop
);
1941 if (expr
->unop
->type
== EXPR_SYMBOL
)
1944 emit_move(addr
, REG_EAX
, NULL
, "begin deref ..");
1946 /* FIXME: operand size */
1947 strcpy(s
, "\tmovl\t(%eax), %ecx\n");
1948 push_text_atom(f
, s
);
1950 new = stack_alloc(4);
1951 emit_move(REG_ECX
, new, NULL
, ".... end deref");
1956 static struct storage
*x86_assignment(struct expression
*expr
)
1958 struct expression
*target
= expr
->left
;
1959 struct storage
*val
, *addr
;
1964 val
= x86_expression(expr
->right
);
1965 addr
= x86_address_gen(target
);
1967 switch (val
->type
) {
1968 /* copy, where both operands are memory */
1971 emit_copy(addr
, val
, expr
->ctype
);
1974 /* copy, one or zero operands are memory */
1979 emit_move(val
, addr
, expr
->left
->ctype
, NULL
);
1989 static int x86_initialization(struct symbol
*sym
, struct expression
*expr
)
1991 struct storage
*val
, *addr
;
1997 bits
= expr
->ctype
->bit_size
;
1998 val
= x86_expression(expr
);
1999 addr
= x86_symbol_expr(sym
);
2000 // FIXME! The "target" expression is for bitfield store information.
2001 // Leave it NULL, which works fine.
2002 emit_store(NULL
, addr
, val
, bits
);
2006 static struct storage
*x86_access(struct expression
*expr
)
2008 return x86_address_gen(expr
);
2011 static struct storage
*x86_preop(struct expression
*expr
)
2014 * '*' is an lvalue access, and is fundamentally different
2015 * from an arithmetic operation. Maybe it should have an
2016 * expression type of its own..
2018 if (expr
->op
== '*')
2019 return x86_access(expr
);
2020 if (expr
->op
== SPECIAL_INCREMENT
|| expr
->op
== SPECIAL_DECREMENT
)
2021 return emit_inc_dec(expr
, 0);
2022 return emit_regular_preop(expr
);
2025 static struct storage
*x86_symbol_expr(struct symbol
*sym
)
2027 struct storage
*new = stack_alloc(4);
2029 if (sym
->ctype
.modifiers
& (MOD_TOPLEVEL
| MOD_EXTERN
| MOD_STATIC
)) {
2030 printf("\tmovi.%d\t\tv%d,$%s\n", bits_in_pointer
, new->pseudo
, show_ident(sym
->ident
));
2033 if (sym
->ctype
.modifiers
& MOD_ADDRESSABLE
) {
2034 printf("\taddi.%d\t\tv%d,vFP,$%lld\n", bits_in_pointer
, new->pseudo
, sym
->value
);
2037 printf("\taddi.%d\t\tv%d,vFP,$offsetof(%s:%p)\n", bits_in_pointer
, new->pseudo
, show_ident(sym
->ident
), sym
);
2041 static void x86_symbol_init(struct symbol
*sym
)
2043 struct symbol_private
*priv
= sym
->aux
;
2044 struct expression
*expr
= sym
->initializer
;
2045 struct storage
*new;
2048 new = x86_expression(expr
);
2050 new = stack_alloc(sym
->bit_size
/ 8);
2053 priv
= calloc(1, sizeof(*priv
));
2055 /* FIXME: leak! we don't free... */
2056 /* (well, we don't free symbols either) */
2062 static int type_is_signed(struct symbol
*sym
)
2064 if (sym
->type
== SYM_NODE
)
2065 sym
= sym
->ctype
.base_type
;
2066 if (sym
->type
== SYM_PTR
)
2068 return !(sym
->ctype
.modifiers
& MOD_UNSIGNED
);
2071 static struct storage
*x86_bitfield_expr(struct expression
*expr
)
2073 return x86_access(expr
);
2076 static struct storage
*x86_label_expr(struct expression
*expr
)
2078 struct storage
*new = stack_alloc(4);
2079 printf("\tmovi.%d\t\tv%d,.L%p\n", bits_in_pointer
, new->pseudo
, expr
->label_symbol
);
2083 static struct storage
*x86_statement_expr(struct expression
*expr
)
2085 return x86_statement(expr
->statement
);
2088 static int x86_position_expr(struct expression
*expr
, struct symbol
*base
)
2090 struct storage
*new = x86_expression(expr
->init_expr
);
2091 struct symbol
*ctype
= expr
->init_sym
;
2093 printf("\tinsert v%d at [%d:%d] of %s\n", new->pseudo
,
2094 expr
->init_offset
, ctype
->bit_offset
,
2095 show_ident(base
->ident
));
2099 static void x86_initializer_expr(struct expression
*expr
, struct symbol
*ctype
)
2101 struct expression
*entry
;
2103 FOR_EACH_PTR(expr
->expr_list
, entry
) {
2104 // Nested initializers have their positions already
2105 // recursively calculated - just output them too
2106 if (entry
->type
== EXPR_INITIALIZER
) {
2107 x86_initializer_expr(entry
, ctype
);
2111 // Ignore initializer indexes and identifiers - the
2112 // evaluator has taken them into account
2113 if (entry
->type
== EXPR_IDENTIFIER
|| entry
->type
== EXPR_INDEX
)
2115 if (entry
->type
== EXPR_POS
) {
2116 x86_position_expr(entry
, ctype
);
2119 x86_initialization(ctype
, entry
);
2124 * Print out an expression. Return the pseudo that contains the
2127 static struct storage
*x86_expression(struct expression
*expr
)
2133 struct position
*pos
= &expr
->pos
;
2134 printf("\tno type at %s:%d:%d\n",
2135 input_streams
[pos
->stream
].name
,
2136 pos
->line
, pos
->pos
);
2140 switch (expr
->type
) {
2142 return x86_call_expression(expr
);
2144 case EXPR_ASSIGNMENT
:
2145 return x86_assignment(expr
);
2148 return emit_compare(expr
);
2152 return emit_binop(expr
);
2154 return x86_preop(expr
);
2156 return emit_postop(expr
);
2158 return emit_symbol_expr_init(expr
->symbol
);
2162 warn(expr
->pos
, "invalid expression after evaluation");
2165 return emit_cast_expr(expr
);
2167 return emit_value(expr
);
2169 return emit_string_expr(expr
);
2171 return x86_bitfield_expr(expr
);
2172 case EXPR_INITIALIZER
:
2173 x86_initializer_expr(expr
, expr
->ctype
);
2176 return emit_select_expr(expr
);
2177 case EXPR_CONDITIONAL
:
2178 return emit_conditional_expr(expr
);
2179 case EXPR_STATEMENT
:
2180 return x86_statement_expr(expr
);
2182 return x86_label_expr(expr
);
2184 // None of these should exist as direct expressions: they are only
2185 // valid as sub-expressions of initializers.
2187 warn(expr
->pos
, "unable to show plain initializer position expression");
2189 case EXPR_IDENTIFIER
:
2190 warn(expr
->pos
, "unable to show identifier expression");
2193 warn(expr
->pos
, "unable to show index expression");
2196 warn(expr
->pos
, "unable to show type expression");
2199 warn(expr
->pos
, "floating point support is not implemented");